From 386074fd3ffd04ae21cb914dc84969c9fd981c5e Mon Sep 17 00:00:00 2001 From: kutayboz Date: Fri, 9 Jun 2023 02:02:07 +0300 Subject: Overhaul. Created bg96 lib. --- CMakeLists.txt | 6 +- include/bg96.h | 16 ++++ include/gpio.h | 4 +- include/serial.h | 3 +- src/bg96.c | 262 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gpio.c | 8 +- src/main.c | 131 +++++++--------------------- src/serial.c | 7 +- 8 files changed, 328 insertions(+), 109 deletions(-) create mode 100644 include/bg96.h create mode 100644 src/bg96.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 141e300..382b534 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,11 @@ 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_include_directories(bg96 PUBLIC ./include) + target_include_directories(network_monitor PUBLIC ./include) -target_link_libraries(network_monitor gpio serial) +target_link_libraries(network_monitor gpio serial bg96) install(TARGETS network_monitor DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin/) diff --git a/include/bg96.h b/include/bg96.h new file mode 100644 index 0000000..116b4ab --- /dev/null +++ b/include/bg96.h @@ -0,0 +1,16 @@ +#ifndef __INCLUDE_BG96__ +#define __INCLUDE_BG96__ + +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 waitForConnection(char *pathToPort, int waitTimeSeconds); + +int tcpipInit(char *pathToPort); + +int tcpipClose(char *pathToPort); + +#endif diff --git a/include/gpio.h b/include/gpio.h index e90a374..4faf2b1 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -1,8 +1,8 @@ #ifndef __INCLUDE_GPIO__ #define __INCLUDE_GPIO__ -int modemPowerToggle(int pinNumber); +int modemPowerToggle(char *pathToChip, int pinNum); -int checkPinVal(int pinNum); +int checkPinVal(char *pathToChip, int pinNum); #endif diff --git a/include/serial.h b/include/serial.h index a4ccb35..ccf0c6e 100644 --- a/include/serial.h +++ b/include/serial.h @@ -3,6 +3,7 @@ int openSerialPort(char pathToPort[]); -int querySerialPort(char **output, int serialPort, char *input); +int querySerialPort(char **output, int serialPort, char *input, + int timeoutSeconds); #endif diff --git a/src/bg96.c b/src/bg96.c new file mode 100644 index 0000000..3ef5b90 --- /dev/null +++ b/src/bg96.c @@ -0,0 +1,262 @@ +#include "gpio.h" +#include "serial.h" +#include +#include +#include +#include +#include + +int powerOn(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin) { + int moduleStatus, serialPort; + char *response; + time_t pwrKeyTime; + + moduleStatus = checkPinVal(pathToChip, statusPin); + if (0 > moduleStatus) { + printf("Error checkPinVal()\n"); + return 1; + } else if (moduleStatus == 1) { + printf("Module is already on\n"); + return 1; + } else if (0 != modemPowerToggle(pathToChip, pwrKeyPin)) { + printf("Error toggling modem power\n"); + return 1; + } + pwrKeyTime = time(NULL); + while (!checkPinVal(pathToChip, statusPin)) { + sleep(1); + if (time(NULL) - pwrKeyTime > 10) { + printf("Error: Modem status pin did not switch on before 10s\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", 10)) { + printf("Error querying serial port\n"); + free(response); + close(serialPort); + return 1; + } + if (NULL == strstr(response, "\r\nOK\r\n")) { + printf("Module responded not OK. Response:\n%s\n", response); + free(response); + close(serialPort); + return 1; + } + + free(response); + close(serialPort); + return 0; +} + +int powerOff(char *pathToPort, char *pathToChip, int statusPin, int pwrKeyPin) { + int serialPort; + char *response; + time_t timePowdCmd, timePwrKey; + + 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)) { + printf("Error querying serial port\n"); + free(response); + close(serialPort); + return 1; + } + free(response); + close(serialPort); + + timePowdCmd = timePwrKey = time(NULL); + while (checkPinVal(pathToChip, statusPin)) { + sleep(1); + if (time(NULL) - timePowdCmd > 24) { + printf("Could not switch modem off\n"); + return 1; + } else if (time(NULL) - timePwrKey > 12) { + printf("Error: Modem status pin did not switch off after 12s\nUsing " + "power key\n"); + if (0 != modemPowerToggle(pathToChip, pwrKeyPin)) { + printf("Error toggling modem power\n"); + return 1; + } + timePwrKey = time(NULL); + } + } + + return 0; +} + +int setupPublicConnection(char *pathToPort) { + unsigned long idx; + int serialPort; + char *response = malloc(sizeof(char)), + *cmdList[] = {"AT+QCFG=\"nwscanmode\",3,1", "AT+QCFG=\"iotopmode\",1,1", + "AT+QCFG=\"band\",F,400A0E189F,A0E189F,1", + "AT+QCFG=\"servicedomain\",1,1", "AT+COPS=0"}; + + serialPort = openSerialPort(pathToPort); + if (0 > serialPort) { + printf("Error opening serial port %s\n", pathToPort); + free(response); + return 1; + } + + for (idx = 0; idx < sizeof(cmdList) / sizeof(*cmdList); idx++) { + if (0 != querySerialPort(&response, serialPort, cmdList[idx], 20)) { + printf("Error querySerialPort()\n"); + close(serialPort); + free(response); + return 1; + } + if (NULL == strstr(response, "\r\nOK\r\n")) { + printf("Module responded not OK. Response:\n%s\n", response); + 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; + time_t startTime; + + serialPort = openSerialPort(pathToPort); + if (0 > serialPort) { + printf("Error opening serial port %s\n", pathToPort); + free(response); + return 1; + } + + startTime = time(NULL); + do { + if (0 != querySerialPort(&response, serialPort, "AT+COPS?", 180)) { + printf("Error querySerialPort()\n"); + close(serialPort); + free(response); + return 1; + } + strPtr = strstr(response, "+COPS: "); + if (waitTimeSeconds - (time(NULL) - startTime) < refreshPeriodSeconds) { + printf("Connection takes longer than %d seconds to initiate\n", + waitTimeSeconds); + close(serialPort); + free(response); + return 1; + } + sleep(refreshPeriodSeconds); + } while (!strchr(strPtr, ',')); + + close(serialPort); + free(response); + return 0; +} + +int tcpipInit(char *pathToPort) { + int serialPort; + char *response = malloc(sizeof(char)), *responseCpy, *strToken; + time_t startTime; + + serialPort = openSerialPort(pathToPort); + if (0 > serialPort) { + printf("Error opening serial port %s\n", pathToPort); + free(response); + 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); + 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"); + 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"); + 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"); + close(serialPort); + free(response); + return 1; + } + } + + close(serialPort); + free(response); + return 0; +} + +int tcpipClose(char *pathToPort) { + int serialPort; + char *response = malloc(sizeof(char)); + + serialPort = openSerialPort(pathToPort); + if (0 > serialPort) { + printf("Error opening serial port %s\n", pathToPort); + free(response); + return 1; + } + + if (0 != querySerialPort(&response, serialPort, "AT+QIDEACT=1", 40)) { + printf("Error querySerialPort()\n"); + close(serialPort); + free(response); + return 1; + } + + return 0; +} diff --git a/src/gpio.c b/src/gpio.c index 74d37ef..fd46fc7 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -2,11 +2,11 @@ #include #include -int modemPowerToggle(int pinNum) { +int modemPowerToggle(char *pathToChip, int pinNum) { struct gpiod_chip *chip; struct gpiod_line *line; - chip = gpiod_chip_open("/dev/gpiochip0"); + chip = gpiod_chip_open(pathToChip); if (!chip) { perror("Error opening GPIO chip"); return 1; @@ -43,12 +43,12 @@ int modemPowerToggle(int pinNum) { return 0; } -int checkPinVal(int pinNum) { +int checkPinVal(char *pathToChip, int pinNum) { int pinVal = -1; struct gpiod_chip *chip; struct gpiod_line *line; - chip = gpiod_chip_open("/dev/gpiochip0"); + chip = gpiod_chip_open(pathToChip); if (!chip) { perror("Error opening GPIO chip"); return -1; diff --git a/src/main.c b/src/main.c index 4f68637..08363b6 100644 --- a/src/main.c +++ b/src/main.c @@ -4,12 +4,13 @@ #include #include -#include -#include +#include "bg96.h" -int main() { +#define PATH_TO_SERIAL_PORT "/dev/serial0" +#define PATH_TO_GPIO_CHIP "/dev/gpiochip0" - char /* *commandList[] = {"AT", +int main() { + /* char *commandList[] = {"AT", "ATI", "AT+QCFG=\"nwscanmode\"", "AT+QCFG=\"iotopmode\"", @@ -20,15 +21,15 @@ int main() { "AT+QNWINFO", "AT+QCSQ", "AT+QSPN", - "AT+CCLK?"}, */ - /* *cmdList5GTNCfg[] = {"AT+QCFG=\"servicedomain\",1", - "AT+QCFG=\"iotopmode\",1", - "AT+QCFG=\"nwscanmode\",3", - "AT+QCFG=\"band\",0,8000000,8000000,1", - "AT+QICSGP=1,1,\"5gtnouluiot\",\"\",\"\",0", - "AT+CGDCONT=1,\"IP\",\"5gtnouluiot\""}, */ - *cmdList5GTNConnectAndPing[] = - {"AT+COPS=1,2,\"24427\",9", + "AT+CCLK?"}, + *cmdList5GTNCfg[] = {"AT+QCFG=\"servicedomain\",1", + "AT+QCFG=\"iotopmode\",1", + "AT+QCFG=\"nwscanmode\",3", + "AT+QCFG=\"band\",0,8000000,8000000,1", + "AT+QICSGP=1,1,\"5gtnouluiot\",\"\",\"\",0", + "AT+CGDCONT=1,\"IP\",\"5gtnouluiot\""}, + *cmdList5GTNConnectAndPing[] = { + "AT+COPS=1,2,\"24427\",9", "AT+CGATT=1", "AT+QHTTPCFG=\"contextid\",1", "AT+QHTTPCFG=\"responseheader\",1", @@ -36,111 +37,45 @@ int main() { "AT+QIACT=1", "AT+QPING=1,\"https://www.google.fi\"", "AT+QPING=1,\"www.google.fi\"", - "AT+QPING=1,\"8.8.8.8\""}, - serialFilePath[] = "/dev/serial0", *output; - - int serialPort, moduleStatus; - unsigned long idx; - time_t pwrKeyTime; + "AT+QPING=1,\"8.8.8.8\""}; */ - moduleStatus = checkPinVal(27); - if (0 > moduleStatus) { - printf("Error checkPinVal()\n"); + if (0 != powerOn(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, 27, 17)) { + printf("Error powering the module on\n"); return 1; - } else if (moduleStatus == 0) { - printf("Module is off\nPowering on\n"); - if (0 != modemPowerToggle(17)) { - printf("Error toggling modem power\n"); - return 1; - } - pwrKeyTime = time(NULL); - while (!checkPinVal(27)) { - sleep(1); - if (time(NULL) - pwrKeyTime > 10) { - printf("Modem power on takes longer than 10s\nAborting\n"); - return 1; - } - } - sleep(5); /* Wait for APP RDY*/ } - serialPort = openSerialPort(serialFilePath); - if (serialPort < 0) { - printf("Error openSerialPort()\n"); + if (0 != setupPublicConnection(PATH_TO_SERIAL_PORT)) { + printf("Error setting public network configuration\n"); return 1; } - output = malloc(1); - /* for (idx = 0; idx < sizeof(commandList) / sizeof(*commandList); idx++) { - if (0 != querySerialPort(&output, serialPort, commandList[idx])) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(output); - return 1; - } - printf("%s\n", output); - } */ - - /* for (idx = 0; idx < sizeof(cmdList5GTNCfg) / sizeof(*cmdList5GTNCfg); - idx++) { if (0 != querySerialPort(&output, serialPort, cmdList5GTNCfg[idx])) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(output); - return 1; - } - printf("%s\n", output); - } - - printf("Rebooting\n"); - if (0 != modemPowerToggle(17)) { - printf("Error toggling modem power\n"); - return 1; - } - sleep(5); - if (0 != modemPowerToggle(17)) { - printf("Error toggling modem power\n"); + if (0 != waitForConnection(PATH_TO_SERIAL_PORT, 120)) { + printf("Error while waiting for connection\n"); return 1; } - pwrKeyTime = time(NULL); - while (!checkPinVal(27)) { - sleep(1); - if (time(NULL) - pwrKeyTime > 10) { - printf("Modem power on takes longer than 10s\nAborting\n"); + + if (0 != tcpipInit(PATH_TO_SERIAL_PORT)) { + printf("Error initiating TCP/IP context\nPowering off\n"); + if (0 != powerOff(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, 27, 17)) { + printf("Error powering the module off\n"); return 1; } + return 1; } - sleep(5);*/ - for (idx = 0; idx < sizeof(cmdList5GTNConnectAndPing) / - sizeof(*cmdList5GTNConnectAndPing); - idx++) { - if (0 != - querySerialPort(&output, serialPort, cmdList5GTNConnectAndPing[idx])) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(output); + 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, 27, 17)) { + printf("Error powering the module off\n"); return 1; } - printf("%s\n", output); - } - - if (0 != querySerialPort(&output, serialPort, "AT+QIACT=0")) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(output); return 1; } - printf("%s\n", output); - if (0 != querySerialPort(&output, serialPort, "AT+CGATT=0")) { - printf("Error querySerialPort()\n"); - close(serialPort); - free(output); + if (0 != powerOff(PATH_TO_SERIAL_PORT, PATH_TO_GPIO_CHIP, 27, 17)) { + printf("Error powering the module off\n"); return 1; } - printf("%s\n", output); - close(serialPort); - free(output); return 0; } diff --git a/src/serial.c b/src/serial.c index 8456e68..88e9a4c 100644 --- a/src/serial.c +++ b/src/serial.c @@ -57,7 +57,8 @@ int openSerialPort(char pathToPort[]) { return serialPort; } -int querySerialPort(char **output, int serialPort, char *input) { +int querySerialPort(char **output, int serialPort, char *input, + int timeoutSeconds) { time_t timeStart; unsigned long idx; @@ -104,8 +105,8 @@ int querySerialPort(char **output, int serialPort, char *input) { break; } } - } else if (bytesRead == 0 && time(NULL) - timeStart > 180) { - printf("Response timeout after 180 seconds\n"); + } else if (bytesRead == 0 && time(NULL) - timeStart > timeoutSeconds) { + printf("Response timeout after %d seconds\n", timeoutSeconds); returnCode = 1; break; } -- cgit v1.3