Peter Ferland / MTS-Cellular_lat1

Fork of MTS-Cellular by MultiTech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Cellular.h Source File

Cellular.h

00001 #ifndef CELLULAR_H
00002 #define CELLULAR_H
00003 
00004 #include <string>
00005 #include <vector>
00006 
00007 #include "IPStack.h"
00008 #include "MTSBufferedIO.h"
00009 #include "CellUtils.h"
00010 
00011 namespace mts
00012 {
00013 
00014 /** This is a class for communicating with a Cellular radio device.
00015 * This class supports three main types of cellular radio interactions including:
00016 * configuration and status processing, SMS processing, and TCP/UDP Socket
00017 * data connections. This class also inherits from IPStack providing a common set of commands
00018 * for communication devices that support IP protocols. It is also integrated with the standard
00019 * mbed Sockets package and can therefore be used seamlessly with clients and services built
00020 * on top of this interface already within the mbed library.
00021 *
00022 * For all examples below please change Pin Names to match your hardware configuration.
00023 * It also assumes the use of RTS/CTS hardware handshaking using GPIOs. To disable this
00024 * you will need to change settings on the radio module and and use the MTSSerial class
00025 * instead of MTSSerialFlowControl.
00026 *
00027 * The following set of example code demonstrates how to send and receive configuration and
00028 * status AT commands with the radio, create a data connection and test it:
00029 * @code
00030 * #include "mbed.h"
00031 * #include "mtsas.h"
00032 *
00033 * int main(){
00034 *    //Modify to match your apn if you are using an HSPA radio with a SIM card
00035 *    const char APN[] = "";
00036 *    
00037 *    //Sets the log level to INFO, higher log levels produce more log output.
00038 *    //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
00039 *    MTSLog::setLogLevel(MTSLog::INFO_LEVEL);
00040 *    
00041 *    // STMicro Nucelo F401RE
00042 *    // The supported jumper configurations of the MTSAS do not line up with
00043 *    // the pin mapping of the Nucleo F401RE. Therefore, the MTSAS serial TX
00044 *    // pin (JP8 Pin 2) must be manually jumped to Serial1 RX (Shield pin D2)
00045 *    // and the MTSAS serial RX pin (JP9 Pin 2) pin must be manually jumped to
00046 *    // Serial1 TX (Shield pin D8).
00047 *    // Uncomment the following line to use the STMicro Nuceleo F401RE
00048 *    //
00049 *    MTSSerialFlowControl* io = new MTSSerialFlowControl(D8, D2, D3, D6);
00050 *    
00051 *    // Freescale KL46Z
00052 *    // To configure the pins for the Freescale KL46Z board, use configuration B
00053 *    // Uncomment the following line to use the Freescale KL46Z board
00054 *    //
00055 *    //MTSSerialFlowControl* io = new MTSSerialFlowControl(D2, D9, D3, D6);
00056 *    
00057 *    // Freescale K64F
00058 *    // To configure the pins for the Freescale KL46Z board, use configuration A
00059 *    // Uncomment the following line to use the Freescale KL46F board
00060 *    //
00061 *    //MTSSerialFlowControl* io = new MTSSerialFlowControl(D1, D0, D3, D6);
00062 *    
00063 *    //Sets the baud rate for communicating with the radio
00064 *    io->baud(115200);
00065 *    
00066 *    //Create radio object
00067 *    Cellular* radio = CellularFactory::create(io);
00068 *    radio->configureSignals(D4,D7,RESET);
00069 *    Transport::setTransport(radio);
00070 *    
00071 *    if (! radio) {
00072 *        logFatal("Failed to initialize radio");
00073 *        return 1;
00074 *    }
00075 *    
00076 *    //Set radio APN
00077 *    for (int i = 0; i < 10; i++) {
00078 *        if (i >= 10) {
00079 *            logError("Failed to set APN to %s", APN);
00080 *        }
00081 *        if (radio->setApn(APN) == MTS_SUCCESS) {
00082 *            logInfo("Successfully set APN to %s", APN);
00083 *            break;
00084 *        } else {
00085 *            wait(1);
00086 *        }
00087 *    }
00088 *    
00089 *    //Establish PPP link
00090 *    for (int i = 0; i < 10; i++) {
00091 *        if (i >= 10) {
00092 *            logError("Failed to establish PPP link");
00093 *        }
00094 *        if (radio->connect() == true) {
00095 *            logInfo("Successfully established PPP link");
00096 *            break;
00097 *        } else {
00098 *            wait(1);
00099 *        }
00100 *    }
00101 *    
00102 *    //Ping google.com
00103 *    for (int i = 0; i < 10; i++) {
00104 *        if (i >= 10) {
00105 *            logError("Failed to ping www.google.com");
00106 *        }
00107 *        if (radio->ping("www.google.com") == true) {
00108 *            logInfo("Successfully pinged www.google.com");
00109 *            break;
00110 *        } else {
00111 *            wait(1);
00112 *        }
00113 *    }
00114 *    
00115 *    //Disconnect ppp link
00116 *    radio->disconnect();
00117 *    
00118 *    logInfo("End of example code");
00119 *    return 0;
00120 * }
00121 *
00122 * @endcode
00123 *
00124 * The following set of example code demonstrates how to process SMS messages:
00125 * @code
00126 * #include "mbed.h"
00127 * #include "mtsas.h"
00128 *
00129 * int main(){
00130 *    
00131 *    //Sets the log level to INFO, higher log levels produce more log output.
00132 *    //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
00133 *    MTSLog::setLogLevel(MTSLog::INFO_LEVEL);
00134 *    
00135 *    //Modify to match your apn if you are using an HSPA radio with a SIM card
00136 *    const char APN[] = "";
00137 *    
00138 *    //Phone number to send to and receive from. Must be in the form "1xxxxxxxxxx"
00139 *    string PHONE_NUMBER = "";
00140 *    
00141 *    Cellular::Sms txtmsg;
00142 *    txtmsg.phoneNumber = PHONE_NUMBER;
00143 *    txtmsg.message = "Hello World! MTSAS is up and running!";
00144 *    
00145 *    // STMicro Nucelo F401RE
00146 *    // The supported jumper configurations of the MTSAS do not line up with
00147 *    // the pin mapping of the Nucleo F401RE. Therefore, the MTSAS serial TX
00148 *    // pin (JP8 Pin 2) must be manually jumped to Serial1 RX (Shield pin D2)
00149 *    // and the MTSAS serial RX pin (JP9 Pin 2) pin must be manually jumped to
00150 *    // Serial1 TX (Shield pin D8).
00151 *    // Uncomment the following line to use the STMicro Nuceleo F401RE
00152 *    //
00153 *    MTSSerialFlowControl* io = new MTSSerialFlowControl(D8, D2, D3, D6);
00154 *    
00155 *    // Freescale KL46Z
00156 *    // To configure the pins for the Freescale KL46Z board, use configuration B
00157 *    // Uncomment the following line to use the Freescale KL46Z board
00158 *    //
00159 *    //MTSSerialFlowControl* io = new MTSSerialFlowControl(D2, D9, D3, D6);
00160 *    
00161 *    // Freescale K64F
00162 *    // To configure the pins for the Freescale KL46Z board, use configuration A
00163 *    // Uncomment the following line to use the Freescale KL46F board
00164 *    //
00165 *    //MTSSerialFlowControl* io = new MTSSerialFlowControl(D1, D0, D3, D6);
00166 *    
00167 *    //Sets the baudrate for communicating with the radio
00168 *    io->baud(115200); 
00169 *    
00170 *    //Creates a radio object
00171 *    Cellular* radio = CellularFactory::create(io);
00172 *    radio->configureSignals(D4,D7,RESET);
00173 *    Transport::setTransport(radio);
00174 *    
00175 *    if (! radio) {
00176 *        logFatal("Failed to initialize radio");
00177 *        return 1;
00178 *    }
00179 *    
00180 *    //Set radio APN
00181 *    for (int i = 0; i < 10; i++) {
00182 *        if (i >= 10) {
00183 *            logError("Failed to set APN\n");
00184 *        }
00185 *        if (radio->setApn(APN) == MTS_SUCCESS) {
00186 *            logInfo("Successfully set APN\n");
00187 *            break;
00188 *        } else {
00189 *            wait(1);
00190 *        }
00191 *    }
00192 *    
00193 *    //Delete any previously received SMS messages
00194 *    for (int i = 0; i < 10; i++) {
00195 *        if (i >= 10) {
00196 *            logError("Failed to delete SMS messages\n");
00197 *        }
00198 *        if (radio->deleteAllReceivedSms() == MTS_SUCCESS) {
00199 *            logInfo("Deleted all SMS messages\n");
00200 *            break;
00201 *        } else {
00202 *            wait(1);
00203 *        }
00204 *    }
00205 *    
00206 *    // Send SMS message to phone
00207 *    for (int i = 1; i < 10; i++) {
00208 *        if(radio->sendSMS(txtmsg) == MTS_SUCCESS) {
00209 *            logInfo("Sent SMS successfully:<%s>\n", txtmsg.message.c_str());
00210 *            break;
00211 *        } else {
00212 *            logError("Failed to send SMS<%s>\n", txtmsg.message.c_str());
00213 *        }
00214 *    }
00215 *    
00216 *    //Checking for received SMS messages
00217 *    while (true) {
00218 *        logInfo("Checking for received messages");
00219 *        vector<Cellular::Sms> recv = radio->getReceivedSms();
00220 *        if(recv.size() > 0) {
00221 *            int size = recv.size();
00222 *            for (int i = 0; i < size; i++) {
00223 *                logInfo("Message %d: [%s] [%s] [%s]", i, recv[i].phoneNumber.c_str(), recv[i].timestamp.c_str(), recv[i].message.c_str());
00224 *            }
00225 *        }
00226 *        
00227 *        if(radio->deleteOnlyReceivedReadSms() != MTS_SUCCESS) {
00228 *            logError("Failed to delete received and read SMS messages");
00229 *        }
00230 *        wait(10);
00231 *    }
00232 *    
00233 *    logDebug("End of example code\n");
00234 *    return 0;
00235 * }
00236 * @endcode
00237 */
00238 
00239 class Cellular : public IPStack
00240 {
00241 public:
00242     // Class ping paramter constants
00243     static const unsigned int PINGDELAY = 3; //Time to wait on each ping for a response before timimg out (seconds)
00244     static const unsigned int PINGNUM = 4; //Number of pings to try on ping command
00245 
00246     /// Enumeration for different cellular radio types.
00247     enum Radio {
00248         NA, MTSMC_H5, MTSMC_EV3, MTSMC_G3, MTSMC_C2, MTSMC_H5_IP, MTSMC_EV3_IP, MTSMC_C2_IP, MTSMC_LAT1, MTSMC_LVW2, MTSMC_LEU1
00249     };
00250 
00251     /// An enumeration of radio registration states with a cell tower.
00252     enum Registration {
00253         NOT_REGISTERED, REGISTERED, SEARCHING, DENIED, UNKNOWN, ROAMING
00254     };
00255 
00256     /** This structure contains the data for an SMS message.
00257     */
00258     struct Sms {
00259         /// Message Phone Number
00260         std::string phoneNumber;
00261         /// Message Body
00262         std::string message;
00263         /// Message Timestamp
00264         std::string timestamp;
00265     };
00266 
00267     /** This structure contains the data for GPS position.
00268     */
00269     struct gpsData {
00270         bool success;
00271         /// Format is ddmm.mmmm N/S. Where: dd - degrees 00..90; mm.mmmm - minutes 00.0000..59.9999; N/S: North/South.
00272         std::string latitude;
00273         /// Format is dddmm.mmmm E/W. Where: ddd - degrees 000..180; mm.mmmm - minutes 00.0000..59.9999; E/W: East/West.
00274         std::string longitude;
00275         /// Horizontal Diluition of Precision.
00276         float hdop;
00277         /// Altitude - mean-sea-level (geoid) in meters.
00278         float altitude;
00279         /// 0 or 1 - Invalid Fix; 2 - 2D fix; 3 - 3D fix.
00280         int fix;
00281         /// Format is ddd.mm - Course over Ground. Where: ddd - degrees 000..360; mm - minutes 00..59.
00282         std::string cog;
00283         /// Speed over ground (Km/hr).
00284         float kmhr;
00285         /// Speed over ground (knots).
00286         float knots;
00287         /// Total number of satellites in use.
00288         int satellites;
00289         /// Date and time in the format YY/MM/DD,HH:MM:SS.
00290         std::string timestamp;
00291     };
00292     
00293     /** This method initializes the object with the underlying radio
00294     * interface to use. Note that this function MUST be called before
00295     * any other calls will function correctly on a Cellular object. Also
00296     * note that MTSBufferedIO is abstract, so you must use one of
00297     * its inherited classes like MTSSerial, MTSSerialFlowControl or write a class
00298     * similar to MTSSerialFlowControl which maps the MTSBufferedIO API
00299     * to your favorite serial library.
00300     *
00301     * @param io the io interface that is attached to the cellular radio.
00302     * The default is not connected.
00303     * @returns true if the init was successful, otherwise false.
00304     */
00305     virtual bool init(MTSBufferedIO* io);
00306     
00307     /** Sets up the physical connection pins
00308     *   (DTR,DCD, and RESET)
00309     */
00310     bool configureSignals(unsigned int DCD = NC, unsigned int DTR = NC, unsigned int RESET = NC);
00311 
00312     /** A method for testing command access to the radio.  This method sends the
00313     * command "AT" to the radio, which is a standard radio test to see if you
00314     * have command access to the radio.  The function returns when it receives
00315     * the expected response from the radio.
00316     *
00317     * @returns the standard AT Code enumeration.
00318     */
00319     virtual Code test();
00320 
00321     /** A method for getting the signal strength of the radio. This method allows you to
00322     * get a value that maps to signal strength in dBm. Here 0-1 is Poor, 2-9 is Marginal,
00323     * 10-14 is Ok, 15-19 is Good, and 20+ is Excellent.  If you get a result of 99 the
00324     * signal strength is not known or not detectable.
00325     *
00326     * @returns an integer representing the signal strength.
00327     */
00328     virtual int getSignalStrength();
00329 
00330     /** This method is used to check the registration state of the radio with the cell tower.
00331     * If not appropriatley registered with the tower you cannot make a cellular connection.
00332     *
00333     * @returns the registration state as an enumeration type.
00334     */
00335     virtual Registration getRegistration();
00336 
00337     /** This method is used to set the radios APN if using a SIM card. Note that the APN
00338     * must be set correctly before you can make a data connection. The APN for your SIM
00339     * can be obtained by contacting your cellular service provider.
00340     *
00341     * @param the APN as a string.
00342     * @returns the standard AT Code enumeration.
00343     */
00344     virtual Code setApn(const std::string& apn) = 0;
00345 
00346     /** This method is used to set the DNS which enables the use of URLs instead
00347     * of IP addresses when making a socket connection.
00348     *
00349     * @param the DNS server address as a string in form xxx.xxx.xxx.xxx.
00350     * @returns the standard AT Code enumeration.
00351     */
00352     virtual Code setDns(const std::string& primary, const std::string& secondary = "0.0.0.0");
00353 
00354     /** This method is used to send an SMS message. Note that you cannot send an
00355     * SMS message and have a data connection open at the same time.
00356     *
00357     * @param phoneNumber the phone number to send the message to as a string.
00358     * @param message the text message to be sent.
00359     * @returns the standard AT Code enumeration.
00360     */
00361     virtual Code sendSMS(const std::string& phoneNumber, const std::string& message);
00362 
00363     /** This method is used to send an SMS message. Note that you cannot send an
00364     * SMS message and have a data connection open at the same time.
00365     *
00366     * @param sms an Sms struct that contains all SMS transaction information.
00367     * @returns the standard AT Code enumeration.
00368     */
00369     virtual Code sendSMS(const Sms& sms);
00370 
00371     /** This method retrieves all of the SMS messages currently available for
00372     * this phone number.
00373     *
00374     * @returns a vector of existing SMS messages each as an Sms struct.
00375     */
00376     virtual std::vector<Cellular::Sms> getReceivedSms();
00377 
00378     /** This method can be used to remove/delete all received SMS messages
00379     * even if they have never been retrieved or read.
00380     *
00381     * @returns the standard AT Code enumeration.
00382     */
00383     virtual Code deleteAllReceivedSms();
00384 
00385     /** This method can be used to remove/delete all received SMS messages
00386     * that have been retrieved by the user through the getReceivedSms method.
00387     * Messages that have not been retrieved yet will be unaffected.
00388     *
00389     * @returns the standard AT Code enumeration.
00390     */
00391     virtual Code deleteOnlyReceivedReadSms();
00392 
00393     //Cellular Radio Specific
00394     /** A method for sending a generic AT command to the radio. Note that you cannot
00395     * send commands and have a data connection at the same time.
00396     *
00397     * @param command the command to send to the radio without the escape character.
00398     * @param timeoutMillis the time in millis to wait for a response before returning.
00399     * @param esc escape character to add at the end of the command, defaults to
00400     * carriage return (CR).  Does not append any character if esc == 0.
00401     * @returns all data received from the radio after the command as a string.
00402     */
00403     virtual std::string sendCommand(const std::string& command, unsigned int timeoutMillis, char esc = CR);
00404 
00405     /** A method for sending a basic AT command to the radio. A basic AT command is
00406     * one that simply has a response of either OK or ERROR without any other information.
00407     * Note that you cannot send commands and have a data connection at the same time.
00408     *
00409     * @param command the command to send to the radio without the escape character.
00410     * @param timeoutMillis the time in millis to wait for a response before returning.
00411     * @param esc escape character to add at the end of the command, defaults to
00412     * carriage return (CR).
00413     * @returns the standard Code enumeration.
00414     */
00415     virtual Code sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc = CR);
00416 
00417     /** A static method for getting a string representation for the Registration
00418     * enumeration.
00419     *
00420     * @param code a Registration enumeration.
00421     * @returns the enumeration name as a string.
00422     */
00423     static std::string getRegistrationNames(Registration registration);
00424 
00425     /** A static method for getting a string representation for the Radio
00426     * enumeration.
00427     *
00428     * @param type a Radio enumeration.
00429     * @returns the enumeration name as a string.
00430     */
00431     static std::string getRadioNames(Radio radio);
00432     
00433     /** A method for changing the echo commands from radio.
00434     * @param state Echo mode is off (an argument of 1 turns echos off, anything else turns echo on)
00435     * @returns standard Code enumeration
00436     */
00437     virtual Code echo(bool state);
00438     
00439     /** This method can be used to trade socket functionality for performance.
00440     * Can disable checking socket closed messages from the data socket, and thus the socket
00441     * will only be visibly closed to the local side if the radio is explicitly checked, or
00442     * the socket is closed by the local side through the use of physical pin manipulation.
00443     *
00444     * Uses the Hayes escape sequence (1 second pause, "+++", 1 second pause) to exit the socket
00445     * connection to check if a received "NO CARRIER" string is from the radio indicating the socket
00446     * has been closed, or is merely part of the data stream. Should not occur very often, however, if 
00447     * data carrying the string "NO CARRIER" is going to be transmitted frequently, then the socket should
00448     * be set closeable and physical-socket-closing-means be used instead to reduce the large amount of
00449     * overhead switching from checking the validity of the "NO CARRIER" message being and indication of
00450     * the socket connection being closed.
00451     *
00452     * @param enabled set to true if you want the socket closeable, otherwise false. The default
00453     * is true.
00454     * @returns the standard AT Code enumeration.
00455     */
00456     virtual Code setSocketCloseable(bool enabled);
00457     
00458     /** Binds the socket to a specific port if able
00459     * @param port integer to bind the socket to.
00460     *   
00461     * @returns true if successfully bound port, false if bind failed.
00462     */
00463     virtual bool bind(unsigned int port);
00464     
00465     /** Checks if a socket is open.
00466     * @returns true if socket is open, false if socket is closed
00467     */
00468     virtual bool isOpen();
00469     
00470     /** Checks if there is data available from the socket.
00471     * @returns number of bytes of data available to read.
00472     */
00473     virtual unsigned int readable();
00474     
00475     /** Checks data to output on the socket
00476     * @returns number of bytes to be written to the socket.
00477     */
00478     virtual unsigned int writeable();
00479     
00480     /** Gets the device IP
00481     * @returns string containing the IP address
00482     */
00483     virtual std::string getDeviceIP();
00484     
00485     /** Sets the device IP
00486     * (Not implemented, IP address values are assigned by DHCP)
00487     * @returns true if the IP was set, false if IP address assignment failed.
00488     */
00489     virtual bool setDeviceIP(std::string address = "DHCP");
00490     
00491     /** Get the device IMEI or MEID (whichever is available)
00492     * @returns string containing the IMEI for GSM, the MEID for CDMA, or an empty string
00493     * if it failed to parse the number.
00494     */
00495     std::string getEquipmentIdentifier();
00496 
00497     /** Get radio type
00498     * @returns the radio type (MTSMC-H5, etc)
00499     */
00500     int getRadioType();
00501 
00502     /** Get string representation of radio type
00503     * @returns string containing the radio type (MTSMC-H5, etc)
00504     */
00505     std::string getRadioTypeString();
00506 
00507     /** Enables GPS.
00508     * @returns true if GPS is enabled, false if GPS is not supported.
00509     */
00510     virtual bool GPSenable();
00511 
00512     /** Disables GPS.
00513     * @returns true if GPS is disabled, false if GPS does not disable.
00514     */
00515     virtual bool GPSdisable();
00516 
00517     /** Checks if GPS is enabled.
00518     * @returns true if GPS is enabled, false if GPS is disabled.
00519     */
00520     virtual bool GPSenabled();
00521         
00522     /** Get GPS position.
00523     * @returns a structure containing the GPS data field information.
00524     */
00525     virtual gpsData GPSgetPosition();
00526 
00527     /** Check for GPS fix.
00528     * @returns true if there is a fix and false otherwise.
00529     */
00530     virtual bool GPSgotFix();
00531             
00532 protected:
00533     MTSBufferedIO* io; //IO interface obect that the radio is accessed through.
00534     bool echoMode; //Specifies if the echo mode is currently enabled.
00535 
00536     bool gpsEnabled;    //true if GPS is enabled, else false.
00537         
00538     bool pppConnected; //Specifies if a PPP session is currently connected.
00539     std::string apn; //A string that holds the APN for the radio.
00540 
00541     Radio type; //The type of radio being used
00542 
00543     Mode socketMode; //The current socket Mode.
00544     bool socketOpened; //Specifies if a Socket is presently opened.
00545     bool socketCloseable; //Specifies is a Socket can be closed.
00546     unsigned int local_port; //Holds the local port for socket connections.
00547     std::string local_address; //Holds the local address for socket connections.
00548     unsigned int host_port; //Holds the remote port for socket connections.
00549     std::string host_address; //Holds the remote address for socket connections.
00550 
00551     DigitalIn* dcd; //Maps to the radio's dcd signal
00552     DigitalOut* dtr; //Maps to the radio's dtr signal
00553     DigitalOut* resetLine; //Maps to the radio's reset signal 
00554 };
00555 
00556 }
00557 
00558 #endif /* CELLULAR_H */