summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--include/bg96.h9
-rw-r--r--include/serial.h6
-rw-r--r--src/bg96.c248
-rw-r--r--src/main.c77
-rw-r--r--src/serial.c31
6 files changed, 273 insertions, 100 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 382b534..43f5ea5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,7 +14,7 @@ target_link_libraries(gpio gpiod)
add_library(serial STATIC ./src/serial.c ./include/serial.h)
add_library(bg96 STATIC ./src/bg96.c ./include/bg96.h)
-target_link_libraries(bg96 serial gpio)
+target_link_libraries(bg96 serial gpio m)
target_include_directories(bg96 PUBLIC ./include)
target_include_directories(network_monitor PUBLIC ./include)
diff --git a/include/bg96.h b/include/bg96.h
index 116b4ab..b304479 100644
--- a/include/bg96.h
+++ b/include/bg96.h
@@ -5,12 +5,13 @@ int powerOn(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin);
int powerOff(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin);
-int setupPublicConnection(char *pathToPort);
+int cfgPublicNetwork(char *pathToPort);
-int waitForConnection(char *pathToPort, int waitTimeSeconds);
+int waitForNetwork(char *pathToPort, int waitTimeSeconds);
-int tcpipInit(char *pathToPort);
+int mqttDisc(char *pathToPort);
-int tcpipClose(char *pathToPort);
+int mqttConn(char *pathToPort, char *hostURL, int hostPort, char *username,
+ char *password);
#endif
diff --git a/include/serial.h b/include/serial.h
index ccf0c6e..033fd54 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -1,9 +1,11 @@
#ifndef __INCLUDE_SERIAL__
#define __INCLUDE_SERIAL__
+typedef enum { SUCCESS, ERROR_READ, ERROR_TIMEOUT } SERIAL_RETURN_CODE;
+
int openSerialPort(char pathToPort[]);
-int querySerialPort(char **output, int serialPort, char *input,
- int timeoutSeconds);
+SERIAL_RETURN_CODE querySerialPort(char **output, int serialPort, char *input,
+ int timeoutSeconds, char *lastLineSubStr);
#endif
diff --git a/src/bg96.c b/src/bg96.c
index 3ef5b90..de874c4 100644
--- a/src/bg96.c
+++ b/src/bg96.c
@@ -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;
}
diff --git a/src/main.c b/src/main.c
index 7d7a575..8293426 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
}
}