Cellular library for MTS Socket Modem Arduino Shield devices from Multi-Tech Systems
Dependents: mtsas mtsas mtsas mtsas
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 MTQ_LAT3, MTQ_LVW3, MTQ_MAT1, MTQ_MVW1 00250 }; 00251 00252 /// An enumeration of radio registration states with a cell tower. 00253 enum Registration { 00254 NOT_REGISTERED, REGISTERED, SEARCHING, DENIED, UNKNOWN, ROAMING 00255 }; 00256 00257 /** This structure contains the data for an SMS message. 00258 */ 00259 struct Sms { 00260 /// Message Phone Number 00261 std::string phoneNumber; 00262 /// Message Body 00263 std::string message; 00264 /// Message Timestamp 00265 std::string timestamp; 00266 }; 00267 00268 /** This structure contains the data for GPS position. 00269 */ 00270 struct gpsData { 00271 bool success; 00272 /// Format is ddmm.mmmm N/S. Where: dd - degrees 00..90; mm.mmmm - minutes 00.0000..59.9999; N/S: North/South. 00273 std::string latitude; 00274 /// Format is dddmm.mmmm E/W. Where: ddd - degrees 000..180; mm.mmmm - minutes 00.0000..59.9999; E/W: East/West. 00275 std::string longitude; 00276 /// Horizontal Diluition of Precision. 00277 float hdop; 00278 /// Altitude - mean-sea-level (geoid) in meters. 00279 float altitude; 00280 /// 0 or 1 - Invalid Fix; 2 - 2D fix; 3 - 3D fix. 00281 int fix; 00282 /// Format is ddd.mm - Course over Ground. Where: ddd - degrees 000..360; mm - minutes 00..59. 00283 std::string cog; 00284 /// Speed over ground (Km/hr). 00285 float kmhr; 00286 /// Speed over ground (knots). 00287 float knots; 00288 /// Total number of satellites in use. 00289 int satellites; 00290 /// Date and time in the format YY/MM/DD,HH:MM:SS. 00291 std::string timestamp; 00292 }; 00293 00294 /** This method initializes the object with the underlying radio 00295 * interface to use. Note that this function MUST be called before 00296 * any other calls will function correctly on a Cellular object. Also 00297 * note that MTSBufferedIO is abstract, so you must use one of 00298 * its inherited classes like MTSSerial, MTSSerialFlowControl or write a class 00299 * similar to MTSSerialFlowControl which maps the MTSBufferedIO API 00300 * to your favorite serial library. 00301 * 00302 * @param io the io interface that is attached to the cellular radio. 00303 * The default is not connected. 00304 * @returns true if the init was successful, otherwise false. 00305 */ 00306 virtual bool init(MTSBufferedIO* io); 00307 00308 /** Sets up the physical connection pins 00309 * (DTR,DCD, and RESET) 00310 */ 00311 bool configureSignals(unsigned int DCD = NC, unsigned int DTR = NC, unsigned int RESET = NC); 00312 00313 /** A method for testing command access to the radio. This method sends the 00314 * command "AT" to the radio, which is a standard radio test to see if you 00315 * have command access to the radio. The function returns when it receives 00316 * the expected response from the radio. 00317 * 00318 * @returns the standard AT Code enumeration. 00319 */ 00320 virtual Code test(); 00321 00322 /** A method for getting the signal strength of the radio. This method allows you to 00323 * get a value that maps to signal strength in dBm. Here 0-1 is Poor, 2-9 is Marginal, 00324 * 10-14 is Ok, 15-19 is Good, and 20+ is Excellent. If you get a result of 99 the 00325 * signal strength is not known or not detectable. 00326 * 00327 * @returns an integer representing the signal strength. 00328 */ 00329 virtual int getSignalStrength(); 00330 00331 /** This method is used to check the registration state of the radio with the cell tower. 00332 * If not appropriatley registered with the tower you cannot make a cellular connection. 00333 * 00334 * @returns the registration state as an enumeration type. 00335 */ 00336 virtual Registration getRegistration(); 00337 00338 /** This method is used to set the radios APN if using a SIM card. Note that the APN 00339 * must be set correctly before you can make a data connection. The APN for your SIM 00340 * can be obtained by contacting your cellular service provider. 00341 * 00342 * @param the APN as a string. 00343 * @returns the standard AT Code enumeration. 00344 */ 00345 virtual Code setApn(const std::string& apn) = 0; 00346 00347 /** This method is used to set the DNS which enables the use of URLs instead 00348 * of IP addresses when making a socket connection. 00349 * 00350 * @param the DNS server address as a string in form xxx.xxx.xxx.xxx. 00351 * @returns the standard AT Code enumeration. 00352 */ 00353 virtual Code setDns(const std::string& primary, const std::string& secondary = "0.0.0.0"); 00354 00355 /** This method is used to send an SMS message. Note that you cannot send an 00356 * SMS message and have a data connection open at the same time. 00357 * 00358 * @param phoneNumber the phone number to send the message to as a string. 00359 * @param message the text message to be sent. 00360 * @returns the standard AT Code enumeration. 00361 */ 00362 virtual Code sendSMS(const std::string& phoneNumber, const std::string& message); 00363 00364 /** This method is used to send an SMS message. Note that you cannot send an 00365 * SMS message and have a data connection open at the same time. 00366 * 00367 * @param sms an Sms struct that contains all SMS transaction information. 00368 * @returns the standard AT Code enumeration. 00369 */ 00370 virtual Code sendSMS(const Sms& sms); 00371 00372 /** This method retrieves all of the SMS messages currently available for 00373 * this phone number. 00374 * 00375 * @returns a vector of existing SMS messages each as an Sms struct. 00376 */ 00377 virtual std::vector<Cellular::Sms> getReceivedSms(); 00378 00379 /** This method can be used to remove/delete all received SMS messages 00380 * even if they have never been retrieved or read. 00381 * 00382 * @returns the standard AT Code enumeration. 00383 */ 00384 virtual Code deleteAllReceivedSms(); 00385 00386 /** This method can be used to remove/delete all received SMS messages 00387 * that have been retrieved by the user through the getReceivedSms method. 00388 * Messages that have not been retrieved yet will be unaffected. 00389 * 00390 * @returns the standard AT Code enumeration. 00391 */ 00392 virtual Code deleteOnlyReceivedReadSms(); 00393 00394 //Cellular Radio Specific 00395 /** A method for sending a generic AT command to the radio. Note that you cannot 00396 * send commands and have a data connection at the same time. 00397 * 00398 * @param command the command to send to the radio without the escape character. 00399 * @param timeoutMillis the time in millis to wait for a response before returning. 00400 * @param esc escape character to add at the end of the command, defaults to 00401 * carriage return (CR). Does not append any character if esc == 0. 00402 * @returns all data received from the radio after the command as a string. 00403 */ 00404 virtual std::string sendCommand(const std::string& command, unsigned int timeoutMillis, char esc = CR); 00405 00406 /** A method for sending a basic AT command to the radio. A basic AT command is 00407 * one that simply has a response of either OK or ERROR without any other information. 00408 * Note that you cannot send commands and have a data connection at the same time. 00409 * 00410 * @param command the command to send to the radio without the escape character. 00411 * @param timeoutMillis the time in millis to wait for a response before returning. 00412 * @param esc escape character to add at the end of the command, defaults to 00413 * carriage return (CR). 00414 * @returns the standard Code enumeration. 00415 */ 00416 virtual Code sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc = CR); 00417 00418 /** A static method for getting a string representation for the Registration 00419 * enumeration. 00420 * 00421 * @param code a Registration enumeration. 00422 * @returns the enumeration name as a string. 00423 */ 00424 static std::string getRegistrationNames(Registration registration); 00425 00426 /** A static method for getting a string representation for the Radio 00427 * enumeration. 00428 * 00429 * @param type a Radio enumeration. 00430 * @returns the enumeration name as a string. 00431 */ 00432 static std::string getRadioNames(Radio radio); 00433 00434 /** A method for changing the echo commands from radio. 00435 * @param state Echo mode is off (an argument of 1 turns echos off, anything else turns echo on) 00436 * @returns standard Code enumeration 00437 */ 00438 virtual Code echo(bool state); 00439 00440 /** This method can be used to trade socket functionality for performance. 00441 * Can disable checking socket closed messages from the data socket, and thus the socket 00442 * will only be visibly closed to the local side if the radio is explicitly checked, or 00443 * the socket is closed by the local side through the use of physical pin manipulation. 00444 * 00445 * Uses the Hayes escape sequence (1 second pause, "+++", 1 second pause) to exit the socket 00446 * connection to check if a received "NO CARRIER" string is from the radio indicating the socket 00447 * has been closed, or is merely part of the data stream. Should not occur very often, however, if 00448 * data carrying the string "NO CARRIER" is going to be transmitted frequently, then the socket should 00449 * be set closeable and physical-socket-closing-means be used instead to reduce the large amount of 00450 * overhead switching from checking the validity of the "NO CARRIER" message being and indication of 00451 * the socket connection being closed. 00452 * 00453 * @param enabled set to true if you want the socket closeable, otherwise false. The default 00454 * is true. 00455 * @returns the standard AT Code enumeration. 00456 */ 00457 virtual Code setSocketCloseable(bool enabled); 00458 00459 /** Binds the socket to a specific port if able 00460 * @param port integer to bind the socket to. 00461 * 00462 * @returns true if successfully bound port, false if bind failed. 00463 */ 00464 virtual bool bind(unsigned int port); 00465 00466 /** Checks if a socket is open. 00467 * @returns true if socket is open, false if socket is closed 00468 */ 00469 virtual bool isOpen(); 00470 00471 /** Checks if there is data available from the socket. 00472 * @returns number of bytes of data available to read. 00473 */ 00474 virtual unsigned int readable(); 00475 00476 /** Checks data to output on the socket 00477 * @returns number of bytes to be written to the socket. 00478 */ 00479 virtual unsigned int writeable(); 00480 00481 /** Gets the device IP 00482 * @returns string containing the IP address 00483 */ 00484 virtual std::string getDeviceIP(); 00485 00486 /** Sets the device IP 00487 * (Not implemented, IP address values are assigned by DHCP) 00488 * @returns true if the IP was set, false if IP address assignment failed. 00489 */ 00490 virtual bool setDeviceIP(std::string address = "DHCP"); 00491 00492 /** Get the device IMEI or MEID (whichever is available) 00493 * @returns string containing the IMEI for GSM, the MEID for CDMA, or an empty string 00494 * if it failed to parse the number. 00495 */ 00496 std::string getEquipmentIdentifier(); 00497 00498 /** Get radio type 00499 * @returns the radio type (MTSMC-H5, etc) 00500 */ 00501 int getRadioType(); 00502 00503 /** Get string representation of radio type 00504 * @returns string containing the radio type (MTSMC-H5, etc) 00505 */ 00506 std::string getRadioTypeString(); 00507 00508 /** Enables GPS. 00509 * @returns true if GPS is enabled, false if GPS is not supported. 00510 */ 00511 virtual bool GPSenable(); 00512 00513 /** Disables GPS. 00514 * @returns true if GPS is disabled, false if GPS does not disable. 00515 */ 00516 virtual bool GPSdisable(); 00517 00518 /** Checks if GPS is enabled. 00519 * @returns true if GPS is enabled, false if GPS is disabled. 00520 */ 00521 virtual bool GPSenabled(); 00522 00523 /** Get GPS position. 00524 * @returns a structure containing the GPS data field information. 00525 */ 00526 virtual gpsData GPSgetPosition(); 00527 00528 /** Check for GPS fix. 00529 * @returns true if there is a fix and false otherwise. 00530 */ 00531 virtual bool GPSgotFix(); 00532 00533 protected: 00534 MTSBufferedIO* io; //IO interface obect that the radio is accessed through. 00535 bool echoMode; //Specifies if the echo mode is currently enabled. 00536 00537 bool gpsEnabled; //true if GPS is enabled, else false. 00538 00539 bool pppConnected; //Specifies if a PPP session is currently connected. 00540 std::string apn; //A string that holds the APN for the radio. 00541 00542 Radio type; //The type of radio being used 00543 00544 Mode socketMode; //The current socket Mode. 00545 bool socketOpened; //Specifies if a Socket is presently opened. 00546 bool socketCloseable; //Specifies is a Socket can be closed. 00547 unsigned int local_port; //Holds the local port for socket connections. 00548 std::string local_address; //Holds the local address for socket connections. 00549 unsigned int host_port; //Holds the remote port for socket connections. 00550 std::string host_address; //Holds the remote address for socket connections. 00551 00552 DigitalIn* dcd; //Maps to the radio's dcd signal 00553 DigitalOut* dtr; //Maps to the radio's dtr signal 00554 DigitalOut* resetLine; //Maps to the radio's reset signal 00555 }; 00556 00557 } 00558 00559 #endif /* CELLULAR_H */
Generated on Tue Jul 12 2022 21:59:41 by 1.7.2