This is a test of the ability to publish code

Dependencies:   mbed SpiFlash25 mtsas

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RadioManager.h Source File

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_