ublox-cellular-base_R4_PR
UbloxCellularBase.h
- Committer:
- wajahat.abbas@u-blox.com
- Date:
- 2019-05-29
- Revision:
- 25:e67d3d9d2e7e
- Parent:
- 24:e26a6ab0dd75
- Child:
- 26:e4e444cc7b14
File content as of revision 25:e67d3d9d2e7e:
/* Copyright (c) 2017 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _UBLOX_CELLULAR_BASE_ #define _UBLOX_CELLULAR_BASE_ #include "mbed.h" #include "mbed_toolchain.h" // for MBED_DEPRECATED #include "ubloxATCmdParser.h" #include "FileHandle.h" /********************************************************************** * CLASSES **********************************************************************/ /** UbloxCellularBase class. * * This class provides all the base support for generic u-blox modems * on C030 and C027 boards: module identification, power-up, network * registration, etc. */ class UbloxCellularBase { public: /** Circuit Switched network registration status (CREG Usage). * UBX-13001820 - AT Commands Example Application Note (Section 7.10.3). */ typedef enum { CSD_NOT_REGISTERED_NOT_SEARCHING = 0, CSD_REGISTERED = 1, CSD_NOT_REGISTERED_SEARCHING = 2, CSD_REGISTRATION_DENIED = 3, CSD_UNKNOWN_COVERAGE = 4, CSD_REGISTERED_ROAMING = 5, CSD_SMS_ONLY = 6, CSD_SMS_ONLY_ROAMING = 7, CSD_CSFB_NOT_PREFERRED = 9 } NetworkRegistrationStatusCsd; /** Packet Switched network registration status (CGREG Usage). * UBX-13001820 - AT Commands Example Application Note (Section 18.27.3). */ typedef enum { PSD_NOT_REGISTERED_NOT_SEARCHING = 0, PSD_REGISTERED = 1, PSD_NOT_REGISTERED_SEARCHING = 2, PSD_REGISTRATION_DENIED = 3, PSD_UNKNOWN_COVERAGE = 4, PSD_REGISTERED_ROAMING = 5, PSD_EMERGENCY_SERVICES_ONLY = 8 } NetworkRegistrationStatusPsd; /** EPS network registration status (CEREG Usage). * UBX-13001820 - AT Commands Example Application Note (Section 18.36.3). */ typedef enum { EPS_NOT_REGISTERED_NOT_SEARCHING = 0, EPS_REGISTERED = 1, EPS_NOT_REGISTERED_SEARCHING = 2, EPS_REGISTRATION_DENIED = 3, EPS_UNKNOWN_COVERAGE = 4, EPS_REGISTERED_ROAMING = 5, EPS_EMERGENCY_SERVICES_ONLY = 8 } NetworkRegistrationStatusEps; /** modem PSM states. * */ typedef enum { AWAKE = 0, ASLEEP = 1 } ModemPSMState; /** Initialise the modem, ready for use. * * @param pin PIN for the SIM card. * @return true if successful, otherwise false. */ bool init(const char *pin = 0); /** Perform registration with the network. * * @return true if successful, otherwise false. */ bool nwk_registration(); /** True if the modem is registered for circuit * switched data, otherwise false. */ bool is_registered_csd(); /** True if the modem is registered for packet * switched data, otherwise false. */ bool is_registered_psd(); /** True if the modem is registered for enhanced * packet switched data (i.e. LTE and beyond), * otherwise false. */ bool is_registered_eps(); /** Perform deregistration from the network. * * @return true if successful, otherwise false. */ bool nwk_deregistration(); /** Put the modem into its lowest power state. */ void deinit(); /** Set the PIN code for the SIM card. * * @param pin PIN for the SIM card. */ void set_pin(const char *pin); /** Enable or disable SIM pin checking. * * @param enableNotDisable true if SIM PIN checking is to be enabled, * otherwise false. * @return true if successful, otherwise false. */ bool sim_pin_check_enable(bool enableNotDisable); /** Change the SIM pin. * * @param new_pin the new PIN to use. * @return true if successful, otherwise false. */ bool change_sim_pin(const char *new_pin); /** Get the IMEI. * * @return true if successful, otherwise false. */ MBED_DEPRECATED("This method is now replaced by const char * imei(), please use that instead") bool get_imei(char *imei_to_send, int size); /** Get the IMEI of the module. * * @return a pointer to the IMEI as a null-terminated string. */ const char *imei(); /** Get the Mobile Equipment ID (which may be the same as the IMEI). * * @return a pointer to the Mobile Equipment ID as a null-terminated string. */ const char *meid(); /** Get the IMSI of the SIM. * * @return a pointer to the IMSI as a null-terminated string. */ const char *imsi(); /** Get the ICCID of the SIM. * * @return a pointer to the ICCID as a null-terminated string. */ const char *iccid(); /** Get the RSSI. * * @return the RSSI in dBm. If it is not possible to obtain an * RSSI reading at the time (e.g. because the modem is in * data mode rather than AT command mode) then 0 is returned. */ int rssi(); /** RAT values for +URAT command * R412M only supports value 7 (CatM1), 8 (NB1), and 9 (GPRS) */ typedef enum { GSM_GPRS_EGPRS = 0, GSM_UMTS = 1, UMTS = 2, URAT_LTE = 3, GSM_UMTS_LTE = 4, GSM_LTE = 5, UMTS_LTE = 6, LTE_CATM1 = 7, LTE_CATNB1 = 8, GPRS_EGPRS = 9, NOT_USED = -1 } RAT; /** Module functionality modes. Ref to section 5.3.3 of UBX-13002752 for details. */ typedef enum { FUNC_MIN = 0, FUNC_FULL = 1, FUNC_AIRPLANE = 4, FUNC_EN_SIM_TLKT_DEDICATED = 6, FUNC_DS_SIM_TLKT = 7, FUNC_EN_SIM_TLKT_RAW = 9, FUNC_RESET = 15, FUNC_RESET_WITH_SIM = 16, FUNC_MIN_WITH_SIM = 19, FUNC_HALT = 127 } FunctionalityMode; #ifdef TARGET_UBLOX_C030_R41XM /** Supported MNO profiles for SARA-R4. */ typedef enum { SW_DEFAULT = 0, SIM_ICCID = 1, ATT = 2, VERIZON = 3, TELSTRA = 4, TMO = 5, CT = 6, VODAFONE = 19, TELUS = 21, DT = 31, STANDARD_EU = 100 } MNOProfile; #if MBED_CONF_UBLOX_CELL_DEFAULT_MNO_PROFILE #define DEFAULT_MNO_PROFILE (MNOProfile)MBED_CONF_UBLOX_CELL_DEFAULT_MNO_PROFILE #else #define DEFAULT_MNO_PROFILE SW_DEFAULT #endif /** Reads the current MNO profile from modem and sets it to user specified profile. * User can also specify profile in mbed_lib.json file and call set_mno_profile without any arguments. * * Note: MNO profile should only be set in detached state and a reboot is required for settings to take effect * * @param profile MNO profile to use * @return true if operation was successful, false if there was an error */ bool set_mno_profile(MNOProfile profile = DEFAULT_MNO_PROFILE); /** Get current MNO profile. * * @param profile pointer to variable that can hold the value for returned profile * @return true if operation was successful, false if there was an error */ bool get_mno_profile(int *profile); /** Enable or disable the UPSV Power Saving Mode. * * @param idle_mode_value 1: enable idle mode * 0: disable idle mode * @return true if successful, otherwise false. */ bool set_idle_mode(bool enable = false); /** Queries the modem for idle mode status. * * @param status pointer to variable that can hold the value for idle mode status * 1: enabled * 0: disabled * @return true if successful, otherwise false. */ bool get_idle_mode(int *status); #endif /** Set Radio Access Technology on modem. * * Note: RAT should only be set in detached state and a reboot is required for settings to take effect * * @param selected_rat Radio Access Technology to use * @param preferred_rat Radio Access Technology to use if selected_rat is not available * @param second_preferred_rat Radio Access Technology to use if selected_rat and preferred_rat are not available * * @return true if successful, otherwise false. */ bool set_modem_rat(RAT selected_rat, RAT preferred_rat = NOT_USED, RAT second_preferred_rat = NOT_USED); /** Get last saved values for RAT using +URAT read command. Note: The current selected RAT is indicated by DeviceInfo.rat * * @param selected_rat pointer to variable that can hold the value for selected_rat * @param preferred_rat pointer to variable that can hold the value for preferred_rat * @param second_preferred_rat pointer to variable that can hold the value for second_preferred_rat * * Note: NOT_USED will be returned in the variables if dual or tri modes are not enabled. * * @return true if successful, otherwise false. */ bool get_modem_rat(int *selected_rat, int *preferred_rat, int *second_preferred_rat); /** Sets the modem to specified functionality mode. * * @return true if successful, otherwise false. */ bool set_functionality_mode(FunctionalityMode mode); /** Get the modem functionality mode * * @return true if successful, otherwise false. */ bool get_functionality_mode(int *mode); /** reboot the modem using AT+CFUN=15. Application should call init() or connect() before making any other API calls. * * @return true if successful, otherwise false. */ bool reboot_modem(); #ifdef TARGET_UBLOX_C030_R412M /** Important: Callback function is executed in context of AT parser so a user should not issue any AT commands from inside the callback. * It is recommended to set a flag/event/signal in callback and application can use that to wake up the modem and re-initialize it * * application callback for modem going in to PSM sleep * * @param func callback function to be executed when modem is going in to PSM sleep * @param param parameter to be passed to callback function. */ void attach_cb_psm_going_in(Callback<void(void*)> func, void *param) { _func_psm_going_in = func; _cb_param_psm_going_in = param; } /** Important: Callback function is executed in context of AT parser so a user should not issue any AT commands from inside the callback. * It is recommended to set a flag/event/signal in callback and application can use that to wake up the modem and re-initialize it * * application callback for modem coming out of PSM sleep * * @param func callback function to be executed when modem is coming out of PSM sleep. * @param param parameter to be passed to callback function. */ void attach_cb_psm_coming_out(Callback<void(void*)> func, void *param) { _func_psm_coming_out = func; _cb_param_psm_coming_out = param; } /** de-register the application callback for modem going in to PSM sleep * */ void detach_cb_psm_going_in() { _func_psm_going_in = NULL; _cb_param_psm_going_in = NULL; } /** de-register application callback for modem coming out of PSM sleep * */ void detach_cb_psm_coming_out() { _func_psm_coming_out = NULL; _cb_param_psm_coming_out = NULL; } /** Enable or disable the 3GPP PSM. * * Note: Application should reboot the module after enabling PSM in order to enter PSM state. (reboot_modem()) * Note: Modem can be woken up by toggling the power-on signal. (wakeup_modem()) * Note: When device enters PSM, all connections(PPP, sockets) and settings that are not saved in NV memory(ATE0, CREG etc) are lost. * host application should be prepared to re-initialize the modem and re-establish the connections. * Note: PSM is disabled if both periodic_time and active_time are 0. * Note: Not all variants/firmware versions support PSM URCs and in that case function will return false. * * PSM string encoding code is borrowed from AT_CellularPower.cpp * * @param periodic_time requested periodic TAU in seconds. * @param active_time requested active time in seconds. * @param func callback function to execute when modem goes to sleep * @param ptr parameter to callback function * @return True if successful, otherwise false. */ bool set_power_saving_mode(int periodic_tau, int active_time); /** Reads the 3GPP PSM status (enabled or disabled) and returns assigned periodic tau and active time values. * * @param status 0: PSM disabled, 1: PSM enabled * @param periodic_tau assigned periodic TAU in seconds. * @param active_time assigned active time in seconds * @return True if command successful, otherwise false. */ bool get_power_saving_mode(int *status, int *periodic_tau, int *active_time); /** Wake up the modem from PSM. Ref to comment on set_power_saving_mode, application should call init() or connect() * before making any other API calls. */ void wakeup_modem(); /** True if the modem is not in PSM sleep * otherwise false. */ bool is_modem_awake(); #endif protected: #define OUTPUT_ENTER_KEY "\r" #if MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_BUFFER_SIZE #define AT_PARSER_BUFFER_SIZE MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_BUFFER_SIZE #else #define AT_PARSER_BUFFER_SIZE 256 #endif #if MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_TIMEOUT #define AT_PARSER_TIMEOUT MBED_CONF_UBLOX_CELL_GEN_DRV_AT_PARSER_TIMEOUT #else #define AT_PARSER_TIMEOUT 8*1000 // Milliseconds #endif /** A string that would not normally be sent by the modem on the AT interface. */ #define UNNATURAL_STRING "\x01" /** Supported u-blox modem variants. */ typedef enum { DEV_TYPE_NONE = 0, DEV_SARA_G35, DEV_LISA_U2, DEV_LISA_U2_03S, DEV_SARA_U2, DEV_SARA_R4, DEV_LEON_G2, DEV_TOBY_L2, DEV_MPCI_L2 } DeviceType; /** Network registration status. * UBX-13001820 - AT Commands Example Application Note (Section 4.1.4.5). */ typedef enum { GSM = 0, COMPACT_GSM = 1, UTRAN = 2, EDGE = 3, HSDPA = 4, HSUPA = 5, HSDPA_HSUPA = 6, LTE = 7, EC_GSM_IoT = 8, E_UTRAN_NB_S1 = 9 } RadioAccessNetworkType; /** Info about the modem. */ typedef struct { DeviceType dev; char iccid[20 + 1]; //!< Integrated Circuit Card ID. char imsi[15 + 1]; //!< International Mobile Station Identity. char imei[15 + 1]; //!< International Mobile Equipment Identity. char meid[18 + 1]; //!< Mobile Equipment IDentifier. volatile RadioAccessNetworkType rat; //!< Type of network (e.g. 2G, 3G, LTE). volatile NetworkRegistrationStatusCsd reg_status_csd; //!< Circuit switched attach status. volatile NetworkRegistrationStatusPsd reg_status_psd; //!< Packet switched attach status. volatile NetworkRegistrationStatusEps reg_status_eps; //!< Evolved Packet Switched (e.g. LTE) attach status. #ifdef TARGET_UBLOX_C030_R412M volatile ModemPSMState modem_psm_state; //!< last known modem PSM state #endif } DeviceInfo; /* IMPORTANT: the variables below are available to * classes that inherit this in order to keep things * simple. However, ONLY this class should free * any of the pointers, or there will be havoc. */ /** Point to the instance of the AT parser in use. */ #ifdef TARGET_UBLOX_C030_R41XM UbloxATCmdParser *_at; #else ATCmdParser *_at; #endif /** The current AT parser timeout value. */ int _at_timeout; /** File handle used by the AT parser. */ FileHandle *_fh; /** The mutex resource. */ Mutex _mtx; /** General info about the modem as a device. */ DeviceInfo _dev_info; /** The SIM PIN to use. */ const char *_pin; /** Set to true to spit out debug traces. */ bool _debug_trace_on; /** The baud rate to the modem. */ int _baud; /** True if the modem is ready register to the network, * otherwise false. */ bool _modem_initialised; /** True it the SIM requires a PIN, otherwise false. */ bool _sim_pin_check_enabled; /** Sets the modem up for powering on * * modem_init() is equivalent to plugging in the device, e.g., attaching power and serial port. * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. */ virtual void modem_init(); /** Sets the modem in unplugged state * * modem_deinit() will be equivalent to pulling the plug off of the device, i.e., detaching power * and serial port. This puts the modem in lowest power state. * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. */ virtual void modem_deinit(); /** Powers up the modem * * modem_power_up() is equivalent to pressing the soft power button. * The driver may repeat this if the modem is not responsive to AT commands. * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. */ virtual void modem_power_up(); /** Powers down the modem * * modem_power_down() is equivalent to turning off the modem by button press. * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. */ virtual void modem_power_down(); /* Note: constructor and destructor protected so that this * class can only ever be inherited, never used directly. */ UbloxCellularBase(); ~UbloxCellularBase(); /** Initialise this class. * * @param tx the UART TX data pin to which the modem is attached. * @param rx the UART RX data pin to which the modem is attached. * @param baud the UART baud rate. * @param debug_on true to switch AT interface debug on, otherwise false. * * Note: it would be more natural to do this in the constructor * however, to avoid the diamond of death, this class is only * every inherited virtually. Classes that are inherited virtually * do not get passed parameters in their constructor and hence * classInit() must be called separately by the first one to wake * the beast. */ void baseClassInit(PinName tx = MDMTXD, PinName rx = MDMRXD, int baud = MBED_CONF_UBLOX_CELL_BAUD_RATE, bool debug_on = false); /** Set the AT parser timeout. */ void at_set_timeout(int timeout); /** Read up to size characters from buf * or until the character "end" is reached, overwriting * the newline with 0 and ensuring a terminator * in all cases. * * @param buf the buffer to write to. * @param size the size of the buffer. * @param end the character to stop at. * @return the number of characters read, * not including the terminator. */ int read_at_to_char(char * buf, int size, char end); /** Powers up the modem. * * @return true if successful, otherwise false. */ bool power_up(); /** Power down the modem. */ void power_down(); /** Lock a mutex when accessing the modem. */ void lock(void) { _mtx.lock(); } /** Helper to make sure that lock unlock pair is always balanced */ #define LOCK() { lock() /** Unlock the modem when done accessing it. */ void unlock(void) { _mtx.unlock(); } /** Helper to make sure that lock unlock pair is always balanced */ #define UNLOCK() } unlock() /** Set the device identity in _dev_info * based on the ATI string returned by * the module. * * @return true if dev is a known value, * otherwise false. */ bool set_device_identity(DeviceType *dev); /** Perform any modem initialisation that is * specialised by device type. * * @return true if successful, otherwise false. */ bool device_init(DeviceType dev); /** Set up the SIM. * * @return true if successful, otherwiss false. */ bool initialise_sim_card(); #ifdef TARGET_UBLOX_C030_R412M /** Converts the given uint to binary string. Fills the given str starting from [0] with the number of bits defined by bit_cnt * For example uint_to_binary_string(9, str, 10) would fill str "0000001001" * For example uint_to_binary_string(9, str, 3) would fill str "001" * * @param num uint to converts to binary string * @param str buffer for converted binary string * @param str_size size of the str buffer * @param bit_cnt defines how many bits are filled to buffer started from lsb */ void uint_to_binary_str(uint32_t num, char* str, int str_size, int bit_cnt); #endif private: void set_nwk_reg_status_csd(int status); void set_nwk_reg_status_psd(int status); void set_nwk_reg_status_eps(int status); void set_rat(int AcTStatus); bool get_iccid(); bool get_imsi(); bool get_imei(); bool get_meid(); bool set_sms(); void parser_abort_cb(); void CMX_ERROR_URC(); void CREG_URC(); void CGREG_URC(); void CEREG_URC(); void UMWI_URC(); #ifdef TARGET_UBLOX_C030_R412M void UUPSMR_URC(); bool _psm_status; void *_cb_param_psm_going_in; Callback<void(void*)> _func_psm_going_in; /**< Callback. */ void *_cb_param_psm_coming_out; Callback<void(void*)> _func_psm_coming_out; /**< Callback. */ void set_modem_psm_state(int state); #endif }; #endif // _UBLOX_CELLULAR_BASE_