diff options
| author | kutayboz <kutayboz@gmail.com> | 2023-06-12 00:16:46 +0300 |
|---|---|---|
| committer | kutayboz <kutayboz@gmail.com> | 2023-06-12 00:16:46 +0300 |
| commit | 15b34952c44f19e6e31d81096c6ee43b6f1a201d (patch) | |
| tree | 2c3096e72bc3a6de20757d67185a0e7cbdbb9671 /src | |
| parent | c516904d94603631a1abccc7525e00c9c35533f8 (diff) | |
| download | celnetmon-15b34952c44f19e6e31d81096c6ee43b6f1a201d.tar.gz | |
Working MQTT publishing
Diffstat (limited to 'src')
| -rw-r--r-- | src/bg96.c | 248 | ||||
| -rw-r--r-- | src/main.c | 77 | ||||
| -rw-r--r-- | src/serial.c | 31 |
3 files changed, 263 insertions, 93 deletions
@@ -1,5 +1,6 @@ #include "gpio.h" #include "serial.h" +#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -37,7 +38,7 @@ int powerOn(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin) { return 1; } response = malloc(sizeof(char)); - if (0 != querySerialPort(&response, serialPort, "AT", 10)) { + if (0 != querySerialPort(&response, serialPort, "AT", 10, NULL)) { printf("Error querying serial port\n"); free(response); close(serialPort); @@ -56,17 +57,27 @@ int powerOn(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin) { } int powerOff(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin) { - int serialPort; + int serialPort, moduleStatus; char *response; time_t timePowdCmd, timePwrKey; + moduleStatus = checkPinVal(pathToChip, statusPin); + if (0 > moduleStatus) { + printf("Error checkPinVal()\n"); + return 1; + } else if (moduleStatus == 0) { + printf("Module is already off\n"); + return 1; + } + serialPort = openSerialPort(pathToPort); if (0 > serialPort) { printf("Error opening serial port %s\n", pathToPort); return 1; } response = malloc(sizeof(char)); - if (0 != querySerialPort(&response, serialPort, "AT+QPOWD", 20)) { + if (0 != + querySerialPort(&response, serialPort, "AT+QPOWD", 20, "POWERED DOWN")) { printf("Error querying serial port\n"); free(response); close(serialPort); @@ -95,7 +106,7 @@ int powerOff(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin) { return 0; } -int setupPublicConnection(char *pathToPort) { +int cfgPublicNetwork(char *pathToPort) { unsigned long idx; int serialPort; char *response = malloc(sizeof(char)), @@ -111,7 +122,7 @@ int setupPublicConnection(char *pathToPort) { } for (idx = 0; idx < sizeof(cmdList) / sizeof(*cmdList); idx++) { - if (0 != querySerialPort(&response, serialPort, cmdList[idx], 20)) { + if (0 != querySerialPort(&response, serialPort, cmdList[idx], 20, NULL)) { printf("Error querySerialPort()\n"); close(serialPort); free(response); @@ -125,14 +136,34 @@ int setupPublicConnection(char *pathToPort) { } } + if (0 != querySerialPort(&response, serialPort, "AT+CPIN?", 2, NULL)) { + printf("Error querySerialPort()\n"); + close(serialPort); + free(response); + return 1; + } else if (NULL == strstr(response, "+CPIN: READY")) { + printf("(U)SIM not ready\nResponse:\n%s\n", response); + close(serialPort); + free(response); + return 1; + } + + if (0 != querySerialPort(&response, serialPort, + "AT+QICSGP=1,1,\"internet\",\"\",\"\",1", 5, NULL)) { + printf("Error querySerialPort()\n"); + close(serialPort); + free(response); + return 1; + } + close(serialPort); free(response); return 0; } -int waitForConnection(char *pathToPort, int waitTimeSeconds) { - int serialPort, refreshPeriodSeconds = 2; - char *response = malloc(sizeof(char)), *strPtr; +int waitForNetwork(char *pathToPort, int waitTimeSeconds) { + int serialPort, refreshPeriodSeconds = 1; + char *response = malloc(sizeof(char)), *responseCpy, *strPtr; time_t startTime; serialPort = openSerialPort(pathToPort); @@ -144,7 +175,7 @@ int waitForConnection(char *pathToPort, int waitTimeSeconds) { startTime = time(NULL); do { - if (0 != querySerialPort(&response, serialPort, "AT+COPS?", 180)) { + if (0 != querySerialPort(&response, serialPort, "AT+COPS?", 180, NULL)) { printf("Error querySerialPort()\n"); close(serialPort); free(response); @@ -161,15 +192,34 @@ int waitForConnection(char *pathToPort, int waitTimeSeconds) { sleep(refreshPeriodSeconds); } while (!strchr(strPtr, ',')); + responseCpy = malloc(sizeof(char)); + startTime = time(NULL); + while (1) { + if (0 != querySerialPort(&response, serialPort, "AT+CEREG?", 2, NULL)) { + printf("Error querySerialPort()\n"); + close(serialPort); + free(responseCpy); + free(response); + return 1; + } + responseCpy = realloc(responseCpy, sizeof(char) * (strlen(response) + 1)); + strncpy(responseCpy, response, strlen(response) + 1); + strPtr = strtok(response, ","); + strPtr = strtok(NULL, ","); + if (NULL != strpbrk(strPtr, "15") || time(NULL) - startTime > 60) + break; + sleep(1); + } + free(responseCpy); + close(serialPort); free(response); return 0; } -int tcpipInit(char *pathToPort) { +int mqttDisc(char *pathToPort) { int serialPort; - char *response = malloc(sizeof(char)), *responseCpy, *strToken; - time_t startTime; + char *response = malloc(sizeof(char)); serialPort = openSerialPort(pathToPort); if (0 > serialPort) { @@ -178,57 +228,32 @@ int tcpipInit(char *pathToPort) { return 1; } - if (0 != querySerialPort(&response, serialPort, "AT+CPIN?", 5)) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(response); - return 1; - } - if (NULL == strstr(response, "+CPIN: READY")) { - printf("(U)SIM not ready\nResponse:\n%s\n", response); + if (0 != querySerialPort(&response, serialPort, "AT+QMTCONN?", 2, NULL)) { + printf("Error querying AT+QMTCONN?\n"); close(serialPort); free(response); return 1; } - - responseCpy = malloc(sizeof(char)); - startTime = time(NULL); - while (1) { - if (0 != querySerialPort(&response, serialPort, "AT+CEREG?", 5)) { - printf("Error querySerialPort()\n"); + if (NULL != strstr(response, "\r\n+QMTCONN: 0,")) { + if (0 != querySerialPort(&response, serialPort, "AT+QMTDISC=0", 60, + "+QMTDISC:")) { + printf("Error querying AT+QMTDISC=0\n"); close(serialPort); - free(responseCpy); free(response); return 1; } - responseCpy = realloc(responseCpy, sizeof(char) * (strlen(response) + 1)); - strncpy(responseCpy, response, strlen(response) + 1); - strToken = strtok(response, ","); - strToken = strtok(NULL, ","); - if (NULL != strpbrk(strToken, "15") || time(NULL) - startTime > 60) - break; - sleep(1); - } - free(responseCpy); - - if (0 != querySerialPort(&response, serialPort, - "AT+QICSGP=1,1,\"internet\",\"\",\"\",1", 5)) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(response); - return 1; } - if (0 != querySerialPort(&response, serialPort, "AT+QIACT=1", 150)) { - printf("Error querySerialPort()\n"); + if (0 != querySerialPort(&response, serialPort, "AT+QMTOPEN?", 2, NULL)) { + printf("Error querying AT+QMTOPEN?\n"); close(serialPort); free(response); return 1; } - if (NULL == strstr(response, "\r\nOK\r\n")) { - printf("Failed to activate PDP context\nDeactivating\n"); - if (0 != querySerialPort(&response, serialPort, "AT+QIDEACT=1", 40)) { - printf("Error querySerialPort()\n"); + if (NULL != strstr(response, "\r\n+QMTOPEN: 0,")) { + if (0 != querySerialPort(&response, serialPort, "AT+QMTCLOSE=0", 2, + "+QMTCLOSE:")) { + printf("Error querying AT+QMTCLOSE=0\n"); close(serialPort); free(response); return 1; @@ -240,23 +265,128 @@ int tcpipInit(char *pathToPort) { return 0; } -int tcpipClose(char *pathToPort) { - int serialPort; - char *response = malloc(sizeof(char)); +int mqttConn(char *pathToPort, char *hostURL, int hostPort, char *username, + char *password) { + int serialPort, cmdStrLen, msgID, msgSize; + unsigned long idx; + char *response = malloc(sizeof(char)), *command, clientID[11], + topic[] = "kboz/feeds/numdata", msg[] = "0"; + + srand(time(NULL)); + for (idx = 0; idx < sizeof(clientID) - 1; idx++) { + clientID[idx] = '0' + rand() % 10; + } + clientID[sizeof(clientID) - 1] = '\0'; serialPort = openSerialPort(pathToPort); if (0 > serialPort) { printf("Error opening serial port %s\n", pathToPort); - free(response); - return 1; + goto mqttConnError4; } - if (0 != querySerialPort(&response, serialPort, "AT+QIDEACT=1", 40)) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(response); - return 1; + if (SUCCESS != querySerialPort(&response, serialPort, + "AT+QMTCFG=\"version\",0,4", 2, NULL)) { + printf("Error querying AT+QMTCFG=\"version\",0,4\n"); + goto mqttConnError3; } + if (SUCCESS != querySerialPort(&response, serialPort, + "AT+QMTCFG=\"pdpcid\",0,1", 2, NULL)) { + printf("Error querying AT+QMTCFG=\"pdpcid\",0,1\n"); + goto mqttConnError3; + } + + if (SUCCESS != querySerialPort(&response, serialPort, + "AT+QMTCFG=\"timeout\",0,5,3,0", 2, NULL)) { + printf("Error configuring MQTT package timeout\n"); + goto mqttConnError3; + } + + if (SUCCESS != querySerialPort(&response, serialPort, + "AT+QMTCFG=\"ssl\",0,1,0", 2, NULL)) { + printf("Error querying AT+QMTCFG=\"ssl\",0,1,0\n"); + goto mqttConnError3; + } + + cmdStrLen = strlen("AT+QMTOPEN=0") + strlen(hostURL) + + (int)(1 + ceil(log10(hostPort))) + 5; + command = malloc(sizeof(char) * (cmdStrLen)); + snprintf(command, cmdStrLen - 1, "AT+QMTOPEN=0,\"%s\",%d", hostURL, hostPort); + if (SUCCESS != + querySerialPort(&response, serialPort, command, 75, "+QMTOPEN:")) { + printf("Error querying %s\n", command); + goto mqttConnError2; + } else if (NULL == strstr(response, "+QMTOPEN: 0,0")) { + printf("Failed to establish network for MQTT connection\n"); + goto mqttConnError2; + } + + if (username == NULL) { + cmdStrLen = strlen("AT+QMTCONN=0") + strlen(clientID) + 9; + command = realloc(command, sizeof(char) * (cmdStrLen + 1)); + snprintf(command, cmdStrLen + 1, "AT+QMTCONN=0,\"%s\"", clientID); + } else if (password == NULL) { + cmdStrLen = + strlen("AT+QMTCONN=0") + strlen(clientID) + strlen(username) + 9; + command = realloc(command, sizeof(char) * (cmdStrLen + 1)); + snprintf(command, cmdStrLen + 1, "AT+QMTCONN=0,\"%s\",\"%s\"", clientID, + username); + } else { + cmdStrLen = strlen("AT+QMTCONN=0") + strlen(clientID) + strlen(username) + + strlen(password) + 9; + command = realloc(command, sizeof(char) * (cmdStrLen + 1)); + snprintf(command, cmdStrLen + 1, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"", + clientID, username, password); + } + if (SUCCESS != + querySerialPort(&response, serialPort, command, 70, "\r\n+QMT")) { + printf("Failed to query %s", command); + goto mqttConnError1; + } else if (NULL == strstr(response, "\r\nOK\r\n")) { + printf("Error with command. Response:\n%s\n", response); + goto mqttConnError1; + } else if (NULL != strstr(response, "+QMTSTAT:")) { + printf("Dropped from network. Response:\n%s\n", response); + goto mqttConnError2; + } else if (NULL == strstr(response, "+QMTCONN: 0,0")) { + printf("Failed to establish connection. Response:\n%s\n", response); + goto mqttConnError1; + } + + msgSize = sizeof(char) * strlen(msg); + msgID = rand() % 65536; + cmdStrLen = strlen("AT+QMTPUB=0") + (int)ceil(log10(msgID)) + 1 + 1 + + strlen(topic) + (int)ceil(log10(msgSize)) + 8; + command = realloc(command, sizeof(char) * (cmdStrLen + 1)); + snprintf(command, cmdStrLen + 1, "AT+QMTPUB=0,%d,1,0,\"%s\",%d", msgID, topic, + msgSize); + if (SUCCESS != querySerialPort(&response, serialPort, command, 15, "\r\n>")) { + printf("Error publishing\n"); + goto mqttConnError1; + } else if (SUCCESS != + querySerialPort(&response, serialPort, msg, 15, "\r\n+QMTPUB:")) { + printf("Error publishing\n"); + goto mqttConnError1; + } + + free(command); + close(serialPort); + free(response); return 0; + +mqttConnError1: + free(command); + close(serialPort); + free(response); + if (0 != mqttDisc(pathToPort)) { + printf("Could not close network for MQTT. Reboot advised\n"); + } + return 1; +mqttConnError2: + free(command); +mqttConnError3: + close(serialPort); +mqttConnError4: + free(response); + return 1; } @@ -11,7 +11,7 @@ #define PIN_NUM_PWR_KEY 17 #define PIN_NUM_STATUS 27 -int main() { +int main(int argc, char **argv) { /* char *commandList[] = {"AT", "ATI", "AT+QCFG=\"nwscanmode\"", @@ -41,47 +41,74 @@ int main() { "AT+QPING=1,\"www.google.fi\"", "AT+QPING=1,\"8.8.8.8\""}; */ - if (0 != powerOn(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, PIN_NUM_STATUS, - PIN_NUM_PWR_KEY)) { - printf("Error powering the module on\n"); + if (argc == 1) { + printf("No arguments provided\n"); return 1; } - if (0 != setupPublicConnection(PATH_TO_SERIAL_PORT)) { - printf("Error setting public network configuration\n"); - return 1; - } + else if (0 == strcmp(argv[1], "--init")) { - if (0 != waitForConnection(PATH_TO_SERIAL_PORT, 120)) { - printf("Error while waiting for connection\n"); - return 1; + if (0 != powerOn(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, PIN_NUM_STATUS, + PIN_NUM_PWR_KEY)) { + printf("Error powering the module on\n"); + return 1; + } + + if (0 != cfgPublicNetwork(PATH_TO_SERIAL_PORT)) { + printf("Error setting public network configuration\n"); + return 1; + } + + if (0 != waitForNetwork(PATH_TO_SERIAL_PORT, 120)) { + printf("Error while waiting for network\n"); + return 1; + } + + return 0; } - if (0 != tcpipInit(PATH_TO_SERIAL_PORT)) { - printf("Error initiating TCP/IP context\nPowering off\n"); + else if (0 == strcmp(argv[1], "--stop")) { + if (0 != mqttDisc(PATH_TO_SERIAL_PORT)) { + printf("Could not disconnect MQTT\n"); + } if (0 != powerOff(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, PIN_NUM_STATUS, PIN_NUM_PWR_KEY)) { printf("Error powering the module off\n"); return 1; } - return 1; + return 0; } - if (0 != tcpipClose(PATH_TO_SERIAL_PORT)) { - printf("Error closing TCP/IP context\nPowering off\n"); - if (0 != powerOff(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, PIN_NUM_STATUS, - PIN_NUM_PWR_KEY)) { - printf("Error powering the module off\n"); + else if (0 == strcmp(argv[1], "--mqttTest")) { + + if (0 != mqttConn(PATH_TO_SERIAL_PORT, "io.adafruit.com", 8883, "kboz", + "aio_eSpl61DrIZEisg3qXNN1NvMUSQdd")) { + printf("Error connecting MQTT\n"); return 1; } - return 1; + + /* if (0 != mqttConn(PATH_TO_SERIAL_PORT, + "29038f72a9d84f18940e0d44daffa687.s2.eu.hivemq.cloud", + 8883, "rpi5gtn", "Raspi132.")) { + printf("Error connecting MQTT\n"); + return 1; + } */ + + /* if (0 != + mqttConn(PATH_TO_SERIAL_PORT, "broker.hivemq.com", 8883, NULL, NULL)) { + printf("Error connecting MQTT\n"); + return 1; + } */ + + if (0 != mqttDisc(PATH_TO_SERIAL_PORT)) { + printf("Could not disconnect MQTT\n"); + return 1; + } + return 0; } - if (0 != powerOff(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, PIN_NUM_STATUS, - PIN_NUM_PWR_KEY)) { - printf("Error powering the module off\n"); + else { + printf("Unknown arguments\n"); return 1; } - - return 0; } diff --git a/src/serial.c b/src/serial.c index 88e9a4c..3d668dd 100644 --- a/src/serial.c +++ b/src/serial.c @@ -9,6 +9,8 @@ #define BUFFER_SIZE sizeof(char) * 256 +typedef enum { SUCCESS, ERROR_READ, ERROR_TIMEOUT } SERIAL_RETURN_CODE; + int openSerialPort(char pathToPort[]) { static int serialPort; @@ -57,12 +59,13 @@ int openSerialPort(char pathToPort[]) { return serialPort; } -int querySerialPort(char **output, int serialPort, char *input, - int timeoutSeconds) { +SERIAL_RETURN_CODE querySerialPort(char **output, int serialPort, char *input, + int timeoutSeconds, char *lastLineSubStr) { time_t timeStart; unsigned long idx; - int bytesRead, returnCode, isEnd, beforeLength; + int bytesRead, isEnd, beforeLength; + SERIAL_RETURN_CODE returnCode; char *txBuffer, *buffer = malloc(BUFFER_SIZE); const char *responseCodes[8] = {"\r\nOK\r\n", "\r\nCONNECT\r\n", "\r\nRING\r\n", "\r\nNO CARRIER\r\n", @@ -83,13 +86,13 @@ int querySerialPort(char **output, int serialPort, char *input, *output = realloc(*output, sizeof(char)); **output = '\0'; bytesRead = 0; - returnCode = isEnd = 0; + returnCode = isEnd = SUCCESS; timeStart = time(NULL); while (!isEnd) { bytesRead = read(serialPort, buffer, BUFFER_SIZE); if (bytesRead < 0) { printf("Error reading serial port\n"); - returnCode = 1; + returnCode = ERROR_READ; break; } @@ -98,16 +101,26 @@ int querySerialPort(char **output, int serialPort, char *input, *output = realloc(*output, sizeof(char) * (beforeLength + 1) + bytesRead); memcpy(*output + beforeLength, buffer, bytesRead); (*output)[beforeLength + (bytesRead / sizeof(char))] = '\0'; - for (idx = 0; idx < sizeof(responseCodes) / sizeof(*responseCodes); - idx++) { - if (strstr(*output, responseCodes[idx])) { + if (lastLineSubStr != NULL) { + if (strstr(*output, lastLineSubStr) && + 0 == strcmp( + &(*output)[beforeLength + (bytesRead / sizeof(char)) - 2], + "\r\n")) { isEnd = 1; break; } + } else { + for (idx = 0; idx < sizeof(responseCodes) / sizeof(*responseCodes); + idx++) { + if (strstr(*output, responseCodes[idx])) { + isEnd = 1; + break; + } + } } } else if (bytesRead == 0 && time(NULL) - timeStart > timeoutSeconds) { printf("Response timeout after %d seconds\n", timeoutSeconds); - returnCode = 1; + returnCode = ERROR_TIMEOUT; break; } } |
