【Construction Monitoring and Security System】12. Kaluga parses the parameters recorded in the SD card file and connects to OneNET
[Copy link]
In my ninth article , I mentioned that the project needs to load configuration parameters from the SD card, mainly parsing the settings.txt file. The parameters are mainly divided into three aspects:
1) port is the TCP port number. In the whole project, the Kaluga board is the "host computer" of the gateway. It sends commands to the gateway through the TCP connection to control the gateway to start the wake-up and collection of the terminal (using LoRa self-organizing network).
port=Gateway's TCP Server port number
2) The next three lines are the time parameters for connecting to the gateway. Period indicates the interval in minutes to connect to the gateway, timeout is the timeout in seconds for the gateway to wake up a terminal, that is, the number of seconds after which it is determined that the terminal wake-up has failed, and repeat is the number of times the wake-up attempt is made after a terminal wake-up failure.
period = the time interval between two polls of all terminals (in minutes)
timeout=Timeout (in seconds) for requesting a terminal to not respond
repeat=Maximum number of times a terminal request fails
3) The next four lines are the parameters for MQTT to access the OneNET cloud platform, which are device ID, product ID, authentication information and APIKey.
deviceid=OneNET platform device ID
productid=OneNET platform product ID
authkey=OneNET platform authentication information (MQTT old version protocol)
OneNET Platform API Key
I have implemented OneNET access in my previous post , but the access parameters are hard-coded, so this post will read the configuration parameters of the settings.txt file in the SD card to build the access parameters of OneNET. The parameters read from the file are saved in the system global variables.
#defineMAX_EID 16 // Max endian number
/* Global variables ----------------------------------------------- */
int port= 2346; //Gateway tcp server port
int period= 10; //polling period (minutes)
int timeout= 8; //timeout of once request (second)
int repeat= 3; //repeat times when once fail
char deviceid[16]; //OneNET device id
char productid[16]; //OneNET product id
char authkey[16]; //OneNET authentication key (MQTT)
char apikey[32]; //OneNET APIKey
Let’s look at the function aita_StartMqtt() that connects to OneNET. The code is slightly modified:
Figure 12-1 Code modification of OneNET access parameters
However, after this modification, an error occurred in connecting to the platform, with the prompt being: username and password are incorrect.
Figure 12-2 OneNET access error
After analysis, I found that the parameters recorded in the settings.txt file are in the form of "parameter name = parameter value" (of course, the format is also customized). When parsing, the C library function strtok() is called to split the string with "=" as the reference. As a result, when the "parameter value" is saved as a string format, it contains a "space character" at the end. This means that if the device ID is "12345", the parsed value is "12345", so it will naturally report an error when connecting to OneNET.
Figure 12-3 Parsing string parameters with trailing spaces
The solution is to change the last extra "space character" to "\0". For example, if the ID is "12345", the length is 5, plus the space length is 6. The string array index starts at 0, so the space is at 5. Start trying the code as follows. Use strlen() to get the string length, and then subtract 1 to get the index to be modified.
deviceid[strlen(deviceid)-1] = '\0';
However, this change is still wrong. There is only one line of console output in the code, and the serial port output display also wraps.
Figure 12-4 Effect of changing the length -1 position to 0
Because I still don't know how to debug the Kaluga board ESP32S2, I can't check the actual value of the memory unit. Here I boldly speculate: "After parsing with the function strtok(), the end of the string may be inserted with a utf-8 character, or other characters that will be displayed as spaces, anyway, it takes up two bytes." So I modified the code again, that is, the position of the string length -2 was changed to 0, and it worked unexpectedly! (Of course, the specific reason is not clear unless you can debug).
deviceid[strlen(deviceid)-2] = '\0';
So I completely modified the function of reading and parsing settings.txt as follows. In fact, when parsing the last four lines of string type parameters, I added a statement that assigned the value of 0 to the end of a line (length - 2).
void readSettings(void) {
//open settings.txt for reading
ESP_LOGI(TAG, "Reading GateWay Settings file %s", file_settings);
FILE *f = fopen(file_settings, "r");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
//read lines
char line[32];
char *pos;
//line 1. tcp server port
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
pos = strtok(line, "=");
pos = strtok(NULL, "=");
port = atoi(pos);
//line 2. polling period(minute)
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
pos = strtok(line, "=");
pos = strtok(NULL, "=");
period = atoi(pos);
//line 3. timeout of once request(second)
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
pos = strtok(line, "=");
pos = strtok(NULL, "=");
timeout = atoi(pos);
//line 4. repeat times when once fail
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
pos = strtok(line, "=");
pos = strtok(NULL, "=");
repeat = atoi(pos);
//line 5. OneNET device id
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
pos = strtok(line, "=");
pos = strtok(NULL, "=");
memset(deviceid, 0, 16);
strcpy(deviceid, pos);
deviceid[strlen(deviceid)-2] = '\0';
//line 6. OneNET product id
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
pos = strtok(line, "=");
pos = strtok(NULL, "=");
memset(productid, 0, 16);
strcpy(productid, pos);
productid[strlen(productid)-2] = '\0';
//line 7. OneNET authentication key (MQTT)
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
pos = strtok(line, "=");
pos = strtok(NULL, "=");
memset(authkey, 0, 16);
strcpy(authkey, pos);
authkey[strlen(authkey)-2] = '\0';
//line 8. OneNET APIKey
fgets(line, sizeof(line), f);
ESP_LOGI(TAG, "%s", line);
memset(apikey, 0, 32);
strcpy(apikey, line);
apikey[strlen(apikey)-2] = '\0';
ESP_LOGI(TAG, "port:%d, period:%d, timeout:%d, repeat:%d",
port, period, timeout, repeat);
ESP_LOGI(TAG, "deviceid:%s, productid:%s", deviceid, productid);
ESP_LOGI(TAG, "authkey:%s, apikey:%s", authkey, apikey);
//close file
fclose(f);
}
|