This is a test of the ability to publish code
Dependencies: mbed SpiFlash25 mtsas
RadioManager.h
00001 00002 #ifndef _RadioManager_h_ 00003 #define _RadioManager_h_ 00004 00005 #include "mtsas.h" 00006 00007 #include <time.h> 00008 00009 // static const char RadioAPN[] = "m2m.com.attz"; // Works with developer SIMs from ATT 00010 static const char RadioAPN[] = "10569.mcs"; // We hope this works with new SIMs 00011 00012 class RadioManager 00013 { 00014 public: 00015 RadioManager() : 00016 m_requestedConnection(false), 00017 m_hasEverConnected(false), 00018 m_io(NULL), 00019 m_cellular(NULL), 00020 m_radioEnablePin(PC_13) 00021 { 00022 } 00023 00024 ~RadioManager() 00025 { 00026 if (m_cellular) 00027 { 00028 m_cellular->disconnect(); 00029 delete m_cellular; 00030 m_cellular = NULL; 00031 } 00032 if (m_io) 00033 { 00034 delete m_io; 00035 m_io = NULL; 00036 } 00037 } 00038 00039 void resumeWatchdog() 00040 { 00041 //printf("resumeWatchdog() already %1.3f\r\n", (float)m_radioRebootWatchdog.read()); 00042 if (m_radioRebootWatchdog.read() > 0) return; // Already started, don't reset it 00043 00044 // Need to start it 00045 m_radioRebootWatchdog.reset(); 00046 m_radioRebootWatchdog.start(); 00047 } 00048 00049 void feedWatchdog() 00050 { 00051 //printf("feedWatchdog()\r\n"); 00052 // Reset it but set to 0 00053 m_radioRebootWatchdog.stop(); 00054 m_radioRebootWatchdog.reset(); 00055 m_radioRebootWatchdog.start(); 00056 } 00057 00058 void stopWatchdog() 00059 { 00060 //printf("stopWatchdog()\r\n"); 00061 m_radioRebootWatchdog.reset(); 00062 m_radioRebootWatchdog.stop(); 00063 } 00064 00065 bool serviceWatchdog() 00066 { 00067 // Check if radio wdt has elapsed and reboot the radio if so 00068 if (m_radioRebootWatchdog.read() > 60*30) // If any radio operation takes longer than this # of seconds, it's time to reboot the radio. 00069 { 00070 printf("Radio watchdog tripped! Rebooting radio.\r\n"); 00071 return initialize(); 00072 } 00073 00074 return true; // true means OK 00075 } 00076 00077 int watchdogValue() 00078 { 00079 return (int)m_radioRebootWatchdog.read(); 00080 } 00081 00082 bool initialize() 00083 { 00084 // Always start/feed the radio watchdog when initializing; we mustn't wait until 00085 // contact has been made to start wondering if contact is going to be made. 00086 feedWatchdog(); 00087 00088 // Hard-reboot the modem for starters. 00089 m_radioEnablePin = 0; 00090 wait_ms(100); // must be <<< than 1 second for hard reset. 00091 m_radioEnablePin = 1; 00092 // Wait for radio to reboot 00093 wait_ms(8500); 00094 printf("Radio rebooted.\r\n"); 00095 00096 if (!m_io) 00097 { 00098 m_io = new mts::MTSSerialFlowControl(RADIO_TX, RADIO_RX, RADIO_RTS, RADIO_CTS); 00099 } 00100 if (!m_io) return false; 00101 00102 // Radio baud rate is 115200 00103 m_io->baud(115200); 00104 00105 // Send a ctrl+z and a \n sequence to escape out of any half-entered commands 00106 char escapeSequence[4] = {0}; 00107 snprintf(escapeSequence,4,"%c%c%c",0x1a,0x1b,'\n'); 00108 m_io->write(escapeSequence, 3); 00109 00110 // Build cellular object 00111 if (!m_cellular) 00112 { 00113 m_cellular = mts::CellularFactory::create(m_io); 00114 } 00115 if (!m_cellular) 00116 { 00117 delete m_io; 00118 m_io = NULL; 00119 return false; 00120 } 00121 00122 std::string result; 00123 00124 // ConnId 1, cid 1, 1500 byte packets, 1000 seconds to socket auto-close, 15 seconds to connect timeout, 50 milliseconds auto send-flush timer. 00125 result = m_cellular->sendCommand("AT#SCFG=1,1,1500,1000,15,50", 5000); 00126 if (!result.find("\nOK\n")) 00127 { 00128 printf("Failed to configure radio (at#SCFG)\r\n"); 00129 return false; 00130 } 00131 00132 // Configure better socket connection timeout than default 00133 result = m_cellular->sendCommand("at#SKTCT=150", 5000); // 100 x 0.1s = 10sec 00134 if (!result.find("\nOK\n")) 00135 { 00136 printf("Failed to configure radio (at#SKTCT)\r\n"); 00137 return false; 00138 } 00139 00140 // Configure the socket-inactivity timeout 00141 result = m_cellular->sendCommand("at#SKTTO=1000", 8000); // 800 sec (10 min) inactivity timeout for socket--basically keep the socket open. 00142 if (!result.find("\nOK\n")) 00143 { 00144 printf("Failed to configure radio (at#SKTTO=120)\r\n"); 00145 return false; 00146 } 00147 00148 /// Configure APN 00149 printf("Configuring radio APN '%s'\r\n", RadioAPN); 00150 if (m_cellular->setApn(RadioAPN) != MTS_SUCCESS) 00151 { 00152 printf("Failed to set Radio APN to '%s'\r\n", RadioAPN); 00153 delete m_cellular; 00154 m_cellular = NULL; 00155 delete m_io; 00156 m_io = NULL; 00157 return false; 00158 } 00159 00160 return true; 00161 } 00162 00163 bool hasEverConnected() const 00164 { 00165 return m_hasEverConnected; 00166 } 00167 00168 bool connect() 00169 { 00170 if (!m_cellular) return false; 00171 m_requestedConnection = true; 00172 if (m_cellular->connect()) 00173 { 00174 m_hasEverConnected = true; 00175 return true; 00176 } 00177 return false; 00178 } 00179 00180 void disconnect() 00181 { 00182 if (!m_cellular) return; 00183 m_requestedConnection = false; 00184 m_cellular->disconnect(); 00185 } 00186 00187 bool isConnected() 00188 { 00189 if (!m_io) return false; 00190 if (!m_cellular) return false; 00191 return m_cellular->isConnected(); 00192 } 00193 00194 string sendCommand(const std::string& command, unsigned int timeoutMillis, char esc = CR) 00195 { 00196 if (!m_cellular) return std::string("NO RADIO\nERROR\n"); 00197 return m_cellular->sendCommand(command, timeoutMillis, esc); 00198 } 00199 00200 string sendCommandWithBinaryPayload(const std::string& command, const char* payload, size_t payloadSize, unsigned int timeoutMillis, char esc = CR) 00201 { 00202 if (!m_cellular) return std::string("NO RADIO\nERROR\n"); 00203 return m_cellular->sendCommandWithBinaryPayload(command, payload, payloadSize, timeoutMillis, esc); 00204 } 00205 00206 int64_t getTime() 00207 { 00208 if (!m_cellular) return 0; 00209 00210 string response = m_cellular->sendCommand("AT+CCLK?", 500); 00211 size_t found = response.find("CCLK: \""); 00212 if (found == string::npos) return 0; 00213 const char* timeSubstr = &response.c_str()[found+7]; 00214 int year, month, dom, hour, min, sec, tzoffset; 00215 char plusMinusChar = '\0'; 00216 if (8 != sscanf(timeSubstr, "%d/%d/%d,%d:%d:%d%c%d", 00217 &year, 00218 &month, 00219 &dom, 00220 &hour, 00221 &min, 00222 &sec, 00223 &plusMinusChar, 00224 &tzoffset)) return -1; 00225 std::tm time; 00226 memset(&time, 0, sizeof(time)); 00227 time.tm_sec = sec; 00228 time.tm_min = min; 00229 time.tm_hour = hour; 00230 time.tm_mday = dom; 00231 time.tm_mon = month - 1; 00232 time.tm_year = year + 2000 - 1900; 00233 time.tm_isdst = 0; 00234 time.tm_yday = 0; 00235 int t = mktime(&time); 00236 // Magic number 15 below: modem reports the timezone in 15-minute increments, so 00237 // we scale that up to seconds. 00238 t -= 15*60*tzoffset * (plusMinusChar == '-' ? -1 : 1); 00239 return (int64_t)t; 00240 } 00241 00242 private: 00243 bool m_requestedConnection; 00244 bool m_hasEverConnected; 00245 mts::MTSSerialFlowControl* m_io; 00246 mts::Cellular* m_cellular; 00247 DigitalOut m_radioEnablePin; 00248 00249 Timer m_radioRebootWatchdog; 00250 }; 00251 00252 00253 #endif //_RadioManager_h_
Generated on Sat Jul 16 2022 20:02:36 by 1.7.2