Fork for new features

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UbloxCellularBase.h Source File

UbloxCellularBase.h

00001 /* Copyright (c) 2017 ARM Limited
00002  *
00003  * Licensed under the Apache License, Version 2.0 (the "License");
00004  * you may not use this file except in compliance with the License.
00005  * You may obtain a copy of the License at
00006  *
00007  *     http://www.apache.org/licenses/LICENSE-2.0
00008  *
00009  * Unless required by applicable law or agreed to in writing, software
00010  * distributed under the License is distributed on an "AS IS" BASIS,
00011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012  * See the License for the specific language governing permissions and
00013  * limitations under the License.
00014  */
00015 
00016 #ifndef _UBLOX_CELLULAR_BASE_
00017 #define _UBLOX_CELLULAR_BASE_
00018 
00019 #include "mbed.h"
00020 #include "mbed_toolchain.h" // for MBED_DEPRECATED
00021 #include "ATCmdParser.h"
00022 #include "FileHandle.h"
00023 
00024 #define PLMN_SIZE 24
00025 /**********************************************************************
00026  * CLASSES
00027  **********************************************************************/
00028 
00029 /** UbloxCellularBase class.
00030  *
00031  *  This class provides all the base support for generic u-blox modems
00032  *  on C030 and C027 boards: module identification, power-up, network
00033  *  registration, etc.
00034  */
00035 class UbloxCellularBase {
00036 
00037 public:
00038     /** Circuit Switched network registration status (CREG Usage).
00039      * UBX-13001820 - AT Commands Example Application Note (Section 7.10.3).
00040      */
00041     typedef enum {
00042         CSD_NOT_REGISTERED_NOT_SEARCHING = 0,
00043         CSD_REGISTERED = 1,
00044         CSD_NOT_REGISTERED_SEARCHING = 2,
00045         CSD_REGISTRATION_DENIED = 3,
00046         CSD_UNKNOWN_COVERAGE = 4,
00047         CSD_REGISTERED_ROAMING = 5,
00048         CSD_SMS_ONLY = 6,
00049         CSD_SMS_ONLY_ROAMING = 7,
00050         CSD_CSFB_NOT_PREFERRED = 9
00051     } NetworkRegistrationStatusCsd;
00052 
00053     /** Packet Switched network registration status (CGREG Usage).
00054      * UBX-13001820 - AT Commands Example Application Note (Section 18.27.3).
00055      */
00056     typedef enum {
00057         PSD_NOT_REGISTERED_NOT_SEARCHING = 0,
00058         PSD_REGISTERED = 1,
00059         PSD_NOT_REGISTERED_SEARCHING = 2,
00060         PSD_REGISTRATION_DENIED = 3,
00061         PSD_UNKNOWN_COVERAGE = 4,
00062         PSD_REGISTERED_ROAMING = 5,
00063         PSD_EMERGENCY_SERVICES_ONLY = 8
00064     } NetworkRegistrationStatusPsd;
00065 
00066     /** EPS network registration status (CEREG Usage).
00067      * UBX-13001820 - AT Commands Example Application Note (Section 18.36.3).
00068      */
00069     typedef enum {
00070         EPS_NOT_REGISTERED_NOT_SEARCHING = 0,
00071         EPS_REGISTERED = 1,
00072         EPS_NOT_REGISTERED_SEARCHING = 2,
00073         EPS_REGISTRATION_DENIED = 3,
00074         EPS_UNKNOWN_COVERAGE = 4,
00075         EPS_REGISTERED_ROAMING = 5,
00076         EPS_EMERGENCY_SERVICES_ONLY = 8
00077     } NetworkRegistrationStatusEps;
00078 
00079     /** Initialise the modem, ready for use.
00080      *
00081      *  @param pin     PIN for the SIM card.
00082      *  @return        true if successful, otherwise false.
00083      */
00084     bool init(const char *pin = 0);
00085 
00086     /** Perform registration with the network.
00087      *
00088      * @return true if successful, otherwise false.
00089      */
00090     bool nwk_registration();
00091 
00092     /** True if the modem is registered for circuit
00093      * switched data, otherwise false.
00094      */
00095     bool is_registered_csd();
00096 
00097     /** True if the modem is registered for packet
00098      * switched data, otherwise false.
00099      */
00100     bool is_registered_psd();
00101 
00102     /** True if the modem is registered for enhanced
00103      * packet switched data (i.e. LTE and beyond),
00104      * otherwise false.
00105      */
00106     bool is_registered_eps();
00107 
00108     /** Perform deregistration from the network.
00109      *
00110      * @return true if successful, otherwise false.
00111      */
00112     bool nwk_deregistration();
00113 
00114     /** Put the modem into its lowest power state.
00115      */
00116     void deinit();
00117 
00118     /** Set the PIN code for the SIM card.
00119      *
00120      *  @param pin PIN for the SIM card.
00121      */
00122     void set_pin(const char *pin);
00123 
00124     /** Enable or disable SIM pin checking.
00125      *
00126      * @param enableNotDisable true if SIM PIN checking is to be enabled,
00127      *                         otherwise false.
00128      * @return                 true if successful, otherwise false.
00129      */
00130     bool sim_pin_check_enable(bool enableNotDisable);
00131 
00132     /** Change the SIM pin.
00133      *
00134      * @param new_pin the new PIN to use.
00135      * @return        true if successful, otherwise false.
00136      */
00137     bool change_sim_pin(const char *new_pin);
00138 
00139     /** Get the IMEI.
00140      *
00141      * @return true if successful, otherwise false.
00142      */
00143     MBED_DEPRECATED("This method is now replaced by const char * imei(), please use that instead")
00144     bool get_imei(char *imei_to_send, int size);
00145 
00146     /** Get the IMEI of the module.
00147      *
00148      * @return a pointer to the IMEI as a null-terminated string.
00149      */
00150     const char *imei();
00151 
00152     /** Get the Mobile Equipment ID (which may be the same as the IMEI).
00153      *
00154      * @return a pointer to the Mobile Equipment ID as a null-terminated string.
00155      */
00156     const char *meid();
00157 
00158     /** Get the IMSI of the SIM.
00159      *
00160      * @return a pointer to the IMSI as a null-terminated string.
00161      */
00162     const char *imsi();
00163 
00164     /** Get the ICCID of the SIM.
00165      *
00166      * @return a pointer to the ICCID as a null-terminated string.
00167      */
00168     const char *iccid();
00169 
00170     /** Get the RSSI.
00171      *
00172      * @return the RSSI in dBm. If it is not possible to obtain an
00173      *         RSSI reading at the time (e.g. because the modem is in
00174      *         data mode rather than AT command mode) then 0 is returned.
00175      */
00176     int rssi();
00177 
00178     /** RAT values for +URAT command
00179      * R412M only supports value 7 (CatM1), 8 (NB1), and 9 (GPRS)
00180      */
00181     typedef enum {
00182         GSM_GPRS_EGPRS = 0,
00183         GSM_UMTS = 1,
00184         UMTS = 2,
00185         URAT_LTE = 3,
00186         GSM_UMTS_LTE = 4,
00187         GSM_LTE = 5,
00188         UMTS_LTE = 6,
00189         LTE_CATM1 = 7,
00190         LTE_CATNB1 = 8,
00191         GPRS_EGPRS = 9,
00192         NOT_USED = 255
00193     } RAT;
00194 
00195 #ifdef TARGET_UBLOX_C030_R41XM
00196     /** Supported MNO profiles for SARA-R4.
00197      */
00198     typedef enum {
00199         SW_DEFAULT = 0,
00200         SIM_ICCID = 1,
00201         ATT = 2,
00202         VERIZON = 3,
00203         TELSTRA = 4,
00204         TMO = 5,
00205         CT = 6,
00206         VODAFONE = 19,
00207         TELUS = 21,
00208         DT = 31,
00209         STANDARD_EU = 100
00210     } MNOProfile;
00211 
00212     #if MBED_CONF_UBLOX_CELL_DEFAULT_MNO_PROFILE
00213     #define DEFAULT_MNO_PROFILE     (MNOProfile)MBED_CONF_UBLOX_CELL_DEFAULT_MNO_PROFILE
00214     #else
00215     #define DEFAULT_MNO_PROFILE     SW_DEFAULT
00216     #endif
00217 
00218     /** Reads the current MNO profile from modem and sets it to user specified profile.
00219      * User can also specify profile in mbed_lib.json file and call set_mno_profile without any arguments.
00220      *
00221      * Note: MNO profile should only be set in detached state and a reboot is required for settings to take effect
00222      *
00223      * @param profile MNO profile to use
00224      * @return    true if operation was successful, false if there was an error
00225      */
00226     bool set_mno_profile(MNOProfile profile = DEFAULT_MNO_PROFILE);
00227 
00228     /** Get current MNO profile.
00229      *
00230      * @param profile pointer to variable that can hold the value for returned profile
00231      * @return    true if operation was successful, false if there was an error
00232      */
00233     bool get_mno_profile(MNOProfile *profile);
00234 #endif
00235 
00236     /** Set Radio Access Technology on modem.
00237      *
00238      * Note: RAT should only be set in detached state and a reboot is required for settings to take effect
00239      *
00240      * @param selected_rat Radio Access Technology to use
00241      * @param preferred_rat Radio Access Technology to use if selected_rat is not available
00242      * @param second_preferred_rat Radio Access Technology to use if selected_rat and preferred_rat are not available
00243      *
00244      * @return        true if successful, otherwise false.
00245      */
00246     bool set_modem_rat(RAT selected_rat, RAT preferred_rat = NOT_USED, RAT second_preferred_rat = NOT_USED);
00247 
00248     /** Get last saved values for RAT using +URAT read command. Note: The current selected RAT is indicated by DeviceInfo.rat
00249      *
00250      * @param selected_rat pointer to variable that can hold the value for selected_rat
00251      * @param preferred_rat pointer to variable that can hold the value for preferred_rat
00252      * @param second_preferred_rat pointer to variable that can hold the value for second_preferred_rat
00253      *
00254      * Note: NOT_USED will be returned in the variables if dual or tri modes are not enabled.
00255      *
00256      * @return        true if successful, otherwise false.
00257      */
00258     bool get_modem_rat(RAT *selected_rat, RAT *preferred_rat, RAT *second_preferred_rat);
00259 
00260     /** reboot the modem using AT+CFUN=15.
00261      *
00262      * @return        true if successful, otherwise false.
00263      */
00264     bool reboot_modem();
00265 protected:
00266 
00267     #define OUTPUT_ENTER_KEY  "\r"
00268 
00269     #if MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_BUFFER_SIZE
00270     #define AT_PARSER_BUFFER_SIZE   MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_BUFFER_SIZE
00271     #else
00272     #define AT_PARSER_BUFFER_SIZE   256
00273     #endif
00274 
00275     #if MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_TIMEOUT
00276     #define AT_PARSER_TIMEOUT       MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_TIMEOUT
00277     #else
00278     #define AT_PARSER_TIMEOUT       8*1000 // Milliseconds
00279     #endif
00280 
00281     /** A string that would not normally be sent by the modem on the AT interface.
00282      */
00283     #define UNNATURAL_STRING "\x01"
00284 
00285     /** Supported u-blox modem variants.
00286      */
00287     typedef enum {
00288         DEV_TYPE_NONE = 0,
00289         DEV_SARA_G35,
00290         DEV_LISA_U2,
00291         DEV_LISA_U2_03S,
00292         DEV_SARA_U2,
00293         DEV_SARA_R4,
00294         DEV_LEON_G2,
00295         DEV_TOBY_L2,
00296         DEV_MPCI_L2
00297     } DeviceType;
00298 
00299     /** Network registration status.
00300      * UBX-13001820 - AT Commands Example Application Note (Section 4.1.4.5).
00301      */
00302     typedef enum {
00303        GSM = 0,
00304        COMPACT_GSM = 1,
00305        UTRAN = 2,
00306        EDGE = 3,
00307        HSDPA = 4,
00308        HSUPA = 5,
00309        HSDPA_HSUPA = 6,
00310        LTE = 7,
00311        EC_GSM_IoT = 8,
00312        E_UTRAN_NB_S1 = 9
00313     } RadioAccessNetworkType;
00314 
00315     /** Info about the modem.
00316      */
00317     typedef struct {
00318         DeviceType dev;
00319         char iccid[20 + 1];   //!< Integrated Circuit Card ID.
00320         char imsi[15 + 1];    //!< International Mobile Station Identity.
00321         char imei[15 + 1];    //!< International Mobile Equipment Identity.
00322         char meid[18 + 1];    //!< Mobile Equipment IDentifier.
00323         volatile RadioAccessNetworkType rat;  //!< Type of network (e.g. 2G, 3G, LTE).
00324         volatile NetworkRegistrationStatusCsd reg_status_csd; //!< Circuit switched attach status.
00325         volatile NetworkRegistrationStatusPsd reg_status_psd; //!< Packet switched attach status.
00326         volatile NetworkRegistrationStatusEps reg_status_eps; //!< Evolved Packet Switched (e.g. LTE) attach status.
00327     } DeviceInfo;
00328 
00329     /* IMPORTANT: the variables below are available to
00330      * classes that inherit this in order to keep things
00331      * simple. However, ONLY this class should free
00332      * any of the pointers, or there will be havoc.
00333      */
00334 
00335     /** Point to the instance of the AT parser in use.
00336      */
00337     ATCmdParser *_at;
00338 
00339     /** The current AT parser timeout value.
00340      */
00341     int _at_timeout;
00342 
00343     /** File handle used by the AT parser.
00344      */
00345     FileHandle *_fh;
00346 
00347     /** The mutex resource.
00348      */
00349     Mutex _mtx;
00350 
00351     /** General info about the modem as a device.
00352      */
00353     DeviceInfo _dev_info;
00354 
00355     /** The SIM PIN to use.
00356      */
00357     const char *_pin;
00358 
00359     /** Set to true to spit out debug traces.
00360      */
00361     bool _debug_trace_on;
00362     
00363     /** The baud rate to the modem.
00364      */
00365     int _baud;
00366 
00367     /** True if the modem is ready register to the network,
00368      * otherwise false.
00369      */
00370     bool _modem_initialised;
00371 
00372     /** True it the SIM requires a PIN, otherwise false.
00373      */
00374     bool _sim_pin_check_enabled;
00375 
00376     /** Sets the modem up for powering on
00377      *
00378      *  modem_init() is equivalent to plugging in the device, e.g., attaching power and serial port.
00379      *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
00380      */
00381     virtual void modem_init();
00382 
00383     /** Sets the modem in unplugged state
00384      *
00385      *  modem_deinit() will be equivalent to pulling the plug off of the device, i.e., detaching power
00386      *  and serial port. This puts the modem in lowest power state.
00387      *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
00388      */
00389     virtual void modem_deinit();
00390 
00391     /** Powers up the modem
00392      *
00393      *  modem_power_up() is equivalent to pressing the soft power button.
00394      *  The driver may repeat this if the modem is not responsive to AT commands.
00395      *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
00396      */
00397     virtual void modem_power_up();
00398 
00399     /** Powers down the modem
00400      *
00401      *  modem_power_down() is equivalent to turning off the modem by button press.
00402      *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
00403      */
00404     virtual void modem_power_down();
00405 
00406     /* Note: constructor and destructor protected so that this
00407     * class can only ever be inherited, never used directly.
00408     */
00409     UbloxCellularBase();
00410     ~UbloxCellularBase();
00411 
00412     /** Initialise this class.
00413      *
00414      * @param tx       the UART TX data pin to which the modem is attached.
00415      * @param rx       the UART RX data pin to which the modem is attached.
00416      * @param baud     the UART baud rate.
00417      * @param debug_on true to switch AT interface debug on, otherwise false.
00418      *
00419      * Note: it would be more natural to do this in the constructor
00420      * however, to avoid the diamond of death, this class is only
00421      * every inherited virtually.  Classes that are inherited virtually
00422      * do not get passed parameters in their constructor and hence
00423      * classInit() must be called separately by the first one to wake
00424      * the beast.
00425      */
00426     void baseClassInit(PinName tx = MDMTXD,
00427                        PinName rx = MDMRXD,
00428                        int baud = MBED_CONF_UBLOX_CELL_BAUD_RATE,
00429                        bool debug_on = false);
00430 
00431     /** Set the AT parser timeout.
00432      */
00433     void at_set_timeout(int timeout);
00434 
00435     /** Read up to size characters from buf
00436      * or until the character "end" is reached, overwriting
00437      * the newline with 0 and ensuring a terminator
00438      * in all cases.
00439      *
00440      * @param buf  the buffer to write to.
00441      * @param size the size of the buffer.
00442      * @param end  the character to stop at.
00443      * @return     the number of characters read,
00444      *             not including the terminator.
00445      */
00446     int read_at_to_char(char * buf, int size, char end);
00447 
00448     /** Powers up the modem.
00449      *
00450      * @return true if successful, otherwise false.
00451      */
00452     bool power_up();
00453 
00454     /** Power down the modem.
00455      */
00456     void power_down();
00457 
00458     /** Lock a mutex when accessing the modem.
00459      */
00460     void lock(void)     { _mtx.lock(); }
00461 
00462     /** Helper to make sure that lock unlock pair is always balanced
00463      */
00464     #define LOCK()         { lock()
00465 
00466     /** Unlock the modem when done accessing it.
00467      */
00468     void unlock(void)   { _mtx.unlock(); }
00469 
00470     /** Helper to make sure that lock unlock pair is always balanced
00471      */
00472     #define UNLOCK()       } unlock()
00473 
00474     /** Set the device identity in _dev_info
00475      * based on the ATI string returned by
00476      * the module.
00477      *
00478      * @return true if dev is a known value,
00479      *         otherwise false.
00480      */
00481     bool set_device_identity(DeviceType *dev);
00482 
00483     /** Perform any modem initialisation that is
00484      * specialised by device type.
00485      *
00486      * @return true if successful, otherwise false.
00487      */
00488     bool device_init(DeviceType dev);
00489 
00490     /** Set up the SIM.
00491      *
00492      * @return true if successful, otherwiss false.
00493      */
00494     bool initialise_sim_card();
00495 
00496     /** PLMN for manual registration
00497      */
00498     char _plmn[PLMN_SIZE + 1];
00499 private:
00500 
00501     void set_nwk_reg_status_csd(int status);
00502     void set_nwk_reg_status_psd(int status);
00503     void set_nwk_reg_status_eps(int status);
00504     void set_rat(int AcTStatus);
00505     bool get_iccid();
00506     bool get_imsi();
00507     bool get_imei();
00508     bool get_meid();
00509     bool set_sms();
00510     void parser_abort_cb();
00511     void CMX_ERROR_URC();
00512     void CREG_URC();
00513     void CGREG_URC();
00514     void CEREG_URC();
00515     void UMWI_URC();
00516 };
00517 
00518 #endif // _UBLOX_CELLULAR_BASE_
00519