diff options
author | Maksym Telychko <maksym.telychko@globallogic.com> | 2019-06-06 16:03:44 +0300 |
---|---|---|
committer | Maksym Telychko <maksym.telychko@globallogic.com> | 2019-06-06 16:03:44 +0300 |
commit | da563a985ccb0b5f316b44e35aabd511687ff4bf (patch) | |
tree | 8c4261bff4b66b16018541004db1cd04258b3ca1 | |
parent | 53efcef2e2f521135b323e194c45f1d9fa7b5d5d (diff) | |
download | libmts-io-da563a985ccb0b5f316b44e35aabd511687ff4bf.tar.gz libmts-io-da563a985ccb0b5f316b44e35aabd511687ff4bf.tar.bz2 libmts-io-da563a985ccb0b5f316b44e35aabd511687ff4bf.zip |
[MTS-MTQ] refactoring: added quectel empty classes, CellularRadio moved to TelitRadio
-rw-r--r-- | include/mts/MTS_IO_CdmaRadio.h | 4 | ||||
-rw-r--r-- | include/mts/MTS_IO_CellularRadio.h | 501 | ||||
-rw-r--r-- | include/mts/MTS_IO_CellularRadioFactory.h | 42 | ||||
-rw-r--r-- | include/mts/MTS_IO_EG95Radio.h | 15 | ||||
-rw-r--r-- | include/mts/MTS_IO_GE910Radio.h | 4 | ||||
-rw-r--r-- | include/mts/MTS_IO_HE910Radio.h | 4 | ||||
-rw-r--r-- | include/mts/MTS_IO_ICellularRadio.h | 399 | ||||
-rw-r--r-- | include/mts/MTS_IO_LE866Radio.h | 4 | ||||
-rw-r--r-- | include/mts/MTS_IO_LE910Radio.h | 4 | ||||
-rw-r--r-- | include/mts/MTS_IO_ME910Radio.h | 4 | ||||
-rw-r--r-- | include/mts/MTS_IO_QuectelRadio.h | 15 | ||||
-rw-r--r-- | include/mts/MTS_IO_TelitRadio.h | 496 | ||||
-rw-r--r-- | src/MTS_IO_CdmaRadio.cpp | 2 | ||||
-rw-r--r-- | src/MTS_IO_CellularRadio.cpp | 1818 | ||||
-rw-r--r-- | src/MTS_IO_CellularRadioFactory.cpp | 12 | ||||
-rw-r--r-- | src/MTS_IO_EG95Radio.cpp | 1 | ||||
-rw-r--r-- | src/MTS_IO_GE910Radio.cpp | 2 | ||||
-rw-r--r-- | src/MTS_IO_HE910Radio.cpp | 2 | ||||
-rw-r--r-- | src/MTS_IO_LE866Radio.cpp | 2 | ||||
-rw-r--r-- | src/MTS_IO_LE910Radio.cpp | 2 | ||||
-rw-r--r-- | src/MTS_IO_ME910Radio.cpp | 2 | ||||
-rw-r--r-- | src/MTS_IO_QuectelRadio.cpp | 1 | ||||
-rw-r--r-- | src/MTS_IO_TelitRadio.cpp | 1838 |
23 files changed, 2813 insertions, 2361 deletions
diff --git a/include/mts/MTS_IO_CdmaRadio.h b/include/mts/MTS_IO_CdmaRadio.h index 448cdc7..7cdba02 100644 --- a/include/mts/MTS_IO_CdmaRadio.h +++ b/include/mts/MTS_IO_CdmaRadio.h @@ -29,12 +29,12 @@ #ifndef MTS_IO_CDMARADIO_H_ #define MTS_IO_CDMARADIO_H_ -#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_TelitRadio.h> namespace MTS { namespace IO { - class CdmaRadio : public CellularRadio { + class CdmaRadio : public TelitRadio { public: virtual ~CdmaRadio(); diff --git a/include/mts/MTS_IO_CellularRadio.h b/include/mts/MTS_IO_CellularRadio.h index 007c130..1378612 100644 --- a/include/mts/MTS_IO_CellularRadio.h +++ b/include/mts/MTS_IO_CellularRadio.h @@ -29,510 +29,13 @@ #ifndef MTS_IO_CELLULARRADIO_H_ #define MTS_IO_CELLULARRADIO_H_ -#include <mts/MTS_IO_SerialConnection.h> -#include <mts/MTS_NonCopyable.h> -#include <mts/MTS_AutoPtr.h> -#include <mts/MTS_Lock.h> -#include <mts/MTS_Stdint.h> -#include <json/json.h> -#include <string> -#include <vector> -#include <functional> - -typedef struct -{ - const char *name; - int32_t low; - int32_t high; -} *pNameRangeMap, nameRangeMap; - -static const unsigned int NUM_GSM_BANDS = 7; -static const unsigned int NUM_WCDMA_BANDS = 6; -static const unsigned int NUM_LTE_BANDS = 42; - -// http://niviuk.free.fr/gsm_band.php -static const nameRangeMap GSMband[] = -{ - {"GSM 450", 259, 293}, {"GSM 480", 306, 340}, - {"GSM 750", 438, 511}, {"GSM 850", 128, 251}, - {"GSM 900 P", 1, 124}, {"GSM 900 E/R", 955, 1023}, - {"GSM DCS 1800/1900", 512, 885}, - -}; - -// http://niviuk.free.fr/umts_band.php -static const nameRangeMap WCDMAband[] = -{ - {"BAND I", 10592, 10838}, {"BAND II", 9662, 9938}, - {"BAND III", 1162, 1513}, {"BAND IV", 1537, 1738}, - {"BAND V", 4357, 4458}, {"BAND VI", 4387, 4413} -}; - -// http://niviuk.free.fr/lte_band.php -static const nameRangeMap EULTRAband[] = -{ - {"EUTRAN BAND1", 0, 599}, {"EUTRAN BAND2", 600, 1199}, - {"EUTRAN BAND3", 1200, 1949}, {"EUTRAN BAND4", 1950, 2399}, - {"EUTRAN BAND5", 2400, 2649}, {"EUTRAN BAND6", 2650, 2749}, - {"EUTRAN BAND7", 2750, 3449}, {"EUTRAN BAND8", 3450, 3799}, - {"EUTRAN BAND9", 3800, 4149}, {"EUTRAN BAND10", 4150, 4749}, - {"EUTRAN BAND11", 4750, 4999}, {"EUTRAN BAND12", 5000, 5179}, - {"EUTRAN BAND13", 5180, 5279}, {"EUTRAN BAND14", 5280, 5379}, - {"EUTRAN BAND17", 5730, 5849}, {"EUTRAN BAND18", 5850, 5999}, - {"EUTRAN BAND19", 6000, 6149}, {"EUTRAN BAND20", 6150, 6449}, - {"EUTRAN BAND21", 6450, 6525}, {"EUTRAN BAND22", 6600, 7399}, - {"EUTRAN BAND23", 7500, 7699}, {"EUTRAN BAND24", 7700, 8039}, - {"EUTRAN BAND25", 8040, 8689}, {"EUTRAN BAND26", 8690, 9039}, - {"EUTRAN BAND27", 9040, 9209}, {"EUTRAN BAND28", 9210, 9659}, - {"EUTRAN BAND29", 9660, 9769}, {"EUTRAN BAND30", 9770, 9869}, - {"EUTRAN BAND31", 9870, 9919}, {"EUTRAN BAND32", 9920, 10359}, - {"EUTRAN BAND33", 36000, 36199}, {"EUTRAN BAND34", 36200, 36349}, - {"EUTRAN BAND35", 36350, 36949}, {"EUTRAN BAND36", 36950, 37549}, - {"EUTRAN BAND37", 37550, 37749}, {"EUTRAN BAND38", 37750, 38249}, - {"EUTRAN BAND39", 38250, 38649}, {"EUTRAN BAND40", 38650, 39649}, - {"EUTRAN BAND41", 39650, 41589}, {"EUTRAN BAND42", 41590, 43589}, - {"EUTRAN BAND43", 43590, 45589}, {"EUTRAN BAND44", 45590, 46589} -}; +#include <mts/MTS_IO_ICellularRadio.h> namespace MTS { namespace IO { - class CellularRadio : NonCopyable { - - public: - static const std::string DEFAULT_RADIO_PORT; - static const std::string DEFAULT_RADIO_DIR; - - static const std::string VALUE_UNKNOWN; - static const std::string VALUE_UNAVAILABLE; - static const std::string VALUE_NOT_SUPPORTED; - - //Special Payload Characters - static const char ETX; //Ends socket connection - static const char DLE; //Escapes ETX and DLE within Payload - static const char CR; - static const char NL; - static const char CTRL_Z; - - static const std::string RSP_OK; - static const std::string RSP_ERROR; - - //Registration Values - enum REGISTRATION : uint8_t { - NOT_REGISTERED = 0, - REGISTERED = 1, - SEARCHING=2, - DENIED=3, - UNKNOWN=4, - ROAMING=5 - }; - - enum SERVICEDOMAIN : uint8_t { - NO_SERVICE = 0, - CS_ONLY = 1, - PS_ONLY = 2, - CSPS = 3 - }; - - enum ACTIVEBAND : uint8_t { - GSM_850 = 0, - GSM_900 = 1, - DCS_1800 = 2, - PCS_1900 = 3 - }; - - enum CODE : uint8_t { - SUCCESS = 0, - ERROR, - FAILURE, - NO_RESPONSE, - NOT_APPLICABLE, - INVALID_ARGS - }; - - enum SIMSTATUS : uint8_t { - READY = 0, - LOCKED, - BLOCKED, - NOT_INSERTED - }; - - static const std::string VALUE_NOT_REGISTERED; - static const std::string VALUE_REGISTERED; - static const std::string VALUE_SEARCHING; - static const std::string VALUE_DENIED; - static const std::string VALUE_ROAMING; - - //Static Data - static const std::string KEY_TYPE; //!< GSM or CDMA - static const std::string KEY_CODE; //!< Product Code : H5, H6, C2, EV3, G3 - static const std::string KEY_MODEL; //!< Model : HE910, CE910, DE910, GE910 - static const std::string KEY_MANUFACTURER; //!< Manufacturer: Telit - static const std::string KEY_HARDWARE; //!< Radio Hardware Version - static const std::string KEY_FIRMWARE; //!< Radio Firmware Version - static const std::string KEY_FIRMWARE_BUILD;//!< Radio Firmware Build - static const std::string KEY_IMEI; //!< International Mobile Station Equipment Identity - static const std::string KEY_MEID; //!< Mobile Equipment Identifier - static const std::string KEY_IMSI; //!< International Mobile Subscriber Identity - static const std::string KEY_MSID; //!< Mobil Station ID (MSID) aka MIN aka MSIN aka Last few digits of IMSI - static const std::string KEY_MDN; //!< Mobile Directory Number : Actual phone number dialed to reach radio - static const std::string KEY_CARRIER; //!< Cellular Service Provider (Home Network) - static const std::string KEY_ICCID; //!< Integrated Circuit Card Identifier - static const std::string KEY_MSL; //!< Master Subsidy Lock - - - //Network Status Data - static const std::string KEY_ROAMING; //!< Indicates whether or not using Home Network - static const std::string KEY_DATETIME; //!< Date and Time from tower - static const std::string KEY_SERVICE; //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO] - static const std::string KEY_NETWORK; //!< Cellular Service Provider - static const std::string KEY_NETWORK_REG; //!< Network Registration - static const std::string KEY_CID; //!< Cellular ID (Tower) in HEX - static const std::string KEY_LAC; //!< Location Area Code in HEX - static const std::string KEY_RAC; //!< Routing Area Code in HEX - static const std::string KEY_RSSI; //!< Received Signal Strength Indication - static const std::string KEY_RSSIDBM; //!< Received Signal Strength Indication in dBm - static const std::string KEY_MCC; //!< Mobile Country Code - static const std::string KEY_MNC; //!< Mobile Network (Operator) Code - static const std::string KEY_CHANNEL; //!< ARFCN or UARFCN Assigned Radio Channel - static const std::string KEY_TXPWR; //!< Transmit Power - static const std::string KEY_PSC; //!< Active Primary Synchronization Code (PSC) - static const std::string KEY_ECIO; //!< Active Ec/Io (chip energy per total wideband power in dBm) - static const std::string KEY_RSCP; //!< Active RSCP (Received Signal Code Power in dBm) - static const std::string KEY_DRX; //!< Discontinuous reception cycle length (ms) - static const std::string KEY_MM; //!< Mobility Management State - static const std::string KEY_RR; //!< Radio Resource State - static const std::string KEY_NOM; //!< Network Operator Mode - static const std::string KEY_ABND; //!< Active Band - static const std::string KEY_BLER; //!< Block Error Rate (percentage) - static const std::string KEY_SD; //!< Service Domain - static const std::string KEY_DEBUG; //!< Debug Information - - static const std::string KEY_MIP; //!< Mobile IP Information - static const std::string KEY_MIP_ID; //!< MIP Profile ID - static const std::string KEY_MIP_ENABLED; //!< MIP Profile Enabled/Disabled - static const std::string KEY_MIP_NAI; //!< Network Access Identifier - static const std::string KEY_MIP_HOMEADDRESS; //!< Home Address - static const std::string KEY_MIP_PRIMARYHA; //!< Primary Home Agent - static const std::string KEY_MIP_SECONDARYHA; //!< Secondary Home Agent - static const std::string KEY_MIP_MNAAASPI; //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index - static const std::string KEY_MIP_MNHASPI; //!< Mobile Node Home Agent Security Server Parameter Index - static const std::string KEY_MIP_REVTUN; //!< Reverse Tunneling Enabled - static const std::string KEY_MIP_MNAAASS; //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret - static const std::string KEY_MIP_MNHASS; //!< Mobile Node Home Agent Shared Secret - - - //Values - Type - static const std::string VALUE_TYPE_LTE; - static const std::string VALUE_TYPE_GSM; - static const std::string VALUE_TYPE_CDMA; - - //Values - Carrier - static const std::string VALUE_CARRIER_VERIZON; - static const std::string VALUE_CARRIER_AERIS; - static const std::string VALUE_CARRIER_SPRINT; - static const std::string VALUE_CARRIER_USCELLULAR; - static const std::string VALUE_CARRIER_ATT; - static const std::string VALUE_CARRIER_TMOBILE; - - static const std::string VALUE_SD_NO_SERVICE; - static const std::string VALUE_SD_CS_ONLY; - static const std::string VALUE_SD_PS_ONLY; - static const std::string VALUE_SD_CSPS; - - static const std::string VALUE_ABND_GSM_850; - static const std::string VALUE_ABND_GSM_900; - static const std::string VALUE_ABND_DCS_1800; - static const std::string VALUE_ABND_PCS_1900; - - static const std::vector<std::string> DEFAULT_BAIL_STRINGS; - - typedef std::function<bool(const std::string&/*iterationData*/, const std::string&/*allData*/)> IsNeedMoreData; - typedef std::function<void(const Json::Value&)> UpdateCb; - - virtual ~CellularRadio(); - - virtual bool initialize(uint32_t iTimeoutMillis = 5000); - virtual bool resetRadio(uint32_t iTimeoutMillis = 5000); - virtual bool resetConnection(uint32_t iTimeoutMillis = 5000); - virtual void shutdown(); - - const std::string& getName() const; - - virtual CODE getModel(std::string& sModel); - static CODE convertModelToType(const std::string& sModel, std::string& sType); - static CODE convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, CellularRadio *radioObj = NULL); - static CODE convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd); - static CODE convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand); - - virtual CODE getFirmware(std::string& sFirmware); - virtual CODE getFirmwareBuild(std::string& sFirmwareBuild); - virtual CODE getHardware(std::string& sHardware); - virtual CODE getManufacturer(std::string& sManufacturer); - virtual CODE getImei(std::string& sImei); - virtual CODE getMeid(std::string& sMeid); - virtual CODE getImsi(std::string& sImsi); - virtual CODE getSimStatus(std::string& sSimStatus); - virtual CODE getIccid(std::string& sIccid); - virtual CODE getService(std::string& sService); - virtual CODE getLac(std::string& sLac); - virtual CODE getMdn(std::string& sMdn); - virtual CODE getMsid(std::string& sMsid); - virtual CODE getType(std::string& sType); - virtual CODE getCarrier(std::string& sCarrier); - virtual CODE getNetwork(std::string& sNetwork); - virtual CODE getTower(std::string& sTower); - virtual CODE getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone); - virtual CODE getRoaming(bool& bRoaming); - - virtual CODE getSignalStrength(int32_t& iRssi); - virtual CODE getModemLocation(std::string& sLocation); - virtual CODE convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& dBm); - virtual CODE convertdBmToSignalStrength(const int32_t& dBm, int32_t& iRssi); - - virtual CODE getRegistration(REGISTRATION& eRegistration); - virtual CODE convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration); - - //! Gather details of the radio's Mobile IP Profile - /*! - \param Json::Value object that will be populated with MIP data - \return Returns result code of gathering MIP - */ - virtual CODE getMipProfile(Json::Value& jMipProfile); - - /* - * jArgs = { - * "msl" : "Master Subsidy Lock (Aeris, Sprint): STRING" - * } - */ - virtual CODE validateMsl(const Json::Value& jArgs); - - /* - * jArgs = { - * "mdn" : "Mobile Directory Number : STRING", - * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" - * } - */ - virtual CODE setMdn(const Json::Value& jArgs); - - /* - * jArgs = { - * "msid" : "Mobil Station ID (MSID) aka MIN aka MSIN : STRING", - * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" - * } - */ - virtual CODE setMsid(const Json::Value& jArgs); - - /* - * jArgs = { - * "activeProfile" : "Set active profile: STRING" - * } - */ - virtual CODE setMipActiveProfile(const Json::Value& jArgs); - - /* - * jArgs = { - * "nai" : "Network Access Identifier : STRING" - * } - */ - virtual CODE setMipNai(const Json::Value& jArgs); - - /* - * jArgs = { - * "homeIp" : "Home Address : STRING" - * } - */ - virtual CODE setMipHomeIp(const Json::Value& jArgs); - - /* - * jArgs = { - * "primaryHa" : "Primary Home Agent : STRING" - * } - */ - virtual CODE setMipPrimaryHa(const Json::Value& jArgs); - - /* - * jArgs = { - * "secondaryHa" : "Secondary Home Agent : STRING" - * } - */ - virtual CODE setMipSecondaryHa(const Json::Value& jArgs); - - /* - * jArgs = { - * "mnAaaSpi" : "Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index : STRING" - * } - */ - virtual CODE setMipMnAaaSpi(const Json::Value& jArgs); - - /* - * jArgs = { - * "mnHaSpi" : "Mobile Node Home Agent Security Server Parameter Index : STRING" - * } - */ - virtual CODE setMipMnHaSpi(const Json::Value& jArgs); - - /* - * jArgs = { - * "revTun" : "[DESCRIPTION] : STRING" - * } - */ - virtual CODE setMipRevTun(const Json::Value& jArgs); - - /* - * jArgs = { - * "mnAaaSs" : "Mobile Node Authentication, Authorization, and Accounting Server Shared Secret : STRING" - * } - */ - virtual CODE setMipMnAaaSs(const Json::Value& jArgs); - - /* - * jArgs = { - * "mnHaSs" : "Mobile Node Home Agent Shared Secret : STRING" - * } - */ - virtual CODE setMipMnHaSs(const Json::Value& jArgs); - - /* - * jArgs = null - */ - virtual CODE updateDc(const Json::Value& jArgs, UpdateCb& stepCb); - - /* - * jArgs = null - */ - virtual CODE updatePrl(const Json::Value& jArgs, UpdateCb& stepCb); - - /* - * jArgs = null - */ - virtual CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb); - - /* - * jArgs = { - * "msl" : "Master Subsidy Lock (Sprint): STRING" - * } - */ - virtual CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb); - - /* - * jArgs = { - * "mdn" : "Mobile Directory Number (Aeris): STRING" - * "msid" : "Mobile Station ID (Aeris): STRING" - * } - */ - virtual CODE activate(const Json::Value& jArgs, UpdateCb& stepCb); - - /* - * jArgs = { - * "enabled" : "RX Diversity Enabled ("0" or "1"): STRING" - * } - */ - virtual CODE setRxDiversity(const Json::Value& jArgs)=0; - /* - * jArgs = { - * "fwid" : "Firmware Image To Be Enabled: STRING" - * } - */ - virtual CODE setActiveFirmware(const Json::Value& jArgs); - virtual CODE getActiveFirmware(std::string& sFwId); - - virtual CODE getEcho(bool& bEnabled); - virtual CODE setEcho(bool bEnabled = true); - - virtual CODE getStaticInformation(Json::Value& jData); - virtual CODE getNetworkStatus(Json::Value& jData); - - virtual CODE sendBasicCommand(const std::string& sCmd, int32_t timeoutMillis = 100, const char& ESC = CR); - - virtual std::string sendCommand(const std::string& sCmd, - const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, - int32_t timeoutMillis = 100, - const char& ESC = CR); - - - static std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, - const std::string& sCmd, - const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, - int32_t timeoutMillis = 100, - const char& ESC = CR); - - virtual std::string sendCommand(const std::string& sCmd, - IsNeedMoreData& isNeedMoreData, - int32_t timeoutMillis = 100, - const char& ESC = CR); - - static std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, - const std::string& sCmd, - IsNeedMoreData& isNeedMoreData, - int32_t timeoutMillis = 100, - const char& ESC = CR); - - static CODE test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds = 30); - - static std::string extractModelFromResult(const std::string& sResult); - static std::string getCodeAsString(CODE code); - - protected: - - CellularRadio(const std::string& sName, const std::string& sRadioPort); - - virtual bool getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier); - virtual bool getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware); - - virtual void getCommonNetworkStats(Json::Value& jData); - - void initMipProfile(Json::Value& jData); - - bool splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType = Json::ValueType::stringValue); - - - - private: - class RadioBandMap : NonCopyable { - public: - RadioBandMap() - { - m_sChannel = CellularRadio::VALUE_UNKNOWN; - m_iChannel = 0; - m_sRadioType = CellularRadio::VALUE_UNKNOWN; - } - - RadioBandMap(const std::string &channel, const std::string &radioType) : - m_sChannel(channel), - m_sRadioType(radioType) - { - m_iChannel = strtol(m_sChannel.c_str(), NULL, 10); - } - - virtual ~RadioBandMap() {} - - const char *getRadioBandName(); - const char *getRadioBandName(const std::string &channel, const std::string &radioType); - - private: - - const char *getLTEBand(const int channel); - const char *getCDMABand(const int channel); - const char *getGSMBand(const int channel); - - std::string m_sChannel; - int m_iChannel; - std::string m_sRadioType; - }; - - std::string m_sName; - std::string m_sRadioPort; - std::string m_sFirmware; - std::string m_sCarrier; - MTS::AutoPtr<MTS::IO::Connection> m_apIo; - - bool m_bEchoEnabled; - bool m_bEnableEchoOnClose; + class CellularRadio : public ICellularRadio { - std::string queryLteLac(); - std::string queryCGREGstring(); - void setCGREG(std::string value); }; } } diff --git a/include/mts/MTS_IO_CellularRadioFactory.h b/include/mts/MTS_IO_CellularRadioFactory.h index 49f63bd..501f314 100644 --- a/include/mts/MTS_IO_CellularRadioFactory.h +++ b/include/mts/MTS_IO_CellularRadioFactory.h @@ -21,7 +21,7 @@ #ifndef MTS_IO_CELLULARRADIOFACTORY_H_ #define MTS_IO_CELLULARRADIOFACTORY_H_ -#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_TelitRadio.h> #include <string> #include <map> @@ -39,26 +39,26 @@ namespace MTS { CellularRadioFactory(); virtual ~CellularRadioFactory() {}; - virtual CellularRadio* create(const std::string& sModel, const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - - virtual CellularRadio* createHE910D(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createHE910EUD(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910NAG(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910C4NF(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910NA1(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910SVG(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910EUG(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910C4EU(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910EU1(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910C1NS(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE910C1AP(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createME910C1NA(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createME910C1NV(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createME910C1WW(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createGE910(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createDE910(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createCE910(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); - virtual CellularRadio* createLE866A1JS(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* create(const std::string& sModel, const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + + virtual CellularRadio* createHE910D(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createHE910EUD(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910NAG(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910C4NF(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910NA1(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910SVG(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910EUG(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910C4EU(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910EU1(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910C1NS(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910C1AP(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createME910C1NA(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createME910C1NV(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createME910C1WW(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createGE910(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createDE910(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createCE910(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE866A1JS(const std::string& sPort = TelitRadio::DEFAULT_RADIO_PORT); protected: typedef MTS::IO::CellularRadio* (CellularRadioFactory::*CREATEFUNCPTR)(const std::string& sPort); diff --git a/include/mts/MTS_IO_EG95Radio.h b/include/mts/MTS_IO_EG95Radio.h new file mode 100644 index 0000000..07db773 --- /dev/null +++ b/include/mts/MTS_IO_EG95Radio.h @@ -0,0 +1,15 @@ +#ifndef MTS_IO_EG95RADIO_H +#define MTS_IO_EG95RADIO_H + +#include "mts/MTS_IO_QuectelRadio.h" + +namespace MTS { + namespace IO { + class EG95Radio : public QuectelRadio + { + + }; + } +} + +#endif diff --git a/include/mts/MTS_IO_GE910Radio.h b/include/mts/MTS_IO_GE910Radio.h index 27efbac..4904ea7 100644 --- a/include/mts/MTS_IO_GE910Radio.h +++ b/include/mts/MTS_IO_GE910Radio.h @@ -29,12 +29,12 @@ #ifndef MTS_IO_GE910RADIO_H_ #define MTS_IO_GE910RADIO_H_ -#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_TelitRadio.h> namespace MTS { namespace IO { - class GE910Radio : public CellularRadio { + class GE910Radio : public TelitRadio { public: static const std::string MODEL_NAME; diff --git a/include/mts/MTS_IO_HE910Radio.h b/include/mts/MTS_IO_HE910Radio.h index e6fc73c..c8700da 100644 --- a/include/mts/MTS_IO_HE910Radio.h +++ b/include/mts/MTS_IO_HE910Radio.h @@ -29,12 +29,12 @@ #ifndef MTS_IO_HE910RADIO_H_ #define MTS_IO_HE910RADIO_H_ -#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_TelitRadio.h> namespace MTS { namespace IO { - class HE910Radio : public CellularRadio { + class HE910Radio : public TelitRadio { public: diff --git a/include/mts/MTS_IO_ICellularRadio.h b/include/mts/MTS_IO_ICellularRadio.h new file mode 100644 index 0000000..da86946 --- /dev/null +++ b/include/mts/MTS_IO_ICellularRadio.h @@ -0,0 +1,399 @@ +#ifndef MTS_IO_ICELLULARRADIO_H +#define MTS_IO_ICELLULARRADIO_H + +#include <string> +#include <vector> +#include <functional> + +#include <json/json.h> + +#include <mts/MTS_AutoPtr.h> +#include <mts/MTS_IO_Connection.h> + +namespace MTS { + namespace IO { + class ICellularRadio; + namespace { + + static const std::string DEFAULT_RADIO_PORT; + static const std::string DEFAULT_RADIO_DIR; + + static const std::string VALUE_UNKNOWN; + static const std::string VALUE_UNAVAILABLE; + static const std::string VALUE_NOT_SUPPORTED; + + //Special Payload Characters + static const char ETX = 0; //Ends socket connection + static const char DLE = 0; //Escapes ETX and DLE within Payload + static const char CR = 0; + static const char NL = 0; + static const char CTRL_Z = 0; + + static const std::string RSP_OK; + static const std::string RSP_ERROR; + + static const std::string VALUE_NOT_REGISTERED; + static const std::string VALUE_REGISTERED; + static const std::string VALUE_SEARCHING; + static const std::string VALUE_DENIED; + static const std::string VALUE_ROAMING; + + //Static Data + static const std::string KEY_TYPE; //!< GSM or CDMA + static const std::string KEY_CODE; //!< Product Code : H5, H6, C2, EV3, G3 + static const std::string KEY_MODEL; //!< Model : HE910, CE910, DE910, GE910 + static const std::string KEY_MANUFACTURER; //!< Manufacturer: Telit + static const std::string KEY_HARDWARE; //!< Radio Hardware Version + static const std::string KEY_FIRMWARE; //!< Radio Firmware Version + static const std::string KEY_FIRMWARE_BUILD;//!< Radio Firmware Build + static const std::string KEY_IMEI; //!< International Mobile Station Equipment Identity + static const std::string KEY_MEID; //!< Mobile Equipment Identifier + static const std::string KEY_IMSI; //!< International Mobile Subscriber Identity + static const std::string KEY_MSID; //!< Mobil Station ID (MSID) aka MIN aka MSIN aka Last few digits of IMSI + static const std::string KEY_MDN; //!< Mobile Directory Number : Actual phone number dialed to reach radio + static const std::string KEY_CARRIER; //!< Cellular Service Provider (Home Network) + static const std::string KEY_ICCID; //!< Integrated Circuit Card Identifier + static const std::string KEY_MSL; //!< Master Subsidy Lock + + + //Network Status Data + static const std::string KEY_ROAMING; //!< Indicates whether or not using Home Network + static const std::string KEY_DATETIME; //!< Date and Time from tower + static const std::string KEY_SERVICE; //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO] + static const std::string KEY_NETWORK; //!< Cellular Service Provider + static const std::string KEY_NETWORK_REG; //!< Network Registration + static const std::string KEY_CID; //!< Cellular ID (Tower) in HEX + static const std::string KEY_LAC; //!< Location Area Code in HEX + static const std::string KEY_RAC; //!< Routing Area Code in HEX + static const std::string KEY_RSSI; //!< Received Signal Strength Indication + static const std::string KEY_RSSIDBM; //!< Received Signal Strength Indication in dBm + static const std::string KEY_MCC; //!< Mobile Country Code + static const std::string KEY_MNC; //!< Mobile Network (Operator) Code + static const std::string KEY_CHANNEL; //!< ARFCN or UARFCN Assigned Radio Channel + static const std::string KEY_TXPWR; //!< Transmit Power + static const std::string KEY_PSC; //!< Active Primary Synchronization Code (PSC) + static const std::string KEY_ECIO; //!< Active Ec/Io (chip energy per total wideband power in dBm) + static const std::string KEY_RSCP; //!< Active RSCP (Received Signal Code Power in dBm) + static const std::string KEY_DRX; //!< Discontinuous reception cycle length (ms) + static const std::string KEY_MM; //!< Mobility Management State + static const std::string KEY_RR; //!< Radio Resource State + static const std::string KEY_NOM; //!< Network Operator Mode + static const std::string KEY_ABND; //!< Active Band + static const std::string KEY_BLER; //!< Block Error Rate (percentage) + static const std::string KEY_SD; //!< Service Domain + static const std::string KEY_DEBUG; //!< Debug Information + + static const std::string KEY_MIP; //!< Mobile IP Information + static const std::string KEY_MIP_ID; //!< MIP Profile ID + static const std::string KEY_MIP_ENABLED; //!< MIP Profile Enabled/Disabled + static const std::string KEY_MIP_NAI; //!< Network Access Identifier + static const std::string KEY_MIP_HOMEADDRESS; //!< Home Address + static const std::string KEY_MIP_PRIMARYHA; //!< Primary Home Agent + static const std::string KEY_MIP_SECONDARYHA; //!< Secondary Home Agent + static const std::string KEY_MIP_MNAAASPI; //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index + static const std::string KEY_MIP_MNHASPI; //!< Mobile Node Home Agent Security Server Parameter Index + static const std::string KEY_MIP_REVTUN; //!< Reverse Tunneling Enabled + static const std::string KEY_MIP_MNAAASS; //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret + static const std::string KEY_MIP_MNHASS; //!< Mobile Node Home Agent Shared Secret + + + //Values - Type + static const std::string VALUE_TYPE_LTE; + static const std::string VALUE_TYPE_GSM; + static const std::string VALUE_TYPE_CDMA; + + //Values - Carrier + static const std::string VALUE_CARRIER_VERIZON; + static const std::string VALUE_CARRIER_AERIS; + static const std::string VALUE_CARRIER_SPRINT; + static const std::string VALUE_CARRIER_USCELLULAR; + static const std::string VALUE_CARRIER_ATT; + static const std::string VALUE_CARRIER_TMOBILE; + + static const std::string VALUE_SD_NO_SERVICE; + static const std::string VALUE_SD_CS_ONLY; + static const std::string VALUE_SD_PS_ONLY; + static const std::string VALUE_SD_CSPS; + + static const std::string VALUE_ABND_GSM_850; + static const std::string VALUE_ABND_GSM_900; + static const std::string VALUE_ABND_DCS_1800; + static const std::string VALUE_ABND_PCS_1900; + + static const std::vector<std::string> DEFAULT_BAIL_STRINGS; + + typedef std::function<bool(const std::string&/*iterationData*/, const std::string&/*allData*/)> IsNeedMoreData; + typedef std::function<void(const Json::Value&)> UpdateCb; + + /* + CODE convertModelToType(const std::string& sModel, std::string& sType); + CODE convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, ICellularRadio *radioObj = NULL); + CODE convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd); + CODE convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand); + + std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, + const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, + const std::string& sCmd, + const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, + int32_t timeoutMillis = 100, + const char& ESC = CR); + CODE test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds = 30); + + std::string extractModelFromResult(const std::string& sResult); + std::string getCodeAsString(CODE code); + */ + + } + class ICellularRadio + { + public: + //Registration Values + enum REGISTRATION : uint8_t { + NOT_REGISTERED = 0, + REGISTERED = 1, + SEARCHING=2, + DENIED=3, + UNKNOWN=4, + ROAMING=5 + }; + + enum SERVICEDOMAIN : uint8_t { + NO_SERVICE = 0, + CS_ONLY = 1, + PS_ONLY = 2, + CSPS = 3 + }; + + enum ACTIVEBAND : uint8_t { + GSM_850 = 0, + GSM_900 = 1, + DCS_1800 = 2, + PCS_1900 = 3 + }; + + enum CODE : uint8_t { + SUCCESS = 0, + ERROR, + FAILURE, + NO_RESPONSE, + NOT_APPLICABLE, + INVALID_ARGS + }; + + enum SIMSTATUS : uint8_t { + READY = 0, + LOCKED, + BLOCKED, + NOT_INSERTED + }; + virtual ~ICellularRadio() = 0; + + virtual bool initialize(uint32_t iTimeoutMillis = 5000) = 0; + virtual bool resetRadio(uint32_t iTimeoutMillis = 5000) = 0; + virtual bool resetConnection(uint32_t iTimeoutMillis = 5000) = 0; + virtual void shutdown() = 0; + + virtual const std::string& getName() const = 0; + + virtual CODE getModel(std::string& sModel) = 0; + + virtual CODE getFirmware(std::string& sFirmware) = 0; + virtual CODE getFirmwareBuild(std::string& sFirmwareBuild) = 0; + virtual CODE getHardware(std::string& sHardware) = 0; + virtual CODE getManufacturer(std::string& sManufacturer) = 0; + virtual CODE getImei(std::string& sImei) = 0; + virtual CODE getMeid(std::string& sMeid) = 0; + virtual CODE getImsi(std::string& sImsi) = 0; + virtual CODE getSimStatus(std::string& sSimStatus) = 0; + virtual CODE getIccid(std::string& sIccid) = 0; + virtual CODE getService(std::string& sService) = 0; + virtual CODE getLac(std::string& sLac) = 0; + virtual CODE getMdn(std::string& sMdn) = 0; + virtual CODE getMsid(std::string& sMsid) = 0; + virtual CODE getType(std::string& sType) = 0; + virtual CODE getCarrier(std::string& sCarrier) = 0; + virtual CODE getNetwork(std::string& sNetwork) = 0; + virtual CODE getTower(std::string& sTower) = 0; + virtual CODE getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) = 0; + virtual CODE getRoaming(bool& bRoaming) = 0; + + virtual CODE getSignalStrength(int32_t& iRssi) = 0; + virtual CODE getModemLocation(std::string& sLocation) = 0; + virtual CODE convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& dBm) = 0; + virtual CODE convertdBmToSignalStrength(const int32_t& dBm, int32_t& iRssi) = 0; + + virtual CODE getRegistration(REGISTRATION& eRegistration) = 0; + virtual CODE convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) = 0; + + //! Gather details of the radio's Mobile IP Profile + /*! + \param Json::Value object that will be populated with MIP data + \return Returns result code of gathering MIP + */ + virtual CODE getMipProfile(Json::Value& jMipProfile) = 0; + + /* + * jArgs = { + * "msl" : "Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE validateMsl(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "mdn" : "Mobile Directory Number : STRING", + * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE setMdn(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "msid" : "Mobil Station ID (MSID) aka MIN aka MSIN : STRING", + * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE setMsid(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "activeProfile" : "Set active profile: STRING" + * } + */ + virtual CODE setMipActiveProfile(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "nai" : "Network Access Identifier : STRING" + * } + */ + virtual CODE setMipNai(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "homeIp" : "Home Address : STRING" + * } + */ + virtual CODE setMipHomeIp(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "primaryHa" : "Primary Home Agent : STRING" + * } + */ + virtual CODE setMipPrimaryHa(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "secondaryHa" : "Secondary Home Agent : STRING" + * } + */ + virtual CODE setMipSecondaryHa(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "mnAaaSpi" : "Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index : STRING" + * } + */ + virtual CODE setMipMnAaaSpi(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "mnHaSpi" : "Mobile Node Home Agent Security Server Parameter Index : STRING" + * } + */ + virtual CODE setMipMnHaSpi(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "revTun" : "[DESCRIPTION] : STRING" + * } + */ + virtual CODE setMipRevTun(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "mnAaaSs" : "Mobile Node Authentication, Authorization, and Accounting Server Shared Secret : STRING" + * } + */ + virtual CODE setMipMnAaaSs(const Json::Value& jArgs) = 0; + + /* + * jArgs = { + * "mnHaSs" : "Mobile Node Home Agent Shared Secret : STRING" + * } + */ + virtual CODE setMipMnHaSs(const Json::Value& jArgs) = 0; + + /* + * jArgs = null + */ + virtual CODE updateDc(const Json::Value& jArgs, UpdateCb& stepCb) = 0; + + /* + * jArgs = null + */ + virtual CODE updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) = 0; + + /* + * jArgs = null + */ + virtual CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) = 0; + + /* + * jArgs = { + * "msl" : "Master Subsidy Lock (Sprint): STRING" + * } + */ + virtual CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) = 0; + + /* + * jArgs = { + * "mdn" : "Mobile Directory Number (Aeris): STRING" + * "msid" : "Mobile Station ID (Aeris): STRING" + * } + */ + virtual CODE activate(const Json::Value& jArgs, UpdateCb& stepCb) = 0; + + /* + * jArgs = { + * "enabled" : "RX Diversity Enabled ("0" or "1"): STRING" + * } + */ + virtual CODE setRxDiversity(const Json::Value& jArgs) = 0; + /* + * jArgs = { + * "fwid" : "Firmware Image To Be Enabled: STRING" + * } + */ + virtual CODE setActiveFirmware(const Json::Value& jArgs) = 0; + virtual CODE getActiveFirmware(std::string& sFwId) = 0; + + virtual CODE getEcho(bool& bEnabled) = 0; + virtual CODE setEcho(bool bEnabled = true) = 0; + + virtual CODE getStaticInformation(Json::Value& jData) = 0; + virtual CODE getNetworkStatus(Json::Value& jData) = 0; + + virtual CODE sendBasicCommand(const std::string& sCmd, int32_t timeoutMillis = 100, const char& ESC = CR) = 0; + + virtual std::string sendCommand(const std::string& sCmd, + const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, + int32_t timeoutMillis = 100, + const char& ESC = CR) = 0; + + virtual std::string sendCommand(const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, + int32_t timeoutMillis = 100, + const char& ESC = CR) = 0; + + }; + } +} + +#endif diff --git a/include/mts/MTS_IO_LE866Radio.h b/include/mts/MTS_IO_LE866Radio.h index c11c5b4..2775e4d 100644 --- a/include/mts/MTS_IO_LE866Radio.h +++ b/include/mts/MTS_IO_LE866Radio.h @@ -35,12 +35,12 @@ A more elaborate description */ -#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_TelitRadio.h> namespace MTS { namespace IO { - class LE866Radio : public CellularRadio { + class LE866Radio : public TelitRadio { public: static const std::string MODEL_NAME; diff --git a/include/mts/MTS_IO_LE910Radio.h b/include/mts/MTS_IO_LE910Radio.h index e8ac21f..35e704d 100644 --- a/include/mts/MTS_IO_LE910Radio.h +++ b/include/mts/MTS_IO_LE910Radio.h @@ -29,12 +29,12 @@ #ifndef MTS_IO_LE910RADIO_H_ #define MTS_IO_LE910RADIO_H_ -#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_TelitRadio.h> namespace MTS { namespace IO { - class LE910Radio : public CellularRadio { + class LE910Radio : public TelitRadio { public: static const std::string MODEL_NAME; diff --git a/include/mts/MTS_IO_ME910Radio.h b/include/mts/MTS_IO_ME910Radio.h index 91cdfc6..09e8ede 100644 --- a/include/mts/MTS_IO_ME910Radio.h +++ b/include/mts/MTS_IO_ME910Radio.h @@ -21,12 +21,12 @@ #ifndef MTS_IO_ME910RADIO_H_ #define MTS_IO_ME910RADIO_H_ -#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_TelitRadio.h> namespace MTS { namespace IO { - class ME910Radio : public CellularRadio { + class ME910Radio : public TelitRadio { public: static const std::string MODEL_NAME; diff --git a/include/mts/MTS_IO_QuectelRadio.h b/include/mts/MTS_IO_QuectelRadio.h new file mode 100644 index 0000000..55eac60 --- /dev/null +++ b/include/mts/MTS_IO_QuectelRadio.h @@ -0,0 +1,15 @@ +#ifndef MTS_IO_QUECTELRADIO_H +#define MTS_IO_QUECTELRADIO_H + +#include <mts/MTS_IO_CellularRadio.h> + +namespace MTS { + namespace IO { + class QuectelRadio : public CellularRadio + { + + }; + } +} + +#endif diff --git a/include/mts/MTS_IO_TelitRadio.h b/include/mts/MTS_IO_TelitRadio.h new file mode 100644 index 0000000..f8fce6a --- /dev/null +++ b/include/mts/MTS_IO_TelitRadio.h @@ -0,0 +1,496 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts-io. + * + * libmts-io is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libmts-io is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libmts-io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef MTS_IO_TELITRADIO_H_ +#define MTS_IO_TELITRADIO_H_ + +#include <mts/MTS_IO_CellularRadio.h> + +#include <mts/MTS_IO_SerialConnection.h> +#include <mts/MTS_NonCopyable.h> +#include <mts/MTS_AutoPtr.h> +#include <mts/MTS_Lock.h> +#include <mts/MTS_Stdint.h> +#include <json/json.h> +#include <string> +#include <vector> +#include <functional> + +typedef struct +{ + const char *name; + int32_t low; + int32_t high; +} *pNameRangeMap, nameRangeMap; + +static const unsigned int NUM_GSM_BANDS = 7; +static const unsigned int NUM_WCDMA_BANDS = 6; +static const unsigned int NUM_LTE_BANDS = 42; + +// http://niviuk.free.fr/gsm_band.php +static const nameRangeMap GSMband[] = +{ + {"GSM 450", 259, 293}, {"GSM 480", 306, 340}, + {"GSM 750", 438, 511}, {"GSM 850", 128, 251}, + {"GSM 900 P", 1, 124}, {"GSM 900 E/R", 955, 1023}, + {"GSM DCS 1800/1900", 512, 885}, + +}; + +// http://niviuk.free.fr/umts_band.php +static const nameRangeMap WCDMAband[] = +{ + {"BAND I", 10592, 10838}, {"BAND II", 9662, 9938}, + {"BAND III", 1162, 1513}, {"BAND IV", 1537, 1738}, + {"BAND V", 4357, 4458}, {"BAND VI", 4387, 4413} +}; + +// http://niviuk.free.fr/lte_band.php +static const nameRangeMap EULTRAband[] = +{ + {"EUTRAN BAND1", 0, 599}, {"EUTRAN BAND2", 600, 1199}, + {"EUTRAN BAND3", 1200, 1949}, {"EUTRAN BAND4", 1950, 2399}, + {"EUTRAN BAND5", 2400, 2649}, {"EUTRAN BAND6", 2650, 2749}, + {"EUTRAN BAND7", 2750, 3449}, {"EUTRAN BAND8", 3450, 3799}, + {"EUTRAN BAND9", 3800, 4149}, {"EUTRAN BAND10", 4150, 4749}, + {"EUTRAN BAND11", 4750, 4999}, {"EUTRAN BAND12", 5000, 5179}, + {"EUTRAN BAND13", 5180, 5279}, {"EUTRAN BAND14", 5280, 5379}, + {"EUTRAN BAND17", 5730, 5849}, {"EUTRAN BAND18", 5850, 5999}, + {"EUTRAN BAND19", 6000, 6149}, {"EUTRAN BAND20", 6150, 6449}, + {"EUTRAN BAND21", 6450, 6525}, {"EUTRAN BAND22", 6600, 7399}, + {"EUTRAN BAND23", 7500, 7699}, {"EUTRAN BAND24", 7700, 8039}, + {"EUTRAN BAND25", 8040, 8689}, {"EUTRAN BAND26", 8690, 9039}, + {"EUTRAN BAND27", 9040, 9209}, {"EUTRAN BAND28", 9210, 9659}, + {"EUTRAN BAND29", 9660, 9769}, {"EUTRAN BAND30", 9770, 9869}, + {"EUTRAN BAND31", 9870, 9919}, {"EUTRAN BAND32", 9920, 10359}, + {"EUTRAN BAND33", 36000, 36199}, {"EUTRAN BAND34", 36200, 36349}, + {"EUTRAN BAND35", 36350, 36949}, {"EUTRAN BAND36", 36950, 37549}, + {"EUTRAN BAND37", 37550, 37749}, {"EUTRAN BAND38", 37750, 38249}, + {"EUTRAN BAND39", 38250, 38649}, {"EUTRAN BAND40", 38650, 39649}, + {"EUTRAN BAND41", 39650, 41589}, {"EUTRAN BAND42", 41590, 43589}, + {"EUTRAN BAND43", 43590, 45589}, {"EUTRAN BAND44", 45590, 46589} +}; + +namespace MTS { + namespace IO { + + class TelitRadio : public CellularRadio { + + public: + static const std::string DEFAULT_RADIO_PORT; + static const std::string DEFAULT_RADIO_DIR; + + static const std::string VALUE_UNKNOWN; + static const std::string VALUE_UNAVAILABLE; + static const std::string VALUE_NOT_SUPPORTED; + + //Special Payload Characters + static const char ETX; //Ends socket connection + static const char DLE; //Escapes ETX and DLE within Payload + static const char CR; + static const char NL; + static const char CTRL_Z; + + static const std::string RSP_OK; + static const std::string RSP_ERROR; + + static const std::string VALUE_NOT_REGISTERED; + static const std::string VALUE_REGISTERED; + static const std::string VALUE_SEARCHING; + static const std::string VALUE_DENIED; + static const std::string VALUE_ROAMING; + + //Static Data + static const std::string KEY_TYPE; //!< GSM or CDMA + static const std::string KEY_CODE; //!< Product Code : H5, H6, C2, EV3, G3 + static const std::string KEY_MODEL; //!< Model : HE910, CE910, DE910, GE910 + static const std::string KEY_MANUFACTURER; //!< Manufacturer: Telit + static const std::string KEY_HARDWARE; //!< Radio Hardware Version + static const std::string KEY_FIRMWARE; //!< Radio Firmware Version + static const std::string KEY_FIRMWARE_BUILD;//!< Radio Firmware Build + static const std::string KEY_IMEI; //!< International Mobile Station Equipment Identity + static const std::string KEY_MEID; //!< Mobile Equipment Identifier + static const std::string KEY_IMSI; //!< International Mobile Subscriber Identity + static const std::string KEY_MSID; //!< Mobil Station ID (MSID) aka MIN aka MSIN aka Last few digits of IMSI + static const std::string KEY_MDN; //!< Mobile Directory Number : Actual phone number dialed to reach radio + static const std::string KEY_CARRIER; //!< Cellular Service Provider (Home Network) + static const std::string KEY_ICCID; //!< Integrated Circuit Card Identifier + static const std::string KEY_MSL; //!< Master Subsidy Lock + + + //Network Status Data + static const std::string KEY_ROAMING; //!< Indicates whether or not using Home Network + static const std::string KEY_DATETIME; //!< Date and Time from tower + static const std::string KEY_SERVICE; //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO] + static const std::string KEY_NETWORK; //!< Cellular Service Provider + static const std::string KEY_NETWORK_REG; //!< Network Registration + static const std::string KEY_CID; //!< Cellular ID (Tower) in HEX + static const std::string KEY_LAC; //!< Location Area Code in HEX + static const std::string KEY_RAC; //!< Routing Area Code in HEX + static const std::string KEY_RSSI; //!< Received Signal Strength Indication + static const std::string KEY_RSSIDBM; //!< Received Signal Strength Indication in dBm + static const std::string KEY_MCC; //!< Mobile Country Code + static const std::string KEY_MNC; //!< Mobile Network (Operator) Code + static const std::string KEY_CHANNEL; //!< ARFCN or UARFCN Assigned Radio Channel + static const std::string KEY_TXPWR; //!< Transmit Power + static const std::string KEY_PSC; //!< Active Primary Synchronization Code (PSC) + static const std::string KEY_ECIO; //!< Active Ec/Io (chip energy per total wideband power in dBm) + static const std::string KEY_RSCP; //!< Active RSCP (Received Signal Code Power in dBm) + static const std::string KEY_DRX; //!< Discontinuous reception cycle length (ms) + static const std::string KEY_MM; //!< Mobility Management State + static const std::string KEY_RR; //!< Radio Resource State + static const std::string KEY_NOM; //!< Network Operator Mode + static const std::string KEY_ABND; //!< Active Band + static const std::string KEY_BLER; //!< Block Error Rate (percentage) + static const std::string KEY_SD; //!< Service Domain + static const std::string KEY_DEBUG; //!< Debug Information + + static const std::string KEY_MIP; //!< Mobile IP Information + static const std::string KEY_MIP_ID; //!< MIP Profile ID + static const std::string KEY_MIP_ENABLED; //!< MIP Profile Enabled/Disabled + static const std::string KEY_MIP_NAI; //!< Network Access Identifier + static const std::string KEY_MIP_HOMEADDRESS; //!< Home Address + static const std::string KEY_MIP_PRIMARYHA; //!< Primary Home Agent + static const std::string KEY_MIP_SECONDARYHA; //!< Secondary Home Agent + static const std::string KEY_MIP_MNAAASPI; //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index + static const std::string KEY_MIP_MNHASPI; //!< Mobile Node Home Agent Security Server Parameter Index + static const std::string KEY_MIP_REVTUN; //!< Reverse Tunneling Enabled + static const std::string KEY_MIP_MNAAASS; //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret + static const std::string KEY_MIP_MNHASS; //!< Mobile Node Home Agent Shared Secret + + + //Values - Type + static const std::string VALUE_TYPE_LTE; + static const std::string VALUE_TYPE_GSM; + static const std::string VALUE_TYPE_CDMA; + + //Values - Carrier + static const std::string VALUE_CARRIER_VERIZON; + static const std::string VALUE_CARRIER_AERIS; + static const std::string VALUE_CARRIER_SPRINT; + static const std::string VALUE_CARRIER_USCELLULAR; + static const std::string VALUE_CARRIER_ATT; + static const std::string VALUE_CARRIER_TMOBILE; + + static const std::string VALUE_SD_NO_SERVICE; + static const std::string VALUE_SD_CS_ONLY; + static const std::string VALUE_SD_PS_ONLY; + static const std::string VALUE_SD_CSPS; + + static const std::string VALUE_ABND_GSM_850; + static const std::string VALUE_ABND_GSM_900; + static const std::string VALUE_ABND_DCS_1800; + static const std::string VALUE_ABND_PCS_1900; + + static const std::vector<std::string> DEFAULT_BAIL_STRINGS; + + typedef std::function<bool(const std::string&/*iterationData*/, const std::string&/*allData*/)> IsNeedMoreData; + typedef std::function<void(const Json::Value&)> UpdateCb; + + virtual ~TelitRadio(); + + virtual bool initialize(uint32_t iTimeoutMillis = 5000); + virtual bool resetRadio(uint32_t iTimeoutMillis = 5000); + virtual bool resetConnection(uint32_t iTimeoutMillis = 5000); + virtual void shutdown(); + + const std::string& getName() const; + + virtual CODE getModel(std::string& sModel); + static CODE convertModelToType(const std::string& sModel, std::string& sType); + static CODE convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, TelitRadio *radioObj = NULL); + static CODE convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd); + static CODE convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand); + + virtual CODE getFirmware(std::string& sFirmware); + virtual CODE getFirmwareBuild(std::string& sFirmwareBuild); + virtual CODE getHardware(std::string& sHardware); + virtual CODE getManufacturer(std::string& sManufacturer); + virtual CODE getImei(std::string& sImei); + virtual CODE getMeid(std::string& sMeid); + virtual CODE getImsi(std::string& sImsi); + virtual CODE getSimStatus(std::string& sSimStatus); + virtual CODE getIccid(std::string& sIccid); + virtual CODE getService(std::string& sService); + virtual CODE getLac(std::string& sLac); + virtual CODE getMdn(std::string& sMdn); + virtual CODE getMsid(std::string& sMsid); + virtual CODE getType(std::string& sType); + virtual CODE getCarrier(std::string& sCarrier); + virtual CODE getNetwork(std::string& sNetwork); + virtual CODE getTower(std::string& sTower); + virtual CODE getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone); + virtual CODE getRoaming(bool& bRoaming); + + virtual CODE getSignalStrength(int32_t& iRssi); + virtual CODE getModemLocation(std::string& sLocation); + virtual CODE convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& dBm); + virtual CODE convertdBmToSignalStrength(const int32_t& dBm, int32_t& iRssi); + + virtual CODE getRegistration(REGISTRATION& eRegistration); + virtual CODE convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration); + + //! Gather details of the radio's Mobile IP Profile + /*! + \param Json::Value object that will be populated with MIP data + \return Returns result code of gathering MIP + */ + virtual CODE getMipProfile(Json::Value& jMipProfile); + + /* + * jArgs = { + * "msl" : "Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE validateMsl(const Json::Value& jArgs); + + /* + * jArgs = { + * "mdn" : "Mobile Directory Number : STRING", + * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE setMdn(const Json::Value& jArgs); + + /* + * jArgs = { + * "msid" : "Mobil Station ID (MSID) aka MIN aka MSIN : STRING", + * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE setMsid(const Json::Value& jArgs); + + /* + * jArgs = { + * "activeProfile" : "Set active profile: STRING" + * } + */ + virtual CODE setMipActiveProfile(const Json::Value& jArgs); + + /* + * jArgs = { + * "nai" : "Network Access Identifier : STRING" + * } + */ + virtual CODE setMipNai(const Json::Value& jArgs); + + /* + * jArgs = { + * "homeIp" : "Home Address : STRING" + * } + */ + virtual CODE setMipHomeIp(const Json::Value& jArgs); + + /* + * jArgs = { + * "primaryHa" : "Primary Home Agent : STRING" + * } + */ + virtual CODE setMipPrimaryHa(const Json::Value& jArgs); + + /* + * jArgs = { + * "secondaryHa" : "Secondary Home Agent : STRING" + * } + */ + virtual CODE setMipSecondaryHa(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnAaaSpi" : "Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index : STRING" + * } + */ + virtual CODE setMipMnAaaSpi(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnHaSpi" : "Mobile Node Home Agent Security Server Parameter Index : STRING" + * } + */ + virtual CODE setMipMnHaSpi(const Json::Value& jArgs); + + /* + * jArgs = { + * "revTun" : "[DESCRIPTION] : STRING" + * } + */ + virtual CODE setMipRevTun(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnAaaSs" : "Mobile Node Authentication, Authorization, and Accounting Server Shared Secret : STRING" + * } + */ + virtual CODE setMipMnAaaSs(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnHaSs" : "Mobile Node Home Agent Shared Secret : STRING" + * } + */ + virtual CODE setMipMnHaSs(const Json::Value& jArgs); + + /* + * jArgs = null + */ + virtual CODE updateDc(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = null + */ + virtual CODE updatePrl(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = null + */ + virtual CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = { + * "msl" : "Master Subsidy Lock (Sprint): STRING" + * } + */ + virtual CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = { + * "mdn" : "Mobile Directory Number (Aeris): STRING" + * "msid" : "Mobile Station ID (Aeris): STRING" + * } + */ + virtual CODE activate(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = { + * "enabled" : "RX Diversity Enabled ("0" or "1"): STRING" + * } + */ + virtual CODE setRxDiversity(const Json::Value& jArgs)=0; + /* + * jArgs = { + * "fwid" : "Firmware Image To Be Enabled: STRING" + * } + */ + virtual CODE setActiveFirmware(const Json::Value& jArgs); + virtual CODE getActiveFirmware(std::string& sFwId); + + virtual CODE getEcho(bool& bEnabled); + virtual CODE setEcho(bool bEnabled = true); + + virtual CODE getStaticInformation(Json::Value& jData); + virtual CODE getNetworkStatus(Json::Value& jData); + + virtual CODE sendBasicCommand(const std::string& sCmd, int32_t timeoutMillis = 100, const char& ESC = CR); + + virtual std::string sendCommand(const std::string& sCmd, + const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + + static std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, + const std::string& sCmd, + const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + virtual std::string sendCommand(const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + static std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, + const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + static CODE test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds = 30); + + static std::string extractModelFromResult(const std::string& sResult); + static std::string getCodeAsString(CODE code); + + protected: + + TelitRadio(const std::string& sName, const std::string& sRadioPort); + + virtual bool getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier); + virtual bool getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware); + + virtual void getCommonNetworkStats(Json::Value& jData); + + void initMipProfile(Json::Value& jData); + + bool splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType = Json::ValueType::stringValue); + + + + private: + class RadioBandMap { + public: + RadioBandMap() + { + m_sChannel = TelitRadio::VALUE_UNKNOWN; + m_iChannel = 0; + m_sRadioType = TelitRadio::VALUE_UNKNOWN; + } + + RadioBandMap(const std::string &channel, const std::string &radioType) : + m_sChannel(channel), + m_sRadioType(radioType) + { + m_iChannel = strtol(m_sChannel.c_str(), NULL, 10); + } + + virtual ~RadioBandMap() {} + + const char *getRadioBandName(); + const char *getRadioBandName(const std::string &channel, const std::string &radioType); + + private: + + const char *getLTEBand(const int channel); + const char *getCDMABand(const int channel); + const char *getGSMBand(const int channel); + + std::string m_sChannel; + int m_iChannel; + std::string m_sRadioType; + }; + + std::string m_sName; + std::string m_sRadioPort; + std::string m_sFirmware; + std::string m_sCarrier; + MTS::AutoPtr<MTS::IO::Connection> m_apIo; + + bool m_bEchoEnabled; + bool m_bEnableEchoOnClose; + + std::string queryLteLac(); + std::string queryCGREGstring(); + void setCGREG(std::string value); + }; + } +} + + + +#endif diff --git a/src/MTS_IO_CdmaRadio.cpp b/src/MTS_IO_CdmaRadio.cpp index 8057650..4ff5d63 100644 --- a/src/MTS_IO_CdmaRadio.cpp +++ b/src/MTS_IO_CdmaRadio.cpp @@ -35,7 +35,7 @@ using namespace MTS::IO; CdmaRadio::CdmaRadio(const std::string& sName, const std::string& sPort) -: CellularRadio(sName, sPort) +: TelitRadio(sName, sPort) { } diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index f89e673..a29d14f 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -18,1820 +18,4 @@ * */ -#include <mts/MTS_IO_CellularRadio.h> -#include <mts/MTS_IO_MccMncTable.h> -#include <mts/MTS_Thread.h> -#include <mts/MTS_Timer.h> -#include <mts/MTS_Logger.h> -#include <mts/MTS_Text.h> -#include <mts/MTS_System.h> -#include <map> -#include <cstring> -#include <sstream> -#include <sys/file.h> -#include <errno.h> -#include <unistd.h> - - -using namespace MTS::IO; - -const char CellularRadio::ETX = 0x03; //Ends socket connection -const char CellularRadio::DLE = 0x10; //Escapes ETX and DLE within Payload -const char CellularRadio::CR = 0x0D; -const char CellularRadio::NL = 0x0A; -const char CellularRadio::CTRL_Z = 0x1A; - -const std::string CellularRadio::RSP_ERROR("ERROR"); -const std::string CellularRadio::RSP_OK("OK"); - - -const std::string CellularRadio::DEFAULT_RADIO_PORT("/dev/modem_at1"); -const std::string CellularRadio::DEFAULT_RADIO_DIR("/var/run/radio/"); -const std::string CellularRadio::VALUE_UNKNOWN("Unknown"); -const std::string CellularRadio::VALUE_UNAVAILABLE("Unavailable"); -const std::string CellularRadio::VALUE_NOT_SUPPORTED("Not Supported"); - -const std::string CellularRadio::VALUE_NOT_REGISTERED("NOT REGISTERED"); -const std::string CellularRadio::VALUE_REGISTERED("REGISTERED"); -const std::string CellularRadio::VALUE_SEARCHING("SEARCHING"); -const std::string CellularRadio::VALUE_DENIED("DENIED"); -const std::string CellularRadio::VALUE_ROAMING("ROAMING"); - -//Static Data -const std::string CellularRadio::KEY_TYPE("type"); //!< GSM or CDMA -const std::string CellularRadio::KEY_CODE("code"); //!< Product Code : H5, H6, C2, EV3, G3 -const std::string CellularRadio::KEY_MODEL("model"); //!< Model : HE910, LE910, CE910, DE910, GE910 -const std::string CellularRadio::KEY_MANUFACTURER("manufacturer"); //!< Manufacturer: Telit -const std::string CellularRadio::KEY_HARDWARE("hardware"); //!< Radio Hardware Version -const std::string CellularRadio::KEY_FIRMWARE("firmware"); //!< Radio Firmware Version -const std::string CellularRadio::KEY_FIRMWARE_BUILD("firmwarebuild"); //!< Radio Firmware Build - -const std::string CellularRadio::KEY_CARRIER("carrier"); //!< Cellular Service Provider (Home Network) -const std::string CellularRadio::VALUE_CARRIER_VERIZON("Verizon"); -const std::string CellularRadio::VALUE_CARRIER_AERIS("Aeris"); -const std::string CellularRadio::VALUE_CARRIER_SPRINT("Sprint"); -const std::string CellularRadio::VALUE_CARRIER_USCELLULAR("U.S. Cellular"); -const std::string CellularRadio::VALUE_CARRIER_ATT("AT&T"); -const std::string CellularRadio::VALUE_CARRIER_TMOBILE("T-Mobile"); - -const std::string CellularRadio::KEY_IMEI("imei"); //!< International Mobile Station Equipment Identity -const std::string CellularRadio::KEY_MEID("meid"); //!< Mobile Equipment Identifier -const std::string CellularRadio::KEY_IMSI("imsi"); //!< International Mobile Subscriber Identity -const std::string CellularRadio::KEY_MSID("msid"); //!< Mobil Station ID / Mobile Identification Number (MSID/MIN) (CDMA-Only) -const std::string CellularRadio::KEY_MDN("mdn"); //!< Mobile Directory Number : Actual phone number dialed to reach radio -const std::string CellularRadio::KEY_ICCID("iccid"); //!< Integrated Circuit Card Identifier -const std::string CellularRadio::KEY_MSL("msl"); //!< Master Subsidy Lock - -//Dynamic Data -const std::string CellularRadio::KEY_ROAMING("roaming"); //!< Indicates whether or not using Home Network -const std::string CellularRadio::KEY_DATETIME("datetime"); //!< Date and Time from tower -const std::string CellularRadio::KEY_SERVICE("service"); //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO] -const std::string CellularRadio::KEY_NETWORK("network"); //!< Cellular Service Provider -const std::string CellularRadio::KEY_NETWORK_REG("netreg"); //!< Network Registration -const std::string CellularRadio::KEY_CID("cid"); //!< Cellular ID (Tower) in HEX -const std::string CellularRadio::KEY_LAC("lac"); //!< Location Area Code in HEX -const std::string CellularRadio::KEY_RAC("rac"); //!< Routing Area Code in HEX -const std::string CellularRadio::KEY_RSSI("rssi"); //!< Signal Strength -const std::string CellularRadio::KEY_RSSIDBM("rssidBm"); //!< Signal Strength in dBm -const std::string CellularRadio::KEY_MCC("mcc"); //!< Country Code -const std::string CellularRadio::KEY_MNC("mnc"); //!< Operator Code -const std::string CellularRadio::KEY_CHANNEL("channel"); //!< ARFCN or UARFCN Assigned Radio Channel -const std::string CellularRadio::KEY_TXPWR("txpwr"); //!< Transmit Power -const std::string CellularRadio::KEY_PSC("psc"); //!< Active Primary Synchronization Code (PSC) -const std::string CellularRadio::KEY_ECIO("ecio"); //!< Active Ec/Io (chip energy per total wideband power in dBm) -const std::string CellularRadio::KEY_RSCP("rscp"); //!< Active RSCP (Received Signal Code Power in dBm) -const std::string CellularRadio::KEY_DRX("drx"); //!< Discontinuous reception cycle length (ms) -const std::string CellularRadio::KEY_MM("mm"); //!< Mobility Management State -const std::string CellularRadio::KEY_RR("rr"); //!< Radio Resource State -const std::string CellularRadio::KEY_NOM("nom"); //!< Network Operator Mode -const std::string CellularRadio::KEY_ABND("abnd"); //!< Active Band -const std::string CellularRadio::KEY_BLER("bler"); //!< Block Error Rate (percentage) -const std::string CellularRadio::KEY_SD("sd"); //!< Service Domain -const std::string CellularRadio::KEY_DEBUG("debug"); //!< Debug Information - -const std::string CellularRadio::KEY_MIP("mipProfile"); //!< Mobile IP Information -const std::string CellularRadio::KEY_MIP_ID("id"); //!< Mobile IP ID -const std::string CellularRadio::KEY_MIP_ENABLED("enabled"); //!< Mobile IP Enabled/Disabled -const std::string CellularRadio::KEY_MIP_NAI("nai"); //!< Network Access Identifier -const std::string CellularRadio::KEY_MIP_HOMEADDRESS("homeAddress"); //!< Home Address -const std::string CellularRadio::KEY_MIP_PRIMARYHA("primaryAddress"); //!< Primary Home Agent -const std::string CellularRadio::KEY_MIP_SECONDARYHA("secondaryAddress"); //!< Secondary Home Agent -const std::string CellularRadio::KEY_MIP_MNAAASPI("mnAaaSpi"); //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index -const std::string CellularRadio::KEY_MIP_MNHASPI("mnHaSpi"); //!< Mobile Node Home Agent Security Server Parameter Index -const std::string CellularRadio::KEY_MIP_REVTUN("revTun"); //!< Reverse Tunneling Enabled -const std::string CellularRadio::KEY_MIP_MNAAASS("mnAaaSs"); //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret -const std::string CellularRadio::KEY_MIP_MNHASS("mnHaSs"); //!< Mobile Node Home Agent Shared Secret - -const std::string CellularRadio::VALUE_TYPE_GSM("GSM"); -const std::string CellularRadio::VALUE_TYPE_LTE("LTE"); -const std::string CellularRadio::VALUE_TYPE_CDMA("CDMA"); - -const std::string CellularRadio::VALUE_SD_NO_SERVICE("NO SERVICE"); -const std::string CellularRadio::VALUE_SD_CS_ONLY("CS ONLY"); -const std::string CellularRadio::VALUE_SD_PS_ONLY("PS ONLY"); -const std::string CellularRadio::VALUE_SD_CSPS("CS+PS"); - -const std::string CellularRadio::VALUE_ABND_GSM_850("GSM 850"); -const std::string CellularRadio::VALUE_ABND_GSM_900("GSM 900"); -const std::string CellularRadio::VALUE_ABND_DCS_1800("DCS 1800"); -const std::string CellularRadio::VALUE_ABND_PCS_1900("PCS 1900"); - -const std::vector<std::string> CellularRadio::DEFAULT_BAIL_STRINGS = { CellularRadio::RSP_OK, CellularRadio::RSP_ERROR }; - -CellularRadio::CellularRadio(const std::string& sName, const std::string& sRadioPort) -: m_sName(sName) -, m_sRadioPort(sRadioPort) -, m_bEchoEnabled(false) -, m_bEnableEchoOnClose(false) -{ - m_apIo.reset(new MTS::IO::SerialConnection( - MTS::IO::SerialConnection::Builder(m_sRadioPort) - .baudRate(115200) - .useLockFile() - .build())); -} - - -CellularRadio::~CellularRadio() { - shutdown(); - m_apIo.reset(); -} - -bool CellularRadio::initialize(uint32_t iTimeoutMillis) { - if(!m_apIo->open(iTimeoutMillis)) { - printError("%s| Failed to open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); - return false; - } - - bool bEnabled; - CODE eCode = getEcho(bEnabled); - if(eCode == SUCCESS && bEnabled) { - printDebug("%s| Disabling 'echo'", m_sName.c_str()); - setEcho(false); - m_bEnableEchoOnClose = true; - } - - return true; -} - -bool CellularRadio::resetRadio(uint32_t iTimeoutMillis) { - - printInfo("%s| Rebooting radio", m_sName.c_str()); - if(sendBasicCommand("AT#REBOOT") == SUCCESS) { - if(iTimeoutMillis > 5000) { - MTS::Thread::sleep(5000); - iTimeoutMillis -= 5000; - } - return resetConnection(iTimeoutMillis); - } - - return false; -} - -bool CellularRadio::resetConnection(uint32_t iTimeoutMillis) { - //Close Current Connection - if(!m_apIo.isNull()) { - m_apIo->close(); - } - - m_apIo.reset(new MTS::IO::SerialConnection( - MTS::IO::SerialConnection::Builder(m_sRadioPort) - .baudRate(115200) - .useLockFile() - .build())); - - //Try to obtain the device port over the given period of time - MTS::Timer oTimer; - oTimer.start(); - uint64_t iCurrentTime = 0; - while(iCurrentTime < iTimeoutMillis) { - - if(!m_apIo->open(iTimeoutMillis - iCurrentTime)) { - printWarning("%s| Failed to re-open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); - } else { - printInfo("%s| Successfully re-opened radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); - printDebug("%s| Recovering 'echo' after connection reset", m_sName.c_str()); // see CellularRadio::initialize - setEcho(m_bEchoEnabled); - break; - } - - ::usleep(500000); //500 millis - iCurrentTime = oTimer.getMillis(); - } - oTimer.stop(); - return !m_apIo->isClosed(); -} - -void CellularRadio::shutdown() { - - if(!m_apIo.isNull()) { - if(m_bEnableEchoOnClose) { - printDebug("%s| Enabling 'echo'", m_sName.c_str()); - setEcho(true); - m_bEnableEchoOnClose = false; - } - m_apIo->close(); - } -} - -const std::string& CellularRadio::getName() const { - return m_sName; -} - - -CellularRadio::CODE CellularRadio::getModel(std::string& sModel) { - printTrace("%s| Get Model", m_sName.c_str()); - //Always returns SUCCESS because the model should be m_sName - sModel = m_sName; - std::string sCmd("ATI4"); - std::string sResult = CellularRadio::sendCommand(m_apIo, sCmd); - if (sResult.find("OK") == std::string::npos) { - printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str()); - return SUCCESS; - } else { - sModel = CellularRadio::extractModelFromResult(sResult); - if(sModel.size() == 0) { - printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str()); - return SUCCESS; - } - } - - printDebug("%s| Extracted [%s] from [%s] query", m_sName.c_str(), sModel.c_str(), sCmd.c_str()); - if(sModel != m_sName) { - printWarning("%s| Model identified [%s] does not match expected [%s]. Returning [%s]", - m_sName.c_str(), sModel.c_str(), m_sName.c_str(), sModel.c_str()); - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, CellularRadio *radioObject) { - CODE eCode = FAILURE; - - if(sModel.find("HE910-D") == 0) { - sCode = "H5"; - eCode = SUCCESS; - } else if (sModel.find("HE910-EUD") == 0) { - sCode = "H6"; - eCode = SUCCESS; - } else if (sModel.find("LE910-JN1") == 0) { - sCode = "LDC3"; - eCode = SUCCESS; - } else if (sModel.find("LE866A1-JS") == 0) { - sCode = "LSB3"; - eCode = SUCCESS; - } else if (sModel.find("LE910-NAG") == 0) { - sCode = "LAT1"; - eCode = SUCCESS; - } else if (sModel.find("LE910C4-NF") == 0) { - sCode = "L4N1"; - eCode = SUCCESS; - } else if (sModel.find("LE910-NA1") == 0) { - if (NULL == radioObject) { - sCode = VALUE_NOT_SUPPORTED; - eCode = ERROR; - } else { - std::string sValue; - eCode = radioObject->getActiveFirmware(sValue); - if (eCode == SUCCESS) { - sCode = "LNA3"; - } else { - sCode = "LAT3"; - } - } - eCode = SUCCESS; - } else if (sModel.find("LE910-SVG") == 0) { - sCode = "LVW2"; - eCode = SUCCESS; - } else if (sModel.find("LE910C1-NS") == 0) { - sCode = "LSP3"; - eCode = SUCCESS; - } else if (sModel.find("LE910C1-AP") == 0) { - sCode = "LAP3"; - eCode = SUCCESS; - } else if (sModel.find("ME910C1-NA") == 0) { - sCode = "MAT1"; - eCode = SUCCESS; - } else if (sModel.find("ME910C1-NV") == 0) { - sCode = "MVW1"; - eCode = SUCCESS; - } else if (sModel.find("ME910C1-WW") == 0) { - sCode = "MNG2"; - eCode = SUCCESS; - } else if (sModel.find("LE910-EUG") == 0) { - sCode = "LEU1"; - eCode = SUCCESS; - } else if (sModel.find("LE910C4-EU") == 0) { - sCode = "L4E1"; - eCode = SUCCESS; - } else if (sModel.find("LE910-EU1") == 0) { - sCode = "LEU3"; - eCode = SUCCESS; - } else if (sModel.find("GE910") == 0) { - sCode = "G3"; - eCode = SUCCESS; - } else if (sModel.find("CE910") == 0) { - sCode = "C2"; - eCode = SUCCESS; - } else if (sModel.find("DE910") == 0) { - sCode = "EV3"; - eCode = SUCCESS; - } else { - sCode = VALUE_NOT_SUPPORTED; - printError("RADIO| Could not identify MTS short code from model. [%s]", sModel.c_str()); - eCode = ERROR; - } - return eCode; -} - -CellularRadio::CODE CellularRadio::convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd) { - CODE eCode = FAILURE; - switch(eSd) { - case NO_SERVICE: sSd = VALUE_SD_NO_SERVICE; eCode = SUCCESS; break; - case CS_ONLY: sSd = VALUE_SD_CS_ONLY; eCode = SUCCESS; break; - case PS_ONLY: sSd = VALUE_SD_PS_ONLY; eCode = SUCCESS; break; - case CSPS: sSd = VALUE_SD_CSPS; eCode = SUCCESS; break; - default: sSd = VALUE_UNKNOWN; eCode = FAILURE; break; - } - return eCode; -} - -CellularRadio::CODE CellularRadio::convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand) { - CODE eCode = FAILURE; - switch(eBand) { - case GSM_850: sBand = VALUE_ABND_GSM_850; eCode = SUCCESS; break; - case GSM_900: sBand = VALUE_ABND_GSM_900; eCode = SUCCESS; break; - case DCS_1800: sBand = VALUE_ABND_DCS_1800; eCode = SUCCESS; break; - case PCS_1900: sBand = VALUE_ABND_PCS_1900; eCode = SUCCESS; break; - default: sBand = VALUE_UNKNOWN; eCode = FAILURE; break; - } - return eCode; -} - -CellularRadio::CODE CellularRadio::convertModelToType(const std::string& sModel, std::string& sType) { - CODE eCode = FAILURE; - sType = VALUE_NOT_SUPPORTED; - - if(sModel.find("HE910-D") == 0) { - sType = VALUE_TYPE_GSM; - eCode = SUCCESS; - } else if (sModel.find("HE910-EUD") == 0) { - sType = VALUE_TYPE_GSM; - eCode = SUCCESS; - } else if (sModel.find("LE910-JN1") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE866A1-JS") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910-NAG") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910C4-NF") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910-NA1") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910-SVG") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910-EUG") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910C4-EU") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910-EU1") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910C1-NS") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("LE910C1-AP") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("ME910C1-NA") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("ME910C1-NV") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("ME910C1-WW") == 0) { - sType = VALUE_TYPE_LTE; - eCode = SUCCESS; - } else if (sModel.find("GE910") == 0) { - sType = VALUE_TYPE_GSM; - eCode = SUCCESS; - } else if (sModel.find("CE910") == 0) { - sType = VALUE_TYPE_CDMA; - eCode = SUCCESS; - } else if (sModel.find("DE910") == 0) { - sType = VALUE_TYPE_CDMA; - eCode = SUCCESS; - } else { - sType = VALUE_TYPE_GSM; - eCode = ERROR; - printError("RADIO| Could not identify type from model. [%s]. Assuming [%s]", sModel.c_str(), sType.c_str()); - } - return eCode; -} - -CellularRadio::CODE CellularRadio::getFirmware(std::string& sFirmware) { - printTrace("%s| Get Firmware", m_sName.c_str()); - sFirmware = VALUE_NOT_SUPPORTED; - std::string sCmd("AT+CGMR"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t pos = sResult.find(RSP_OK); - if (pos == std::string::npos) { - printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - sFirmware = MTS::Text::trim(sResult.substr(0, pos)); - if(sFirmware.size() == 0) { - printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - m_sFirmware = sFirmware; - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getFirmwareBuild(std::string& sFirmwareBuild) { - sFirmwareBuild = VALUE_NOT_SUPPORTED; - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getHardware(std::string& sHardware) { - printTrace("%s| Get Hardware", m_sName.c_str()); - sHardware = VALUE_NOT_SUPPORTED; - - if(m_sFirmware.size() == 0) { - getFirmware(m_sFirmware); - } - - if(getHardwareVersionFromFirmware(m_sFirmware, sHardware)) { - return SUCCESS; - } - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getManufacturer(std::string& sManufacturer) { - printTrace("%s| Get Manufacturer", m_sName.c_str()); - sManufacturer = VALUE_NOT_SUPPORTED; - std::string sCmd("AT+GMI"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t pos = sResult.find(RSP_OK); - if (pos == std::string::npos) { - printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - sManufacturer = MTS::Text::trim(sResult.substr(0, pos)); - if(sManufacturer.size() == 0) { - printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getImei(std::string& sImei) { - printTrace("%s| Get IMEI", m_sName.c_str()); - sImei = VALUE_NOT_SUPPORTED; - std::string sCmd("AT+CGSN"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t pos = sResult.find(RSP_OK); - if (pos == std::string::npos) { - printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - sImei = MTS::Text::trim(sResult.substr(0, pos)); - if(sImei.size() == 0) { - printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getMeid(std::string& sMeid) { - printTrace("%s| Get MEID", m_sName.c_str()); - return getImei(sMeid); -} - -CellularRadio::CODE CellularRadio::getImsi(std::string& sImsi) { - printTrace("%s| Get IMSI", m_sName.c_str()); - sImsi = VALUE_NOT_SUPPORTED; - std::string sCmd("AT+CIMI"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t pos = sResult.find(RSP_OK); - if (pos == std::string::npos) { - printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - sImsi = MTS::Text::trim(sResult.substr(0, pos)); - if(sImsi.size() == 0) { - printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getSimStatus(std::string& sSimStatus) { - printTrace("%s| Get SIM Status", getName().c_str()); - sSimStatus = VALUE_UNKNOWN; - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getIccid(std::string& sIccid) { - printTrace("%s| Get ICCID", m_sName.c_str()); - sIccid = VALUE_NOT_SUPPORTED; - std::string sCmd("AT#CCID"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t end = sResult.find(RSP_OK); - if (end == std::string::npos) { - printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - size_t start = sResult.find("#CCID:"); - if(start != std::string::npos) { - start += sizeof("#CCID:"); - sIccid = MTS::Text::trim(sResult.substr(start, end-start)); - if(sIccid.size() == 0) { - printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - } - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getService(std::string& sService) { - printTrace("%s| Get Service", m_sName.c_str()); - sService = VALUE_NOT_SUPPORTED; - std::string sCmd("AT#PSNT?"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t end = sResult.find(RSP_OK); - if (end == std::string::npos) { - printWarning("%s| Unable to get Service from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - size_t start = sResult.find(","); - if(start != std::string::npos) { - start += 1; //comma - std::string sPsnt = MTS::Text::trim(sResult.substr(start, end-start)); - int32_t iService; - sscanf(sPsnt.c_str(), "%d", &iService); - - switch(iService) { - case 0: sService = "GPRS"; break; - case 1: sService = "EGPRS"; break; - case 2: sService = "WCDMA"; break; - case 3: sService = "HSDPA"; break; - case 4: sService = "LTE"; break; - default: sService = VALUE_UNKNOWN; break; - } - - printDebug("%s| Service ID: [%d][%s]", m_sName.c_str(), iService, sService.c_str()); - } - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getLac(std::string& sLac) { - Json::Value jData; - - printTrace("%s| Get LAC", m_sName.c_str()); - sLac = VALUE_NOT_SUPPORTED; - - if(getNetworkStatus(jData) == SUCCESS) { - if(jData.isMember(KEY_LAC)) { - sLac = jData[KEY_LAC].asString(); - return SUCCESS; - } - } - - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getMdn(std::string& sMdn) { - printTrace("%s| Get MDN", m_sName.c_str()); - sMdn = VALUE_NOT_SUPPORTED; - std::string sCmd("AT+CNUM"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t end = sResult.find(RSP_OK); - if (end == std::string::npos) { - printWarning("%s| Unable to get MDN from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - size_t start = sResult.find("CNUM:"); - if(start != std::string::npos) { - start += sizeof("CNUM:"); - std::vector<std::string> vParts = MTS::Text::split(sResult.substr(start, end - start), ','); - if(vParts.size() < 3) { - printWarning("%s| Unable to parse MDN from response [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - sMdn = MTS::Text::strip(vParts[1], '"'); - if(sMdn.size() == 0) { - printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str()); - } - } else { - sMdn = ""; - printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str()); - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getMsid(std::string& sMsid) { - printTrace("%s| Get MSID", m_sName.c_str()); - sMsid = ""; - - std::string sImsi; - if(getImsi(sImsi) == SUCCESS) { - if(sImsi.size() >= 10) { - sMsid = sImsi.substr(sImsi.size() - 10); - printTrace("IMSI: [%s] MEID [%s]", sImsi.c_str(), sMsid.c_str()); - return SUCCESS; - } - } - printWarning("%s| Unable to get MSID from radio", m_sName.c_str()); - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getType(std::string& sType) { - printTrace("%s| Get Type", m_sName.c_str()); - sType = VALUE_NOT_SUPPORTED; - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getCarrier(std::string& sCarrier) { - printTrace("%s| Get Carrier", m_sName.c_str()); - if(m_sCarrier == "") { - Json::Value jData; - if(getNetworkStatus(jData) == SUCCESS) { - if(jData.isMember(KEY_MCC) && jData.isMember(KEY_MNC)) { - std::string sMcc = jData[KEY_MCC].asString(); - std::string sMnc = jData[KEY_MNC].asString(); - Json::Value jLookup = MccMncTable::getInstance()->lookup(sMcc, sMnc); - printTrace("%s| MCC-MNC Lookup: [%s][%s][%s]", m_sName.c_str(), - sMcc.c_str(), sMnc.c_str(), jLookup.toStyledString().c_str()); - if(jLookup.isMember(KEY_CARRIER)) { - m_sCarrier = jLookup[KEY_CARRIER].asString(); - } else { - printWarning("%s| MCC-MNC Lookup did not contain carrier", m_sName.c_str()); - return FAILURE; - } - } else { - printWarning("%s| Network Status did no contain MCC or MNC", m_sName.c_str()); - return FAILURE; - } - } else { - return FAILURE; - } - } - - sCarrier = m_sCarrier; - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getTower(std::string& sTower) { - Json::Value jData; - - printTrace("%s| Get Tower", m_sName.c_str()); - sTower = VALUE_NOT_SUPPORTED; - - if(getNetworkStatus(jData) == SUCCESS) { - if(jData.isMember(KEY_CID)) { - sTower = jData[KEY_CID].asString(); - return SUCCESS; - } - } - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) { - Json::Value jData; - - printTrace("%s| Get Time", m_sName.c_str()); - sDate = ""; - sTime = ""; - sTimeZone = ""; - - std::string sCmd("AT+CCLK?"); - std::string sResult = CellularRadio::sendCommand(sCmd); - size_t end = sResult.find(RSP_OK); - if (end == std::string::npos) { - printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - size_t start = sResult.find("CCLK: "); - if(start != std::string::npos) { - start += sizeof("CCLK: "); - std::string sValue = MTS::Text::trim(sResult.substr(start, end - start)); - sValue = MTS::Text::strip(sValue, '"'); - - std::vector<std::string> vParts = MTS::Text::split(sValue, ','); - if(vParts.size() != 2) { - printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - - - std::vector<std::string> vDateParts = MTS::Text::split(vParts[0], '/'); - if(vDateParts.size() != 3) { - printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - - //The Date format is YY/MM/DD -> Change to MM/DD/YY - sDate = vDateParts[1] + "/" + vDateParts[2] + "/" + vDateParts[0]; - - vParts = MTS::Text::split(vParts[1], '-'); - if(vParts.size() != 2) { - printWarning("%s| Unable to parse Time from response [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - sTime = vParts[0]; - - int32_t iZoneUnits; //the difference, expressed in quarters of an hour, between the local time and GMT - if(!MTS::Text::parse(iZoneUnits, MTS::Text::strip(vParts[1], '+'))) { - printWarning("%s| Unable to parse Time Zone from response [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - - int32_t iZone = iZoneUnits/4; //Divide by 4 to get hours difference - int32_t iZonePartial = (iZoneUnits % 4) * 15; //Remainder in minutes - std::string sPlusSign = "+"; - if(iZonePartial < 0) { - //Remove negative sign from partial and clear plus sign component - iZonePartial *= -1; - sPlusSign = ""; - } - std::stringstream ss; - ss << sPlusSign << iZone; - if(iZonePartial != 0) { - ss << ":" << iZonePartial; - } - - sTimeZone = ss.str(); - return SUCCESS; - - } else { - printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - } - - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getRoaming(bool& bRoaming) { - Json::Value jData; - - printTrace("%s| Get Roaming", m_sName.c_str()); - bRoaming = false; - - REGISTRATION eReg; - if(getRegistration(eReg) == SUCCESS) { - bRoaming = (eReg == ROAMING); - return SUCCESS; - } - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getNetwork(std::string& sNetwork) { - Json::Value jData; - - printTrace("%s| Get Network", m_sName.c_str()); - sNetwork = VALUE_NOT_SUPPORTED; - - if(getNetworkStatus(jData) == SUCCESS) { - if(jData.isMember(KEY_NETWORK)) { - sNetwork = jData[KEY_NETWORK].asString(); - return SUCCESS; - } - } - return FAILURE; -} - -CellularRadio::CODE CellularRadio::getSignalStrength(int32_t& rssi) { - printTrace("%s| Get Signal Strength", m_sName.c_str()); - std::string sCmd("AT+CSQ"); - std::string sResult = sendCommand(sCmd); - if (sResult.find("+CSQ: ") == std::string::npos) { - printDebug("%s| Signal Strength command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - - size_t start = sResult.find(':'); - size_t stop = sResult.find(',', start); - if(start == std::string::npos || stop == std::string::npos) { - printDebug("%s| Signal Strength command returned malformed response: [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - std::string signal = sResult.substr(start + 2, stop - start - 2); - - sscanf(signal.c_str(), "%d", &rssi); - printDebug("%s| Signal Strength: [%d]", m_sName.c_str(), rssi); - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getModemLocation(std::string& sLocation) { - printTrace("%s|CellularRadio getModemLocation - not supported", m_sName.c_str()); - return FAILURE; -} - -CellularRadio::CODE CellularRadio::convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& iDbm) { - - //Telit Conversion - if(iRssi < 0 || iRssi == 99) { - return FAILURE; - } - - if(iRssi == 0) { - iDbm = -113; - } else if(iRssi == 1) { - iDbm = -111; - } else if(iRssi <= 30) { - //28 steps between 2 and 30 - //54 dbm between 53 and 109 - float stepSize = 54.0 / 28.0; - iDbm = -109 + (int)(stepSize * (iRssi-2)); - } else { - iDbm = -51; - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::convertdBmToSignalStrength(const int32_t& iDBm, int32_t& iRssi) { - //Telit Conversion - if(iDBm <= -113) { - iRssi = 0; - } else if(iDBm <= -111) { - iRssi = 1; - } else if(iDBm <= -53) { - //54 dbm between -109 and -53 - //28 steps between 2 and 30 - float stepSize = 28.0/54.0; - iRssi = ((iDBm + 109)*stepSize) + 2; - } else { - iRssi = 31; - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::getEcho(bool& bEnabled) { - printTrace("%s| Echo Test", m_sName.c_str()); - std::string sResult = sendCommand("AT"); - if(sResult.size() == 0) { - return NO_RESPONSE; - } - - if(sResult.find("AT") != std::string::npos) { - bEnabled = true; - } else { - bEnabled = false; - } - m_bEchoEnabled = bEnabled; - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::setEcho(bool bEnabled) { - CODE eCode = FAILURE; - if(bEnabled) { - eCode = sendBasicCommand("ATE1"); - m_bEchoEnabled = (eCode == SUCCESS ) ? true : m_bEchoEnabled; - } else { - eCode = sendBasicCommand("ATE0"); - m_bEchoEnabled = (eCode == SUCCESS ) ? false : m_bEchoEnabled; - } - - return eCode; -} - -CellularRadio::CODE CellularRadio::getStaticInformation(Json::Value& jData) { - printTrace("%s| Get Static Information", m_sName.c_str()); - - printTrace("%s| Static Information:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); - - return FAILURE; -} - -/* AT#RFSTS - NETWORK STATUS - - (GSM network) - #RFSTS:<PLMN>,<ARFCN>,<RSSI>,<LAC>,<RAC>,<TXPWR>,<MM>,<RR>,<NOM>,<CID>,<IMSI>,<NetNameAsc>,<SD>,<ABND> - Where: - <PLMN> - Country code and operator code(MCC, MNC) - <ARFCN> - GSM Assigned Radio Channel - <RSSI> - Received Signal Strength Indication - <LAC> - Localization Area Code - <RAC> - Routing Area Code - <TXPWR> - Tx Power - <MM> - Mobility Management state - <RR> - Radio Resource state - <NOM> - Network Operator Mode - <CID> - Cell ID - <IMSI> - International Mobile Subscriber Identity - <NetNameAsc> - Operator name - <SD> - Service Domain - 0 - No Service - 1 - CS only - 2 - PS only - 3 - CS+PS - <ABND> - Active Band - 1 - GSM 850 - 2 - GSM 900 - 3 - DCS 1800 - 4 - PCS 1900 - - - (WCDMA network) - #RFSTS: - <PLMN>,<UARFCN>,<PSC>,<Ec/Io>,<RSCP>, RSSI>,<LAC>,<RAC>,<TXPWR>,<DRX>,<MM>,<RRC>,<NOM>,<BLER>,<CID>,<IMSI>, - <NetNameAsc>,<SD>,<nAST>[,<nUARFCN><nPSC>,<nEc/Io>] - Where: - <PLMN> - Country code and operator code(MCC, MNC) - <UARFCN> - UMTS Assigned Radio Channel - <PSC> - Active PSC(Primary Synchronization Code) - <Ec/Io> - Active Ec/Io(chip energy per total wideband power in dBm) - <RSCP> - Active RSCP (Received Signal Code Power in dBm) - <RSSI> - Received Signal Strength Indication - <LAC> - Localization Area Code - <RAC> - Routing Area Code - <TXPWR> - Tx Power - <DRX> - Discontinuous reception cycle Length (cycle length in ms) - <MM> - Mobility Management state - <RR> - Radio Resource state - <NOM> - Network Operator Mode - <BLER> - Block Error Rate (e.g., 005 means 0.5 %) - <CID> - Cell ID - <IMSI> - International Mobile Station ID - <NetNameAsc> - Operator name - <SD> - Service Domain (see above) - <nAST> - Number of Active Set (Maximum 6) - <nUARFCN> UARFCN of n th active set - <nPSC> PSC of n th active set - <nEc/Io > Ec/Io of n th active Set - - (LTE Network) - #RFSTS: - <PLMN> - - <EARFCN> - - <RSRP> - - <RSSI> - - <RSRQ> - - <TAC> - - [<TXPWR>] - - <DRX> - - <MM> - - <RRC> - - <CID> - - <IMSI> - - [<NetNameAsc>] - - <SD> - - <ABND> - -*/ -CellularRadio::CODE CellularRadio::getNetworkStatus(Json::Value& jData) { - int32_t iValue; - std::string sValue; - const uint32_t GSM_NETWORK_FORMAT = 14; - const uint32_t WCDMA_NETWORK_FORMAT = 19; - const uint32_t LTE_NETWORK_FORMAT = 16; - - printTrace("%s| Get Network Status", m_sName.c_str()); - - //Always get common network stats because this should never fail - //This way the basic stats are always returned even if AT#RFSTS fails below - getCommonNetworkStats(jData); - - std::string sCmd; - std::string sResult; - // LE910 radios have a bug where issuing AT#RFSTS with a locked SIM - // will cause the radio to stop responding until a radio power cycle - // Telit Support Portal Case #5069697 - // LE910C1-NS is an LE910, so we stop the scan after the 0. - if (m_sName.find("LE910") != std::string::npos) { - sCmd = "AT+CPIN?"; - sResult = sendCommand(sCmd); - if (sResult.find("+CPIN:") == std::string::npos) { - printDebug("%s| AT+CPIN? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); - printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); - return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function - } - if (sResult.find("SIM PIN") != std::string::npos) { - printError("%s| The SIM is locked and must first be unlocked", m_sName.c_str()); - printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); - return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function - } - } - - sCmd = "AT#RFSTS"; - sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 200); - if (sResult.find("#RFSTS:") == std::string::npos) { - //On LTE radios without signal, this case will run because AT#RFSTS just returns "OK" - printDebug("%s| Network Status command returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); - printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); - return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function - } - - size_t start = sResult.find(":") + 1; //Position right after "#RFSTS:" - std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start)), ","); - - if (vParts.size() < 3) { - printDebug("%s| Network Status command reponse is an unknown format: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); - printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); - return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function - } else { - //Country Code and Operator Code - std::vector<std::string> vPLMN = MTS::Text::split(vParts[0], ' '); - if(vPLMN.size() == 2) { - jData[KEY_MCC] = MTS::Text::strip(vPLMN[0], '"'); - jData[KEY_MNC] = MTS::Text::strip(vPLMN[1], '"'); - } - - jData[KEY_CHANNEL] = vParts[1]; - } - - if (vParts.size() == GSM_NETWORK_FORMAT ) { - //Parse as GSM Network Format - jData[KEY_RSSIDBM] = vParts[2]; - jData[KEY_LAC] = vParts[3]; - jData[KEY_RAC] = vParts[4]; - jData[KEY_TXPWR] = vParts[5]; - jData[KEY_MM] = vParts[6]; - jData[KEY_RR] = vParts[7]; - jData[KEY_NOM] = vParts[8]; - jData[KEY_CID] = vParts[9]; - jData[KEY_IMSI] = MTS::Text::strip(vParts[10], '"'); - jData[KEY_NETWORK] = MTS::Text::strip(vParts[11], '"'); - if(MTS::Text::parse(iValue, vParts[12]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { - jData[KEY_SD] = sValue; - } - if(MTS::Text::parse(iValue, vParts[13]) && convertActiveBandToString((ACTIVEBAND)iValue, sValue) == SUCCESS) { - jData[KEY_ABND] = sValue; - } - // IN003567 ME910C1 radios have some odd behavior with regards to WCDMA. The ordering of the fields from #RFSTS are - // the same as LTE up to the 16th field (for ME901C1-WW anyway). Drop into LTE parsing for ME910C1-WW. - } else if((vParts.size() >= WCDMA_NETWORK_FORMAT) && (m_sName.find("ME910C1-WW") == std::string::npos)) { - Json::Value jDebug; - - //Parse as WCDMA Network Format - - jDebug[KEY_PSC] = vParts[2]; - jDebug[KEY_ECIO] = vParts[3]; - jDebug[KEY_RSCP] = vParts[4]; - - jData[KEY_RSSIDBM] = vParts[5]; - jData[KEY_LAC] = vParts[6]; - jData[KEY_RAC] = vParts[7]; - - jDebug[KEY_TXPWR] = vParts[8]; - jDebug[KEY_DRX] = vParts[9]; - jDebug[KEY_MM] = vParts[10]; - jDebug[KEY_RR] = vParts[11]; - jDebug[KEY_NOM] = vParts[12]; - - if(vParts[13].size() != 0) { - jDebug[KEY_BLER] = vParts[13]; - } else { - jDebug[KEY_BLER] = "000"; - } - - jData[KEY_CID] = vParts[14]; - jData[KEY_IMSI] = MTS::Text::strip(vParts[15], '"'); - jData[KEY_NETWORK] = MTS::Text::strip(vParts[16], '"'); - - // Get the radio band given the channel (UARFCN) - RadioBandMap radioBandMap(vParts[1], CellularRadio::VALUE_TYPE_CDMA); - jData[KEY_ABND] = radioBandMap.getRadioBandName(); - - if(MTS::Text::parse(iValue, vParts[17]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { - jDebug[KEY_SD] = sValue; - } - //Ignoring Active Set Values - // <nAST> - Number of Active Set (Maximum 6) - // <nUARFCN> - UARFCN of n th active set - // <nPSC> - PSC of n th active set - // <nEc/Io > - Ec/Io of n th active Set - - jData[KEY_DEBUG] = jDebug; - } else if(vParts.size() >= LTE_NETWORK_FORMAT) { - Json::Value jDebug; - - //Parse as LTE Network Format - - // - // MD: It is noticed that LTE Network format may vary depending on the firmware version: - // - // <PLMN>,<EARFCN>,<RSRP>,<RSSI>,<RSRQ>,<TAC>,[<TXPWR>],<DRX>,<MM>,<RRC>,<CID>,<IMSI>,[<NetNameAsc>],<SD>,<ABND>,<SINR> - // Ex 1: #RFSTS: "310 260",2300,-98,-63,-14,AA06,,128,19,0,0501D02,"310260754792598","T-Mobile",3,4,197 - // - // <PLMN>,<EARFCN>,<RSRP>,<RSSI>,<RSRQ>,<TAC>,<RAC>,[<TXPWR>],<DRX>,<MM>,<RRC>,<CID>,<IMSI>,[<NetNameAsc>],<SD>,<ABND> - // Ex 2: #RFSTS:"310 410",5780,-105,-73,-14,4603,255,,128,19,0,0000098,"310410536498694","AT&T",3,17 - // #RFSTS:"311 480",1150,-96,-66,-9.0,bf35,FF,0,0,19,1,"2ED1B0E","311480148817753","Verizon",2,2,720000,10800 - // #RFSTS:"310 410",2175,-120,-89,-17.5,4612,FF,0,0,19,1,"4E5E916","310410807276607","AT&T",3,4 - // - // Additional <RAC> parameter in the second example shifts the rest of the parameters. Here we are trying to figure out - // which format is currently produced based on <NetNameAsc> field position which always has double quotation marks. - // - if (vParts[13].find("\"") != std::string::npos) { - // parse the RAC and then remove it from the vector - jData[KEY_RAC] = vParts[6]; - vParts.erase(vParts.begin() + 6); - } - - jDebug["rsrp"] = vParts[2]; - jDebug[KEY_RSSIDBM] = vParts[3]; - jDebug["rsrq"] = vParts[4]; - - jData["tac"] = vParts[5]; - jDebug[KEY_TXPWR] = vParts[6]; - jData[KEY_DRX] = vParts[7]; - jDebug[KEY_MM] = vParts[8]; - jDebug["rrc"] = vParts[9]; - jData[KEY_CID] = MTS::Text::strip(vParts[10], '"'); - jData[KEY_IMSI] = MTS::Text::strip(vParts[11], '"'); - jData[KEY_NETWORK] = MTS::Text::strip(vParts[12], '"'); - - // Get the radio band given the channel (EARFCN) - RadioBandMap radioBandMap(vParts[1], CellularRadio::VALUE_TYPE_LTE); - jData[KEY_ABND] = radioBandMap.getRadioBandName(); - - jData[KEY_LAC] = queryLteLac(); - - if(MTS::Text::parse(iValue, vParts[13]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { - jDebug[KEY_SD] = sValue; - } - - jData[KEY_DEBUG] = jDebug; - } - - printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); - return SUCCESS; -} - -// Get the LAC for the LTE radio that's not in the #RFSTS response -std::string CellularRadio::queryLteLac() { - std::string CGREGstring; - std::string originalCGREG; - std::string result; - - CGREGstring = queryCGREGstring(); - if (CGREGstring == RSP_ERROR) { - originalCGREG = "0"; - } else { - originalCGREG = CGREGstring.at(CGREGstring.find(",") - 1); //Position right before first comma ("+CGREG: 0,1") - } - - // Temporarily set CGREG=2 to get more info - setCGREG("2"); - - CGREGstring = queryCGREGstring(); - if (CGREGstring == RSP_ERROR) { - result = CellularRadio::VALUE_UNKNOWN; - } else { - size_t start = CGREGstring.find(":") + 1; //Position right after "#RFSTS:" - std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(CGREGstring.substr(start)), ","); - if(vParts.size() < 3) { - result = CellularRadio::VALUE_UNAVAILABLE; - } else { - result = MTS::Text::strip(vParts[2], '"'); - } - } - - setCGREG(originalCGREG); - - return result; -} - -void CellularRadio::setCGREG(std::string value) { - std::string sCmd("AT+CGREG=" + value); - std::string cmdResult(sendCommand(sCmd)); - if (cmdResult.find("OK") == std::string::npos) { - printDebug("%s| AT#CGREG=%s returned unexpected response: [%s][%s]", m_sName.c_str(), value.c_str(), sCmd.c_str(), cmdResult.c_str()); - } -} - -std::string CellularRadio::queryCGREGstring() { - std::string sCmd("AT+CGREG?"); - std::string cmdResult(sendCommand(sCmd)); - if (cmdResult.find("+CGREG:") == std::string::npos) { - printDebug("%s| AT#CGREG? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), cmdResult.c_str()); - return RSP_ERROR; - } - return cmdResult; -} - -void CellularRadio::getCommonNetworkStats(Json::Value& jData) { - - bool bRoaming = false; - if(getRoaming(bRoaming) == SUCCESS) { - jData[KEY_ROAMING] = bRoaming; - } - - int32_t iRssi; - if(getSignalStrength(iRssi) == SUCCESS) { - jData[KEY_RSSI] = iRssi; - int32_t dBm; - if(!jData.isMember(KEY_RSSIDBM) && convertSignalStrengthTodBm(iRssi, dBm) == SUCCESS) { - //Add RSSI in dBm format - jData[KEY_RSSIDBM] = MTS::Text::format(dBm); - } - } - - std::string sService; - if(getService(sService) == SUCCESS) { - jData[KEY_SERVICE] = sService; - } - std::string sDate, sTime, sTimeZone; - if(getTime(sDate, sTime, sTimeZone) == SUCCESS) { - jData[KEY_DATETIME] = sDate + " " + sTime + " GMT" + sTimeZone; - } - - std::string sNetworkReg; - CellularRadio::REGISTRATION eReg; - if (getRegistration(eReg) == SUCCESS) { - if (convertRegistrationToString(eReg, sNetworkReg) == SUCCESS) { - jData[CellularRadio::KEY_NETWORK_REG] = sNetworkReg; - } - } -} - -void CellularRadio::initMipProfile(Json::Value& jData) { - jData[KEY_MIP_ID] = 0; - jData[KEY_MIP_ENABLED] = false; - jData[KEY_MIP_NAI] = VALUE_UNKNOWN; - jData[KEY_MIP_HOMEADDRESS] = VALUE_UNKNOWN; - jData[KEY_MIP_PRIMARYHA] = VALUE_UNKNOWN; - jData[KEY_MIP_SECONDARYHA] = VALUE_UNKNOWN; - jData[KEY_MIP_MNAAASPI] = VALUE_UNKNOWN; - jData[KEY_MIP_MNHASPI] = VALUE_UNKNOWN; - jData[KEY_MIP_MNAAASS] = false; - jData[KEY_MIP_MNHASS] = false; -} - -CellularRadio::CODE CellularRadio::getRegistration(REGISTRATION& eRegistration) { - std::string sCmd; - std::string sResp; - - // LE910C1-NS is an LE910, so we stop the scan after the 0. - if (m_sName.find("LE910") != std::string::npos) { - // use AT+CGREG instead for LE910 models - sCmd = "AT+CGREG?"; - sResp = "+CGREG: "; - } - else { - sCmd = "AT+CREG?"; - sResp = "+CREG: "; - } - - std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 5000); - if (sResult.find(sResp) == std::string::npos) { - if(sResult.size() == 0) { - printDebug("%s| Registration command returned no response: [%s]", m_sName.c_str()); - return NO_RESPONSE; - } - printDebug("%s| Registration command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str()); - return FAILURE; - } - - size_t start = sResult.find(','); - size_t stop = sResult.find(' ', start); - std::string sRegStat = sResult.substr(start + 1, stop - start - 1); - int32_t value; - sscanf(sRegStat.c_str(), "%d", &value); - eRegistration = (REGISTRATION)value; - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) { - - CODE eCode = FAILURE; - switch (eRegistration) { - case NOT_REGISTERED: sRegistration = VALUE_NOT_REGISTERED; eCode = SUCCESS; break; - case REGISTERED: sRegistration = VALUE_REGISTERED; eCode = SUCCESS; break; - case SEARCHING: sRegistration = VALUE_SEARCHING; eCode = SUCCESS; break; - case DENIED: sRegistration = VALUE_DENIED; eCode = SUCCESS; break; - case UNKNOWN: sRegistration = VALUE_UNKNOWN; eCode = SUCCESS; break; - case ROAMING: sRegistration = VALUE_ROAMING; eCode = SUCCESS; break; - } - return eCode; -} - -CellularRadio::CODE CellularRadio::validateMsl(const Json::Value& jArgs) { - printTrace("%s| Validate MSL", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMdn(const Json::Value& jArgs) { - printTrace("%s| Set MDN", m_sName.c_str()); - - if(!jArgs["mdn"].isString()) { - return INVALID_ARGS; - } - - std::string sCmd("AT#SNUM=1,\""); - sCmd += jArgs["mdn"].asString() + "\""; - - std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 1000); - size_t end = sResult.find(RSP_OK); - if (end == std::string::npos) { - printWarning("%s| Unable to set MDN for radio using command [%s]", m_sName.c_str(), sCmd.c_str()); - return FAILURE; - } - - return SUCCESS; -} - -CellularRadio::CODE CellularRadio::setMsid(const Json::Value& jArgs) { - printTrace("%s| Set MSID", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::getMipProfile(Json::Value& jMipProfile) { - printTrace("%s| Get MIP Active Profile", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipActiveProfile(const Json::Value& jArgs) { - printTrace("%s| Set MIP Active Profile", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipNai(const Json::Value& jArgs) { - printTrace("%s| Set MIP NAI", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipHomeIp(const Json::Value& jArgs) { - printTrace("%s| Set MIP Home IP", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipPrimaryHa(const Json::Value& jArgs) { - printTrace("%s| Set MIP Primary HA", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipSecondaryHa(const Json::Value& jArgs) { - printTrace("%s| Set MIP Secondary HA", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipMnAaaSpi(const Json::Value& jArgs) { - printTrace("%s| Set MIP MN-AAA SPI", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipMnHaSpi(const Json::Value& jArgs) { - printTrace("%s| Set MIP MN-HA SPI", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipRevTun(const Json::Value& jArgs) { - printTrace("%s| Set MIP Rev Tun", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipMnAaaSs(const Json::Value& jArgs) { - printTrace("%s| Set MIP MN-AAA SS", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setMipMnHaSs(const Json::Value& jArgs) { - printTrace("%s| Set MIP MN-HA SS", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) { - printTrace("%s| Update Device Configuration", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) { - printTrace("%s| Update Preferred Roaming List", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) { - printTrace("%s| Update Firmware Update Management Object", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) { - printTrace("%s| HFA Reset", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) { - printTrace("%s| Activation", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::setActiveFirmware(const Json::Value& jArgs) { - printTrace("%s| Set Active Firmware Image Number: not applicable", m_sName.c_str()); - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::getActiveFirmware(std::string& sFwId) { - printTrace("%s| Get Active Firmware Image Number: not applicable", m_sName.c_str()); - sFwId = VALUE_NOT_SUPPORTED; - - return NOT_APPLICABLE; -} - -CellularRadio::CODE CellularRadio::sendBasicCommand(const std::string& sCmd, int32_t iTimeoutMillis, const char& ESC) { - std::string response = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, iTimeoutMillis, ESC); - if (response.size() == 0) { - return NO_RESPONSE; - } else if (response.find(RSP_OK) != std::string::npos) { - return SUCCESS; - } else if (response.find(RSP_ERROR) != std::string::npos) { - return ERROR; - } else { - return FAILURE; - } -} - -std::string CellularRadio::sendCommand(const std::string& sCmd, const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) { - return sendCommand(m_apIo, sCmd, vBail, timeoutMillis, ESC); -} - -std::string CellularRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd, - const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) { - IsNeedMoreData isNeedMoreData = [&vBail](const std::string& iterationData, const std::string& allData)->bool { - for(size_t i = 0; i < vBail.size(); i++) { - const std::string& sBail = vBail[i]; - if(sBail.size() > 0) { - if(allData.find(sBail) != std::string::npos) { - //Return when bail string is found - printTrace("RADIO| Found bail string [%s]", sBail.c_str()); - return false; - } - } - } - return true; - }; - - return sendCommand(apIo, sCmd, isNeedMoreData, timeoutMillis, ESC); -} - -std::string CellularRadio::sendCommand(const std::string& sCmd, MTS::IO::CellularRadio::IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) { - return sendCommand(m_apIo, sCmd, isNeedMoreData, timeoutMillis, ESC); -} - -std::string CellularRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd, - IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) { - if(MTS::Logger::getPrintLevel() >= MTS::Logger::PrintLevel::TRACE_LEVEL) { - printTrace("RADIO| Sending command [%s]", sCmd.c_str()); - } - if(apIo.isNull()) { - printError("RADIO| IO is not set in sendCommand"); - return ""; - } - - int32_t iResult; - if(ESC == 0x00) { - iResult = apIo->write(sCmd.data(), sCmd.size()); - } else { - std::string sNewCmd(sCmd); - sNewCmd.push_back(ESC); - iResult = apIo->write(sNewCmd.data(), sNewCmd.size()); - } - - if(iResult == -1) { - printError("RADIO| Failed to send command to radio"); - return ""; - } - - bool done = false; - const uint32_t capacity = 1024; - char buffer[capacity]; - std::string sResult; - Timer timer; - timer.start(); - do { - int32_t iterationTimeout = 100; - int bytesRead = apIo->read((char*)buffer, capacity, iterationTimeout); - if(bytesRead == -1) { - printError("RADIO| Failed to read from radio"); - break; - } - - std::string sIteration((char*)buffer, bytesRead); - sResult += sIteration; - - if(isNeedMoreData && !isNeedMoreData(sIteration, sResult)) { - printTrace("RADIO| No more data needed"); - return sResult; - } - if(timeoutMillis >= 0) { - done = (timer.getMillis() >= (uint64_t)timeoutMillis); - } else { - //Do not stop looping until bail string is found - } - } while(!done); - - //Timed out - return sResult; -} - -CellularRadio::CODE CellularRadio::test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds) { - printTrace("RADIO| Basic Test"); - uint32_t count = 0; - std::string sCmd("AT"); - do { - std::string sResult = sendCommand(apIo, sCmd); - if (sResult.find(RSP_OK) == std::string::npos) { - printTrace("RADIO| Waiting for basic radio communication [%s] ...", sResult.c_str()); - } else { - break; - } - count++; - } while (count < timeoutSeconds); - - if(count == timeoutSeconds) { - printWarning("RADIO| Basic radio communication FAILED"); - return NO_RESPONSE; - } - return SUCCESS; -} - -std::string CellularRadio::extractModelFromResult(const std::string& sResult) { - std::string sModel(CellularRadio::VALUE_NOT_SUPPORTED); - - if(sResult.find("HE910-D") != std::string::npos) { - sModel = "HE910-D"; - } else if(sResult.find("HE910-EUD") != std::string::npos) { - sModel = "HE910-EUD"; - } else if(sResult.find("LE910-JN1") != std::string::npos) { - sModel = "LE910-JN1"; - } else if(sResult.find("LE866A1-JS") != std::string::npos) { - sModel = "LE866A1-JS"; - } else if(sResult.find("LE910-NAG") != std::string::npos) { - sModel = "LE910-NAG"; - } else if(sResult.find("LE910C4-NF") != std::string::npos) { - sModel = "LE910C4-NF"; - } else if(sResult.find("LE910-NA1") != std::string::npos) { - sModel = "LE910-NA1"; - } else if(sResult.find("ME910C1-NA") != std::string::npos) { - sModel = "ME910C1-NA"; - } else if(sResult.find("ME910C1-NV") != std::string::npos) { - sModel = "ME910C1-NV"; - } else if(sResult.find("ME910C1-WW") != std::string::npos) { - sModel = "ME910C1-WW"; - } else if(sResult.find("LE910-SVG") != std::string::npos) { - sModel = "LE910-SVG"; - } else if(sResult.find("LE910-EUG") != std::string::npos) { - sModel = "LE910-EUG"; - } else if(sResult.find("LE910C4-EU") != std::string::npos) { - sModel = "LE910C4-EU"; - } else if(sResult.find("LE910-EU1") != std::string::npos) { - sModel = "LE910-EU1"; - } else if(sResult.find("LE910C1-NS") != std::string::npos) { - sModel = "LE910C1-NS"; - } else if(sResult.find("LE910C1-AP") != std::string::npos) { - sModel = "LE910C1-AP"; - } else if(sResult.find("GE910") != std::string::npos) { - sModel = "GE910"; - } else if(sResult.find("DE910-DUAL") != std::string::npos) { - sModel = "DE910-DUAL"; - } else if(sResult.find("CE910") != std::string::npos) { - sModel = "CE910"; - } - return sModel; -} - -std::string CellularRadio::getCodeAsString(CODE eCode) { - switch(eCode) { - case SUCCESS: - return "SUCCESS"; - case ERROR: - return "ERROR"; - case FAILURE: - return "FAILURE"; - case NO_RESPONSE: - return "NO RESPONSE"; - default: - return "UNKNOWN"; - } -} - -bool CellularRadio::splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType) { - - std::vector<std::string> vParts = MTS::Text::split(sLine, ":", 2); - - if(vParts.size() == 2 && vParts[0] == sKey) { - if(eType == Json::ValueType::stringValue) { - jParent[sJsonKey] = MTS::Text::trim(vParts[1]); - } else if (eType == Json::ValueType::intValue || eType == Json::ValueType::uintValue) { - //TODO: - printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); - return false; - } else if(eType == Json::ValueType::realValue) { - //TODO: - printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); - return false; - } else if(eType == Json::ValueType::booleanValue) { - //TODO: - printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); - return false; - } else { - printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); - return false; - } - } else { - printWarning("%s| Unable to parse %s from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); - return false; - } - - return true; -} - -bool CellularRadio::getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier) { - // Telit Radios - // H.ab.zyx => 3 Main Components - // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family - // "a" = Hardware version - // "b" = Software Major Version - // "z" = is the product type, i.e. DUAL or SC - // "y" = is the carrier variant - // "x" = is the firmware version - // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, "2" for Verizon, and "3" for U.S. Cellular. - - const uint32_t CARRIER_INDEX = 1; //y in [zyx] - - bool bResult = false; - std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.'); - - if(vParts.size() == 3) { - //CDMA firmware version notation - if(vParts[0] == "15" || vParts[0] == "18") { - //DE910 or CE910 -> Good good - std::string sID = vParts[2]; - if(sID.size() == 3) { - char cId = sID[CARRIER_INDEX]; - - //Good good - if(cId == '0') { - sCarrier = VALUE_CARRIER_SPRINT; - bResult = true; - } else - if(cId == '1') { - sCarrier = VALUE_CARRIER_AERIS; - bResult = true; - } else - if(cId == '2') { - sCarrier = VALUE_CARRIER_VERIZON; - bResult = true; - } else - if(cId == '3') { - sCarrier = VALUE_CARRIER_USCELLULAR; - bResult = true; - } - } - } - } - - return bResult; -} - -bool CellularRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware) { - // Telit Radios - // H.ab.zyx => 3 Main Components - // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family - // "a" = Hardware version - // "b" = Software Major Version - // "z" = is the product type, i.e. DUAL or SC - // "y" = is the carrier variant - // "x" = is the firmware version - // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, and "2" for Verizon. - - const uint32_t HARDWARE_INDEX = 0; //a in [ab] - - bool bResult = false; - std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.'); - - if(vParts.size() == 3) { - //GSM Hardware Version - if(!(vParts[0] == "15" || vParts[0] == "18")) { - //Not DE910 or CE910 -> Good good - std::string sVersion = vParts[1]; - if(sVersion.size() == 2) { - sHardware = "1."; - sHardware += sVersion[HARDWARE_INDEX]; - bResult = true; - } - } - } - - return bResult; - -} - -const char *CellularRadio::RadioBandMap::getLTEBand(const int32_t channel) -{ - for (unsigned int ii = 0; ii < NUM_LTE_BANDS; ii++) - { - if (EULTRAband[ii].low <= channel && EULTRAband[ii].high >= channel) - { - return EULTRAband[ii].name; - } - } - return VALUE_UNKNOWN.c_str(); -} - -const char *CellularRadio::RadioBandMap::getCDMABand(const int channel) -{ - for (unsigned int ii = 0; ii < NUM_WCDMA_BANDS; ii++) - { - if (WCDMAband[ii].low <= channel && WCDMAband[ii].high >= channel) - { - return WCDMAband[ii].name; - } - } - return VALUE_UNKNOWN.c_str(); -} - -const char *CellularRadio::RadioBandMap::getGSMBand(const int channel) -{ - for (unsigned int ii = 0; ii < NUM_GSM_BANDS; ii++) - { - if (GSMband[ii].low <= channel && GSMband[ii].high >= channel) - { - return GSMband[ii].name; - } - } - return VALUE_UNKNOWN.c_str(); -} - -const char *CellularRadio::RadioBandMap::getRadioBandName() -{ - const char *band = CellularRadio::VALUE_UNKNOWN.c_str(); - - if (m_sRadioType == CellularRadio::VALUE_TYPE_LTE) - { - band = getLTEBand(m_iChannel); - } - else if (m_sRadioType == CellularRadio::VALUE_TYPE_CDMA) - { - band = getCDMABand(m_iChannel); - } - else if (m_sRadioType == CellularRadio::VALUE_TYPE_GSM) - { - band = getGSMBand(m_iChannel); - } - - return band; -} - -const char *CellularRadio::RadioBandMap::getRadioBandName(const std::string &channel, const std::string &radioType) -{ - const char *band = CellularRadio::VALUE_UNKNOWN.c_str(); - int32_t chan = strtol(channel.c_str(), NULL, 10); - if (radioType == CellularRadio::VALUE_TYPE_LTE) - { - band = getLTEBand(chan); - } - else if (radioType == CellularRadio::VALUE_TYPE_CDMA) - { - band = getCDMABand(chan); - } - else if (radioType == CellularRadio::VALUE_TYPE_GSM) - { - band = getGSMBand(chan); - } - - return band; -} +#include "mts/MTS_IO_CellularRadio.h" diff --git a/src/MTS_IO_CellularRadioFactory.cpp b/src/MTS_IO_CellularRadioFactory.cpp index ef87f0e..17cbd05 100644 --- a/src/MTS_IO_CellularRadioFactory.cpp +++ b/src/MTS_IO_CellularRadioFactory.cpp @@ -87,14 +87,14 @@ std::string CellularRadioFactory::identifyRadio(const std::string& sPort) { apIo.reset(new SerialConnection(SerialConnection::Builder(sPort).baudRate(115200).useLockFile().build())); while(!apIo->open(30000)) { printError("CellularRadioFactory| Failed to open radio port [%s]", sPort.c_str()); - return CellularRadio::VALUE_UNKNOWN; + return TelitRadio::VALUE_UNKNOWN; } //Attempt basic radio communication - if(CellularRadio::test(apIo) != CellularRadio::SUCCESS) { + if(TelitRadio::test(apIo) != TelitRadio::SUCCESS) { printError("CellularRadioFactory| Failed to communicate with radio on port [%s]", sPort.c_str()); apIo->close(); - return CellularRadio::VALUE_UNKNOWN; + return TelitRadio::VALUE_UNKNOWN; } //Get model @@ -102,7 +102,7 @@ std::string CellularRadioFactory::identifyRadio(const std::string& sPort) { std::string sCmd("ATI4"); std::string sResult; do { - sResult = CellularRadio::sendCommand(apIo, sCmd, CellularRadio::DEFAULT_BAIL_STRINGS, 1000, CellularRadio::CR); + sResult = TelitRadio::sendCommand(apIo, sCmd, TelitRadio::DEFAULT_BAIL_STRINGS, 1000, TelitRadio::CR); if (sResult.find("OK") == std::string::npos) { printDebug("RADIO| Attempting to get radio model [%s] ...", sResult.c_str()); } else { @@ -114,10 +114,10 @@ std::string CellularRadioFactory::identifyRadio(const std::string& sPort) { if(count == 30) { printDebug("RADIO| Unable to get radio model"); apIo->close(); - return CellularRadio::VALUE_UNKNOWN; + return TelitRadio::VALUE_UNKNOWN; } - std::string sModel = CellularRadio::extractModelFromResult(sResult); + std::string sModel = TelitRadio::extractModelFromResult(sResult); printDebug("RADIO| Extracted [%s] from ATI4 query", sModel.c_str()); apIo->close(); return sModel; diff --git a/src/MTS_IO_EG95Radio.cpp b/src/MTS_IO_EG95Radio.cpp new file mode 100644 index 0000000..2fca48f --- /dev/null +++ b/src/MTS_IO_EG95Radio.cpp @@ -0,0 +1 @@ +#include "mts/MTS_IO_EG95Radio.h" diff --git a/src/MTS_IO_GE910Radio.cpp b/src/MTS_IO_GE910Radio.cpp index f31f4fc..c99d16c 100644 --- a/src/MTS_IO_GE910Radio.cpp +++ b/src/MTS_IO_GE910Radio.cpp @@ -34,7 +34,7 @@ using namespace MTS::IO; const std::string GE910Radio::MODEL_NAME("GE910"); GE910Radio::GE910Radio(const std::string& sPort) -: CellularRadio(MODEL_NAME, sPort) +: TelitRadio(MODEL_NAME, sPort) { } diff --git a/src/MTS_IO_HE910Radio.cpp b/src/MTS_IO_HE910Radio.cpp index 0178c9d..cc0e873 100644 --- a/src/MTS_IO_HE910Radio.cpp +++ b/src/MTS_IO_HE910Radio.cpp @@ -32,7 +32,7 @@ using namespace MTS::IO; HE910Radio::HE910Radio(const std::string& sHE910Model, const std::string& sPort) -: CellularRadio(sHE910Model, sPort) +: TelitRadio(sHE910Model, sPort) { } diff --git a/src/MTS_IO_LE866Radio.cpp b/src/MTS_IO_LE866Radio.cpp index 2e92f67..85b8dc3 100644 --- a/src/MTS_IO_LE866Radio.cpp +++ b/src/MTS_IO_LE866Radio.cpp @@ -31,7 +31,7 @@ using namespace MTS::IO; LE866Radio::LE866Radio(const std::string& sLE866Model, const std::string& sPort) -: CellularRadio(sLE866Model, sPort) +: TelitRadio(sLE866Model, sPort) { } diff --git a/src/MTS_IO_LE910Radio.cpp b/src/MTS_IO_LE910Radio.cpp index f383b68..b02c2ce 100644 --- a/src/MTS_IO_LE910Radio.cpp +++ b/src/MTS_IO_LE910Radio.cpp @@ -33,7 +33,7 @@ using namespace MTS::IO; LE910Radio::LE910Radio(const std::string& sLE910Model, const std::string& sPort) -: CellularRadio(sLE910Model, sPort) +: TelitRadio(sLE910Model, sPort) { } diff --git a/src/MTS_IO_ME910Radio.cpp b/src/MTS_IO_ME910Radio.cpp index 590a883..3ed9e50 100644 --- a/src/MTS_IO_ME910Radio.cpp +++ b/src/MTS_IO_ME910Radio.cpp @@ -25,7 +25,7 @@ using namespace MTS::IO; ME910Radio::ME910Radio(const std::string& sME910Model, const std::string& sPort) -: CellularRadio(sME910Model, sPort) +: TelitRadio(sME910Model, sPort) { } diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp new file mode 100644 index 0000000..365bbca --- /dev/null +++ b/src/MTS_IO_QuectelRadio.cpp @@ -0,0 +1 @@ +#include "mts/MTS_IO_QuectelRadio.h" diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp new file mode 100644 index 0000000..de863c3 --- /dev/null +++ b/src/MTS_IO_TelitRadio.cpp @@ -0,0 +1,1838 @@ +/* + * Copyright (C) 2019 by Multi-Tech Systems + * + * This file is part of libmts-io. + * + * libmts-io is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libmts-io is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libmts-io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <mts/MTS_IO_TelitRadio.h> + +#include <mts/MTS_IO_MccMncTable.h> +#include <mts/MTS_Thread.h> +#include <mts/MTS_Timer.h> +#include <mts/MTS_Logger.h> +#include <mts/MTS_Text.h> +#include <mts/MTS_System.h> +#include <map> +#include <cstring> +#include <sstream> +#include <sys/file.h> +#include <errno.h> +#include <unistd.h> + + +using namespace MTS::IO; + +const char TelitRadio::ETX = 0x03; //Ends socket connection +const char TelitRadio::DLE = 0x10; //Escapes ETX and DLE within Payload +const char TelitRadio::CR = 0x0D; +const char TelitRadio::NL = 0x0A; +const char TelitRadio::CTRL_Z = 0x1A; + +const std::string TelitRadio::RSP_ERROR("ERROR"); +const std::string TelitRadio::RSP_OK("OK"); + + +const std::string TelitRadio::DEFAULT_RADIO_PORT("/dev/modem_at1"); +const std::string TelitRadio::DEFAULT_RADIO_DIR("/var/run/radio/"); +const std::string TelitRadio::VALUE_UNKNOWN("Unknown"); +const std::string TelitRadio::VALUE_UNAVAILABLE("Unavailable"); +const std::string TelitRadio::VALUE_NOT_SUPPORTED("Not Supported"); + +const std::string TelitRadio::VALUE_NOT_REGISTERED("NOT REGISTERED"); +const std::string TelitRadio::VALUE_REGISTERED("REGISTERED"); +const std::string TelitRadio::VALUE_SEARCHING("SEARCHING"); +const std::string TelitRadio::VALUE_DENIED("DENIED"); +const std::string TelitRadio::VALUE_ROAMING("ROAMING"); + +//Static Data +const std::string TelitRadio::KEY_TYPE("type"); //!< GSM or CDMA +const std::string TelitRadio::KEY_CODE("code"); //!< Product Code : H5, H6, C2, EV3, G3 +const std::string TelitRadio::KEY_MODEL("model"); //!< Model : HE910, LE910, CE910, DE910, GE910 +const std::string TelitRadio::KEY_MANUFACTURER("manufacturer"); //!< Manufacturer: Telit +const std::string TelitRadio::KEY_HARDWARE("hardware"); //!< Radio Hardware Version +const std::string TelitRadio::KEY_FIRMWARE("firmware"); //!< Radio Firmware Version +const std::string TelitRadio::KEY_FIRMWARE_BUILD("firmwarebuild"); //!< Radio Firmware Build + +const std::string TelitRadio::KEY_CARRIER("carrier"); //!< Cellular Service Provider (Home Network) +const std::string TelitRadio::VALUE_CARRIER_VERIZON("Verizon"); +const std::string TelitRadio::VALUE_CARRIER_AERIS("Aeris"); +const std::string TelitRadio::VALUE_CARRIER_SPRINT("Sprint"); +const std::string TelitRadio::VALUE_CARRIER_USCELLULAR("U.S. Cellular"); +const std::string TelitRadio::VALUE_CARRIER_ATT("AT&T"); +const std::string TelitRadio::VALUE_CARRIER_TMOBILE("T-Mobile"); + +const std::string TelitRadio::KEY_IMEI("imei"); //!< International Mobile Station Equipment Identity +const std::string TelitRadio::KEY_MEID("meid"); //!< Mobile Equipment Identifier +const std::string TelitRadio::KEY_IMSI("imsi"); //!< International Mobile Subscriber Identity +const std::string TelitRadio::KEY_MSID("msid"); //!< Mobil Station ID / Mobile Identification Number (MSID/MIN) (CDMA-Only) +const std::string TelitRadio::KEY_MDN("mdn"); //!< Mobile Directory Number : Actual phone number dialed to reach radio +const std::string TelitRadio::KEY_ICCID("iccid"); //!< Integrated Circuit Card Identifier +const std::string TelitRadio::KEY_MSL("msl"); //!< Master Subsidy Lock + +//Dynamic Data +const std::string TelitRadio::KEY_ROAMING("roaming"); //!< Indicates whether or not using Home Network +const std::string TelitRadio::KEY_DATETIME("datetime"); //!< Date and Time from tower +const std::string TelitRadio::KEY_SERVICE("service"); //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO] +const std::string TelitRadio::KEY_NETWORK("network"); //!< Cellular Service Provider +const std::string TelitRadio::KEY_NETWORK_REG("netreg"); //!< Network Registration +const std::string TelitRadio::KEY_CID("cid"); //!< Cellular ID (Tower) in HEX +const std::string TelitRadio::KEY_LAC("lac"); //!< Location Area Code in HEX +const std::string TelitRadio::KEY_RAC("rac"); //!< Routing Area Code in HEX +const std::string TelitRadio::KEY_RSSI("rssi"); //!< Signal Strength +const std::string TelitRadio::KEY_RSSIDBM("rssidBm"); //!< Signal Strength in dBm +const std::string TelitRadio::KEY_MCC("mcc"); //!< Country Code +const std::string TelitRadio::KEY_MNC("mnc"); //!< Operator Code +const std::string TelitRadio::KEY_CHANNEL("channel"); //!< ARFCN or UARFCN Assigned Radio Channel +const std::string TelitRadio::KEY_TXPWR("txpwr"); //!< Transmit Power +const std::string TelitRadio::KEY_PSC("psc"); //!< Active Primary Synchronization Code (PSC) +const std::string TelitRadio::KEY_ECIO("ecio"); //!< Active Ec/Io (chip energy per total wideband power in dBm) +const std::string TelitRadio::KEY_RSCP("rscp"); //!< Active RSCP (Received Signal Code Power in dBm) +const std::string TelitRadio::KEY_DRX("drx"); //!< Discontinuous reception cycle length (ms) +const std::string TelitRadio::KEY_MM("mm"); //!< Mobility Management State +const std::string TelitRadio::KEY_RR("rr"); //!< Radio Resource State +const std::string TelitRadio::KEY_NOM("nom"); //!< Network Operator Mode +const std::string TelitRadio::KEY_ABND("abnd"); //!< Active Band +const std::string TelitRadio::KEY_BLER("bler"); //!< Block Error Rate (percentage) +const std::string TelitRadio::KEY_SD("sd"); //!< Service Domain +const std::string TelitRadio::KEY_DEBUG("debug"); //!< Debug Information + +const std::string TelitRadio::KEY_MIP("mipProfile"); //!< Mobile IP Information +const std::string TelitRadio::KEY_MIP_ID("id"); //!< Mobile IP ID +const std::string TelitRadio::KEY_MIP_ENABLED("enabled"); //!< Mobile IP Enabled/Disabled +const std::string TelitRadio::KEY_MIP_NAI("nai"); //!< Network Access Identifier +const std::string TelitRadio::KEY_MIP_HOMEADDRESS("homeAddress"); //!< Home Address +const std::string TelitRadio::KEY_MIP_PRIMARYHA("primaryAddress"); //!< Primary Home Agent +const std::string TelitRadio::KEY_MIP_SECONDARYHA("secondaryAddress"); //!< Secondary Home Agent +const std::string TelitRadio::KEY_MIP_MNAAASPI("mnAaaSpi"); //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index +const std::string TelitRadio::KEY_MIP_MNHASPI("mnHaSpi"); //!< Mobile Node Home Agent Security Server Parameter Index +const std::string TelitRadio::KEY_MIP_REVTUN("revTun"); //!< Reverse Tunneling Enabled +const std::string TelitRadio::KEY_MIP_MNAAASS("mnAaaSs"); //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret +const std::string TelitRadio::KEY_MIP_MNHASS("mnHaSs"); //!< Mobile Node Home Agent Shared Secret + +const std::string TelitRadio::VALUE_TYPE_GSM("GSM"); +const std::string TelitRadio::VALUE_TYPE_LTE("LTE"); +const std::string TelitRadio::VALUE_TYPE_CDMA("CDMA"); + +const std::string TelitRadio::VALUE_SD_NO_SERVICE("NO SERVICE"); +const std::string TelitRadio::VALUE_SD_CS_ONLY("CS ONLY"); +const std::string TelitRadio::VALUE_SD_PS_ONLY("PS ONLY"); +const std::string TelitRadio::VALUE_SD_CSPS("CS+PS"); + +const std::string TelitRadio::VALUE_ABND_GSM_850("GSM 850"); +const std::string TelitRadio::VALUE_ABND_GSM_900("GSM 900"); +const std::string TelitRadio::VALUE_ABND_DCS_1800("DCS 1800"); +const std::string TelitRadio::VALUE_ABND_PCS_1900("PCS 1900"); + +const std::vector<std::string> TelitRadio::DEFAULT_BAIL_STRINGS = { TelitRadio::RSP_OK, TelitRadio::RSP_ERROR }; + +TelitRadio::TelitRadio(const std::string& sName, const std::string& sRadioPort) +: m_sName(sName) +, m_sRadioPort(sRadioPort) +, m_bEchoEnabled(false) +, m_bEnableEchoOnClose(false) +{ + m_apIo.reset(new MTS::IO::SerialConnection( + MTS::IO::SerialConnection::Builder(m_sRadioPort) + .baudRate(115200) + .useLockFile() + .build())); +} + + +TelitRadio::~TelitRadio() { + shutdown(); + m_apIo.reset(); +} + +bool TelitRadio::initialize(uint32_t iTimeoutMillis) { + if(!m_apIo->open(iTimeoutMillis)) { + printError("%s| Failed to open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); + return false; + } + + bool bEnabled; + CODE eCode = getEcho(bEnabled); + if(eCode == SUCCESS && bEnabled) { + printDebug("%s| Disabling 'echo'", m_sName.c_str()); + setEcho(false); + m_bEnableEchoOnClose = true; + } + + return true; +} + +bool TelitRadio::resetRadio(uint32_t iTimeoutMillis) { + + printInfo("%s| Rebooting radio", m_sName.c_str()); + if(sendBasicCommand("AT#REBOOT") == SUCCESS) { + if(iTimeoutMillis > 5000) { + MTS::Thread::sleep(5000); + iTimeoutMillis -= 5000; + } + return resetConnection(iTimeoutMillis); + } + + return false; +} + +bool TelitRadio::resetConnection(uint32_t iTimeoutMillis) { + //Close Current Connection + if(!m_apIo.isNull()) { + m_apIo->close(); + } + + m_apIo.reset(new MTS::IO::SerialConnection( + MTS::IO::SerialConnection::Builder(m_sRadioPort) + .baudRate(115200) + .useLockFile() + .build())); + + //Try to obtain the device port over the given period of time + MTS::Timer oTimer; + oTimer.start(); + uint64_t iCurrentTime = 0; + while(iCurrentTime < iTimeoutMillis) { + + if(!m_apIo->open(iTimeoutMillis - iCurrentTime)) { + printWarning("%s| Failed to re-open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); + } else { + printInfo("%s| Successfully re-opened radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); + printDebug("%s| Recovering 'echo' after connection reset", m_sName.c_str()); // see TelitRadio::initialize + setEcho(m_bEchoEnabled); + break; + } + + ::usleep(500000); //500 millis + iCurrentTime = oTimer.getMillis(); + } + oTimer.stop(); + return !m_apIo->isClosed(); +} + +void TelitRadio::shutdown() { + + if(!m_apIo.isNull()) { + if(m_bEnableEchoOnClose) { + printDebug("%s| Enabling 'echo'", m_sName.c_str()); + setEcho(true); + m_bEnableEchoOnClose = false; + } + m_apIo->close(); + } +} + +const std::string& TelitRadio::getName() const { + return m_sName; +} + + +TelitRadio::CODE TelitRadio::getModel(std::string& sModel) { + printTrace("%s| Get Model", m_sName.c_str()); + //Always returns SUCCESS because the model should be m_sName + sModel = m_sName; + std::string sCmd("ATI4"); + std::string sResult = TelitRadio::sendCommand(m_apIo, sCmd); + if (sResult.find("OK") == std::string::npos) { + printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str()); + return SUCCESS; + } else { + sModel = TelitRadio::extractModelFromResult(sResult); + if(sModel.size() == 0) { + printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str()); + return SUCCESS; + } + } + + printDebug("%s| Extracted [%s] from [%s] query", m_sName.c_str(), sModel.c_str(), sCmd.c_str()); + if(sModel != m_sName) { + printWarning("%s| Model identified [%s] does not match expected [%s]. Returning [%s]", + m_sName.c_str(), sModel.c_str(), m_sName.c_str(), sModel.c_str()); + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, TelitRadio *radioObject) { + CODE eCode = FAILURE; + + if(sModel.find("HE910-D") == 0) { + sCode = "H5"; + eCode = SUCCESS; + } else if (sModel.find("HE910-EUD") == 0) { + sCode = "H6"; + eCode = SUCCESS; + } else if (sModel.find("LE910-JN1") == 0) { + sCode = "LDC3"; + eCode = SUCCESS; + } else if (sModel.find("LE866A1-JS") == 0) { + sCode = "LSB3"; + eCode = SUCCESS; + } else if (sModel.find("LE910-NAG") == 0) { + sCode = "LAT1"; + eCode = SUCCESS; + } else if (sModel.find("LE910C4-NF") == 0) { + sCode = "L4N1"; + eCode = SUCCESS; + } else if (sModel.find("LE910-NA1") == 0) { + if (NULL == radioObject) { + sCode = VALUE_NOT_SUPPORTED; + eCode = ERROR; + } else { + std::string sValue; + eCode = radioObject->getActiveFirmware(sValue); + if (eCode == SUCCESS) { + sCode = "LNA3"; + } else { + sCode = "LAT3"; + } + } + eCode = SUCCESS; + } else if (sModel.find("LE910-SVG") == 0) { + sCode = "LVW2"; + eCode = SUCCESS; + } else if (sModel.find("LE910C1-NS") == 0) { + sCode = "LSP3"; + eCode = SUCCESS; + } else if (sModel.find("LE910C1-AP") == 0) { + sCode = "LAP3"; + eCode = SUCCESS; + } else if (sModel.find("ME910C1-NA") == 0) { + sCode = "MAT1"; + eCode = SUCCESS; + } else if (sModel.find("ME910C1-NV") == 0) { + sCode = "MVW1"; + eCode = SUCCESS; + } else if (sModel.find("ME910C1-WW") == 0) { + sCode = "MNG2"; + eCode = SUCCESS; + } else if (sModel.find("LE910-EUG") == 0) { + sCode = "LEU1"; + eCode = SUCCESS; + } else if (sModel.find("LE910C4-EU") == 0) { + sCode = "L4E1"; + eCode = SUCCESS; + } else if (sModel.find("LE910-EU1") == 0) { + sCode = "LEU3"; + eCode = SUCCESS; + } else if (sModel.find("GE910") == 0) { + sCode = "G3"; + eCode = SUCCESS; + } else if (sModel.find("CE910") == 0) { + sCode = "C2"; + eCode = SUCCESS; + } else if (sModel.find("DE910") == 0) { + sCode = "EV3"; + eCode = SUCCESS; + } else { + sCode = VALUE_NOT_SUPPORTED; + printError("RADIO| Could not identify MTS short code from model. [%s]", sModel.c_str()); + eCode = ERROR; + } + return eCode; +} + +TelitRadio::CODE TelitRadio::convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd) { + CODE eCode = FAILURE; + switch(eSd) { + case NO_SERVICE: sSd = VALUE_SD_NO_SERVICE; eCode = SUCCESS; break; + case CS_ONLY: sSd = VALUE_SD_CS_ONLY; eCode = SUCCESS; break; + case PS_ONLY: sSd = VALUE_SD_PS_ONLY; eCode = SUCCESS; break; + case CSPS: sSd = VALUE_SD_CSPS; eCode = SUCCESS; break; + default: sSd = VALUE_UNKNOWN; eCode = FAILURE; break; + } + return eCode; +} + +TelitRadio::CODE TelitRadio::convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand) { + CODE eCode = FAILURE; + switch(eBand) { + case GSM_850: sBand = VALUE_ABND_GSM_850; eCode = SUCCESS; break; + case GSM_900: sBand = VALUE_ABND_GSM_900; eCode = SUCCESS; break; + case DCS_1800: sBand = VALUE_ABND_DCS_1800; eCode = SUCCESS; break; + case PCS_1900: sBand = VALUE_ABND_PCS_1900; eCode = SUCCESS; break; + default: sBand = VALUE_UNKNOWN; eCode = FAILURE; break; + } + return eCode; +} + +TelitRadio::CODE TelitRadio::convertModelToType(const std::string& sModel, std::string& sType) { + CODE eCode = FAILURE; + sType = VALUE_NOT_SUPPORTED; + + if(sModel.find("HE910-D") == 0) { + sType = VALUE_TYPE_GSM; + eCode = SUCCESS; + } else if (sModel.find("HE910-EUD") == 0) { + sType = VALUE_TYPE_GSM; + eCode = SUCCESS; + } else if (sModel.find("LE910-JN1") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE866A1-JS") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910-NAG") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910C4-NF") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910-NA1") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910-SVG") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910-EUG") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910C4-EU") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910-EU1") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910C1-NS") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910C1-AP") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("ME910C1-NA") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("ME910C1-NV") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("ME910C1-WW") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("GE910") == 0) { + sType = VALUE_TYPE_GSM; + eCode = SUCCESS; + } else if (sModel.find("CE910") == 0) { + sType = VALUE_TYPE_CDMA; + eCode = SUCCESS; + } else if (sModel.find("DE910") == 0) { + sType = VALUE_TYPE_CDMA; + eCode = SUCCESS; + } else { + sType = VALUE_TYPE_GSM; + eCode = ERROR; + printError("RADIO| Could not identify type from model. [%s]. Assuming [%s]", sModel.c_str(), sType.c_str()); + } + return eCode; +} + +TelitRadio::CODE TelitRadio::getFirmware(std::string& sFirmware) { + printTrace("%s| Get Firmware", m_sName.c_str()); + sFirmware = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CGMR"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sFirmware = MTS::Text::trim(sResult.substr(0, pos)); + if(sFirmware.size() == 0) { + printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + m_sFirmware = sFirmware; + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getFirmwareBuild(std::string& sFirmwareBuild) { + sFirmwareBuild = VALUE_NOT_SUPPORTED; + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getHardware(std::string& sHardware) { + printTrace("%s| Get Hardware", m_sName.c_str()); + sHardware = VALUE_NOT_SUPPORTED; + + if(m_sFirmware.size() == 0) { + getFirmware(m_sFirmware); + } + + if(getHardwareVersionFromFirmware(m_sFirmware, sHardware)) { + return SUCCESS; + } + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getManufacturer(std::string& sManufacturer) { + printTrace("%s| Get Manufacturer", m_sName.c_str()); + sManufacturer = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+GMI"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sManufacturer = MTS::Text::trim(sResult.substr(0, pos)); + if(sManufacturer.size() == 0) { + printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getImei(std::string& sImei) { + printTrace("%s| Get IMEI", m_sName.c_str()); + sImei = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CGSN"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sImei = MTS::Text::trim(sResult.substr(0, pos)); + if(sImei.size() == 0) { + printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getMeid(std::string& sMeid) { + printTrace("%s| Get MEID", m_sName.c_str()); + return getImei(sMeid); +} + +TelitRadio::CODE TelitRadio::getImsi(std::string& sImsi) { + printTrace("%s| Get IMSI", m_sName.c_str()); + sImsi = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CIMI"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sImsi = MTS::Text::trim(sResult.substr(0, pos)); + if(sImsi.size() == 0) { + printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getSimStatus(std::string& sSimStatus) { + printTrace("%s| Get SIM Status", getName().c_str()); + sSimStatus = VALUE_UNKNOWN; + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getIccid(std::string& sIccid) { + printTrace("%s| Get ICCID", m_sName.c_str()); + sIccid = VALUE_NOT_SUPPORTED; + std::string sCmd("AT#CCID"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("#CCID:"); + if(start != std::string::npos) { + start += sizeof("#CCID:"); + sIccid = MTS::Text::trim(sResult.substr(start, end-start)); + if(sIccid.size() == 0) { + printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + } + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getService(std::string& sService) { + printTrace("%s| Get Service", m_sName.c_str()); + sService = VALUE_NOT_SUPPORTED; + std::string sCmd("AT#PSNT?"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get Service from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find(","); + if(start != std::string::npos) { + start += 1; //comma + std::string sPsnt = MTS::Text::trim(sResult.substr(start, end-start)); + int32_t iService; + sscanf(sPsnt.c_str(), "%d", &iService); + + switch(iService) { + case 0: sService = "GPRS"; break; + case 1: sService = "EGPRS"; break; + case 2: sService = "WCDMA"; break; + case 3: sService = "HSDPA"; break; + case 4: sService = "LTE"; break; + default: sService = VALUE_UNKNOWN; break; + } + + printDebug("%s| Service ID: [%d][%s]", m_sName.c_str(), iService, sService.c_str()); + } + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getLac(std::string& sLac) { + Json::Value jData; + + printTrace("%s| Get LAC", m_sName.c_str()); + sLac = VALUE_NOT_SUPPORTED; + + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_LAC)) { + sLac = jData[KEY_LAC].asString(); + return SUCCESS; + } + } + + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getMdn(std::string& sMdn) { + printTrace("%s| Get MDN", m_sName.c_str()); + sMdn = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CNUM"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get MDN from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("CNUM:"); + if(start != std::string::npos) { + start += sizeof("CNUM:"); + std::vector<std::string> vParts = MTS::Text::split(sResult.substr(start, end - start), ','); + if(vParts.size() < 3) { + printWarning("%s| Unable to parse MDN from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + sMdn = MTS::Text::strip(vParts[1], '"'); + if(sMdn.size() == 0) { + printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str()); + } + } else { + sMdn = ""; + printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str()); + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getMsid(std::string& sMsid) { + printTrace("%s| Get MSID", m_sName.c_str()); + sMsid = ""; + + std::string sImsi; + if(getImsi(sImsi) == SUCCESS) { + if(sImsi.size() >= 10) { + sMsid = sImsi.substr(sImsi.size() - 10); + printTrace("IMSI: [%s] MEID [%s]", sImsi.c_str(), sMsid.c_str()); + return SUCCESS; + } + } + printWarning("%s| Unable to get MSID from radio", m_sName.c_str()); + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getType(std::string& sType) { + printTrace("%s| Get Type", m_sName.c_str()); + sType = VALUE_NOT_SUPPORTED; + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getCarrier(std::string& sCarrier) { + printTrace("%s| Get Carrier", m_sName.c_str()); + if(m_sCarrier == "") { + Json::Value jData; + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_MCC) && jData.isMember(KEY_MNC)) { + std::string sMcc = jData[KEY_MCC].asString(); + std::string sMnc = jData[KEY_MNC].asString(); + Json::Value jLookup = MccMncTable::getInstance()->lookup(sMcc, sMnc); + printTrace("%s| MCC-MNC Lookup: [%s][%s][%s]", m_sName.c_str(), + sMcc.c_str(), sMnc.c_str(), jLookup.toStyledString().c_str()); + if(jLookup.isMember(KEY_CARRIER)) { + m_sCarrier = jLookup[KEY_CARRIER].asString(); + } else { + printWarning("%s| MCC-MNC Lookup did not contain carrier", m_sName.c_str()); + return FAILURE; + } + } else { + printWarning("%s| Network Status did no contain MCC or MNC", m_sName.c_str()); + return FAILURE; + } + } else { + return FAILURE; + } + } + + sCarrier = m_sCarrier; + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getTower(std::string& sTower) { + Json::Value jData; + + printTrace("%s| Get Tower", m_sName.c_str()); + sTower = VALUE_NOT_SUPPORTED; + + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_CID)) { + sTower = jData[KEY_CID].asString(); + return SUCCESS; + } + } + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) { + Json::Value jData; + + printTrace("%s| Get Time", m_sName.c_str()); + sDate = ""; + sTime = ""; + sTimeZone = ""; + + std::string sCmd("AT+CCLK?"); + std::string sResult = TelitRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("CCLK: "); + if(start != std::string::npos) { + start += sizeof("CCLK: "); + std::string sValue = MTS::Text::trim(sResult.substr(start, end - start)); + sValue = MTS::Text::strip(sValue, '"'); + + std::vector<std::string> vParts = MTS::Text::split(sValue, ','); + if(vParts.size() != 2) { + printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + + std::vector<std::string> vDateParts = MTS::Text::split(vParts[0], '/'); + if(vDateParts.size() != 3) { + printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + //The Date format is YY/MM/DD -> Change to MM/DD/YY + sDate = vDateParts[1] + "/" + vDateParts[2] + "/" + vDateParts[0]; + + vParts = MTS::Text::split(vParts[1], '-'); + if(vParts.size() != 2) { + printWarning("%s| Unable to parse Time from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + sTime = vParts[0]; + + int32_t iZoneUnits; //the difference, expressed in quarters of an hour, between the local time and GMT + if(!MTS::Text::parse(iZoneUnits, MTS::Text::strip(vParts[1], '+'))) { + printWarning("%s| Unable to parse Time Zone from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + int32_t iZone = iZoneUnits/4; //Divide by 4 to get hours difference + int32_t iZonePartial = (iZoneUnits % 4) * 15; //Remainder in minutes + std::string sPlusSign = "+"; + if(iZonePartial < 0) { + //Remove negative sign from partial and clear plus sign component + iZonePartial *= -1; + sPlusSign = ""; + } + std::stringstream ss; + ss << sPlusSign << iZone; + if(iZonePartial != 0) { + ss << ":" << iZonePartial; + } + + sTimeZone = ss.str(); + return SUCCESS; + + } else { + printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + } + + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getRoaming(bool& bRoaming) { + Json::Value jData; + + printTrace("%s| Get Roaming", m_sName.c_str()); + bRoaming = false; + + REGISTRATION eReg; + if(getRegistration(eReg) == SUCCESS) { + bRoaming = (eReg == ROAMING); + return SUCCESS; + } + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getNetwork(std::string& sNetwork) { + Json::Value jData; + + printTrace("%s| Get Network", m_sName.c_str()); + sNetwork = VALUE_NOT_SUPPORTED; + + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_NETWORK)) { + sNetwork = jData[KEY_NETWORK].asString(); + return SUCCESS; + } + } + return FAILURE; +} + +TelitRadio::CODE TelitRadio::getSignalStrength(int32_t& rssi) { + printTrace("%s| Get Signal Strength", m_sName.c_str()); + std::string sCmd("AT+CSQ"); + std::string sResult = sendCommand(sCmd); + if (sResult.find("+CSQ: ") == std::string::npos) { + printDebug("%s| Signal Strength command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + size_t start = sResult.find(':'); + size_t stop = sResult.find(',', start); + if(start == std::string::npos || stop == std::string::npos) { + printDebug("%s| Signal Strength command returned malformed response: [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + std::string signal = sResult.substr(start + 2, stop - start - 2); + + sscanf(signal.c_str(), "%d", &rssi); + printDebug("%s| Signal Strength: [%d]", m_sName.c_str(), rssi); + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getModemLocation(std::string& sLocation) { + printTrace("%s|TelitRadio getModemLocation - not supported", m_sName.c_str()); + return FAILURE; +} + +TelitRadio::CODE TelitRadio::convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& iDbm) { + + //Telit Conversion + if(iRssi < 0 || iRssi == 99) { + return FAILURE; + } + + if(iRssi == 0) { + iDbm = -113; + } else if(iRssi == 1) { + iDbm = -111; + } else if(iRssi <= 30) { + //28 steps between 2 and 30 + //54 dbm between 53 and 109 + float stepSize = 54.0 / 28.0; + iDbm = -109 + (int)(stepSize * (iRssi-2)); + } else { + iDbm = -51; + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::convertdBmToSignalStrength(const int32_t& iDBm, int32_t& iRssi) { + //Telit Conversion + if(iDBm <= -113) { + iRssi = 0; + } else if(iDBm <= -111) { + iRssi = 1; + } else if(iDBm <= -53) { + //54 dbm between -109 and -53 + //28 steps between 2 and 30 + float stepSize = 28.0/54.0; + iRssi = ((iDBm + 109)*stepSize) + 2; + } else { + iRssi = 31; + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::getEcho(bool& bEnabled) { + printTrace("%s| Echo Test", m_sName.c_str()); + std::string sResult = sendCommand("AT"); + if(sResult.size() == 0) { + return NO_RESPONSE; + } + + if(sResult.find("AT") != std::string::npos) { + bEnabled = true; + } else { + bEnabled = false; + } + m_bEchoEnabled = bEnabled; + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::setEcho(bool bEnabled) { + CODE eCode = FAILURE; + if(bEnabled) { + eCode = sendBasicCommand("ATE1"); + m_bEchoEnabled = (eCode == SUCCESS ) ? true : m_bEchoEnabled; + } else { + eCode = sendBasicCommand("ATE0"); + m_bEchoEnabled = (eCode == SUCCESS ) ? false : m_bEchoEnabled; + } + + return eCode; +} + +TelitRadio::CODE TelitRadio::getStaticInformation(Json::Value& jData) { + printTrace("%s| Get Static Information", m_sName.c_str()); + + printTrace("%s| Static Information:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + + return FAILURE; +} + +/* AT#RFSTS - NETWORK STATUS + + (GSM network) + #RFSTS:<PLMN>,<ARFCN>,<RSSI>,<LAC>,<RAC>,<TXPWR>,<MM>,<RR>,<NOM>,<CID>,<IMSI>,<NetNameAsc>,<SD>,<ABND> + Where: + <PLMN> - Country code and operator code(MCC, MNC) + <ARFCN> - GSM Assigned Radio Channel + <RSSI> - Received Signal Strength Indication + <LAC> - Localization Area Code + <RAC> - Routing Area Code + <TXPWR> - Tx Power + <MM> - Mobility Management state + <RR> - Radio Resource state + <NOM> - Network Operator Mode + <CID> - Cell ID + <IMSI> - International Mobile Subscriber Identity + <NetNameAsc> - Operator name + <SD> - Service Domain + 0 - No Service + 1 - CS only + 2 - PS only + 3 - CS+PS + <ABND> - Active Band + 1 - GSM 850 + 2 - GSM 900 + 3 - DCS 1800 + 4 - PCS 1900 + + + (WCDMA network) + #RFSTS: + <PLMN>,<UARFCN>,<PSC>,<Ec/Io>,<RSCP>, RSSI>,<LAC>,<RAC>,<TXPWR>,<DRX>,<MM>,<RRC>,<NOM>,<BLER>,<CID>,<IMSI>, + <NetNameAsc>,<SD>,<nAST>[,<nUARFCN><nPSC>,<nEc/Io>] + Where: + <PLMN> - Country code and operator code(MCC, MNC) + <UARFCN> - UMTS Assigned Radio Channel + <PSC> - Active PSC(Primary Synchronization Code) + <Ec/Io> - Active Ec/Io(chip energy per total wideband power in dBm) + <RSCP> - Active RSCP (Received Signal Code Power in dBm) + <RSSI> - Received Signal Strength Indication + <LAC> - Localization Area Code + <RAC> - Routing Area Code + <TXPWR> - Tx Power + <DRX> - Discontinuous reception cycle Length (cycle length in ms) + <MM> - Mobility Management state + <RR> - Radio Resource state + <NOM> - Network Operator Mode + <BLER> - Block Error Rate (e.g., 005 means 0.5 %) + <CID> - Cell ID + <IMSI> - International Mobile Station ID + <NetNameAsc> - Operator name + <SD> - Service Domain (see above) + <nAST> - Number of Active Set (Maximum 6) + <nUARFCN> UARFCN of n th active set + <nPSC> PSC of n th active set + <nEc/Io > Ec/Io of n th active Set + + (LTE Network) + #RFSTS: + <PLMN> - + <EARFCN> - + <RSRP> - + <RSSI> - + <RSRQ> - + <TAC> - + [<TXPWR>] - + <DRX> - + <MM> - + <RRC> - + <CID> - + <IMSI> - + [<NetNameAsc>] - + <SD> - + <ABND> - +*/ +TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) { + int32_t iValue; + std::string sValue; + const uint32_t GSM_NETWORK_FORMAT = 14; + const uint32_t WCDMA_NETWORK_FORMAT = 19; + const uint32_t LTE_NETWORK_FORMAT = 16; + + printTrace("%s| Get Network Status", m_sName.c_str()); + + //Always get common network stats because this should never fail + //This way the basic stats are always returned even if AT#RFSTS fails below + getCommonNetworkStats(jData); + + std::string sCmd; + std::string sResult; + // LE910 radios have a bug where issuing AT#RFSTS with a locked SIM + // will cause the radio to stop responding until a radio power cycle + // Telit Support Portal Case #5069697 + // LE910C1-NS is an LE910, so we stop the scan after the 0. + if (m_sName.find("LE910") != std::string::npos) { + sCmd = "AT+CPIN?"; + sResult = sendCommand(sCmd); + if (sResult.find("+CPIN:") == std::string::npos) { + printDebug("%s| AT+CPIN? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); + printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function + } + if (sResult.find("SIM PIN") != std::string::npos) { + printError("%s| The SIM is locked and must first be unlocked", m_sName.c_str()); + printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function + } + } + + sCmd = "AT#RFSTS"; + sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 200); + if (sResult.find("#RFSTS:") == std::string::npos) { + //On LTE radios without signal, this case will run because AT#RFSTS just returns "OK" + printDebug("%s| Network Status command returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); + printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function + } + + size_t start = sResult.find(":") + 1; //Position right after "#RFSTS:" + std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start)), ","); + + if (vParts.size() < 3) { + printDebug("%s| Network Status command reponse is an unknown format: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); + printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function + } else { + //Country Code and Operator Code + std::vector<std::string> vPLMN = MTS::Text::split(vParts[0], ' '); + if(vPLMN.size() == 2) { + jData[KEY_MCC] = MTS::Text::strip(vPLMN[0], '"'); + jData[KEY_MNC] = MTS::Text::strip(vPLMN[1], '"'); + } + + jData[KEY_CHANNEL] = vParts[1]; + } + + if (vParts.size() == GSM_NETWORK_FORMAT ) { + //Parse as GSM Network Format + jData[KEY_RSSIDBM] = vParts[2]; + jData[KEY_LAC] = vParts[3]; + jData[KEY_RAC] = vParts[4]; + jData[KEY_TXPWR] = vParts[5]; + jData[KEY_MM] = vParts[6]; + jData[KEY_RR] = vParts[7]; + jData[KEY_NOM] = vParts[8]; + jData[KEY_CID] = vParts[9]; + jData[KEY_IMSI] = MTS::Text::strip(vParts[10], '"'); + jData[KEY_NETWORK] = MTS::Text::strip(vParts[11], '"'); + if(MTS::Text::parse(iValue, vParts[12]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { + jData[KEY_SD] = sValue; + } + if(MTS::Text::parse(iValue, vParts[13]) && convertActiveBandToString((ACTIVEBAND)iValue, sValue) == SUCCESS) { + jData[KEY_ABND] = sValue; + } + // IN003567 ME910C1 radios have some odd behavior with regards to WCDMA. The ordering of the fields from #RFSTS are + // the same as LTE up to the 16th field (for ME901C1-WW anyway). Drop into LTE parsing for ME910C1-WW. + } else if((vParts.size() >= WCDMA_NETWORK_FORMAT) && (m_sName.find("ME910C1-WW") == std::string::npos)) { + Json::Value jDebug; + + //Parse as WCDMA Network Format + + jDebug[KEY_PSC] = vParts[2]; + jDebug[KEY_ECIO] = vParts[3]; + jDebug[KEY_RSCP] = vParts[4]; + + jData[KEY_RSSIDBM] = vParts[5]; + jData[KEY_LAC] = vParts[6]; + jData[KEY_RAC] = vParts[7]; + + jDebug[KEY_TXPWR] = vParts[8]; + jDebug[KEY_DRX] = vParts[9]; + jDebug[KEY_MM] = vParts[10]; + jDebug[KEY_RR] = vParts[11]; + jDebug[KEY_NOM] = vParts[12]; + + if(vParts[13].size() != 0) { + jDebug[KEY_BLER] = vParts[13]; + } else { + jDebug[KEY_BLER] = "000"; + } + + jData[KEY_CID] = vParts[14]; + jData[KEY_IMSI] = MTS::Text::strip(vParts[15], '"'); + jData[KEY_NETWORK] = MTS::Text::strip(vParts[16], '"'); + + // Get the radio band given the channel (UARFCN) + RadioBandMap radioBandMap(vParts[1], TelitRadio::VALUE_TYPE_CDMA); + jData[KEY_ABND] = radioBandMap.getRadioBandName(); + + if(MTS::Text::parse(iValue, vParts[17]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { + jDebug[KEY_SD] = sValue; + } + //Ignoring Active Set Values + // <nAST> - Number of Active Set (Maximum 6) + // <nUARFCN> - UARFCN of n th active set + // <nPSC> - PSC of n th active set + // <nEc/Io > - Ec/Io of n th active Set + + jData[KEY_DEBUG] = jDebug; + } else if(vParts.size() >= LTE_NETWORK_FORMAT) { + Json::Value jDebug; + + //Parse as LTE Network Format + + // + // MD: It is noticed that LTE Network format may vary depending on the firmware version: + // + // <PLMN>,<EARFCN>,<RSRP>,<RSSI>,<RSRQ>,<TAC>,[<TXPWR>],<DRX>,<MM>,<RRC>,<CID>,<IMSI>,[<NetNameAsc>],<SD>,<ABND>,<SINR> + // Ex 1: #RFSTS: "310 260",2300,-98,-63,-14,AA06,,128,19,0,0501D02,"310260754792598","T-Mobile",3,4,197 + // + // <PLMN>,<EARFCN>,<RSRP>,<RSSI>,<RSRQ>,<TAC>,<RAC>,[<TXPWR>],<DRX>,<MM>,<RRC>,<CID>,<IMSI>,[<NetNameAsc>],<SD>,<ABND> + // Ex 2: #RFSTS:"310 410",5780,-105,-73,-14,4603,255,,128,19,0,0000098,"310410536498694","AT&T",3,17 + // #RFSTS:"311 480",1150,-96,-66,-9.0,bf35,FF,0,0,19,1,"2ED1B0E","311480148817753","Verizon",2,2,720000,10800 + // #RFSTS:"310 410",2175,-120,-89,-17.5,4612,FF,0,0,19,1,"4E5E916","310410807276607","AT&T",3,4 + // + // Additional <RAC> parameter in the second example shifts the rest of the parameters. Here we are trying to figure out + // which format is currently produced based on <NetNameAsc> field position which always has double quotation marks. + // + if (vParts[13].find("\"") != std::string::npos) { + // parse the RAC and then remove it from the vector + jData[KEY_RAC] = vParts[6]; + vParts.erase(vParts.begin() + 6); + } + + jDebug["rsrp"] = vParts[2]; + jDebug[KEY_RSSIDBM] = vParts[3]; + jDebug["rsrq"] = vParts[4]; + + jData["tac"] = vParts[5]; + jDebug[KEY_TXPWR] = vParts[6]; + jData[KEY_DRX] = vParts[7]; + jDebug[KEY_MM] = vParts[8]; + jDebug["rrc"] = vParts[9]; + jData[KEY_CID] = MTS::Text::strip(vParts[10], '"'); + jData[KEY_IMSI] = MTS::Text::strip(vParts[11], '"'); + jData[KEY_NETWORK] = MTS::Text::strip(vParts[12], '"'); + + // Get the radio band given the channel (EARFCN) + RadioBandMap radioBandMap(vParts[1], TelitRadio::VALUE_TYPE_LTE); + jData[KEY_ABND] = radioBandMap.getRadioBandName(); + + jData[KEY_LAC] = queryLteLac(); + + if(MTS::Text::parse(iValue, vParts[13]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { + jDebug[KEY_SD] = sValue; + } + + jData[KEY_DEBUG] = jDebug; + } + + printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + return SUCCESS; +} + +// Get the LAC for the LTE radio that's not in the #RFSTS response +std::string TelitRadio::queryLteLac() { + std::string CGREGstring; + std::string originalCGREG; + std::string result; + + CGREGstring = queryCGREGstring(); + if (CGREGstring == RSP_ERROR) { + originalCGREG = "0"; + } else { + originalCGREG = CGREGstring.at(CGREGstring.find(",") - 1); //Position right before first comma ("+CGREG: 0,1") + } + + // Temporarily set CGREG=2 to get more info + setCGREG("2"); + + CGREGstring = queryCGREGstring(); + if (CGREGstring == RSP_ERROR) { + result = TelitRadio::VALUE_UNKNOWN; + } else { + size_t start = CGREGstring.find(":") + 1; //Position right after "#RFSTS:" + std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(CGREGstring.substr(start)), ","); + if(vParts.size() < 3) { + result = TelitRadio::VALUE_UNAVAILABLE; + } else { + result = MTS::Text::strip(vParts[2], '"'); + } + } + + setCGREG(originalCGREG); + + return result; +} + +void TelitRadio::setCGREG(std::string value) { + std::string sCmd("AT+CGREG=" + value); + std::string cmdResult(sendCommand(sCmd)); + if (cmdResult.find("OK") == std::string::npos) { + printDebug("%s| AT#CGREG=%s returned unexpected response: [%s][%s]", m_sName.c_str(), value.c_str(), sCmd.c_str(), cmdResult.c_str()); + } +} + +std::string TelitRadio::queryCGREGstring() { + std::string sCmd("AT+CGREG?"); + std::string cmdResult(sendCommand(sCmd)); + if (cmdResult.find("+CGREG:") == std::string::npos) { + printDebug("%s| AT#CGREG? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), cmdResult.c_str()); + return RSP_ERROR; + } + return cmdResult; +} + +void TelitRadio::getCommonNetworkStats(Json::Value& jData) { + + bool bRoaming = false; + if(getRoaming(bRoaming) == SUCCESS) { + jData[KEY_ROAMING] = bRoaming; + } + + int32_t iRssi; + if(getSignalStrength(iRssi) == SUCCESS) { + jData[KEY_RSSI] = iRssi; + int32_t dBm; + if(!jData.isMember(KEY_RSSIDBM) && convertSignalStrengthTodBm(iRssi, dBm) == SUCCESS) { + //Add RSSI in dBm format + jData[KEY_RSSIDBM] = MTS::Text::format(dBm); + } + } + + std::string sService; + if(getService(sService) == SUCCESS) { + jData[KEY_SERVICE] = sService; + } + std::string sDate, sTime, sTimeZone; + if(getTime(sDate, sTime, sTimeZone) == SUCCESS) { + jData[KEY_DATETIME] = sDate + " " + sTime + " GMT" + sTimeZone; + } + + std::string sNetworkReg; + TelitRadio::REGISTRATION eReg; + if (getRegistration(eReg) == SUCCESS) { + if (convertRegistrationToString(eReg, sNetworkReg) == SUCCESS) { + jData[TelitRadio::KEY_NETWORK_REG] = sNetworkReg; + } + } +} + +void TelitRadio::initMipProfile(Json::Value& jData) { + jData[KEY_MIP_ID] = 0; + jData[KEY_MIP_ENABLED] = false; + jData[KEY_MIP_NAI] = VALUE_UNKNOWN; + jData[KEY_MIP_HOMEADDRESS] = VALUE_UNKNOWN; + jData[KEY_MIP_PRIMARYHA] = VALUE_UNKNOWN; + jData[KEY_MIP_SECONDARYHA] = VALUE_UNKNOWN; + jData[KEY_MIP_MNAAASPI] = VALUE_UNKNOWN; + jData[KEY_MIP_MNHASPI] = VALUE_UNKNOWN; + jData[KEY_MIP_MNAAASS] = false; + jData[KEY_MIP_MNHASS] = false; +} + +TelitRadio::CODE TelitRadio::getRegistration(REGISTRATION& eRegistration) { + std::string sCmd; + std::string sResp; + + // LE910C1-NS is an LE910, so we stop the scan after the 0. + if (m_sName.find("LE910") != std::string::npos) { + // use AT+CGREG instead for LE910 models + sCmd = "AT+CGREG?"; + sResp = "+CGREG: "; + } + else { + sCmd = "AT+CREG?"; + sResp = "+CREG: "; + } + + std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 5000); + if (sResult.find(sResp) == std::string::npos) { + if(sResult.size() == 0) { + printDebug("%s| Registration command returned no response: [%s]", m_sName.c_str()); + return NO_RESPONSE; + } + printDebug("%s| Registration command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + size_t start = sResult.find(','); + size_t stop = sResult.find(' ', start); + std::string sRegStat = sResult.substr(start + 1, stop - start - 1); + int32_t value; + sscanf(sRegStat.c_str(), "%d", &value); + eRegistration = (REGISTRATION)value; + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) { + + CODE eCode = FAILURE; + switch (eRegistration) { + case NOT_REGISTERED: sRegistration = VALUE_NOT_REGISTERED; eCode = SUCCESS; break; + case REGISTERED: sRegistration = VALUE_REGISTERED; eCode = SUCCESS; break; + case SEARCHING: sRegistration = VALUE_SEARCHING; eCode = SUCCESS; break; + case DENIED: sRegistration = VALUE_DENIED; eCode = SUCCESS; break; + case UNKNOWN: sRegistration = VALUE_UNKNOWN; eCode = SUCCESS; break; + case ROAMING: sRegistration = VALUE_ROAMING; eCode = SUCCESS; break; + } + return eCode; +} + +TelitRadio::CODE TelitRadio::validateMsl(const Json::Value& jArgs) { + printTrace("%s| Validate MSL", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMdn(const Json::Value& jArgs) { + printTrace("%s| Set MDN", m_sName.c_str()); + + if(!jArgs["mdn"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT#SNUM=1,\""); + sCmd += jArgs["mdn"].asString() + "\""; + + std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 1000); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MDN for radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +TelitRadio::CODE TelitRadio::setMsid(const Json::Value& jArgs) { + printTrace("%s| Set MSID", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::getMipProfile(Json::Value& jMipProfile) { + printTrace("%s| Get MIP Active Profile", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipActiveProfile(const Json::Value& jArgs) { + printTrace("%s| Set MIP Active Profile", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipNai(const Json::Value& jArgs) { + printTrace("%s| Set MIP NAI", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipHomeIp(const Json::Value& jArgs) { + printTrace("%s| Set MIP Home IP", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipPrimaryHa(const Json::Value& jArgs) { + printTrace("%s| Set MIP Primary HA", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipSecondaryHa(const Json::Value& jArgs) { + printTrace("%s| Set MIP Secondary HA", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipMnAaaSpi(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-AAA SPI", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipMnHaSpi(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-HA SPI", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipRevTun(const Json::Value& jArgs) { + printTrace("%s| Set MIP Rev Tun", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipMnAaaSs(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-AAA SS", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setMipMnHaSs(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-HA SS", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Device Configuration", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Preferred Roaming List", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Firmware Update Management Object", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| HFA Reset", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Activation", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::setActiveFirmware(const Json::Value& jArgs) { + printTrace("%s| Set Active Firmware Image Number: not applicable", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::getActiveFirmware(std::string& sFwId) { + printTrace("%s| Get Active Firmware Image Number: not applicable", m_sName.c_str()); + sFwId = VALUE_NOT_SUPPORTED; + + return NOT_APPLICABLE; +} + +TelitRadio::CODE TelitRadio::sendBasicCommand(const std::string& sCmd, int32_t iTimeoutMillis, const char& ESC) { + std::string response = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, iTimeoutMillis, ESC); + if (response.size() == 0) { + return NO_RESPONSE; + } else if (response.find(RSP_OK) != std::string::npos) { + return SUCCESS; + } else if (response.find(RSP_ERROR) != std::string::npos) { + return ERROR; + } else { + return FAILURE; + } +} + +std::string TelitRadio::sendCommand(const std::string& sCmd, const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) { + return sendCommand(m_apIo, sCmd, vBail, timeoutMillis, ESC); +} + +std::string TelitRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd, + const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) { + IsNeedMoreData isNeedMoreData = [&vBail](const std::string& iterationData, const std::string& allData)->bool { + for(size_t i = 0; i < vBail.size(); i++) { + const std::string& sBail = vBail[i]; + if(sBail.size() > 0) { + if(allData.find(sBail) != std::string::npos) { + //Return when bail string is found + printTrace("RADIO| Found bail string [%s]", sBail.c_str()); + return false; + } + } + } + return true; + }; + + return sendCommand(apIo, sCmd, isNeedMoreData, timeoutMillis, ESC); +} + +std::string TelitRadio::sendCommand(const std::string& sCmd, MTS::IO::TelitRadio::IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) { + return sendCommand(m_apIo, sCmd, isNeedMoreData, timeoutMillis, ESC); +} + +std::string TelitRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) { + if(MTS::Logger::getPrintLevel() >= MTS::Logger::PrintLevel::TRACE_LEVEL) { + printTrace("RADIO| Sending command [%s]", sCmd.c_str()); + } + if(apIo.isNull()) { + printError("RADIO| IO is not set in sendCommand"); + return ""; + } + + int32_t iResult; + if(ESC == 0x00) { + iResult = apIo->write(sCmd.data(), sCmd.size()); + } else { + std::string sNewCmd(sCmd); + sNewCmd.push_back(ESC); + iResult = apIo->write(sNewCmd.data(), sNewCmd.size()); + } + + if(iResult == -1) { + printError("RADIO| Failed to send command to radio"); + return ""; + } + + bool done = false; + const uint32_t capacity = 1024; + char buffer[capacity]; + std::string sResult; + Timer timer; + timer.start(); + do { + int32_t iterationTimeout = 100; + int bytesRead = apIo->read((char*)buffer, capacity, iterationTimeout); + if(bytesRead == -1) { + printError("RADIO| Failed to read from radio"); + break; + } + + std::string sIteration((char*)buffer, bytesRead); + sResult += sIteration; + + if(isNeedMoreData && !isNeedMoreData(sIteration, sResult)) { + printTrace("RADIO| No more data needed"); + return sResult; + } + if(timeoutMillis >= 0) { + done = (timer.getMillis() >= (uint64_t)timeoutMillis); + } else { + //Do not stop looping until bail string is found + } + } while(!done); + + //Timed out + return sResult; +} + +TelitRadio::CODE TelitRadio::test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds) { + printTrace("RADIO| Basic Test"); + uint32_t count = 0; + std::string sCmd("AT"); + do { + std::string sResult = sendCommand(apIo, sCmd); + if (sResult.find(RSP_OK) == std::string::npos) { + printTrace("RADIO| Waiting for basic radio communication [%s] ...", sResult.c_str()); + } else { + break; + } + count++; + } while (count < timeoutSeconds); + + if(count == timeoutSeconds) { + printWarning("RADIO| Basic radio communication FAILED"); + return NO_RESPONSE; + } + return SUCCESS; +} + +std::string TelitRadio::extractModelFromResult(const std::string& sResult) { + std::string sModel(TelitRadio::VALUE_NOT_SUPPORTED); + + if(sResult.find("HE910-D") != std::string::npos) { + sModel = "HE910-D"; + } else if(sResult.find("HE910-EUD") != std::string::npos) { + sModel = "HE910-EUD"; + } else if(sResult.find("LE910-JN1") != std::string::npos) { + sModel = "LE910-JN1"; + } else if(sResult.find("LE866A1-JS") != std::string::npos) { + sModel = "LE866A1-JS"; + } else if(sResult.find("LE910-NAG") != std::string::npos) { + sModel = "LE910-NAG"; + } else if(sResult.find("LE910C4-NF") != std::string::npos) { + sModel = "LE910C4-NF"; + } else if(sResult.find("LE910-NA1") != std::string::npos) { + sModel = "LE910-NA1"; + } else if(sResult.find("ME910C1-NA") != std::string::npos) { + sModel = "ME910C1-NA"; + } else if(sResult.find("ME910C1-NV") != std::string::npos) { + sModel = "ME910C1-NV"; + } else if(sResult.find("ME910C1-WW") != std::string::npos) { + sModel = "ME910C1-WW"; + } else if(sResult.find("LE910-SVG") != std::string::npos) { + sModel = "LE910-SVG"; + } else if(sResult.find("LE910-EUG") != std::string::npos) { + sModel = "LE910-EUG"; + } else if(sResult.find("LE910C4-EU") != std::string::npos) { + sModel = "LE910C4-EU"; + } else if(sResult.find("LE910-EU1") != std::string::npos) { + sModel = "LE910-EU1"; + } else if(sResult.find("LE910C1-NS") != std::string::npos) { + sModel = "LE910C1-NS"; + } else if(sResult.find("LE910C1-AP") != std::string::npos) { + sModel = "LE910C1-AP"; + } else if(sResult.find("GE910") != std::string::npos) { + sModel = "GE910"; + } else if(sResult.find("DE910-DUAL") != std::string::npos) { + sModel = "DE910-DUAL"; + } else if(sResult.find("CE910") != std::string::npos) { + sModel = "CE910"; + } + return sModel; +} + +std::string TelitRadio::getCodeAsString(CODE eCode) { + switch(eCode) { + case SUCCESS: + return "SUCCESS"; + case ERROR: + return "ERROR"; + case FAILURE: + return "FAILURE"; + case NO_RESPONSE: + return "NO RESPONSE"; + default: + return "UNKNOWN"; + } +} + +bool TelitRadio::splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType) { + + std::vector<std::string> vParts = MTS::Text::split(sLine, ":", 2); + + if(vParts.size() == 2 && vParts[0] == sKey) { + if(eType == Json::ValueType::stringValue) { + jParent[sJsonKey] = MTS::Text::trim(vParts[1]); + } else if (eType == Json::ValueType::intValue || eType == Json::ValueType::uintValue) { + //TODO: + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } else if(eType == Json::ValueType::realValue) { + //TODO: + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } else if(eType == Json::ValueType::booleanValue) { + //TODO: + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } else { + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } + } else { + printWarning("%s| Unable to parse %s from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } + + return true; +} + +bool TelitRadio::getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier) { + // Telit Radios + // H.ab.zyx => 3 Main Components + // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family + // "a" = Hardware version + // "b" = Software Major Version + // "z" = is the product type, i.e. DUAL or SC + // "y" = is the carrier variant + // "x" = is the firmware version + // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, "2" for Verizon, and "3" for U.S. Cellular. + + const uint32_t CARRIER_INDEX = 1; //y in [zyx] + + bool bResult = false; + std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.'); + + if(vParts.size() == 3) { + //CDMA firmware version notation + if(vParts[0] == "15" || vParts[0] == "18") { + //DE910 or CE910 -> Good good + std::string sID = vParts[2]; + if(sID.size() == 3) { + char cId = sID[CARRIER_INDEX]; + + //Good good + if(cId == '0') { + sCarrier = VALUE_CARRIER_SPRINT; + bResult = true; + } else + if(cId == '1') { + sCarrier = VALUE_CARRIER_AERIS; + bResult = true; + } else + if(cId == '2') { + sCarrier = VALUE_CARRIER_VERIZON; + bResult = true; + } else + if(cId == '3') { + sCarrier = VALUE_CARRIER_USCELLULAR; + bResult = true; + } + } + } + } + + return bResult; +} + +bool TelitRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware) { + // Telit Radios + // H.ab.zyx => 3 Main Components + // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family + // "a" = Hardware version + // "b" = Software Major Version + // "z" = is the product type, i.e. DUAL or SC + // "y" = is the carrier variant + // "x" = is the firmware version + // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, and "2" for Verizon. + + const uint32_t HARDWARE_INDEX = 0; //a in [ab] + + bool bResult = false; + std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.'); + + if(vParts.size() == 3) { + //GSM Hardware Version + if(!(vParts[0] == "15" || vParts[0] == "18")) { + //Not DE910 or CE910 -> Good good + std::string sVersion = vParts[1]; + if(sVersion.size() == 2) { + sHardware = "1."; + sHardware += sVersion[HARDWARE_INDEX]; + bResult = true; + } + } + } + + return bResult; + +} + +const char *TelitRadio::RadioBandMap::getLTEBand(const int32_t channel) +{ + for (unsigned int ii = 0; ii < NUM_LTE_BANDS; ii++) + { + if (EULTRAband[ii].low <= channel && EULTRAband[ii].high >= channel) + { + return EULTRAband[ii].name; + } + } + return VALUE_UNKNOWN.c_str(); +} + +const char *TelitRadio::RadioBandMap::getCDMABand(const int channel) +{ + for (unsigned int ii = 0; ii < NUM_WCDMA_BANDS; ii++) + { + if (WCDMAband[ii].low <= channel && WCDMAband[ii].high >= channel) + { + return WCDMAband[ii].name; + } + } + return VALUE_UNKNOWN.c_str(); +} + +const char *TelitRadio::RadioBandMap::getGSMBand(const int channel) +{ + for (unsigned int ii = 0; ii < NUM_GSM_BANDS; ii++) + { + if (GSMband[ii].low <= channel && GSMband[ii].high >= channel) + { + return GSMband[ii].name; + } + } + return VALUE_UNKNOWN.c_str(); +} + +const char *TelitRadio::RadioBandMap::getRadioBandName() +{ + const char *band = TelitRadio::VALUE_UNKNOWN.c_str(); + + if (m_sRadioType == TelitRadio::VALUE_TYPE_LTE) + { + band = getLTEBand(m_iChannel); + } + else if (m_sRadioType == TelitRadio::VALUE_TYPE_CDMA) + { + band = getCDMABand(m_iChannel); + } + else if (m_sRadioType == TelitRadio::VALUE_TYPE_GSM) + { + band = getGSMBand(m_iChannel); + } + + return band; +} + +const char *TelitRadio::RadioBandMap::getRadioBandName(const std::string &channel, const std::string &radioType) +{ + const char *band = TelitRadio::VALUE_UNKNOWN.c_str(); + int32_t chan = strtol(channel.c_str(), NULL, 10); + if (radioType == TelitRadio::VALUE_TYPE_LTE) + { + band = getLTEBand(chan); + } + else if (radioType == TelitRadio::VALUE_TYPE_CDMA) + { + band = getCDMABand(chan); + } + else if (radioType == TelitRadio::VALUE_TYPE_GSM) + { + band = getGSMBand(chan); + } + + return band; +} |