/* * Module_4g.c * * Created on: 2019-11-29 * Update on: 2021-12-06 * Author: Eason Yang / Folus Wen * Version: V0.12 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "define.h" #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 enum DONGLE_MODEL { DONGLE_QUECTEL=0, DONGLE_THALES, DONGLE_UBLOX }; enum CONNECT_STEP { CONNECT_STEP_CHECK_MODULE=0, CONNECT_STEP_READ_MODULE_INFO, CONNECT_STEP_READ_SIM_INFO, CONNECT_STEP_CONNECTING, CONNECT_STEP_CONNECTED, CONNECT_STEP_DISCONNECTED }; enum NETWORK_MODE { NETWORK_MODE_AUTO=0, NETWORK_MODE_GSM, NETWORK_MODE_WCDMA, NETWORK_MODE_LTE, NETWORK_MODE_TDSCDMA, NETWORK_MODE_UMTS, NETWORK_MODE_CDMA, NETWORK_MODE_HDR, NETWORK_MODE_CDMA_HDR }; // Define Module network mode #define NET_MODE_NO_SERVICE 0 #define NET_MODE_CDMA 1 #define NET_MODE_GMS_GPRS 2 #define NET_MODE_WCDMA 3 #define NET_MODE_GSM_WCDMA 4 #define NET_MODE_TD_SCDMA 5 #define NET_MODE_HSPA 6 #define NET_MODE_LTE 7 #define NET_MODE_UNKNOWN 9 // Define interval #define DefaultInterval 5 // Seconds #define SystemInterval 30 // Seconds #define CheckModemInterval 30 // Seconds #define CheckSimInterval 30 // Seconds #define CheckModemInfoInterval 30 // Seconds #define CheckConnectionInterval 60 // Seconds #define CheckInternetInterval 30 // Seconds #define DisconnInterval 60 // Seconds // Define Telecom mode #define DISABLE_4G_MODULE 0 #define ENABLE_4G 1 int Check4GModem(void); int isPppUp(void); int isReadInfo(int connectStep); int isReadSimInfo(void); int isReachableInternet(void); int isModuleUnbind(void); int isModuleBind(void); int rstModule(void); int Load4gConfiguration(void); int CheckSignalRssi(void); int at_command(int uart, char* cmd, char* rx); int openPort(char *tty); int set_interface_attribs (int fd, int speed, int parity); int set_blocking (int fd, int should_block); void trim_s(char *s, unsigned char len); void substr(char *dest, const char* src, unsigned int start, unsigned int cnt); char *portName[3] = {"/dev/ttyUSB2", "/dev/ttyACM2", "/dev/ttyACM2"}; char *valid_Internet[2] = {"8.8.8.8", "180.76.76.76"}; char *Version_And_Date[2] = {"V0.13","2022-04-21"}; pid_t pid; struct dongle_info { int Model; char ICCID[20]; char IMSI[16]; char IMEI[16]; char MANUFACTURER[16]; char MODELNAME[10]; char REVISION[18]; unsigned char MODE; char act[16]; char operator[16]; char band[16]; int channel; int CSQ; int cnt_InternetFail; int cnt_ReadInfoFail; int cnt_pppFail; int cnt_SearchModuleFail; int cnt_ReadSimInfoFail; uint64_t bytesTx; uint64_t bytesRx; uint32_t lastCounter; }Dongle; struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct FanModuleData *ShmFanModuleData; struct OCPP16Data *ShmOCPP16Data; int StoreLogMsg(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); CurrentTime = time(NULL); tm=localtime(&CurrentTime); sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d]%s\" >> /Storage/SystemLog/[%04d.%02d]4g_SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer, tm->tm_year+1900,tm->tm_mon+1); #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d] - %s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer); #endif return rc; } int DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second unsigned int StartTime,StopTime; StartTime=(unsigned int)ST.time; StopTime=(unsigned int)ET.time; return (StopTime-StartTime)*1000+ET.millitm-ST.millitm; } //========================================== // Init all share memory //========================================== int InitShareMemory() { int result = PASS; int MeterSMId; //creat ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n"); result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n"); result = FAIL; } else {} //creat ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { DEBUG_ERROR("shmget ShmStatusCodeData NG\n"); result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmStatusCodeData NG\n"); result = FAIL; } else {} //creat ShmOCPP16Data if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0) { DEBUG_ERROR("shmget ShmOCPP16Data NG"); result = FAIL; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16Data NG"); result = FAIL; } else {} return result; } //========================================== // Check dongle model //========================================== int Check4GModem(void) { int result = FAIL; if((access("/dev/ttyUSB0", F_OK) != -1) && (access("/dev/ttyUSB1", F_OK) != -1) && (access("/dev/ttyUSB2", F_OK) != -1) && (access("/dev/ttyUSB3", F_OK) != -1)) { result = DONGLE_QUECTEL; } else if((access("/dev/ttyACM0", F_OK) != -1) && (access("/dev/ttyACM1", F_OK) != -1) && (access("/dev/ttyACM2", F_OK) != -1) && (access("/dev/ttyACM3", F_OK) != -1)) { if(access("/dev/ttyACM4", F_OK) != -1) result = DONGLE_UBLOX; else result = DONGLE_THALES; } else {} switch(result) { case DONGLE_QUECTEL: DEBUG_INFO("Quectel 4G modem be found\n"); break; case DONGLE_THALES: DEBUG_INFO("Thelas 4G modem be found\n"); break; case DONGLE_UBLOX: DEBUG_INFO("Ublox 4G modem be found\n"); break; default: DEBUG_WARN("No 4G modem be found\n"); break; } return result; } //========================================== // Check ppp interface status //========================================== int isPppUp(void) { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; char tmp[512]; strcpy(cmd, "ifconfig ppp0");; fp = popen(cmd, "r"); if(fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if(strstr(buf, "ppp") > 0) { result = PASS; } if(strstr(buf, "addr:") > 0) { sscanf(buf, "%*s%s", tmp); substr((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress, tmp, strspn(tmp, "addr:"), (strlen(tmp) - strspn(tmp, "addr:"))); } } } pclose(fp); return result; } //========================================== // Check dongle info read status //========================================== int isReadInfo(int connectStep) { int result = PASS; int uart; char rx[512]; char tmp[512]; char Length; if((uart = openPort(portName[Dongle.Model])) != FAIL) { switch(Dongle.Model) { case DONGLE_QUECTEL: default: //============================== // Set don't echo command //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "ate0\r", rx); if(Length > 0) { if(strstr(rx, "ERROR")) { result = FAIL; } else {} } else result = FAIL; if(connectStep == CONNECT_STEP_READ_MODULE_INFO) { //============================== // Read Manufacturer //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+gmi\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx,"OK")); memset(rx, 0, ARRAY_SIZE(rx)); trim_s(tmp,Length); if(strstr(tmp, "atgmi") != NULL) { substr(tmp, tmp, 5, strlen(tmp)-5); } memset(Dongle.MANUFACTURER, 0x00, ARRAY_SIZE(Dongle.MANUFACTURER)); strncpy(Dongle.MANUFACTURER, tmp, strlen(tmp)); } else result = FAIL; //============================== // Read Model //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+gmm\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx,"OK")); memset(rx, 0, ARRAY_SIZE(rx)); trim_s(tmp,Length); if(strstr(tmp, "atgmm") != NULL) { substr(tmp, tmp, 5, strlen(tmp)-5); } memset(Dongle.MODELNAME, 0x00, ARRAY_SIZE(Dongle.MODELNAME)); strncpy(Dongle.MODELNAME, tmp, strlen(tmp)); } else result = FAIL; //============================== // Read Revision //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+gmr\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx, "OK")); memset(rx, 0, ARRAY_SIZE(rx)); trim_s(tmp,Length); if(strstr(tmp, "atgmr") != NULL) { substr(tmp, tmp, 5, strlen(tmp)-5); } memset(Dongle.REVISION, 0x00, ARRAY_SIZE(Dongle.REVISION)); strncpy(Dongle.REVISION, tmp, strlen(tmp)); } else result = FAIL; //============================== // Read IMEI //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+gsn\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx, "OK")); memset(rx, 0, ARRAY_SIZE(rx)); trim_s(tmp,Length); if(strstr(tmp, "atgsn") != NULL) { substr(tmp, tmp, 5, strlen(tmp)-5); } memset(Dongle.IMEI, 0x00, ARRAY_SIZE(Dongle.IMEI)); strncpy(Dongle.IMEI, tmp, strlen(tmp)); } else result = FAIL; } else if(connectStep == CONNECT_STEP_CONNECTED) { //============================== // Read CSQ //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+csq\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx,",")); strncpy(rx, tmp + strcspn(tmp,":")+1, 10); Dongle.CSQ = atoi(rx); } else result = FAIL; //============================== // Read Mode //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+qnwinfo\r", rx); if(Length > 0) { memset(tmp, 0, sizeof tmp); if(sscanf(rx, "%*[^:]:%[^,],%[^,],%[^,],%d", Dongle.act, Dongle.operator, Dongle.band, &Dongle.channel) == 4) { //strncpy(tmp, &rx[strcspn(rx,":")+2], strcspn(rx,",")-(strcspn(rx,":")+2)); if((strstr(Dongle.act, "GPRS") != NULL) || (strstr(Dongle.act, "EDGE") != NULL)) Dongle.MODE = NET_MODE_GMS_GPRS; else if(strstr(Dongle.act, "WCDMA") != NULL) Dongle.MODE = NET_MODE_WCDMA; else if(strstr(Dongle.act, "GSM") != NULL) Dongle.MODE = NET_MODE_GSM_WCDMA; else if(strstr(Dongle.act, "TDSCDMA") != NULL) Dongle.MODE = NET_MODE_TD_SCDMA; else if(strstr(Dongle.act, "CDMA") != NULL) Dongle.MODE = NET_MODE_CDMA; else if(strstr(Dongle.act, "LTE") != NULL) Dongle.MODE = NET_MODE_LTE; else if((strstr(Dongle.act, "HSDPA") != NULL) || (strstr(Dongle.act, "HSUPA") != NULL) || (strstr(Dongle.act, "HSPA+") != NULL)) Dongle.MODE = NET_MODE_HSPA; else Dongle.MODE = NET_MODE_UNKNOWN; } else { DEBUG_WARN("at+qnwinfo response can not parse.\n"); } } else result = FAIL; //============================== // Read data counter //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+qgdcnt?\r", rx); if(Length > 0) { if(sscanf(rx, "%*[^:]:%lld,%lld", &Dongle.bytesTx, &Dongle.bytesRx) != 2) { DEBUG_WARN("at+qgdcnt response can not parse.\n"); } } else result = FAIL; } break; case DONGLE_THALES: //============================== // Set don't echo command //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "ate0\r", rx); if(Length > 0) { if(strstr(rx, "ERROR")) { result = FAIL; } else {} } else result = FAIL; if(connectStep == CONNECT_STEP_READ_MODULE_INFO) { //============================== // Read Manufacturer //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+cgmi\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx,"OK")); memset(rx, 0, ARRAY_SIZE(rx)); memset(Dongle.MANUFACTURER, 0x00, ARRAY_SIZE(Dongle.MANUFACTURER)); strncpy(Dongle.MANUFACTURER, tmp+2, 9); } else result = FAIL; //============================== // Read Model //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+cgmm\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, &rx[strcspn(rx,"PLS")], strcspn(rx,"OK")); memset(rx, 0, ARRAY_SIZE(rx)); memset(Dongle.MODELNAME, 0x00, ARRAY_SIZE(Dongle.MODELNAME)); strncpy(Dongle.MODELNAME , tmp, 8); } else result = FAIL; //============================== // Read Revision //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "at+cgmr\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, &rx[strcspn(rx, "REVISION")+9], strcspn(rx, "OK")); memset(rx, 0, ARRAY_SIZE(rx)); memset(Dongle.REVISION, 0x00, ARRAY_SIZE(Dongle.REVISION)); strncpy(Dongle.REVISION, tmp, 6); } else result = FAIL; //============================== // Read IMEI //============================== Length = at_command(uart, "at+cgsn\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx, "OK")); memset(rx, 0, ARRAY_SIZE(rx)); trim_s(tmp,Length); memset(Dongle.IMEI, 0x00, ARRAY_SIZE(Dongle.IMEI)); strncpy(Dongle.IMEI, tmp, strlen(tmp)); } else result = FAIL; } else if(connectStep == CONNECT_STEP_CONNECTED) { //============================== // Read CSQ //============================== Length = at_command(uart, "at+csq\r", rx); if(Length > 0) { memset(tmp, 0, ARRAY_SIZE(tmp)); memcpy(tmp, rx, strcspn(rx,",")); strncpy(rx, tmp + strcspn(tmp,":")+1, 10); Dongle.CSQ = atoi(rx); } else result = FAIL; //============================== // Read Mode //============================== memset(rx, 0x00, ARRAY_SIZE(rx)); Length = at_command(uart, "AT^SMONI\r", rx); if(Length > 0) { memset(tmp, 0, sizeof tmp); if(strstr(rx, "2G,") != NULL) { DEBUG_INFO("2G network\n"); if(sscanf(rx, "%*[^:]:%*[^,],%d,%*[^,],%*[^,],%[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%[^,],", &Dongle.channel, Dongle.operator, Dongle.act) == 2) { if(strstr(Dongle.act, "G") != NULL) Dongle.MODE = NET_MODE_GMS_GPRS; else if(strstr(Dongle.act, "E") != NULL) Dongle.MODE = NET_MODE_GMS_GPRS; else Dongle.MODE = NET_MODE_CDMA; } else { DEBUG_WARN("AT^SMONI response can not parse.\n"); } } else if(strstr(rx, "3G,") != NULL) { if(sscanf(rx, "%*[^:]:%*[^,],%d,%*[^,],%*[^,],%*[^,],%*[^,],%[^,]", &Dongle.channel, Dongle.operator) == 2) { Dongle.MODE = NET_MODE_GSM_WCDMA; memset(Dongle.band, 0x00, ARRAY_SIZE(Dongle.band)); memset(Dongle.act, 0x00, ARRAY_SIZE(Dongle.act)); } else { DEBUG_WARN("AT^SMONI response can not parse.\n"); } } else if(strstr(rx, "4G,") != NULL) { if(sscanf(rx, "%*[^:]:%*[^,],%d,%[^,],%*[^,],%*[^,],%[^,],%*[^,],%[^,],", &Dongle.channel, Dongle.band, Dongle.act, Dongle.operator) == 4) { if(strstr(Dongle.act, "FDD") != NULL) Dongle.MODE = NET_MODE_LTE; else if(strstr(Dongle.act, "TDD") != NULL) Dongle.MODE = NET_MODE_TD_SCDMA; else Dongle.MODE = NET_MODE_UNKNOWN; } else { DEBUG_WARN("AT^SMONI response can not parse.\n"); } } else { DEBUG_WARN("AT^SMONI response can not parse.\n"); } } else result = FAIL; } break; } } else { #ifdef SystemLogMessage DEBUG_ERROR("%s open fail.\n", portName[Dongle.Model]); #endif result = FAIL; } close(uart); return result; } //========================================== // Read sim card information //========================================== int isReadSimInfo(void) { int result = PASS; int uart; char rx[512]; char tmp[512]; char Length; if((uart = openPort(portName[Dongle.Model])) != FAIL) { switch(Dongle.Model) { case DONGLE_QUECTEL: default: //============================== // Set don't echo command //============================== Length = at_command(uart, "ate0\r", rx); if(Length > 0) { if(strstr(rx, "ERROR")) { result = FAIL; } else {} } else result = FAIL; //============================== // Read IMSI //============================== Length = at_command(uart, "at+cimi\r", rx); if(Length > 0) { memset(tmp, 0, sizeof tmp); if(strstr(rx, "ERROR")) { memset(Dongle.IMSI, 0, sizeof Dongle.IMSI); result = FAIL; } else { memcpy(tmp, rx, strcspn(rx, "OK")); trim_s(tmp, Length); memset(rx, 0, sizeof rx); if(strstr(tmp, "atcimi") != NULL) { substr(tmp, tmp, 6, strlen(tmp)-6); } memset(Dongle.IMSI, 0x00, ARRAY_SIZE(Dongle.IMSI)); strncpy(Dongle.IMSI, tmp, strlen(tmp)); } } else result = FAIL; //============================== // Read CCID //============================== Length = at_command(uart, "at+qccid\r", rx); if(Length > 0) { memset(tmp, 0, sizeof tmp); if(strstr(rx, "ERROR")) { memset(Dongle.ICCID, 0, sizeof Dongle.ICCID); result = FAIL; } else { memcpy(tmp, rx, strcspn(rx, "OK")); memset(rx, 0, sizeof rx); memset(Dongle.ICCID, 0x00, ARRAY_SIZE(Dongle.ICCID)); strncpy(Dongle.ICCID, tmp + strcspn(tmp, ":") + 2, 20); } } else result = FAIL; break; case DONGLE_THALES: //============================== // Set don't echo command //============================== Length = at_command(uart, "ate0\r", rx); if(Length > 0) { if(strstr(rx, "ERROR")) { result = FAIL; } else {} } else result = FAIL; //============================== // Read IMSI //============================== Length = at_command(uart, "at+cimi\r", rx); if(Length > 0) { memset(tmp, 0, sizeof tmp); if(strstr(rx, "ERROR")) { memset(Dongle.IMSI, 0, sizeof Dongle.IMSI); result = FAIL; } else { memcpy(tmp, rx, strcspn(rx,"OK")); memset(rx, 0, sizeof rx); trim_s(tmp,Length); if(strstr(tmp, "atcimi") != NULL) { substr(tmp, tmp, 6, strlen(tmp)-6); } memset(Dongle.IMSI, 0x00, ARRAY_SIZE(Dongle.IMSI)); strncpy(Dongle.IMSI, tmp, strlen(tmp)); } } else result = FAIL; //============================== // Read CCID //============================== Length = at_command(uart, "at+ccid\r", rx); if(Length > 0) { memset(tmp, 0, sizeof tmp); if(strstr(rx, "ERROR")) { memset(Dongle.ICCID, 0, sizeof Dongle.ICCID); result = FAIL; } else { memcpy(tmp, rx, strcspn(rx, "OK")); memset(rx, 0, sizeof rx); memset(Dongle.ICCID, 0x00, ARRAY_SIZE(Dongle.ICCID)); strncpy(Dongle.ICCID, tmp + strcspn(tmp, ":") + 2, 20); } } else result = FAIL; break; } } else { DEBUG_ERROR("%s open fail.\n", portName[Dongle.Model]); result = FAIL; } close(uart); return result; } //========================================== // Read signal information //========================================== int CheckSignalRssi(void) { int result = PASS; int uart; char rx[512]; char tmp[512]; char Lenght; if((uart = openPort(portName[Dongle.Model])) != FAIL) { switch (Dongle.Model) { case DONGLE_THALES: //============================== // Set don't echo command //============================== Lenght = at_command(uart, "ate0\r", rx); if(Lenght > 0) { if(strstr(rx, "ERROR")) { result = FAIL; } else {} } else result = FAIL; //============================== // Read CSQ //============================== Lenght = at_command(uart, "at+csq\r", rx); if(Lenght > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rx, strcspn(rx, ",")); strncpy(rx, tmp + strcspn(tmp, ":") + 1, 10); Dongle.CSQ = atoi(rx); } else result = FAIL; break; case DONGLE_QUECTEL: default: //============================== // Set don't echo command //============================== Lenght = at_command(uart, "ate0\r", rx); if(Lenght > 0) { if(strstr(rx, "ERROR")) { result = FAIL; } else {} } else result = FAIL; //============================== // Read CSQ //============================== Lenght = at_command(uart, "at+csq\r", rx); if(Lenght > 0) { memset(tmp, 0, sizeof tmp); memcpy(tmp, rx, strcspn(rx, ",")); strncpy(rx, tmp + strcspn(tmp, ":") + 1, 10); Dongle.CSQ = atoi(rx); } else result = FAIL; break; } } else { #ifdef SystemLogMessage DEBUG_ERROR("%s open fail.\n", portName[Dongle.Model]); #endif result = FAIL; } close(uart); return result; } //========================================== // Init 4G dongle configuration //========================================== int Load4gConfiguration() { int result = FAIL; unsigned char CopyTmp[1024]; if(strlen((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn) > 0) { system("cat /dev/null > /root/ppp/auto-apn.conf"); system("chmod 600 /root/ppp/auto-apn.conf"); system("cat /dev/null > /etc/ppp/pap-secrets"); system("chmod 600 /etc/ppp/pap-secrets"); system("cat /dev/null > /etc/ppp/chap-secrets"); system("chmod 600 /etc/ppp/chap-secrets"); system("cat /dev/null > /etc/ppp/auth"); system("chmod 600 /etc/ppp/auth"); memset(CopyTmp,0,sizeof(CopyTmp)); sprintf((char*)CopyTmp,"echo APN=\"%s\" > /root/ppp/auto-apn.conf",ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn); system((char*)CopyTmp); memset(CopyTmp,0,sizeof(CopyTmp)); sprintf((char*)CopyTmp,"echo ACCOUNT=\"%s\" >> /root/ppp/auto-apn.conf",ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId); system((char*)CopyTmp); memset(CopyTmp,0,sizeof(CopyTmp)); sprintf((char*)CopyTmp,"echo PASSWORD=\"%s\" >> /root/ppp/auto-apn.conf",ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd); system((char*)CopyTmp); memset(CopyTmp,0,sizeof(CopyTmp)); sprintf((char*)CopyTmp,"echo %s > /etc/ppp/auth",ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId); system((char*)CopyTmp); sprintf((char*)CopyTmp,"echo %s >> /etc/ppp/auth",ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd); system((char*)CopyTmp); if(strlen((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId)>0) { memset(CopyTmp,0,sizeof(CopyTmp)); if(strlen((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd)>0) sprintf((char*)CopyTmp,"echo \"%s * %s \" > /etc/ppp/pap-secrets", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId, ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd); else sprintf((char*)CopyTmp,"echo \"%s * \\ \" > /etc/ppp/pap-secrets", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId); system((char*)CopyTmp); memset(CopyTmp,0,sizeof(CopyTmp)); if(strlen((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd)>0) sprintf((char*)CopyTmp,"echo \"%s * %s \" > /etc/ppp/chap-secrets", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId, ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd); else sprintf((char*)CopyTmp,"echo \"%s * \\ \" > /etc/ppp/chap-secrets", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId); system((char*)CopyTmp); } result = PASS; } return result; } //========================================== // Check internet access status //========================================== int isReachableInternet(void) { int result = FAIL; FILE *fp; char cmd[512]; char buf[512]; char tmp[256]; char isPppGetGw = FALSE; for(int idx=0;idx 0) { //sscanf(buf, "%*s%*s%*s%*s%*s%s", tmp); if(strstr(buf,"100%") != NULL) {} else { result = PASS; break; } //DEBUG_INFO("%s",buf); //DEBUG_INFO("%s\n",tmp); } } } pclose(fp); } // Check ppp0 gateway if(result == TRUE) { fp = popen("ip route", "r"); if(fp == NULL) result = FAIL; else { while(fgets(buf, sizeof(buf), fp) != NULL) { if((strstr(buf, "default") != NULL) && (strstr(buf, "ppp0") != NULL)) { isPppGetGw = TRUE; break; } if(strstr(buf, "ppp0") != NULL) { break; } } if((isPppGetGw == FALSE) && (strstr(buf, "ppp0") != NULL)) { sscanf(buf, "%s", tmp); DEBUG_INFO("ppp0 does not get default route gateway force assign to %s\n", tmp); sprintf(cmd,"route add default gw %s ppp0 &", tmp); system(cmd); } } pclose(fp); memset(buf, 0x00, sizeof(buf)); } return result; } //========================================== // Unbind USB port //========================================== int isModuleUnbind(void) { int result = FAIL; FILE *fp; char cmd[256]; strcpy(cmd, "echo '1-1'> /sys/bus/usb/drivers/usb/unbind"); fp = popen(cmd, "r"); if(fp == NULL) { result = FAIL; } else { result = PASS; #ifdef SystemLogMessage DEBUG_INFO("Unbind USB for dongle.\n"); #endif } return result; } //========================================== // Bind USB port //========================================== int isModuleBind(void) { int result = FAIL; FILE *fp; char cmd[256]; strcpy(cmd, "echo '1-1'> /sys/bus/usb/drivers/usb/bind"); fp = popen(cmd, "r"); if(fp == NULL) { result = FAIL; } else { #ifdef SystemLogMessage DEBUG_INFO("Bind USB for dongle.\n"); #endif result = PASS; } return result; } //========================================== // Dongle reset process //========================================== int rstModule(void) { int result = PASS; int uart; char rx[512]; if((uart = openPort(portName[Dongle.Model])) != FAIL) { //============================== // Reset module //============================== switch(Dongle.Model) { case DONGLE_QUECTEL: default: if(at_command(uart, "at+cfun=1,1\r", rx) <= 0) { result = FAIL; } DEBUG_INFO("Dongle hardware reset...\n"); break; case DONGLE_THALES: if(at_command(uart, "at+cfun=1,1\r", rx) <= 0) { result = FAIL; } DEBUG_INFO("Dongle hardware reset...\n"); break; } } else { #ifdef SystemLogMessage DEBUG_ERROR("%s open fail.\n", portName[Dongle.Model]); #endif result = FAIL; } close(uart); sleep(40); return result; } //========================================== // AT command send/receive //========================================== int at_command(int uart, char* cmd, char* rx) { int len; //sleep(2); //required to make flush work, for some reason //DEBUG_INFO("cmd : %s \n", cmd); tcflush(uart,TCIOFLUSH); if(write(uart, cmd, strlen(cmd)) >= strlen(cmd)) { usleep(500000); len = read(uart, rx, 512); //DEBUG_INFO("rx : %s \n", rx); } else { #ifdef SystemLogMessage DEBUG_ERROR("AT command %s response fail.\n", cmd); #endif } return len; } //========================================== // Dongle communication port open //========================================== int openPort(char *tty) { int uart = open(tty, O_RDWR | O_NOCTTY | O_NDELAY); if(uart!=FAIL) { if((set_interface_attribs(uart, B115200, 0) != PASS) || (set_blocking(uart, 0) != PASS)) uart = FAIL; } return uart; } //========================================== // Port parameter set //========================================== int set_interface_attribs (int fd, int speed, int parity) { int result = FAIL; struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) == 0) { cfsetospeed (&tty, speed); cfsetispeed (&tty, speed); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars // disable IGNBRK for mismatched speed tests; otherwise receive break // as \000 chars tty.c_iflag &= ~IGNBRK; // disable break processing tty.c_lflag = 0; // no signaling chars, no echo, // no canonical processing tty.c_oflag = 0; // no remapping, no delays tty.c_cc[VMIN] = 0; // read doesn't block tty.c_cc[VTIME] = 10; // 1 seconds read timeout tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl tty.c_cflag |= (CLOCAL | CREAD); // ignore modem controls, // enable reading tty.c_cflag &= ~(PARENB | PARODD); // shut off parity tty.c_cflag |= parity; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CRTSCTS; if (tcsetattr (fd, TCSANOW, &tty) == 0) result = PASS; } return result; } int set_blocking (int fd, int should_block) { int result = FAIL; struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) == 0) { tty.c_cc[VMIN] = should_block ? 1 : 0; tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout if (tcsetattr (fd, TCSANOW, &tty) == 0) result = PASS; } return result; } //========================================== // Common routine //========================================== void trim_s(char *s, unsigned char len) { for(unsigned char i = 0 ; i < len; i++) { if (!((s[i]>='a') && (s[i]<='z')) && !((s[i]>='A') && (s[i]<='Z'))&& !((s[i]>='0') && (s[i]<='9'))) { s[i] = s[i + 1]; strncpy(s + i, s + i + 1, len); i -= 1; len -= 1; } } s[len + 1] = '\0'; } void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) { strncpy(dest, src + start, cnt); dest[cnt] = 0; } int csq2rssi(int csq) { int result = 0; switch(csq) { case 0 ... 31: result = -113+(2*csq); break; case 100 ... 191: result = -116 + (csq-102); break; case 99: case 199: default: result = csq; break; } return result; } void configNetworkMode(uint8_t actReq) { FILE *fpOrg = fopen("/root/ppp/ppp-on-dialer-org", "r"); FILE *fpDst = fopen("/root/ppp/ppp-on-dialer", "w+"); char str[512]={0}; if(Dongle.Model == DONGLE_QUECTEL) { while (fgets(str, ARRAY_SIZE(str), fpOrg) != NULL) { fprintf(fpDst,"%s", str); if(strstr(str, "ATE1") != NULL) { fprintf(fpDst, " OK \"AT+QCFG=\\\"nwscanmode\\\",%d,1\" \\\n", actReq); } memset(str, 0x00, ARRAY_SIZE(str)); } } else if(Dongle.Model == DONGLE_THALES) { system("cp /root/ppp/ppp-on-dialer-org /root/ppp/ppp-on-dialer"); } fclose(fpOrg); fclose(fpDst); } //========================================== // Main process //========================================== int main(void) { unsigned char Previous_Module_Mode = 0xff; int connectStep=0; int preConnectStep=-1; int delayInterval = DefaultInterval; //========================================== //Initialization share memory //========================================== if(InitShareMemory() == FAIL) { DEBUG_ERROR("InitShareMemory NG\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1; } sleep(5); return 0; } DEBUG_INFO("========================================\n"); DEBUG_INFO("Latest Firmware Version : [ %s ].\n", Version_And_Date[0]); DEBUG_INFO("Latest Upgrade Date : [ %s ].\n", Version_And_Date[1]); for(;;) { if(Previous_Module_Mode != ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled) { Previous_Module_Mode = ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled; DEBUG_INFO("========================================\n"); DEBUG_INFO("4G module : [ %s ]\n", (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled?"Enable":"Disable")); } if(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled) { // Enable 4G switch(connectStep) { case CONNECT_STEP_READ_MODULE_INFO: if(preConnectStep != connectStep) { preConnectStep = connectStep; DEBUG_INFO("----------------------------------------\n"); DEBUG_INFO("Into CONNECT_STEP_READ_MODULE_INFO.\n"); } if(isReadInfo(connectStep) == PASS) { if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, Dongle.MODELNAME) != 0) memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName)); memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, Dongle.MODELNAME, sizeof Dongle.MODELNAME); if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, Dongle.REVISION) != 0) memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer)); memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, Dongle.REVISION, sizeof Dongle.REVISION); if(strcmp((char*)ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, Dongle.REVISION) != 0) memset(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev)); memcpy(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, Dongle.REVISION, sizeof Dongle.REVISION); if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, Dongle.IMEI) != 0) memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei)); memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, Dongle.IMEI, sizeof Dongle.IMEI); DEBUG_INFO("Device MANUFACTURER: %s\n", Dongle.MANUFACTURER); DEBUG_INFO("Device MODEL: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName); DEBUG_INFO("Device REVISION: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer); DEBUG_INFO("Device IMEI: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei); Dongle.cnt_ReadSimInfoFail = 0; connectStep = CONNECT_STEP_READ_SIM_INFO; delayInterval = DefaultInterval; } else { DEBUG_ERROR("Device info read error fail: %d\n", Dongle.cnt_ReadInfoFail); ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = 1; ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi = 1; Dongle.MODE = NET_MODE_NO_SERVICE; memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer); memset(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, 0, sizeof ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei); ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode = 0; Dongle.cnt_ReadInfoFail++; if(Dongle.cnt_ReadInfoFail > 3) { system("killall 4GDetection"); system("killall pppd"); sleep(2); Dongle.cnt_ReadInfoFail = 0; rstModule(); connectStep = CONNECT_STEP_CHECK_MODULE; } delayInterval = CheckModemInfoInterval; } break; case CONNECT_STEP_READ_SIM_INFO: if(preConnectStep != connectStep) { preConnectStep = connectStep; DEBUG_INFO("----------------------------------------\n"); DEBUG_INFO("Into CONNECT_STEP_READ_SIM_INFO.\n"); } if(isReadSimInfo() == PASS) { ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus = 1; if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, Dongle.ICCID) != 0) memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid)); memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, Dongle.ICCID, sizeof Dongle.ICCID); if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, Dongle.IMSI) != 0) memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi)); memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, Dongle.IMSI, sizeof Dongle.IMSI); DEBUG_INFO("Device IMSI: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi); DEBUG_INFO("Device ICCID: %.20s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid); DEBUG_INFO("TelcomSimStatus: %d\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus); Dongle.cnt_ReadSimInfoFail = 0; connectStep = CONNECT_STEP_CONNECTING; delayInterval = DefaultInterval; } else { DEBUG_ERROR("SIM card info read error fail: %d\n", Dongle.cnt_ReadSimInfoFail); ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = 1; ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi = 1; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus = 0; memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress, 0 , sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress); Dongle.cnt_ReadSimInfoFail ++; if(Dongle.cnt_ReadSimInfoFail > 3) { system("killall 4GDetection"); system("killall pppd"); sleep(2); Dongle.cnt_ReadSimInfoFail = 0; rstModule(); connectStep = CONNECT_STEP_CHECK_MODULE; } delayInterval = CheckSimInterval; } break; case CONNECT_STEP_CONNECTING: if(preConnectStep != connectStep) { preConnectStep = connectStep; DEBUG_INFO("----------------------------------------\n"); DEBUG_INFO("Into CONNECT_STEP_CONNECTING.\n"); } if(isPppUp() == PASS) { ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomNetworkConn = 1; ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi = 0; DEBUG_INFO("PPP IP: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress); DEBUG_INFO("Telecom network connection: %d\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomNetworkConn); DEBUG_INFO("Apn connnection status: %s\n", (ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi == 0)? "Connected":"Disconnected"); Dongle.cnt_pppFail = 0; connectStep = CONNECT_STEP_CONNECTED; delayInterval = DefaultInterval; } else { ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomNetworkConn = 0; ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi = 1; if(Load4gConfiguration() == FAIL) { DEBUG_ERROR("4G configuration value NG.\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Telecom4GModuleCommFail=1; } } else { memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress, 0 , sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress); DEBUG_INFO("Apn connnection status: %s\n", (ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi == 0)? "Connected":"Disconnected"); Dongle.cnt_pppFail++; if(Dongle.cnt_pppFail > 3) { system("killall 4GDetection"); system("killall pppd"); sleep(2); Dongle.cnt_pppFail = 0; rstModule(); connectStep = CONNECT_STEP_CHECK_MODULE; } system("killall 4GDetection"); system("killall pppd"); sleep(2); /* * TODO: * 1. Act priority check */ configNetworkMode(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomNetworkType); if(Dongle.Model == DONGLE_QUECTEL) { system("/root/ppp/4GDetection /dev/ttyUSB3 &"); printf("4GDetection for primary device.\n"); } else if(Dongle.Model == DONGLE_THALES) { system("/root/ppp/4GDetection /dev/ttyACM0 &"); printf("4GDetection for second device.\n"); } else {} } delayInterval = CheckConnectionInterval; } break; case CONNECT_STEP_CONNECTED: if(preConnectStep != connectStep) { preConnectStep = connectStep; DEBUG_INFO("----------------------------------------\n"); DEBUG_INFO("Into CONNECT_STEP_CONNECTED.\n"); } if((isReadInfo(connectStep) == PASS) && (isReachableInternet() == PASS)) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Telecom4GModuleCommFail = 0; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = 0; Dongle.cnt_InternetFail = 0; DEBUG_INFO("Dongle internet valid result: Pass\n"); delayInterval = CheckInternetInterval; } else { DEBUG_INFO("Dongle internet valid result: Fail %d time\n", Dongle.cnt_InternetFail); ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = 1; Dongle.cnt_InternetFail++; if((Dongle.cnt_InternetFail > 3) && !ShmSysConfigAndInfo->SysInfo.OcppConnStatus) { system("killall 4GDetection"); system("killall pppd"); sleep(2); Dongle.cnt_InternetFail = 0; rstModule(); connectStep = CONNECT_STEP_CHECK_MODULE; } delayInterval = DisconnInterval; } if(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi != csq2rssi(Dongle.CSQ)) { ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi = csq2rssi(Dongle.CSQ); DEBUG_INFO("RSSI: %d dBm (CSQ:%d)\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi, Dongle.CSQ); } if(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode != Dongle.MODE) { ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode = Dongle.MODE; DEBUG_INFO("Device MODE: %d\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode); DEBUG_INFO("Device Act: %s\n", Dongle.act); DEBUG_INFO("Device Band: %s\n", Dongle.band); DEBUG_INFO("Device Channel: %d\n", Dongle.channel); } DEBUG_INFO("TX counter: %d bytes\n", Dongle.bytesTx); DEBUG_INFO("RX counter: %d bytes\n", Dongle.bytesRx); DEBUG_INFO("Delta counter: %d bytes\n", (Dongle.bytesTx+Dongle.bytesRx)-Dongle.lastCounter); Dongle.lastCounter = (Dongle.bytesTx+Dongle.bytesRx); DEBUG_INFO("++++++++++++++++++++++++++++++++++++++++\n"); break; default: case CONNECT_STEP_CHECK_MODULE: if(preConnectStep != connectStep) { preConnectStep = connectStep; DEBUG_INFO("----------------------------------------\n"); DEBUG_INFO("Into CONNECT_STEP_CHECK_MODULE.\n"); } if(((Dongle.Model = Check4GModem()) != FAIL)) { ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode = 0; ShmStatusCodeData->FaultCode.FaultEvents.bits.Telecom4GModuleBroken = 0; Dongle.cnt_SearchModuleFail = 0; connectStep = CONNECT_STEP_READ_MODULE_INFO; delayInterval = DefaultInterval; } else { DEBUG_ERROR("Device search error fail: %d\n", Dongle.cnt_SearchModuleFail); ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = 1; ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi = 1; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Telecom4GModuleCommFail = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomNetworkConn = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode = 0; memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer); memset(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, 0, sizeof ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName); Dongle.cnt_SearchModuleFail++; if(Dongle.cnt_SearchModuleFail > 3) { DEBUG_ERROR("4G Module was broken.\n"); if(isModuleUnbind() == PASS) { isModuleBind(); } ShmStatusCodeData->FaultCode.FaultEvents.bits.Telecom4GModuleBroken = 1; Dongle.cnt_SearchModuleFail = 0; } delayInterval = CheckModemInterval; } break; } } else { // Disable 4G ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = 0; ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi= 0; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Telecom4GModuleCommFail = 0; ShmStatusCodeData->FaultCode.FaultEvents.bits.Telecom4GModuleBroken = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomNetworkConn = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus = 0; ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode = 0; memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer); memset(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, 0, sizeof ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev); memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, 0, sizeof ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName); if(system("pidof -s 4GDetection > /dev/null") == 0) { DEBUG_INFO("4GDetection running, stop it.\n"); system("killall 4GDetection"); } if(system("pidof -s pppd > /dev/null") == 0) { DEBUG_INFO("pppd running, stop it.\n"); system("killall pppd"); } if(isPppUp() == PASS) { system("ifconfig ppp0 down"); } connectStep = CONNECT_STEP_CHECK_MODULE; delayInterval = DefaultInterval; } sleep(delayInterval); } return 0; }