OK, I am having a bit of an issue here.
I would like to be able to set the APN for used with a 3rd party SIM stored in the emulated EEPROM section in an Electron. This design was chosen so that I would not be tieing the firmware that I may deploy in the future to a specific APN that is hard-coded in.
To further complication that, the electron needs to start up, pause briefly to see if a connection is made quickly, but otherwise progress on and continue the rest of its tasks (display, calculation) without a connection.
The issue that I am having is that the APN is apparently not set correctly, even though the correct APN is being loaded from EEPROM and set with cellular_credentials_set. The cell connection is never made.
If I flash the exact same firmware but using the STARTUP line with the hard-coded APN and the EEPROM one commented, then the Electron does connect properly.
What is going wrong here?
Dammit, as I am writing this, I do now realize that I am not verifying that the credentials have been set with cellular_credentials_get, and there is indeed a TODO in cellular_hal_constants.h about string storage :\
I’ll try it in hardware tomorrow morning, but just looking at it now my reading is that the fields of CellularCredentials will end up pointing to the autovar EEPROM data struct in set_APN_from_eeprom(), whose lifetime is limited.
Doing it the hard-coded way gives us a global scope string literal with forever lifetime.
The only workarounds I see are: using the absolute flash address for EEPROM to refer to the string literal there, or using a static struct in set_APN_from_eeprom() and keeping a RAM copy of the EEPROM data.
The code is summarized as:
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
STARTUP(set_APN_from_eeprom()); //APN from eeprom
//STARTUP(cellular_credentials_set("my.apn.com","","",NULL); //alternate hard coded APN
void set_APN_from_eeprom(){
eeprom_data_t eeprom; //structure
EPROM.get(0, eeprom);
print_eeprom_data_contents(&eeprom);
cellular_credentials_set(eeprom.apn, eeprom.apn_username, eeprom.apn_password, NULL);
}
void setup(){
//stuff
Particle.connect();
}
void loop(){
display_loop();
calculation_loop();
if(Particle.connected()){
open_socket();
}
}