📄 gprs.c
字号:
/* socket is open */ blueTCPSocketOpen = utTrue; return utTrue; }utBool blueIsTCPSocketOpen(){ return blueTCPSocketOpen;}// ----------------------------------------------------------------------------/* close whatever type of socket is open (TCP/IDP) */utBool blueCloseSocket(){ ComPort_t *com = &blueComPort; char resp[128]; blueTCPSocketOpen = utFalse; comPortWrite(com, (UInt8*)ETX_STRINGZ, strlen(ETX_STRINGZ)); while (utTrue) { if (!BLUE_READLINE(com, 3, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_SOCKET_CLOSED)) { logDEBUG(LOGSRC,"Socket closed"); return utTrue; } }}// ----------------------------------------------------------------------------static char *_blueStartConnection(){ ComPort_t *com = &blueComPort; char resp[128]; /* reset ipAddress */ *ipAddress = 0; /* connect [ AT#CONNECTIONSTART ] */ // Expect: "<ipAddr>","Ok_Info_GprsActivation" | "#CME ERROR: 35865" comPortWriteAT(com, "#CONNECTIONSTART"); while (utTrue) { if (!BLUE_READLINE(com, 3, 10000L, resp, sizeof(resp))) { return (char*)0; } if (strEqualsIgnoreCase(resp, RESULT_GPRS_ACTIVATION)) { break; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (strStartsWithIgnoreCase(resp, RESULT_ALREADY_CONNECTED)) { break; } if (strStartsWithIgnoreCase(resp, RESULT_NOT_REGISTERED)) { // Registration was supposed to have been verified above. If we get // this error here, then we must have a serious problem. Reset modem. logERROR(LOGSRC,"Connection failed with 'Not Registered', sending reset ..."); bluePowerOnReset = utTrue; return (char*)0; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return (char*)0; } if (isdigit(resp[0])) { logDEBUG(LOGSRC,"[IP] %s", resp); strcpy(ipAddress, resp); } } comPortFlush(com, 100L); /* Get IP address [ AT#DISPLAYIP ]*/ // Expect: '#MY IP: "10.80.71.42"','#PEER IP: "0.0.0.0",'#GATEWAY IP: "0.0.0.0",'OK' | '#CME ERROR: 35867' if (!*ipAddress || logIsLevel(SYSLOG_DEBUG)) { // Either we didn't get the IP address above, or we are at debug logging level // The most likely case is that we are currently in debug logging mode comPortWriteAT(com, "#DISPLAYIP"); while (utTrue) { if (!BLUE_READLINE(com, 2, 1000L, resp, sizeof(resp))) { return (char*)0; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { if (strEqualsIgnoreCase(resp, RESULT_INACTV_PHYS_LAYER)) { // if we get here we need to close the current connection and start over. blueConnectionReset = utTrue; } return (char*)0; } logDEBUG(LOGSRC,"[IP] %s", resp); if (!*ipAddress && strStartsWithIgnoreCase(resp, "#MY IP: \"")) { char *ip = resp + 9; // first character after first quote const char *x = strLastIndexOfChar(ip, '\"'); if (x == (char*)0) { x = ip + strlen(ip); } // save IP address strncpy(ipAddress, ip, (x - ip)); ipAddress[x - ip] = 0; } } comPortFlush(com, 100L); } /* Get DNS addresses [ AT#VDNS ]*/ // Expect: '#DNSSERV1: "X.X.X.X"','#DNSSERV2: "X.X.X.X", 'OK' if (logIsLevel(SYSLOG_DEBUG)) { // Show iff we are at debug logging level comPortWriteAT(com, "#VDNS"); while (utTrue) { // ignore any errors if (!BLUE_READLINE(com, 2, 1000L, resp, sizeof(resp))) { break; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { break; } logDEBUG(LOGSRC,"[DNS] %s", resp); } comPortFlush(com, 100L); } /* return IP address */ return ipAddress; }static void _blueStopConnection(){ ComPort_t *com = &blueComPort; char resp[128]; /* clear/reset ipAddress */ *ipAddress = 0; /* close open socket */ blueCloseSocket(); /* disconnect [ AT#CONNECTIONSTOP ] */ // Expect: "OK" comPortWriteAT(com, "#CONNECTIONSTOP"); while (utTrue) { // ignore any errors if (!BLUE_READLINE(com, 3, 5000L, resp, sizeof(resp))) { break; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { break; } // possible 35866 } comPortFlush(com, 100L);}// ----------------------------------------------------------------------------static utBool _blueInitModem(){ ComPort_t *com = &blueComPort; logDEBUG(LOGSRC,"Initializing ... (reset=%u)", (UInt16)bluePowerOnReset); char resp[256]; /* assert DTR */ //comPortSetDTR(com, utTrue); //comPortSetRTS(com, utTrue); /* discard existing characters */ comPortFlush(com, 100L); /* software power-on reset */ // This should be used sparingly. The modem will need to re-aquire any // tower signal, and thus may take a few seconds/minutes. if (bluePowerOnReset) { //bluePowerOnReset = utFalse; /* reset */ logWARNING(LOGSRC,"Issuing 'Power-On' reset ..."); comPortWriteAT(com, "+CFUN=1"); threadSleepMS(1000L); // besides the "OK", this command does produce some cruft while (utTrue) { if (!BLUE_READLINE(com, 2, 2000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } //logDEBUG(LOGSRC,"[Reset] %s", resp); } comPortFlush(com, 300L); // clear out slag firstOutOfRangeTimer = 0L; // reset firstNotRegisteredTimer = 0L; // reset blueStartupReset = utTrue; /* clear power-on reset */ bluePowerOnReset = utFalse; /* query for required PIN */ } /* stop any current connection */ if (blueConnectionReset) { blueConnectionReset = utFalse; // This may cause a "Comport read timeout" warning _blueStopConnection(); blueStartupReset = utTrue; } /* reset & turn off echo */ comPortWriteAT(com, "ZE0"); while (utTrue) { if (!BLUE_READLINE(com, 2, 1000L, resp, sizeof(resp))) { // read error, or timeout // If we get here too many consecutive times, then one of the following may have occurred: // 1) The modem was disconnected (nothing we can do about this) // 2) The modem is powered-off (nothing we can do about this) // 3) We've openned the wrong serial port // 4) Something is wrong with the serial port configuration (BPS, etc) // 5) The platform has a bug in their implementation of serial ports. if (++blueLastATZErrorCount > 5L) { // close comPort (reopen on next connection attempt) blueLastATZErrorCount = 0L; // reset counter blueCloseCom(); // This case can occur on Cygwin (for #5 above). I have found that closing the // serial port and re-openning it on the next connection attempt appear to fix // the problem (however comPortReopen doesn't work in this case). } return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } //logDEBUG(LOGSRC,"[Init] %s", resp); } comPortFlush(com, 100L); blueLastATZErrorCount = 0L; // reset counter /* enable "#CME ERROR: <>" messages */ comPortWriteAT(com, "+CMEE=1"); while (utTrue) { if (!BLUE_READLINE(com, 2, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } //logDEBUG(LOGSRC,"[CME] %s", resp); } comPortFlush(com, 100L); /* get modem model */ // As far as I can tell, this command is not essential to communication // Expect: "MULTIBAND G850 1900" comPortWriteAT(com, "+GMM"); while (utTrue) { if (!BLUE_READLINE(com, 2, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } memset(blueModemModel, 0, sizeof(blueModemModel)); strncpy(blueModemModel, resp, sizeof(blueModemModel) - 1); //logDEBUG(LOGSRC,"[Model] %s", resp); } comPortFlush(com, 100L); /* start-up reset */ // This is used for startup initialization if (blueStartupReset) { blueStartupReset = utFalse; /* start TCP/IP stack [ AT+WOPEN=1 ] */ // This needs to be done only once for each modem // Expect: "OK" logINFO(LOGSRC,"Restarting TCP/IP stack ..."); comPortWriteAT(com, "+WOPEN=1"); while (utTrue) { if (!BLUE_READLINE(com, 4, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } } comPortFlush(com, 100L); } /* signal strength [ AT+CSQ ] */ // Expect: "+CSQ: 99,99"; int sigStrength = -1; comPortWriteAT(com, "+CSQ"); while (utTrue) { if (!BLUE_READLINE(com, 2, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } if (strStartsWithIgnoreCase(resp, "+CSQ: ")) { char *s = resp + 6; sigStrength = (int)strParseInt32(s, -1); if (sigStrength >= 99) { logWARNING(LOGSRC,"[Signal out-of-range] %s", resp); if (firstOutOfRangeTimer <= 0L) { firstOutOfRangeTimer = utcGetTimer(); } else if (utcIsTimerExpired(firstOutOfRangeTimer,MAX_OUTOFRANGE_TIMEOUT)) { // we've been getting this result too many time, reset modem logERROR(LOGSRC,"Too many 'Out-Of-Range' errors, sending reset ..."); firstOutOfRangeTimer = 0L; // reset bluePowerOnReset = utTrue; } return utFalse; } else { logINFO(LOGSRC,"Signal Strength: %d/31", sigStrength); } } } comPortFlush(com, 100L); if (firstOutOfRangeTimer > 0L) { // If this is the first ok signal strength (after an bad one), // then reset the 'Not Registered' timer also. firstOutOfRangeTimer = 0L; // clear firstNotRegisteredTimer = 0L; } if (sigStrength <= 1) { logWARNING(LOGSRC,"[Weak signal] %s", resp); return utFalse; } /* set for automatic registration */ /* check if registered */ // Expect: "+CREG: 0,1" | "+CREG: 0,2" | "+CREG: 0,5" // Note: "+CREG: 0,0" means that it's not registered, and it's not even trying to BE registered. utBool registered = utFalse; comPortWriteAT(com, "+CGREG?"); // "+CREG?"/"+CGREG?" while (utTrue) { if (!BLUE_READLINE(com, 3, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } if (strStartsWithIgnoreCase(resp, "+CGREG: ") || strStartsWithIgnoreCase(resp, "+CREG: ") ) { char *s = resp + 6; // skip shortest header length while (*s && (*s != ' ')) { s++; } // find first space while (*s && (*s == ' ')) { s++; } // skip spaces if (isdigit(*s)) { s++; } // skip first digit ("0") if (*s == ',') { s++; } // skip "," if (*s == '1') { registered = utTrue; // home network } else if (*s == '5') { registered = utTrue; // roaming } if (!registered) { // If were here, we've passed the signal strength test, so we should be // registered, or will be soon. // If we return here too many times, we should reset the modem. logWARNING(LOGSRC,"[Not registered on network] %s", resp); if (firstNotRegisteredTimer <= 0L) { firstNotRegisteredTimer = utcGetTimer(); } else if (utcIsTimerExpired(firstNotRegisteredTimer,MAX_UNREGISTERED_TIMEOUT)) { // we've been getting this result too many times, reset modem logERROR(LOGSRC,"Too many 'Not Registered' errors, sending reset ..."); firstNotRegisteredTimer = 0L; // reset bluePowerOnReset = utTrue; } return utFalse; } } } comPortFlush(com, 100L); firstNotRegisteredTimer = 0L; // clear /* advanced diagnostics [ AT+CCED=0,1 ] */ // As far as I can tell, this command is not essential to communication // Expect: "+CCED: 310,380,1914,3059,42,163,23,,,0,,,0" comPortWriteAT(com, "+CCED=0,1"); while (utTrue) { if (!BLUE_READLINE(com, 3, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } } comPortFlush(com, 100L); /* get APN info */ int apnCID = 1; const char *apnName = blueGetApnName(); const char *apnServ = blueGetApnServer(); const char *apnUser = blueGetApnUser(); const char *apnPass = blueGetApnPassword(); logINFO(LOGSRC,"APN: name=%s serv=%s user=%s pass=%s", apnName, apnServ, apnUser, apnPass); /* specify ISP [ AT+CGDCONT=1,"IP","proxy" ] */ // Rogers Wireless // APN: name=internet.com serv= user=wapuser1 pass=wap // DNS: dns1=207.181.101.4 dns2=207.181.101.5 // AT&T Wireless // APN: name=proxy serv=proxy user= pass= // APN: name=public serv=public user= pass= // Cingular Wireless // APN: name=isp.cingular serv= user=ISP@CINGULARGPRS.COM pass=CINGULAR1 // DNS: dns1=66.209.10.201 dns2=66.209.10.202 // T-Mobile // APN: name=internet3.voicestream.com serv= user= pass= // DNS: dns1=216.155.175.40 dns2=216.155.175.41 // Microcell // APN: name=internet.fido.ca serv= user=fido pass=fido // Entel PCS // APN: name=imovil.entelpcs.cl serv= user=entelpcs pass=entelpcs // Expect: "OK" if (apnName && *apnName) { comPortWriteATFmt(com, "+CGDCONT=%d,\"IP\",\"%s\"", apnCID, apnName); } else { comPortWriteATFmt(com, "+CGDCONT=%d,\"IP\"", apnCID); } while (utTrue) { if (!BLUE_READLINE(com, 3, 1000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } //logDEBUG(LOGSRC,"[ISP] %s", resp); } comPortFlush(com, 100L); /* GPRS mode #1 ("ATTach") [ AT+CGATT=1 ]*/ // Expect: "OK" | "ERROR" comPortWriteAT(com, "+CGATT=1"); while (utTrue) { if (!BLUE_READLINE(com, 3, 2000L, resp, sizeof(resp))) { return utFalse; } if (strEqualsIgnoreCase(resp, RESULT_OK_VERBOSE)) { break; } if (ERROR_CHECK(resp) || CME_ERROR_CHECK(resp)) { return utFalse; } //logDEBUG(LOGSRC,"[GPRS1] %s", resp); } comPortFlush(com, 100L); /* GPRS mode #2 [ AT#GPRSMODE=1 ]*/ // Expect: "OK" | "ERROR" comPortWriteAT(com, "#GPRSMODE=1"); while (utTrue) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -