diff options
| -rw-r--r-- | CMakeLists.txt | 8 | ||||
| -rw-r--r-- | include/gpio.h | 6 | ||||
| -rw-r--r-- | include/serial.h | 8 | ||||
| -rw-r--r-- | src/gpio.c | 44 | ||||
| -rw-r--r-- | src/main.c | 147 | ||||
| -rw-r--r-- | src/serial.c | 122 |
6 files changed, 216 insertions, 119 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a9a7334..c2bf1ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,4 +8,12 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g -O0") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O2") add_executable(network_monitor ./src/main.c) +add_library(gpio STATIC ./src/gpio.c ./include/gpio.h) +target_link_libraries(gpio gpiod) + +add_library(serial STATIC ./src/serial.c ./include/serial.h) + +target_include_directories(network_monitor PUBLIC ./include) +target_link_libraries(network_monitor gpio serial) + install(TARGETS network_monitor DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin/) diff --git a/include/gpio.h b/include/gpio.h new file mode 100644 index 0000000..7074d1e --- /dev/null +++ b/include/gpio.h @@ -0,0 +1,6 @@ +#ifndef __INCLUDE_GPIO__ +#define __INCLUDE_GPIO__ + +int modemPowerToggle(int pinNumber); + +#endif diff --git a/include/serial.h b/include/serial.h new file mode 100644 index 0000000..a4ccb35 --- /dev/null +++ b/include/serial.h @@ -0,0 +1,8 @@ +#ifndef __INCLUDE_SERIAL__ +#define __INCLUDE_SERIAL__ + +int openSerialPort(char pathToPort[]); + +int querySerialPort(char **output, int serialPort, char *input); + +#endif diff --git a/src/gpio.c b/src/gpio.c new file mode 100644 index 0000000..0ccfd6b --- /dev/null +++ b/src/gpio.c @@ -0,0 +1,44 @@ +#include <gpiod.h> +#include <stdio.h> + +int modemPowerToggle(int pinNum) { + struct gpiod_chip *chip; + struct gpiod_line *line; + + chip = gpiod_chip_open("/dev/gpiochip0"); + if (!chip) { + perror("Error opening GPIO chip"); + return 1; + } + + line = gpiod_chip_get_line( + chip, pinNum); // Replace with the desired GPIO pin number + if (!line) { + perror("Error getting GPIO line"); + gpiod_chip_close(chip); + return 1; + } + + if (gpiod_line_request_output(line, "cellular modem power toggle", 0) < 0) { + perror("Error setting GPIO line as output"); + gpiod_chip_close(chip); + return 1; + } + + if (gpiod_line_set_value(line, 1) < 0) { + perror("Error setting GPIO line high"); + gpiod_chip_close(chip); + return 1; + } + + sleep(1); + + if (gpiod_line_set_value(line, 0) < 0) { + perror("Error setting GPIO line low"); + gpiod_chip_close(chip); + return 1; + } + + gpiod_chip_close(chip); + return 0; +} @@ -1,130 +1,15 @@ -#include <errno.h> /* strerror() */ -#include <fcntl.h> /* O_RDWR */ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <termios.h> -#include <time.h> -#include <unistd.h> /* write(), read(), close() */ -#define BUFFER_SIZE 256 - -int openSerialPort(char pathToPort[]) { - - static int serialPort; - struct termios serialTerminal; - - serialPort = open(pathToPort, O_RDWR); - if (serialPort < 0) { - printf("Error open(): %s\n", strerror(errno)); - return -1; - } - - if (tcgetattr(serialPort, &serialTerminal) != 0) { - printf("Error tcgetattr(): %s\n", strerror(errno)); - close(serialPort); - return -1; - } - - serialTerminal.c_cflag |= CREAD; - - /* serialTerminal.c_iflag &= ~(BRKINT | IGNBRK | INLCR | IGNCR | ICRNL | IXOFF - | IUTF8 | IUCLC | IXANY | IMAXBEL); */ - serialTerminal.c_iflag &= - ~(IGNBRK | BRKINT | INLCR | IGNCR | ICRNL | IXON | IXOFF | IUCLC | IXANY | - IMAXBEL | IGNPAR | PARMRK | INPCK | ISTRIP); - - /* serialTerminal.c_lflag &= ~(ECHO | ECHONL | NOFLSH | ISIG | TOSTOP | ICANON - | IEXTEN | ECHOE | ECHOK); */ - serialTerminal.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK); - - /* serialTerminal.c_oflag &= - ~(OLCUC | OCRNL | OPOST | OFILL | ONLCR | ONOCR | ONLRET | OFDEL); */ - serialTerminal.c_oflag &= ~(OPOST); - - serialTerminal.c_cc[VTIME] = 0; - serialTerminal.c_cc[VMIN] = 0; - - cfsetispeed(&serialTerminal, B115200); - cfsetospeed(&serialTerminal, B115200); - - if (tcsetattr(serialPort, TCSANOW, &serialTerminal) != 0) { - printf("Error tcsetattr(): %s\n", strerror(errno)); - close(serialPort); - return -1; - } - - return serialPort; -} - -int querySerialPort(int serialPort, char *input) { - - time_t timeStart; - unsigned long idx; - int bytesRead, bufferFree, returnCode, isEnd, - bufferSize = sizeof(char) * BUFFER_SIZE; /* initial size in bytes */ - char *txBuffer, *buffer = calloc(BUFFER_SIZE, sizeof(char)); - const char *responseCodes[8] = {"\r\nOK\r\n", "\r\nCONNECT\r\n", - "\r\nRING\r\n", "\r\nNO CARRIER\r\n", - "\r\nERROR\r\n", "\r\nNO DIALTONE\r\n", - "\r\nBUSY\r\n", "\r\nNO ANSWER\r\n"}; - - txBuffer = malloc(sizeof(char) * (strlen(input) + 2)); - strncpy(txBuffer, input, sizeof(char) * (strlen(input) + 1)); - strncat(txBuffer, "\r", 2 * sizeof(char)); - if (write(serialPort, txBuffer, sizeof(char) * (strlen(txBuffer))) < 0) { - printf("Error write(): %s\n", strerror(errno)); - free(txBuffer); - free(buffer); - return 1; - } - free(txBuffer); - - bytesRead = bufferFree = bufferSize; - returnCode = isEnd = 0; - timeStart = time(NULL); - while (!isEnd) { - bytesRead = - read(serialPort, buffer + bufferSize - bufferFree, bufferFree - 1); - if (bytesRead < 0) { - printf("Error reading serial port\n"); - returnCode = 1; - break; - } - - else if (bytesRead > 0) { - buffer[bytesRead] = '\0'; - bufferFree -= (bytesRead + 1); - - if (bufferFree == 0) { - bufferSize += bufferFree = BUFFER_SIZE; - buffer = realloc(buffer, bufferSize); - } - - for (idx = 0; idx < sizeof(responseCodes) / sizeof(*responseCodes); - idx++) { - if (strstr(buffer, responseCodes[idx])) { - isEnd = 1; - break; - } - } - } else if (bytesRead == 0 && time(NULL) - timeStart > 180) { - printf("Response timeout after 180 seconds\n"); - returnCode = 1; - break; - } - } - - printf("%s\n", buffer); - free(buffer); - return returnCode; -} +#include <gpio.h> +#include <serial.h> int main() { char *commandList[] = {"AT", "ATI", "AT+COPS?"/* , "AT+COPS=?" */}, - serialFilePath[] = "/dev/serial0"; + serialFilePath[] = "/dev/serial0", *output = malloc(1); int serialPort; unsigned long idx; @@ -132,18 +17,42 @@ int main() { serialPort = openSerialPort(serialFilePath); if (serialPort < 0) { printf("Error openSerialPort()\n"); + free(output); return 1; } + if (0 != querySerialPort(&output, serialPort, "AT")) { + printf("Error querySerialPort()\n"); + close(serialPort); + free(output); + return 1; + } + if (NULL == strstr(output, "OK\r\n")) { + if (0 != modemPowerToggle(17)) { + printf("Error toggling modem power\n"); + free(output); + return 1; + } + } + for (idx = 0; idx < sizeof(commandList) / sizeof(*commandList); idx++) { - if (0 != querySerialPort(serialPort, commandList[idx])) { + if (0 != querySerialPort(&output, serialPort, commandList[idx])) { printf("Error querySerialPort()\n"); close(serialPort); + free(output); return 1; } + printf("%s", output); } close(serialPort); + if (0 != modemPowerToggle(17)) { + printf("Error toggling modem power\n"); + free(output); + return 1; + } + + free(output); return 0; } diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..0fd83fd --- /dev/null +++ b/src/serial.c @@ -0,0 +1,122 @@ +#include <errno.h> +#include <fcntl.h> /* O_RDWR */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <time.h> + +#define BUFFER_SIZE 256 + +int openSerialPort(char pathToPort[]) { + + static int serialPort; + struct termios serialTerminal; + + serialPort = open(pathToPort, O_RDWR); + if (serialPort < 0) { + printf("Error open(): %s\n", strerror(errno)); + return -1; + } + + if (tcgetattr(serialPort, &serialTerminal) != 0) { + printf("Error tcgetattr(): %s\n", strerror(errno)); + close(serialPort); + return -1; + } + + serialTerminal.c_cflag |= CREAD; + + /* serialTerminal.c_iflag &= ~(BRKINT | IGNBRK | INLCR | IGNCR | ICRNL | IXOFF + | IUTF8 | IUCLC | IXANY | IMAXBEL); */ + serialTerminal.c_iflag &= + ~(IGNBRK | BRKINT | INLCR | IGNCR | ICRNL | IXON | IXOFF | IUCLC | IXANY | + IMAXBEL | IGNPAR | PARMRK | INPCK | ISTRIP); + + /* serialTerminal.c_lflag &= ~(ECHO | ECHONL | NOFLSH | ISIG | TOSTOP | ICANON + | IEXTEN | ECHOE | ECHOK); */ + serialTerminal.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK); + + /* serialTerminal.c_oflag &= + ~(OLCUC | OCRNL | OPOST | OFILL | ONLCR | ONOCR | ONLRET | OFDEL); */ + serialTerminal.c_oflag &= ~(OPOST); + + serialTerminal.c_cc[VTIME] = 0; + serialTerminal.c_cc[VMIN] = 0; + + cfsetispeed(&serialTerminal, B115200); + cfsetospeed(&serialTerminal, B115200); + + if (tcsetattr(serialPort, TCSANOW, &serialTerminal) != 0) { + printf("Error tcsetattr(): %s\n", strerror(errno)); + close(serialPort); + return -1; + } + + return serialPort; +} + +int querySerialPort(char **output, int serialPort, char *input) { + + time_t timeStart; + unsigned long idx; + int bytesRead, bufferFree, returnCode, isEnd, + bufferSize = sizeof(char) * BUFFER_SIZE; /* initial size in bytes */ + char *txBuffer, *buffer = calloc(BUFFER_SIZE, sizeof(char)); + const char *responseCodes[8] = {"\r\nOK\r\n", "\r\nCONNECT\r\n", + "\r\nRING\r\n", "\r\nNO CARRIER\r\n", + "\r\nERROR\r\n", "\r\nNO DIALTONE\r\n", + "\r\nBUSY\r\n", "\r\nNO ANSWER\r\n"}; + + txBuffer = malloc(sizeof(char) * (strlen(input) + 2)); + strncpy(txBuffer, input, sizeof(char) * (strlen(input) + 1)); + strncat(txBuffer, "\r", 2 * sizeof(char)); + if (write(serialPort, txBuffer, sizeof(char) * (strlen(txBuffer))) < 0) { + printf("Error write(): %s\n", strerror(errno)); + free(txBuffer); + free(buffer); + return 1; + } + free(txBuffer); + + bytesRead = 0; + bufferFree = bufferSize; + returnCode = isEnd = 0; + timeStart = time(NULL); + while (!isEnd) { + bytesRead = + read(serialPort, buffer + bufferSize - bufferFree, bufferFree - 1); + if (bytesRead < 0) { + printf("Error reading serial port\n"); + returnCode = 1; + break; + } + + else if (bytesRead > 0) { + buffer[bytesRead] = '\0'; + bufferFree -= (bytesRead + 1); + + if (bufferFree == 0) { + bufferSize += bufferFree = BUFFER_SIZE; + buffer = realloc(buffer, bufferSize); + } + + for (idx = 0; idx < sizeof(responseCodes) / sizeof(*responseCodes); + idx++) { + if (strstr(buffer, responseCodes[idx])) { + isEnd = 1; + break; + } + } + } else if (bytesRead == 0 && time(NULL) - timeStart > 180) { + printf("Response timeout after 180 seconds\n"); + returnCode = 1; + break; + } + } + + *output = realloc(*output, bufferSize); + strncpy(*output, buffer, bufferSize); + free(buffer); + return returnCode; +}
\ No newline at end of file |
