#include "bg96.h" #include "gpio.h" #include "serial.h" #include #include #include #include #include #include #include int initNetworkData(networkData *nD) { nD->operatorName = calloc(1, sizeof(char)); nD->networkName = calloc(1, sizeof(char)); nD->tech = calloc(1, sizeof(char)); nD->band = calloc(1, sizeof(char)); nD->channel = calloc(1, sizeof(char)); nD->networkRegStat = calloc(1, sizeof(char)); nD->trkAreaCode = calloc(1, sizeof(char)); nD->cellID = calloc(1, sizeof(char)); nD->rssi = calloc(1, sizeof(char)); nD->rsrp = calloc(1, sizeof(char)); nD->sinr = calloc(1, sizeof(char)); nD->rsrq = calloc(1, sizeof(char)); nD->ber = calloc(1, sizeof(char)); return 0; } int freeNetworkData(networkData *nD) { free(nD->operatorName); free(nD->networkName); free(nD->tech); free(nD->band); free(nD->channel); free(nD->networkRegStat); free(nD->trkAreaCode); free(nD->cellID); free(nD->rssi); free(nD->rsrp); free(nD->sinr); free(nD->rsrq); free(nD->ber); return 0; } 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, NULL)) { 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, 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, "POWERED DOWN")) { printf("Error querying serial port\n"); } 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 cfgPublicNetwork(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,0", "AT+CEREG=2"}; 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, NULL)) { 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; } } 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 waitForNetwork(char *pathToPort, int waitTimeSeconds) { int serialPort, refreshPeriodSeconds = 1; char *response = malloc(sizeof(char)), *responseCpy, *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, NULL)) { 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, ',')); 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 mqttDisc(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+QMTCONN?", 2, NULL)) { printf("Error querying AT+QMTCONN?\n"); close(serialPort); free(response); return 1; } 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(response); return 1; } } 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\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; } } close(serialPort); free(response); return 0; } int mqttConn(char *pathToPort, char *hostURL, int hostPort, char *username, char *password) { int serialPort, cmdStrLen; unsigned long idx; char *response = malloc(sizeof(char)), *command, clientID[11]; 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); goto mqttConnError3; } if (0 != querySerialPort(&response, serialPort, "AT+QMTCFG=\"version\",0,4", 2, NULL)) { printf("Error querying AT+QMTCFG=\"version\",0,4\n"); goto mqttConnError2; } if (0 != querySerialPort(&response, serialPort, "AT+QMTCFG=\"pdpcid\",0,1", 2, NULL)) { printf("Error querying AT+QMTCFG=\"pdpcid\",0,1\n"); goto mqttConnError2; } if (0 != querySerialPort(&response, serialPort, "AT+QMTCFG=\"timeout\",0,5,3,0", 2, NULL)) { printf("Error configuring MQTT package timeout\n"); goto mqttConnError2; } if (0 != querySerialPort(&response, serialPort, "AT+QMTCFG=\"ssl\",0,1,0", 2, NULL)) { printf("Error querying AT+QMTCFG=\"ssl\",0,1,0\n"); goto mqttConnError2; } 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 (0 != querySerialPort(&response, serialPort, command, 75, "+QMTOPEN:")) { printf("Error querying %s\n", command); goto mqttConnError1; } else if (NULL == strstr(response, "+QMTOPEN: 0,0")) { printf("Failed to establish network for MQTT connection\n"); goto mqttConnError1; } 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 (0 != 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 mqttConnError1; } else if (NULL == strstr(response, "+QMTCONN: 0,0")) { printf("Failed to establish connection. Response:\n%s\n", response); goto mqttConnError1; } free(command); close(serialPort); free(response); return 0; mqttConnError1: free(command); mqttConnError2: close(serialPort); mqttConnError3: free(response); return 1; } int mqttPubNetData(char *pathToPort, networkData nD) { int serialPort, cmdStrLen, msgID, msgSize; char *response = malloc(sizeof(char)), *command = malloc(sizeof(char)), *msg = malloc(sizeof(char)); char template[] = "Operator: %s\n" "Network: %s\n" "Reg Status: %s\n" "Tracking Area Code: %s\n" "Cell ID: %s\n" "Technology: %s\n" "Band: %s\n" "Channel: %s\n" "Network Time (GMT): %s"; msgSize = sizeof(char) * (strlen(template) + strlen(nD.operatorName) + strlen(nD.networkName) + strlen(nD.networkRegStat) + strlen(nD.trkAreaCode) + strlen(nD.cellID) + strlen(nD.tech) + strlen(nD.band) + strlen(nD.channel) + strlen(asctime(&nD.netTime)) + 1 - 9 * 2); /* REMOVE THE EXTRA %s FROM TEMPLATE */ msg = realloc(msg, msgSize); snprintf(msg, msgSize / sizeof(char), template, nD.operatorName, nD.networkName, nD.networkRegStat, nD.trkAreaCode, nD.cellID, nD.tech, nD.band, nD.channel, asctime(&nD.netTime)); serialPort = openSerialPort(pathToPort); if (0 > serialPort) { printf("Error opening serial port %s\n", pathToPort); goto mqttPubError2; } msgID = rand() % 65536; cmdStrLen = strlen("AT+QMTPUB=0") + (int)ceil(log10(msgID)) + 1 + 1 + strlen("kboz/feeds/textInfo") + (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, "kboz/feeds/textInfo", msgSize); if (0 != querySerialPort(&response, serialPort, command, 15, (char *)-1)) { printf("Error querying publish command: %s\n", command); goto mqttPubError1; } else if (0 != querySerialPort(&response, serialPort, msg, 15, "\r\n+QMTPUB:")) { printf("Error querying publish message\n"); goto mqttPubError1; } msgSize = sizeof(char) * (strlen(nD.rssi) + 1); msg = realloc(msg, msgSize); strncpy(msg, nD.rssi, msgSize / sizeof(char)); msgID = rand() % 65536; cmdStrLen = strlen("AT+QMTPUB=0") + (int)ceil(log10(msgID)) + 1 + 1 + strlen("kboz/feeds/rssi") + (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, "kboz/feeds/rssi", msgSize); if (0 != querySerialPort(&response, serialPort, command, 15, (char *)-1)) { printf("Error querying publish command: %s\n", command); goto mqttPubError1; } else if (0 != querySerialPort(&response, serialPort, msg, 15, "\r\n+QMTPUB:")) { printf("Error querying publish message\n"); goto mqttPubError1; } msgSize = sizeof(char) * (strlen(nD.rsrp) + 1); msg = realloc(msg, msgSize); strncpy(msg, nD.rsrp, msgSize / sizeof(char)); msgID = rand() % 65536; cmdStrLen = strlen("AT+QMTPUB=0") + (int)ceil(log10(msgID)) + 1 + 1 + strlen("kboz/feeds/rsrp") + (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, "kboz/feeds/rsrp", msgSize); if (0 != querySerialPort(&response, serialPort, command, 15, (char *)-1)) { printf("Error querying publish command: %s\n", command); goto mqttPubError1; } else if (0 != querySerialPort(&response, serialPort, msg, 15, "\r\n+QMTPUB:")) { printf("Error querying publish message\n"); goto mqttPubError1; } msgSize = sizeof(char) * (strlen(nD.sinr) + 1); msg = realloc(msg, msgSize); strncpy(msg, nD.sinr, msgSize / sizeof(char)); msgID = rand() % 65536; cmdStrLen = strlen("AT+QMTPUB=0") + (int)ceil(log10(msgID)) + 1 + 1 + strlen("kboz/feeds/sinr") + (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, "kboz/feeds/sinr", msgSize); if (0 != querySerialPort(&response, serialPort, command, 15, (char *)-1)) { printf("Error querying publish command: %s\n", command); goto mqttPubError1; } else if (0 != querySerialPort(&response, serialPort, msg, 15, "\r\n+QMTPUB:")) { printf("Error querying publish message\n"); goto mqttPubError1; } msgSize = sizeof(char) * (strlen(nD.rsrq) + 1); msg = realloc(msg, msgSize); strncpy(msg, nD.rsrq, msgSize / sizeof(char)); msgID = rand() % 65536; cmdStrLen = strlen("AT+QMTPUB=0") + (int)ceil(log10(msgID)) + 1 + 1 + strlen("kboz/feeds/rsrq") + (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, "kboz/feeds/rsrq", msgSize); if (0 != querySerialPort(&response, serialPort, command, 15, (char *)-1)) { printf("Error querying publish command: %s\n", command); goto mqttPubError1; } else if (0 != querySerialPort(&response, serialPort, msg, 15, "\r\n+QMTPUB:")) { printf("Error querying publish message\n"); goto mqttPubError1; } msgSize = sizeof(char) * (strlen(nD.ber) + 1); msg = realloc(msg, msgSize); strncpy(msg, nD.ber, msgSize / sizeof(char)); msgID = rand() % 65536; cmdStrLen = strlen("AT+QMTPUB=0") + (int)ceil(log10(msgID)) + 1 + 1 + strlen("kboz/feeds/ber") + (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, "kboz/feeds/ber", msgSize); if (0 != querySerialPort(&response, serialPort, command, 15, (char *)-1)) { printf("Error querying publish command: %s\n", command); goto mqttPubError1; } else if (0 != querySerialPort(&response, serialPort, msg, 15, "\r\n+QMTPUB:")) { printf("Error querying publish message\n"); goto mqttPubError1; } free(command); free(response); free(msg); close(serialPort); return 0; mqttPubError1: close(serialPort); mqttPubError2: free(command); free(response); free(msg); return 1; } int gatherData(networkData *output, char *pathToPort) { int serialPort, strLen, tmpNum; char *response = malloc(sizeof(char)), *varPtr, *qcsqSystemMode; serialPort = openSerialPort(pathToPort); if (0 > serialPort) { printf("Error opening serial port %s\n", pathToPort); goto gatherDataError2; } if (0 != querySerialPort(&response, serialPort, "AT+COPS?", 1, NULL)) { printf("Error querying AT+COPS?\n"); goto gatherDataError1; } varPtr = strtok(response, ",\r"); while (strstr(varPtr, "\n+COPS:") == NULL) { varPtr = strtok(NULL, ",\r"); } varPtr = strtok(NULL, ",\r"); varPtr = strtok(NULL, ",\r"); strLen = strlen(varPtr) + 1; output->operatorName = realloc(output->operatorName, sizeof(char) * strLen); strncpy(output->operatorName, varPtr, strLen); if (0 != querySerialPort(&response, serialPort, "AT+CEREG?", 1, NULL)) { printf("Error querying AT+CEREG?\n"); goto gatherDataError1; } varPtr = strtok(response, ",\r"); while (strstr(varPtr, "\n+CEREG:") == NULL) { varPtr = strtok(NULL, ",\r"); } varPtr = strtok(NULL, ",\r"); switch (*varPtr) { case '1': strLen = strlen("Not roaming") + 1; output->networkRegStat = realloc(output->networkRegStat, sizeof(char) * strLen); strncpy(output->networkRegStat, "Not roaming", strLen); break; case '5': strLen = strlen("Roaming") + 1; output->networkRegStat = realloc(output->networkRegStat, sizeof(char) * strLen); strncpy(output->networkRegStat, "Roaming", strLen); break; } varPtr = strtok(NULL, "\",\r"); strLen = strlen(varPtr) + 1; output->trkAreaCode = realloc(output->trkAreaCode, sizeof(char) * strLen); strncpy(output->trkAreaCode, varPtr, strLen); varPtr = strtok(NULL, "\",\r"); strLen = strlen(varPtr) + 1; output->cellID = realloc(output->cellID, sizeof(char) * strLen); strncpy(output->cellID, varPtr, strLen); if (0 != querySerialPort(&response, serialPort, "AT+CSQ", 1, NULL)) { printf("Error querying AT+CSQ\n"); goto gatherDataError1; } varPtr = strtok(response, ",\r"); while (strstr(varPtr, "\n+CSQ:") == NULL) { varPtr = strtok(NULL, " ,\r"); } varPtr = strtok(NULL, " ,\r"); varPtr = strtok(NULL, " ,\r"); if (0 == strcmp(varPtr, "99")) { strLen = strlen("NULL") + 1; output->ber = realloc(output->ber, sizeof(char) * strLen); strncpy(output->ber, "NULL", strLen); } else { tmpNum = exp2(strtoimax(varPtr, NULL, 10)); strLen = 7; output->ber = realloc(output->ber, sizeof(char) * strLen); snprintf(output->ber, strLen * sizeof(char), "%f.2%%", 0.14 * tmpNum); } if (0 != querySerialPort(&response, serialPort, "AT+QLTS=1", 1, NULL)) { printf("Error querying AT+QLTS=1\n"); goto gatherDataError1; } varPtr = strtok(response, " ,\r"); while (strstr(varPtr, "\n+QLTS:") == NULL) { varPtr = strtok(NULL, " ,\r"); } varPtr = strtok(NULL, " \"/:+-,\r"); output->netTime.tm_year = strtoimax(varPtr, NULL, 10) - 1900; varPtr = strtok(NULL, " \"/:+-,\r"); output->netTime.tm_mon = strtoimax(varPtr, NULL, 10) - 1; varPtr = strtok(NULL, " \"/:+-,\r"); output->netTime.tm_mday = strtoimax(varPtr, NULL, 10); varPtr = strtok(NULL, " \"/:+-,\r"); output->netTime.tm_hour = strtoimax(varPtr, NULL, 10); varPtr = strtok(NULL, " \"/:+-,\r"); output->netTime.tm_min = strtoimax(varPtr, NULL, 10); varPtr = strtok(NULL, " \"/:+-,\r"); output->netTime.tm_sec = strtoimax(varPtr, NULL, 10); varPtr = strtok(NULL, " \"/:+-,\r"); varPtr = strtok(NULL, " \"/:+-,\r"); output->netTime.tm_isdst = strtoimax(varPtr, NULL, 2); output->netTime.tm_wday = 0; output->netTime.tm_yday = 0; output->netTime.tm_gmtoff = 0; if (-1 == mktime(&output->netTime)) { printf("Error parsing network time\n"); goto gatherDataError1; } output->netTime.tm_gmtoff = 0; output->netTime.tm_zone = NULL; if (0 != querySerialPort(&response, serialPort, "AT+QNWINFO", 1, NULL)) { printf("Error querying AT+QNWINFO\n"); goto gatherDataError1; } varPtr = strtok(response, "\",\r"); while (strstr(varPtr, "\n+QNWINFO:") == NULL) { varPtr = strtok(NULL, " \",\r"); } varPtr = strtok(NULL, "\",\r"); strLen = strlen(varPtr) + 1; output->tech = realloc(output->tech, sizeof(char) * strLen); strncpy(output->tech, varPtr, strLen); varPtr = strtok(NULL, "\",\r"); varPtr = strtok(NULL, "\",\r"); strLen = strlen(varPtr) + 1; output->band = realloc(output->band, sizeof(char) * strLen); strncpy(output->band, varPtr, strLen); varPtr = strtok(NULL, "\",\r"); strLen = strlen(varPtr) + 1; output->channel = realloc(output->channel, sizeof(char) * strLen); strncpy(output->channel, varPtr, strLen); if (0 != querySerialPort(&response, serialPort, "AT+QSPN", 1, NULL)) { printf("Error querying AT+QSPN\n"); goto gatherDataError1; } varPtr = strtok(response, "\",\r"); while (strstr(varPtr, "\n+QSPN:") == NULL) { varPtr = strtok(NULL, " \",\r"); } varPtr = strtok(NULL, "\",\r"); strLen = strlen(varPtr) + 1; output->networkName = realloc(output->networkName, sizeof(char) * strLen); strncpy(output->networkName, varPtr, strLen); if (0 != querySerialPort(&response, serialPort, "AT+QCSQ", 1, NULL)) { printf("Error querying AT+QCSQ\n"); goto gatherDataError1; } varPtr = strtok(response, " \",\r"); while (strstr(varPtr, "\n+QCSQ:") == NULL) { varPtr = strtok(NULL, " \",\r"); } qcsqSystemMode = varPtr = strtok(NULL, " \",\r"); if (0 != strcmp(qcsqSystemMode, "NOSERVICE")) { varPtr = strtok(NULL, " \",\r"); strLen = strlen(varPtr) + 1; output->rssi = realloc(output->rssi, sizeof(char) * strLen); strncpy(output->rssi, varPtr, strLen); if (0 != strcmp(qcsqSystemMode, "GSM")) { varPtr = strtok(NULL, " \",\r"); strLen = strlen(varPtr) + 1; output->rsrp = realloc(output->rsrp, sizeof(char) * strLen); strncpy(output->rsrp, varPtr, strLen); varPtr = strtok(NULL, " \",\r"); strLen = strlen(varPtr) + 1; output->sinr = realloc(output->sinr, sizeof(char) * strLen); strncpy(output->sinr, varPtr, strLen); varPtr = strtok(NULL, " \",\r"); strLen = strlen(varPtr) + 1; output->rsrq = realloc(output->rsrq, sizeof(char) * strLen); strncpy(output->rsrq, varPtr, strLen); } else { strLen = strlen("NULL") + 1; output->rsrp = realloc(output->rsrp, sizeof(char) * strLen); output->sinr = realloc(output->sinr, sizeof(char) * strLen); output->rsrq = realloc(output->rsrq, sizeof(char) * strLen); strncpy(output->rsrp, "NULL", strLen); strncpy(output->sinr, "NULL", strLen); strncpy(output->rsrq, "NULL", strLen); } } close(serialPort); free(response); return 0; gatherDataError1: close(serialPort); gatherDataError2: free(response); return 1; }