summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Hatch <jhatch@multitech.com>2019-07-23 08:51:41 -0500
committerJeff Hatch <jhatch@multitech.com>2019-07-23 08:51:41 -0500
commitf6f7d0e174d2bf5eb4494e2508c17d3d7fbdc4e9 (patch)
tree4f0e44ed31f0e536835260ff5b4849f84289ee9c
parent86e572b513259e1f7164dd4e4b0f490c870bfc30 (diff)
parent0330513b8913d1d7bf14bad99d64ab002b770b7c (diff)
downloadlibmts-io-f6f7d0e174d2bf5eb4494e2508c17d3d7fbdc4e9.tar.gz
libmts-io-f6f7d0e174d2bf5eb4494e2508c17d3d7fbdc4e9.tar.bz2
libmts-io-f6f7d0e174d2bf5eb4494e2508c17d3d7fbdc4e9.zip
Merge branch 'quectel-radio' into 'master'
Quectel radio See merge request !1
-rw-r--r--Makefile143
-rw-r--r--include/mts/MTS_IO_CdmaRadio.h4
-rw-r--r--include/mts/MTS_IO_CellularRadio.h557
-rw-r--r--include/mts/MTS_IO_CellularRadioFactory.h53
-rw-r--r--include/mts/MTS_IO_EG95Radio.h47
-rw-r--r--include/mts/MTS_IO_GE910Radio.h4
-rw-r--r--include/mts/MTS_IO_HE910Radio.h4
-rw-r--r--include/mts/MTS_IO_ICellularRadio.h453
-rw-r--r--include/mts/MTS_IO_LE866Radio.h4
-rw-r--r--include/mts/MTS_IO_LE910Radio.h4
-rw-r--r--include/mts/MTS_IO_ME910C1WWRadio.h4
-rw-r--r--include/mts/MTS_IO_ME910Radio.h4
-rw-r--r--include/mts/MTS_IO_QuectelRadio.h62
-rw-r--r--include/mts/MTS_IO_TelitRadio.h60
-rw-r--r--src/MTS_IO_CE910Radio.cpp2
-rw-r--r--src/MTS_IO_CdmaRadio.cpp216
-rw-r--r--src/MTS_IO_CellularRadio.cpp1338
-rw-r--r--src/MTS_IO_CellularRadioFactory.cpp61
-rw-r--r--src/MTS_IO_DE910Radio.cpp2
-rw-r--r--src/MTS_IO_EG95Radio.cpp47
-rw-r--r--src/MTS_IO_GE910Radio.cpp4
-rw-r--r--src/MTS_IO_HE910Radio.cpp4
-rw-r--r--src/MTS_IO_ICellularRadio.cpp472
-rw-r--r--src/MTS_IO_LE866Radio.cpp2
-rw-r--r--src/MTS_IO_LE910C1APRadio.cpp2
-rw-r--r--src/MTS_IO_LE910C1NSRadio.cpp2
-rw-r--r--src/MTS_IO_LE910NA1Radio.cpp10
-rw-r--r--src/MTS_IO_LE910Radio.cpp8
-rw-r--r--src/MTS_IO_LE910SVGRadio.cpp2
-rw-r--r--src/MTS_IO_ME910C1NVRadio.cpp70
-rw-r--r--src/MTS_IO_ME910C1WWRadio.cpp10
-rw-r--r--src/MTS_IO_ME910Radio.cpp8
-rw-r--r--src/MTS_IO_QuectelRadio.cpp612
-rw-r--r--src/MTS_IO_TelitRadio.cpp666
34 files changed, 3117 insertions, 1824 deletions
diff --git a/Makefile b/Makefile
index 677c34d..8472075 100644
--- a/Makefile
+++ b/Makefile
@@ -1,104 +1,73 @@
include version
-includedir ?= /usr/include
+APPNAME = libmts-io
+SONAME = $(APPNAME).so.$(VERSION)
libdir ?= /usr/lib
OBJS += \
-MTS_IO_CdmaRadio.o \
-MTS_IO_CE910Radio.o \
-MTS_IO_CellularRadio.o \
-MTS_IO_CellularRadioFactory.o \
-MTS_IO_Connection.o \
-MTS_IO_DE910Radio.o \
-MTS_IO_GE910Radio.o \
-MTS_IO_HE910Radio.o \
-MTS_IO_HE910DRadio.o \
-MTS_IO_HE910EUDRadio.o \
-MTS_IO_LE910JN1Radio.o \
-MTS_IO_LE866Radio.o \
-MTS_IO_LE866A1JSRadio.o \
-MTS_IO_LE910Radio.o \
-MTS_IO_LE910NAGRadio.o \
-MTS_IO_LE910C4NFRadio.o \
-MTS_IO_LE910NA1Radio.o \
-MTS_IO_LE910SVGRadio.o \
-MTS_IO_LE910EUGRadio.o \
-MTS_IO_LE910C4EURadio.o \
-MTS_IO_LE910EU1Radio.o \
-MTS_IO_LE910C1NSRadio.o \
-MTS_IO_LE910C1APRadio.o \
-MTS_IO_ME910C1NARadio.o \
-MTS_IO_ME910C1NVRadio.o \
-MTS_IO_ME910C1WWRadio.o \
-MTS_IO_ME910Radio.o \
-MTS_IO_LockFile.o \
-MTS_IO_MccMncTable.o \
-MTS_IO_SerialConnection.o
+ src/MTS_IO_TelitRadio.o \
+ src/MTS_IO_EG95Radio.o \
+ src/MTS_IO_QuectelRadio.o \
+ src/MTS_IO_CdmaRadio.o \
+ src/MTS_IO_CE910Radio.o \
+ src/MTS_IO_CellularRadio.o \
+ src/MTS_IO_ICellularRadio.o \
+ src/MTS_IO_CellularRadioFactory.o \
+ src/MTS_IO_Connection.o \
+ src/MTS_IO_DE910Radio.o \
+ src/MTS_IO_GE910Radio.o \
+ src/MTS_IO_HE910Radio.o \
+ src/MTS_IO_HE910DRadio.o \
+ src/MTS_IO_HE910EUDRadio.o \
+ src/MTS_IO_LE910JN1Radio.o \
+ src/MTS_IO_LE866Radio.o \
+ src/MTS_IO_LE866A1JSRadio.o \
+ src/MTS_IO_LE910Radio.o \
+ src/MTS_IO_LE910NAGRadio.o \
+ src/MTS_IO_LE910C4NFRadio.o \
+ src/MTS_IO_LE910NA1Radio.o \
+ src/MTS_IO_LE910SVGRadio.o \
+ src/MTS_IO_LE910EUGRadio.o \
+ src/MTS_IO_LE910C4EURadio.o \
+ src/MTS_IO_LE910EU1Radio.o \
+ src/MTS_IO_LE910C1NSRadio.o \
+ src/MTS_IO_LE910C1APRadio.o \
+ src/MTS_IO_ME910C1NARadio.o \
+ src/MTS_IO_ME910C1NVRadio.o \
+ src/MTS_IO_ME910C1WWRadio.o \
+ src/MTS_IO_ME910Radio.o \
+ src/MTS_IO_LockFile.o \
+ src/MTS_IO_MccMncTable.o \
+ src/MTS_IO_SerialConnection.o
-CPP_DEPS += \
-MTS_IO_CdmaRadio.d \
-MTS_IO_CE910Radio.d \
-MTS_IO_CellularRadio.d \
-MTS_IO_CellularRadioFactory.d \
-MTS_IO_Connection.d \
-MTS_IO_DE910Radio.d \
-MTS_IO_GE910Radio.d \
-MTS_IO_HE910Radio.d \
-MTS_IO_HE910DRadio.d \
-MTS_IO_HE910EUDRadio.d \
-MTS_IO_LE910JN1Radio.d \
-MTS_IO_LE866Radio.d \
-MTS_IO_LE866A1JSRadio.d \
-MTS_IO_LE910Radio.d \
-MTS_IO_LE910NAGRadio.d \
-MTS_IO_LE910C4NFRadio.d \
-MTS_IO_LE910NA1Radio.d \
-MTS_IO_LE910SVGRadio.d \
-MTS_IO_LE910EUGRadio.d \
-MTS_IO_LE910C4EURadio.d \
-MTS_IO_LE910EU1Radio.d \
-MTS_IO_LE910C1NSRadio.d \
-MTS_IO_LE910C1APRadio.d \
-MTS_IO_ME910C1NARadio.d \
-MTS_IO_ME910C1NVRadio.d \
-MTS_IO_ME910C1WWRadio.d \
-MTS_IO_ME910Radio.d \
-MTS_IO_LockFile.d \
-MTS_IO_MccMncTable.d \
-MTS_IO_SerialConnection.d
+CC := $(CXX)
+#-Werror
+CXXFLAGS += -Wall -std=c++0x -fmessage-length=0 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden
+CPPFLAGS += -I=/usr/include/jsoncpp -Iinclude
+LDFLAGS += -s -shared -Wl,-soname,$(APPNAME).so.0
-all: libmts-io.a libmts-io.so.0
+.PHONY: all clean install
-libmts-io.a: $(OBJS)
- @echo 'Building target: $@'
- $(AR) -r libmts-io.a $(OBJS)
- @echo 'Finished building target: $@'
- @echo ' '
+all: $(APPNAME).a $(SONAME)
-libmts-io.so.0: $(OBJS)
- @echo 'Building target: $@'
- $(CXX) $(LDFLAGS) -shared -Wl,-soname,$@ -o libmts-io.so.$(VERSION) $(OBJS)
- @echo 'Finished building target: $@'
- @echo ' '
+$(APPNAME).a: $(OBJS)
+ $(AR) -rs $@ $?
-%.o: src/%.cpp
- @echo 'Building file: $<'
- $(CXX) $(CFLAGS) -I=$(includedir)/jsoncpp -Iinclude -Wall -Werror -c -fPIC -fmessage-length=0 -std=c++0x -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
+$(SONAME): $(OBJS)
+ $(CC) $(LDFLAGS) -o $@ $? $(LDLIBS)
+
+# Handle header dependencies
+DEPS = $(OBJS:.o=.d)
+CPPFLAGS += -MMD
+-include $(DEPS)
install:
mkdir -p $(DESTDIR)$(libdir)
mkdir -p $(DESTDIR)$(includedir)/mts
- install -m 0644 libmts-io.a libmts-io.so.$(VERSION) $(DESTDIR)$(libdir)/
- ln -sf libmts-io.so.$(VERSION) $(DESTDIR)$(libdir)/libmts-io.so.0
- ln -sf libmts-io.so.0 $(DESTDIR)$(libdir)/libmts-io.so
+ install -m 0644 $(APPNAME).a $(SONAME) $(DESTDIR)$(libdir)/
+ ln -sf $(SONAME) $(DESTDIR)$(libdir)/$(APPNAME).so.0
+ ln -sf $(SONAME) $(DESTDIR)$(libdir)/$(APPNAME).so
install -m 0644 include/mts/* $(DESTDIR)$(includedir)/mts/
clean:
- -$(RM) $(OBJS) $(CPP_DEPS) libmts-io.a libmts-io.so*
- -@echo ' '
-
-.PHONY: all clean dependents install
-.SECONDARY:
-
+ $(RM) $(OBJS) $(APPNAME).a $(SONAME) $(DEPS)
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..eecefee 100644
--- a/include/mts/MTS_IO_CellularRadio.h
+++ b/include/mts/MTS_IO_CellularRadio.h
@@ -29,449 +29,93 @@
#ifndef MTS_IO_CELLULARRADIO_H_
#define MTS_IO_CELLULARRADIO_H_
+#include <string>
+#include <vector>
+
+#include <json/json.h>
+
+#include <mts/MTS_IO_ICellularRadio.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 CellularRadio : NonCopyable {
+ class CellularRadio : public ICellularRadio {
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::string& getName() const override;
+
+ ~CellularRadio() override;
+
+ bool initialize(uint32_t iTimeoutMillis = 5000) override;
+ bool resetConnection(uint32_t iTimeoutMillis = 5000) override;
+ void shutdown() override;
+
+ CODE getFirmware(std::string& sFirmware) override;
+ CODE getFirmwareBuild(std::string& sFirmwareBuild) override;
+ CODE getHardware(std::string& sHardware) override;
+ CODE getManufacturer(std::string& sManufacturer) override;
+ CODE getImei(std::string& sImei) override;
+ CODE getMeid(std::string& sMeid) override;
+ CODE getImsi(std::string& sImsi) override;
+ CODE getSimStatus(std::string& sSimStatus) override;
+ CODE getSimStatusSummary(Json::Value& jData) override;
+ CODE getLac(std::string& sLac) override;
+ CODE getMdn(std::string& sMdn) override;
+ CODE getMsid(std::string& sMsid) override;
+ CODE getType(std::string& sType) override;
+ CODE getCarrier(std::string& sCarrier) override;
+ CODE getTower(std::string& sTower) override;
+ CODE getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) override;
+ CODE getRoaming(bool& bRoaming) override;
+
+ CODE getSignalStrength(int32_t& iRssi) override;
+ CODE getModemLocation(std::string& sLocation) override;
+
+ CODE getRegistration(REGISTRATION& eRegistration) override;
+ CODE convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) override;
+
+ CODE unlockSimCard(const Json::Value& jArgs) override;
+
+ CODE getMipProfile(Json::Value& jMipProfile) override;
+ CODE validateMsl(const Json::Value& jArgs) override;
+ CODE setMsid(const Json::Value& jArgs) override;
+ CODE setMipActiveProfile(const Json::Value& jArgs) override;
+ CODE setMipNai(const Json::Value& jArgs) override;
+ CODE setMipHomeIp(const Json::Value& jArgs) override;
+ CODE setMipPrimaryHa(const Json::Value& jArgs) override;
+ CODE setMipSecondaryHa(const Json::Value& jArgs) override;
+ CODE setMipMnAaaSpi(const Json::Value& jArgs) override;
+ CODE setMipMnHaSpi(const Json::Value& jArgs) override;
+ CODE setMipRevTun(const Json::Value& jArgs) override;
+ CODE setMipMnAaaSs(const Json::Value& jArgs) override;
+ CODE setMipMnHaSs(const Json::Value& jArgs) override;
+ CODE updateDc(const Json::Value& jArgs, UpdateCb& stepCb) override;
+ CODE updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) override;
+ CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) override;
+ CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) override;
+ CODE activate(const Json::Value& jArgs, UpdateCb& stepCb) override;
+ CODE setActiveFirmware(const Json::Value& jArgs) override;
+ CODE getActiveFirmware(std::string& sFwId) override;
+ CODE getEcho(bool& bEnabled) override;
+ CODE setEcho(bool bEnabled = true) override;
+ CODE getStaticInformation(Json::Value& jData) override;
+ CODE sendBasicCommand(const std::string& sCmd, int32_t timeoutMillis = 100, const char& ESC = ICellularRadio::CR) override;
+
+ std::string sendCommand(const std::string& sCmd,
const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS,
int32_t timeoutMillis = 100,
- const char& ESC = CR);
+ const char& ESC = ICellularRadio::CR) override;
- 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,
+ 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);
+ const char& ESC = ICellularRadio::CR) override;
- 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:
@@ -482,27 +126,61 @@ namespace MTS {
virtual void getCommonNetworkStats(Json::Value& jData);
- void initMipProfile(Json::Value& jData);
+ /**
+ * @brief getIsSimInserted - returns if the SIM card is inserted / installed or not.
+ *
+ * @param bData - an object to be filled with the SIM card insertion status.
+ * `true` when SIM card is inserted / installed / present,
+ * `false` otherwise.
+ * @return CODE::SUCCESS when SIM insertion status is fetched successfully,
+ * CODE::NOT_APPLICABLE when the modem doesn't support this feature,
+ * CODE::ERROR otherwise (when modem is inaccessible or in other cases).
+ */
+ virtual CODE getIsSimInserted(bool& bData) = 0;
+
+ /**
+ * @brief getSimLockStatus - return the SIM lock status as defined by AT+CPIN? command.
+ * Returns "READY", "SIM PIN", "SIM PUK" or other SIM status.
+ *
+ * @param sData - an object to be filled with the SIM lock status
+ * @return CODE::SUCCESS when SIM status is fetched successfully,
+ * CODE::NOT_APPLICABLE when the modem doesn't support this feature,
+ * CODE::ERROR otherwise (SIM card removed, modem is inaccessible, etc).
+ */
+ virtual CODE getSimLockStatus(std::string& sData);
+
+ /**
+ * @brief getSimLockAttempts - get the number of SIM unlock attempts left.
+ *
+ * @param iAttemptsPin - the number of attempts left to enter a PIN code.
+ * @param iAttemptsPuk - the number of attempts left to enter a PUK code.
+ * @return CODE::SUCCESS when both numbers are fetched successfully,
+ * CODE::NOT_APPLICABLE when the modem doesn't support this feature,
+ * CODE::ERROR otherwise (SIM card removed, modem is inaccessible, etc).
+ */
+ virtual CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) = 0;
+ 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);
+ virtual std::string queryLteLac();
+ virtual std::string queryCGREGstring();
+ virtual void setCGREG(std::string value);
-
- private:
- class RadioBandMap : NonCopyable {
+ class RadioBandMap : public MTS::NonCopyable {
public:
- RadioBandMap()
- {
- m_sChannel = CellularRadio::VALUE_UNKNOWN;
+ RadioBandMap()
+ {
+ m_sChannel = ICellularRadio::VALUE_UNKNOWN;
m_iChannel = 0;
- m_sRadioType = CellularRadio::VALUE_UNKNOWN;
- }
+ m_sRadioType = ICellularRadio::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);
+ m_iChannel = strtol(m_sChannel.c_str(), NULL, 10);
}
virtual ~RadioBandMap() {}
@@ -521,6 +199,7 @@ namespace MTS {
std::string m_sRadioType;
};
+ private:
std::string m_sName;
std::string m_sRadioPort;
std::string m_sFirmware;
@@ -529,14 +208,8 @@ namespace MTS {
bool m_bEchoEnabled;
bool m_bEnableEchoOnClose;
-
- std::string queryLteLac();
- std::string queryCGREGstring();
- void setCGREG(std::string value);
};
}
}
-
-
#endif /* MTS_IO_CELLULARRADIO_H_ */
diff --git a/include/mts/MTS_IO_CellularRadioFactory.h b/include/mts/MTS_IO_CellularRadioFactory.h
index 49f63bd..c9cb56f 100644
--- a/include/mts/MTS_IO_CellularRadioFactory.h
+++ b/include/mts/MTS_IO_CellularRadioFactory.h
@@ -21,47 +21,44 @@
#ifndef MTS_IO_CELLULARRADIOFACTORY_H_
#define MTS_IO_CELLULARRADIOFACTORY_H_
-#include <mts/MTS_IO_CellularRadio.h>
#include <string>
#include <map>
+#include <mts/MTS_IO_ICellularRadio.h>
+
namespace MTS {
namespace IO {
-
- class HE910Radio;
- class GE910Radio;
- class DE910Radio;
- class CE910Radio;
- class CellularRadioFactory {
+ class EXPORT CellularRadioFactory {
public:
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);
+ ICellularRadio* create(const std::string& sModel, const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT);
+
+ ICellularRadio* createHE910D(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createHE910EUD(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910NAG(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910C4NF(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910NA1(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910SVG(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910EUG(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910C4EU(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910EU1(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910C1NS(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE910C1AP(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createME910C1NA(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createME910C1NV(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createME910C1WW(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createGE910(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createDE910(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createCE910(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createLE866A1JS(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
+ ICellularRadio* createEG95Radio(const std::string& sPort = ICellularRadio::DEFAULT_RADIO_PORT) const;
protected:
- typedef MTS::IO::CellularRadio* (CellularRadioFactory::*CREATEFUNCPTR)(const std::string& sPort);
+ typedef MTS::IO::ICellularRadio* (CellularRadioFactory::*CREATEFUNCPTR)(const std::string& sPort) const;
std::map< std::string, CREATEFUNCPTR > m_mCreationMap;
virtual std::string identifyRadio(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..f3021cc
--- /dev/null
+++ b/include/mts/MTS_IO_EG95Radio.h
@@ -0,0 +1,47 @@
+/*
+ * 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/>.
+ *
+ */
+
+
+#ifndef MTS_IO_EG95RADIO_H_
+#define MTS_IO_EG95RADIO_H_
+
+#include "mts/MTS_IO_QuectelRadio.h"
+
+namespace MTS {
+ namespace IO {
+
+ class EG95Radio : public QuectelRadio {
+
+ public:
+ static const std::string MODEL_NAME;
+
+ EG95Radio(const std::string& sPort);
+ virtual ~EG95Radio();
+ CODE setRxDiversity(const Json::Value& jArgs);
+
+ protected:
+
+ private:
+
+ };
+ }
+}
+
+#endif /* MTS_IO_EG95RADIO_H_ */
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..e2bf652
--- /dev/null
+++ b/include/mts/MTS_IO_ICellularRadio.h
@@ -0,0 +1,453 @@
+#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_SerialConnection.h>
+
+#define EXPORT __attribute__((visibility("default")))
+
+namespace MTS {
+ namespace IO {
+ class EXPORT ICellularRadio
+ {
+ public:
+ typedef std::function<bool(const std::string&/*iterationData*/, const std::string&/*allData*/)> IsNeedMoreData;
+ typedef std::function<void(const Json::Value&)> UpdateCb;
+
+ //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
+ };
+
+ enum RADIO_NETWORK_MODE : uint8_t {
+ RADIO_NETWORK_MODE_UNKNOWN = 0,
+ RADIO_NETWORK_MODE_AUTO,
+ RADIO_NETWORK_MODE_GSM_ONLY,
+ RADIO_NETWORK_MODE_UMTS_ONLY,
+ RADIO_NETWORK_MODE_LTE_ONLY
+ };
+
+ static CODE convertModelToType(const std::string& sModel, std::string& sType);
+ static CODE convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, ICellularRadio *radioObj = NULL);
+ static CODE convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd);
+ static CODE convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand);
+
+ 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 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);
+ 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);
+
+ static const char *DEFAULT_RADIO_PORT;
+ static const char *DEFAULT_RADIO_DIR;
+
+ static const char *VALUE_UNKNOWN;
+ static const char *VALUE_UNAVAILABLE;
+ static const char *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 char *RSP_OK;
+ static const char *RSP_ERROR;
+
+ static const char *VALUE_NOT_REGISTERED;
+ static const char *VALUE_REGISTERED;
+ static const char *VALUE_SEARCHING;
+ static const char *VALUE_DENIED;
+ static const char *VALUE_ROAMING;
+
+ //Static Data
+ static const char *KEY_TYPE; //!< GSM or CDMA
+ static const char *KEY_CODE; //!< Product Code : H5, H6, C2, EV3, G3
+ static const char *KEY_MODEL; //!< Model : HE910, CE910, DE910, GE910
+ static const char *KEY_MANUFACTURER; //!< Manufacturer: Telit
+ static const char *KEY_HARDWARE; //!< Radio Hardware Version
+ static const char *KEY_FIRMWARE; //!< Radio Firmware Version
+ static const char *KEY_FIRMWARE_BUILD;//!< Radio Firmware Build
+ static const char *KEY_IMEI; //!< International Mobile Station Equipment Identity
+ static const char *KEY_MEID; //!< Mobile Equipment Identifier
+ static const char *KEY_IMSI; //!< International Mobile Subscriber Identity
+ static const char *KEY_MSID; //!< Mobil Station ID (MSID) aka MIN aka MSIN aka Last few digits of IMSI
+ static const char *KEY_MDN; //!< Mobile Directory Number : Actual phone number dialed to reach radio
+ static const char *KEY_CARRIER; //!< Cellular Service Provider (Home Network)
+ static const char *KEY_ICCID; //!< Integrated Circuit Card Identifier
+ static const char *KEY_MSL; //!< Master Subsidy Lock
+
+
+ //Network Status Data
+ static const char *KEY_ROAMING; //!< Indicates whether or not using Home Network
+ static const char *KEY_DATETIME; //!< Date and Time from tower
+ static const char *KEY_SERVICE; //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO]
+ static const char *KEY_NETWORK; //!< Cellular Service Provider
+ static const char *KEY_NETWORK_REG; //!< Network Registration
+ static const char *KEY_CID; //!< Cellular ID (Tower) in HEX
+ static const char *KEY_LAC; //!< Location Area Code in HEX
+ static const char *KEY_RAC; //!< Routing Area Code in HEX
+ static const char *KEY_RSSI; //!< Received Signal Strength Indication
+ static const char *KEY_RSSIDBM; //!< Received Signal Strength Indication in dBm
+ static const char *KEY_MCC; //!< Mobile Country Code
+ static const char *KEY_MNC; //!< Mobile Network (Operator) Code
+ static const char *KEY_CHANNEL; //!< ARFCN or UARFCN Assigned Radio Channel
+ static const char *KEY_TXPWR; //!< Transmit Power
+ static const char *KEY_PSC; //!< Active Primary Synchronization Code (PSC)
+ static const char *KEY_ECIO; //!< Active Ec/Io (chip energy per total wideband power in dBm)
+ static const char *KEY_RSCP; //!< Active RSCP (Received Signal Code Power in dBm)
+ static const char *KEY_DRX; //!< Discontinuous reception cycle length (ms)
+ static const char *KEY_MM; //!< Mobility Management State
+ static const char *KEY_RR; //!< Radio Resource State
+ static const char *KEY_NOM; //!< Network Operator Mode
+ static const char *KEY_ABND; //!< Active Band
+ static const char *KEY_BLER; //!< Block Error Rate (percentage)
+ static const char *KEY_SD; //!< Service Domain
+ static const char *KEY_DEBUG; //!< Debug Information
+
+ static const char *KEY_MIP; //!< Mobile IP Information
+ static const char *KEY_MIP_ID; //!< MIP Profile ID
+ static const char *KEY_MIP_ENABLED; //!< MIP Profile Enabled/Disabled
+ static const char *KEY_MIP_NAI; //!< Network Access Identifier
+ static const char *KEY_MIP_HOMEADDRESS; //!< Home Address
+ static const char *KEY_MIP_PRIMARYHA; //!< Primary Home Agent
+ static const char *KEY_MIP_SECONDARYHA; //!< Secondary Home Agent
+ static const char *KEY_MIP_MNAAASPI; //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index
+ static const char *KEY_MIP_MNHASPI; //!< Mobile Node Home Agent Security Server Parameter Index
+ static const char *KEY_MIP_REVTUN; //!< Reverse Tunneling Enabled
+ static const char *KEY_MIP_MNAAASS; //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret
+ static const char *KEY_MIP_MNHASS; //!< Mobile Node Home Agent Shared Secret
+
+ //SIM Status Summary data
+ static const char *KEY_IS_SIM_INSERTED; //!< SIM card insertion indicator. True when a SIM card is inserted
+ static const char *KEY_IS_SIM_LOCKED; //!< SIM card lock status indicator. True when a SIM card is locked by PIN / PUK / other code
+ static const char *KEY_SIM_LOCK_STATUS; //!< SIM card lock status string. Either "READY", "SIM PIN", "SIM PUK" or other state
+ static const char *KEY_ATTEMPTS_PIN; //!< The number of attempts left to unlock the SIM card using PIN code
+ static const char *KEY_ATTEMPTS_PUK; //!< The number of attempts left to unlock the SIM card using PUK code
+
+ //Values - Type
+ static const char *VALUE_TYPE_LTE;
+ static const char *VALUE_TYPE_GSM;
+ static const char *VALUE_TYPE_CDMA;
+
+ //Values - Carrier
+ static const char *VALUE_CARRIER_VERIZON;
+ static const char *VALUE_CARRIER_AERIS;
+ static const char *VALUE_CARRIER_SPRINT;
+ static const char *VALUE_CARRIER_USCELLULAR;
+ static const char *VALUE_CARRIER_ATT;
+ static const char *VALUE_CARRIER_TMOBILE;
+
+ static const char *VALUE_SD_NO_SERVICE;
+ static const char *VALUE_SD_CS_ONLY;
+ static const char *VALUE_SD_PS_ONLY;
+ static const char *VALUE_SD_CSPS;
+
+ static const char *VALUE_ABND_GSM_850;
+ static const char *VALUE_ABND_GSM_900;
+ static const char *VALUE_ABND_DCS_1800;
+ static const char *VALUE_ABND_PCS_1900;
+
+ static const std::vector<std::string> DEFAULT_BAIL_STRINGS;
+
+ 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;
+
+ /**
+ * @brief getSimStatusSummary - get summary on the SIM card status
+ * (if there is a SIM card inserted, is it locked, etc).
+ * See below for the full list of returned fields.
+ *
+ * - `isSimInserted` - bool, is the SIM card installed or not;
+ * - `isSimLocked` - bool, is the SIM card blocked with PIN/PUK or not (or is READY);
+ * - `lockStatus` - string, either "READY", "SIM PUK", "SIM PIN" or other status as
+ * returned by "AT+CPIN?" AT command;
+ * - `attemptsPin` - integer, the number of attempts lef to enter a PIN code;
+ * - `attemptsPuk` - integer, the number of attempts lef to enter a PUK code.
+ *
+ * **Only `isSimInserted` is always present.** All other fields are omitted if
+ * the SIM card is removed.
+ *
+ * @param jData - an object to be filled with data
+ * @return CODE::SUCCESS on success,
+ * CODE::NOT_APPLICABLE if not supported by this radio
+ * and CODE::ERROR otherwise
+ */
+ virtual CODE getSimStatusSummary(Json::Value& jData) = 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;
+
+ /**
+ * @brief unlockSimCard - unlock the SIM card using PIN code provided
+ *
+ * This command does not peform any checks on the number of attempts left.
+ * Use with caution, verify the SIM status manually before execution.
+ *
+ * @param jArgs - a JSON object with the following format:
+ *
+ * jArgs = {
+ * "pin" : "A correct PIN code to unlock the SIM card: STRING"
+ * }
+ *
+ * @return CODE::SUCCESS when SIM card was succeffully unlocked,
+ * CODE::INVALID_ARGS when passed arguments are invalid,
+ * CODE::ERROR otherwise (i.e. when modem is not responding,
+ * when SIM card is removed, when PIN code is not correct
+ * or on any other error).
+ */
+ virtual CODE unlockSimCard(const Json::Value& jArgs) = 0;
+ virtual CODE getRadioNetworkMode(RADIO_NETWORK_MODE &mode) = 0;
+ virtual CODE setRadioNetworkMode(RADIO_NETWORK_MODE mode) = 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_ME910C1WWRadio.h b/include/mts/MTS_IO_ME910C1WWRadio.h
index bfbb8a6..d45d86a 100644
--- a/include/mts/MTS_IO_ME910C1WWRadio.h
+++ b/include/mts/MTS_IO_ME910C1WWRadio.h
@@ -33,8 +33,8 @@ namespace MTS {
ME910C1WWRadio(const std::string& sPort);
virtual ~ME910C1WWRadio(){};
- CellularRadio::CODE setActiveFirmware(const Json::Value& jArgs);
- CellularRadio::CODE getActiveFirmware(std::string& sFwId);
+ ICellularRadio::CODE setActiveFirmware(const Json::Value& jArgs);
+ ICellularRadio::CODE getActiveFirmware(std::string& sFwId);
protected:
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..3b1ba5a
--- /dev/null
+++ b/include/mts/MTS_IO_QuectelRadio.h
@@ -0,0 +1,62 @@
+/*
+ * 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/>.
+ *
+ */
+
+#ifndef MTS_IO_QUECTELRADIO_H_
+#define MTS_IO_QUECTELRADIO_H_
+
+#include <mts/MTS_IO_CellularRadio.h>
+
+namespace MTS {
+ namespace IO {
+
+ class QuectelRadio : public CellularRadio {
+
+ public:
+ bool resetRadio(uint32_t iTimeoutMillis = 5000) override;
+
+ CODE getModel(std::string& sModel) override;
+ CODE getIccid(std::string& sIccid) override;
+ CODE getService(std::string& sService) override;
+ CODE getNetwork(std::string& sNetwork) override;
+ CODE getNetworkStatus(Json::Value& jData) override;
+
+ CODE convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& dBm) override;
+ CODE convertdBmToSignalStrength(const int32_t& dBm, int32_t& iRssi) override;
+
+ CODE setMdn(const Json::Value& jArgs) override;
+ CODE getRadioNetworkMode(RADIO_NETWORK_MODE &mode) override;
+ CODE setRadioNetworkMode(RADIO_NETWORK_MODE mode) override;
+
+ protected:
+ QuectelRadio(const std::string& sName, const std::string& sRadioPort);
+
+ CODE getIsSimInserted(bool& bData) override;
+ CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) override;
+
+ virtual CODE getServiceDomain(SERVICEDOMAIN& sd);
+ virtual CODE convertToActiveBand(const std::string& sQuectelBand, ACTIVEBAND& band);
+
+ private:
+
+ };
+ }
+}
+
+#endif /* MTS_IO_QUECTELRADIO_H_ */
diff --git a/include/mts/MTS_IO_TelitRadio.h b/include/mts/MTS_IO_TelitRadio.h
new file mode 100644
index 0000000..6382696
--- /dev/null
+++ b/include/mts/MTS_IO_TelitRadio.h
@@ -0,0 +1,60 @@
+/*
+ * 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/>.
+ *
+ */
+
+#ifndef MTS_IO_TELITRADIO_H_
+#define MTS_IO_TELITRADIO_H_
+
+#include <mts/MTS_IO_CellularRadio.h>
+
+namespace MTS {
+ namespace IO {
+ class TelitRadio : public CellularRadio {
+ public:
+ bool resetRadio(uint32_t iTimeoutMillis = 5000) override;
+
+ CODE getModel(std::string& sModel) override;
+ CODE getIccid(std::string& sIccid) override;
+ CODE getService(std::string& sService) override;
+ CODE getNetwork(std::string& sNetwork) override;
+ CODE getNetworkStatus(Json::Value& jData) override;
+
+ CODE convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& dBm) override;
+ CODE convertdBmToSignalStrength(const int32_t& dBm, int32_t& iRssi) override;
+
+ CODE setMdn(const Json::Value& jArgs) override;
+ CODE getRadioNetworkMode(RADIO_NETWORK_MODE &mode) override;
+ CODE setRadioNetworkMode(RADIO_NETWORK_MODE mode) override;
+
+ protected:
+ TelitRadio(const std::string& sName, const std::string& sRadioPort);
+
+ bool getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier) override;
+ bool getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware) override;
+
+ CODE getIsSimInserted(bool& bData) override;
+ CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) override;
+
+ private:
+ virtual CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk, const std::string& sLockStatus);
+
+ };
+ }
+}
+#endif
diff --git a/src/MTS_IO_CE910Radio.cpp b/src/MTS_IO_CE910Radio.cpp
index 7bdf280..d1cad9b 100644
--- a/src/MTS_IO_CE910Radio.cpp
+++ b/src/MTS_IO_CE910Radio.cpp
@@ -39,7 +39,7 @@ CE910Radio::CE910Radio(const std::string& sPort)
}
-CellularRadio::CODE CE910Radio::setRxDiversity(const Json::Value& jArgs) {
+ICellularRadio::CODE CE910Radio::setRxDiversity(const Json::Value& jArgs) {
/* Command string for CE radios: N/A */
return FAILURE;
}
diff --git a/src/MTS_IO_CdmaRadio.cpp b/src/MTS_IO_CdmaRadio.cpp
index 5b53f02..f84fd34 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)
{
}
@@ -44,17 +44,17 @@ CdmaRadio::~CdmaRadio() {
}
-CellularRadio::CODE CdmaRadio::getImei(std::string& sImei) {
+ICellularRadio::CODE CdmaRadio::getImei(std::string& sImei) {
printTrace("%s| Get IMEI", getName().c_str());
return getMeid(sImei);
}
-CellularRadio::CODE CdmaRadio::getMeid(std::string& sMeid) {
+ICellularRadio::CODE CdmaRadio::getMeid(std::string& sMeid) {
printTrace("%s| Get MEID", getName().c_str());
- sMeid = VALUE_NOT_SUPPORTED;
+ sMeid = ICellularRadio::VALUE_NOT_SUPPORTED;
std::string sCmd("AT#MEIDESN?");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t pos = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t pos = sResult.find(ICellularRadio::RSP_OK);
if (pos == std::string::npos) {
printWarning("%s| Unable to get MEID from radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -72,12 +72,12 @@ CellularRadio::CODE CdmaRadio::getMeid(std::string& sMeid) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::getMsid(std::string& sMsid) {
+ICellularRadio::CODE CdmaRadio::getMsid(std::string& sMsid) {
printTrace("%s| Get MSID", getName().c_str());
- sMsid = VALUE_NOT_SUPPORTED;
+ sMsid = ICellularRadio::VALUE_NOT_SUPPORTED;
std::string sCmd("AT$MSID?");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to get MSID from radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -92,14 +92,14 @@ CellularRadio::CODE CdmaRadio::getMsid(std::string& sMsid) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::getCarrier(std::string& sCarrier) {
+ICellularRadio::CODE CdmaRadio::getCarrier(std::string& sCarrier) {
if(m_sCarrier != "") {
sCarrier = m_sCarrier;
return SUCCESS;
}
std::string sFirmware;
- CODE code = getFirmware(sFirmware);
+ ICellularRadio::CODE code = getFirmware(sFirmware);
if(code != SUCCESS) {
return code;
}
@@ -113,34 +113,34 @@ CellularRadio::CODE CdmaRadio::getCarrier(std::string& sCarrier) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::getNetwork(std::string& sNetwork) {
+ICellularRadio::CODE CdmaRadio::getNetwork(std::string& sNetwork) {
return getCarrier(sNetwork);
}
-CellularRadio::CODE CdmaRadio::getSimStatus(std::string& sSimStatus) {
+ICellularRadio::CODE CdmaRadio::getSimStatus(std::string& sSimStatus) {
printTrace("%s| Get SIM Status", getName().c_str());
- sSimStatus = VALUE_NOT_SUPPORTED;
+ sSimStatus = ICellularRadio::VALUE_NOT_SUPPORTED;
return NOT_APPLICABLE;
}
-CellularRadio::CODE CdmaRadio::getIccid(std::string& sIccid) {
+ICellularRadio::CODE CdmaRadio::getIccid(std::string& sIccid) {
printTrace("%s| Get ICCID", getName().c_str());
- sIccid = VALUE_NOT_SUPPORTED;
+ sIccid = ICellularRadio::VALUE_NOT_SUPPORTED;
return NOT_APPLICABLE;
}
-CellularRadio::CODE CdmaRadio::getLac(std::string& sLac) {
+ICellularRadio::CODE CdmaRadio::getLac(std::string& sLac) {
printTrace("%s| Get LAC", getName().c_str());
- sLac = VALUE_NOT_SUPPORTED;
+ sLac = ICellularRadio::VALUE_NOT_SUPPORTED;
return NOT_APPLICABLE;
}
-CellularRadio::CODE CdmaRadio::getService(std::string& sService) {
+ICellularRadio::CODE CdmaRadio::getService(std::string& sService) {
printTrace("%s| Get Service", getName().c_str());
- sService = VALUE_NOT_SUPPORTED;
+ sService = ICellularRadio::VALUE_NOT_SUPPORTED;
std::string sCmd("AT+SERVICE?");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to get Service from radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -159,7 +159,7 @@ CellularRadio::CODE CdmaRadio::getService(std::string& sService) {
case 2: sService = "EVDO"; break; //Release 0
case 3: sService = "EVDO"; break; //Release A
case 4: sService = "GPRS"; break;
- default: sService = VALUE_UNKNOWN; break;
+ default: sService = ICellularRadio::VALUE_UNKNOWN; break;
}
printDebug("%s| Service ID: [%d][%s]", getName().c_str(), iService, sService.c_str());
@@ -167,12 +167,12 @@ CellularRadio::CODE CdmaRadio::getService(std::string& sService) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::getHardware(std::string& sHardware) {
+ICellularRadio::CODE CdmaRadio::getHardware(std::string& sHardware) {
printTrace("%s| Get Hardware", getName().c_str());
- sHardware = VALUE_NOT_SUPPORTED;
+ sHardware = ICellularRadio::VALUE_NOT_SUPPORTED;
std::string sCmd("AT#HWREV");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t pos = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t pos = sResult.find(ICellularRadio::RSP_OK);
if (pos == std::string::npos) {
printWarning("%s| Unable to get hardware from radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -187,12 +187,12 @@ CellularRadio::CODE CdmaRadio::getHardware(std::string& sHardware) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::getMdn(std::string& sMdn) {
+ICellularRadio::CODE CdmaRadio::getMdn(std::string& sMdn) {
printTrace("%s| Get MDN", getName().c_str());
- sMdn = VALUE_NOT_SUPPORTED;
+ sMdn = ICellularRadio::VALUE_NOT_SUPPORTED;
std::string sCmd("AT+CNUM");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to get MDN from radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -213,7 +213,7 @@ CellularRadio::CODE CdmaRadio::getMdn(std::string& sMdn) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::validateMsl(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::validateMsl(const Json::Value& jArgs) {
printTrace("%s| Validate MSL", getName().c_str());
if(!jArgs["msl"].isString()) {
@@ -239,7 +239,7 @@ CellularRadio::CODE CdmaRadio::validateMsl(const Json::Value& jArgs) {
return setMdn(jMdn);
}
-CellularRadio::CODE CdmaRadio::setMdn(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMdn(const Json::Value& jArgs) {
printTrace("%s| Set MDN", getName().c_str());
if(!jArgs["mdn"].isString()) {
@@ -274,7 +274,7 @@ CellularRadio::CODE CdmaRadio::setMdn(const Json::Value& jArgs) {
sCmd += sMdn;
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set MDN for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -283,7 +283,7 @@ CellularRadio::CODE CdmaRadio::setMdn(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMsid(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMsid(const Json::Value& jArgs) {
printTrace("%s| Set MSID", getName().c_str());
if(!jArgs["msid"].isString()) {
printError("%s| Arguments missing \"msid\"", getName().c_str());
@@ -309,7 +309,7 @@ CellularRadio::CODE CdmaRadio::setMsid(const Json::Value& jArgs) {
sCmd += jArgs["msid"].asString();
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set MSID for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -318,7 +318,7 @@ CellularRadio::CODE CdmaRadio::setMsid(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
+ICellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
printTrace("%s| Get MIP Active Profile", getName().c_str());
initMipProfile(jMipProfile);
@@ -329,7 +329,7 @@ CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
if(sCarrier == "Aeris" || sCarrier == "Sprint") {
std::string sCmd("AT$QCMIPGETP");
std::string sResult = MTS::Text::trim(sendCommand(sCmd));
- if (sResult.find(RSP_OK) == std::string::npos) {
+ if (sResult.find(ICellularRadio::RSP_OK) == std::string::npos) {
printWarning("%s| Unable to get active MIP profile for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
}
@@ -341,34 +341,34 @@ CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
std::vector<std::string> vParts = MTS::Text::split(sLine, ':', 2);
if(vParts.size() == 2 && vParts[0] == "Profile") {
if(vParts[1].find("Enabled") != std::string::npos) {
- jMipProfile[KEY_MIP_ENABLED] = true;
+ jMipProfile[ICellularRadio::KEY_MIP_ENABLED] = true;
} else {
- jMipProfile[KEY_MIP_ENABLED] = false;
+ jMipProfile[ICellularRadio::KEY_MIP_ENABLED] = false;
}
int32_t id;
sscanf(vParts[1].c_str(), "%d", &id);
- jMipProfile[KEY_MIP_ID] = id;
+ jMipProfile[ICellularRadio::KEY_MIP_ID] = id;
} else {
printWarning("%s| Unable to parse active MIP profile from line [%s]", getName().c_str(), sLine.c_str());
}
- splitAndAssign(vLine[1], "NAI", jMipProfile, KEY_MIP_NAI);
- splitAndAssign(vLine[2], "Home Addr", jMipProfile, KEY_MIP_HOMEADDRESS);
- splitAndAssign(vLine[3], "Primary HA", jMipProfile, KEY_MIP_PRIMARYHA);
- splitAndAssign(vLine[4], "Secondary HA", jMipProfile, KEY_MIP_SECONDARYHA);
- splitAndAssign(vLine[5], "MN-AAA SPI", jMipProfile, KEY_MIP_MNAAASPI);
- splitAndAssign(vLine[6], "MN-HA SPI", jMipProfile, KEY_MIP_MNHASPI);
+ splitAndAssign(vLine[1], "NAI", jMipProfile, ICellularRadio::KEY_MIP_NAI);
+ splitAndAssign(vLine[2], "Home Addr", jMipProfile, ICellularRadio::KEY_MIP_HOMEADDRESS);
+ splitAndAssign(vLine[3], "Primary HA", jMipProfile, ICellularRadio::KEY_MIP_PRIMARYHA);
+ splitAndAssign(vLine[4], "Secondary HA", jMipProfile, ICellularRadio::KEY_MIP_SECONDARYHA);
+ splitAndAssign(vLine[5], "MN-AAA SPI", jMipProfile, ICellularRadio::KEY_MIP_MNAAASPI);
+ splitAndAssign(vLine[6], "MN-HA SPI", jMipProfile, ICellularRadio::KEY_MIP_MNHASPI);
//Reverse Tunneling
sLine = vLine[7];
vParts = MTS::Text::split(sLine, ':', 2);
if(vParts.size() == 2 && vParts[0] == "Rev Tun") {
if(vParts[1] == "1") {
- jMipProfile[KEY_MIP_REVTUN] = true;
+ jMipProfile[ICellularRadio::KEY_MIP_REVTUN] = true;
} else {
- jMipProfile[KEY_MIP_REVTUN] = false;
+ jMipProfile[ICellularRadio::KEY_MIP_REVTUN] = false;
}
} else {
printWarning("%s| Unable to parse Reverse Tunneling from line [%s]", getName().c_str(), sLine.c_str());
@@ -379,9 +379,9 @@ CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
vParts = MTS::Text::split(sLine, ':', 2);
if(vParts.size() == 2 && vParts[0] == "MN-AAA SS") {
if(vParts[1] == "Set") {
- jMipProfile[KEY_MIP_MNAAASS] = true;
+ jMipProfile[ICellularRadio::KEY_MIP_MNAAASS] = true;
} else {
- jMipProfile[KEY_MIP_MNAAASS] = false;
+ jMipProfile[ICellularRadio::KEY_MIP_MNAAASS] = false;
}
} else {
printWarning("%s| Unable to parse MN-AAA SS from line [%s]", getName().c_str(), sLine.c_str());
@@ -392,9 +392,9 @@ CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
vParts = MTS::Text::split(sLine, ':', 2);
if(vParts.size() == 2 && vParts[0] == "MN-HA SS") {
if(vParts[1] == "Set") {
- jMipProfile[KEY_MIP_MNHASS] = true;
+ jMipProfile[ICellularRadio::KEY_MIP_MNHASS] = true;
} else {
- jMipProfile[KEY_MIP_MNHASS] = false;
+ jMipProfile[ICellularRadio::KEY_MIP_MNHASS] = false;
}
} else {
printWarning("%s| Unable to parse MN-HA SS from line [%s]", getName().c_str(), sLine.c_str());
@@ -406,7 +406,7 @@ CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
}
-CellularRadio::CODE CdmaRadio::setMipActiveProfile(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipActiveProfile(const Json::Value& jArgs) {
printTrace("%s| Set MIP Active Profile", getName().c_str());
if(!jArgs["activeProfile"].isString()) {
@@ -417,7 +417,7 @@ CellularRadio::CODE CdmaRadio::setMipActiveProfile(const Json::Value& jArgs) {
sCmd += jArgs["activeProfile"].asString();
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set Active profile for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -426,7 +426,7 @@ CellularRadio::CODE CdmaRadio::setMipActiveProfile(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipNai(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipNai(const Json::Value& jArgs) {
printTrace("%s| Set MIP NAI", getName().c_str());
if(!jArgs["nai"].isString()) {
@@ -437,7 +437,7 @@ CellularRadio::CODE CdmaRadio::setMipNai(const Json::Value& jArgs) {
sCmd += jArgs["nai"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set NAI for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -446,7 +446,7 @@ CellularRadio::CODE CdmaRadio::setMipNai(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipHomeIp(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipHomeIp(const Json::Value& jArgs) {
printTrace("%s| Set MIP Home IP", getName().c_str());
if(!jArgs["homeIp"].isString()) {
@@ -457,7 +457,7 @@ CellularRadio::CODE CdmaRadio::setMipHomeIp(const Json::Value& jArgs) {
sCmd += jArgs["homeIp"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set Home IP profile for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -466,7 +466,7 @@ CellularRadio::CODE CdmaRadio::setMipHomeIp(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipPrimaryHa(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipPrimaryHa(const Json::Value& jArgs) {
printTrace("%s| Set MIP Primary HA", getName().c_str());
if(!jArgs["primaryHa"].isString()) {
@@ -477,7 +477,7 @@ CellularRadio::CODE CdmaRadio::setMipPrimaryHa(const Json::Value& jArgs) {
sCmd += jArgs["primaryHa"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set Primary HA for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -486,7 +486,7 @@ CellularRadio::CODE CdmaRadio::setMipPrimaryHa(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipSecondaryHa(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipSecondaryHa(const Json::Value& jArgs) {
printTrace("%s| Set MIP Secondary HA", getName().c_str());
if(!jArgs["secondaryHa"].isString()) {
@@ -497,7 +497,7 @@ CellularRadio::CODE CdmaRadio::setMipSecondaryHa(const Json::Value& jArgs) {
sCmd += jArgs["secondaryHa"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set Secondary HA for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -506,7 +506,7 @@ CellularRadio::CODE CdmaRadio::setMipSecondaryHa(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipMnAaaSpi(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipMnAaaSpi(const Json::Value& jArgs) {
printTrace("%s| Set MIP MN-AAA SPI", getName().c_str());
if(!jArgs["mnAaaSpi"].isString()) {
@@ -517,7 +517,7 @@ CellularRadio::CODE CdmaRadio::setMipMnAaaSpi(const Json::Value& jArgs) {
sCmd += jArgs["mnAaaSpi"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set MN-AAA SPI for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -526,7 +526,7 @@ CellularRadio::CODE CdmaRadio::setMipMnAaaSpi(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipMnHaSpi(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipMnHaSpi(const Json::Value& jArgs) {
printTrace("%s| Set MIP MN-HA SPI", getName().c_str());
if(!jArgs["mnHaSpi"].isString()) {
@@ -537,7 +537,7 @@ CellularRadio::CODE CdmaRadio::setMipMnHaSpi(const Json::Value& jArgs) {
sCmd += jArgs["mnHaSpi"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set MN-HA SPI for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -546,7 +546,7 @@ CellularRadio::CODE CdmaRadio::setMipMnHaSpi(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipRevTun(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipRevTun(const Json::Value& jArgs) {
printTrace("%s| Set MIP Rev Tun", getName().c_str());
if(!jArgs["revTun"].isString()) {
@@ -557,7 +557,7 @@ CellularRadio::CODE CdmaRadio::setMipRevTun(const Json::Value& jArgs) {
sCmd += jArgs["revTun"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set Rev Tun for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -566,7 +566,7 @@ CellularRadio::CODE CdmaRadio::setMipRevTun(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipMnAaaSs(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipMnAaaSs(const Json::Value& jArgs) {
printTrace("%s| Set MIP MN-AAA SS", getName().c_str());
if(!jArgs["mnAaaSs"].isString()) {
@@ -577,7 +577,7 @@ CellularRadio::CODE CdmaRadio::setMipMnAaaSs(const Json::Value& jArgs) {
sCmd += jArgs["mnAaaSs"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set MN-AAA SS for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -586,7 +586,7 @@ CellularRadio::CODE CdmaRadio::setMipMnAaaSs(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::setMipMnHaSs(const Json::Value& jArgs) {
+ICellularRadio::CODE CdmaRadio::setMipMnHaSs(const Json::Value& jArgs) {
printTrace("%s| Set MIP MN-HA SS", getName().c_str());
if(!jArgs["mnHaSs"].isString()) {
@@ -597,7 +597,7 @@ CellularRadio::CODE CdmaRadio::setMipMnHaSs(const Json::Value& jArgs) {
sCmd += jArgs["mnHaSs"].asString() + ",1";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to set MN-HA SS for radio using command [%s]", getName().c_str(), sCmd.c_str());
return FAILURE;
@@ -606,7 +606,7 @@ CellularRadio::CODE CdmaRadio::setMipMnHaSs(const Json::Value& jArgs) {
return SUCCESS;
}
-CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) {
printTrace("%s| Update Device Configuration", getName().c_str());
std::string sCarrier;
@@ -616,7 +616,7 @@ CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& step
return NOT_APPLICABLE;
}
- CellularRadio::CODE result = FAILURE;
+ ICellularRadio::CODE result = FAILURE;
std::size_t pos = 0;
std::size_t end = 0;
@@ -627,7 +627,7 @@ CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& step
return true;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
printTrace("%s| Update DC Callback Started", this->getName().c_str());
while(end != std::string::npos) {
@@ -683,7 +683,7 @@ CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& step
stepCb(Json::Value("DC Error: update fails with other reasons"));
}
return false;
- }else if(sLine == RSP_ERROR) {
+ }else if(sLine == ICellularRadio::RSP_ERROR) {
result = ERROR;
return false;
}
@@ -692,7 +692,7 @@ CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& step
if(next != std::string::npos) {
pos = next;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
}
printTrace("%s| Update DC Callback Finished", this->getName().c_str());
@@ -703,7 +703,7 @@ CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& step
return result;
}
-CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) {
printTrace("%s| Update Preferred Roaming List", getName().c_str());
std::string sCarrier;
@@ -713,7 +713,7 @@ CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& ste
return NOT_APPLICABLE;
}
- CellularRadio::CODE result = FAILURE;
+ ICellularRadio::CODE result = FAILURE;
std::size_t pos = 0;
std::size_t end = 0;
@@ -724,7 +724,7 @@ CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& ste
return true;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
printTrace("%s| Update PRL Callback Started", this->getName().c_str());
while(end != std::string::npos) {
@@ -780,7 +780,7 @@ CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& ste
stepCb(Json::Value("PRL Error: update fails with other reasons"));
}
return false;
- } else if(sLine == RSP_ERROR) {
+ } else if(sLine == ICellularRadio::RSP_ERROR) {
result = ERROR;
return false;
}
@@ -789,7 +789,7 @@ CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& ste
if(next != std::string::npos) {
pos = next;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
}
printTrace("%s| Update PRL Callback Finished", this->getName().c_str());
@@ -800,7 +800,7 @@ CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& ste
return result;
}
-CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) {
printTrace("%s| Update Firmware Update Management Object", getName().c_str());
std::string sCarrier;
@@ -810,7 +810,7 @@ CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& st
return NOT_APPLICABLE;
}
- CellularRadio::CODE result = FAILURE;
+ ICellularRadio::CODE result = FAILURE;
std::size_t pos = 0;
std::size_t end = 0;
@@ -821,7 +821,7 @@ CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& st
return true;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
printTrace("%s| Update FUMO Callback Started", this->getName().c_str());
while(end != std::string::npos) {
@@ -937,7 +937,7 @@ CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& st
if(stepCb) {
stepCb(Json::Value("FUMO Info: reporting of firmware update result to server"));
}
- } else if(sLine == RSP_ERROR) {
+ } else if(sLine == ICellularRadio::RSP_ERROR) {
result = ERROR;
return false;
}
@@ -946,7 +946,7 @@ CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& st
if(next != std::string::npos) {
pos = next;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
}
printTrace("%s| Update FUMO Callback Finished", this->getName().c_str());
@@ -957,7 +957,7 @@ CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& st
return result;
}
-CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) {
printTrace("%s| HFA Reset (after device reboot HFA will occur)", getName().c_str());
std::string sCarrier;
@@ -971,7 +971,7 @@ CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& step
return INVALID_ARGS;
}
- CellularRadio::CODE result = FAILURE;
+ ICellularRadio::CODE result = FAILURE;
std::size_t pos = 0;
std::size_t end = 0;
@@ -992,7 +992,7 @@ CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& step
return true;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
printTrace("%s| HFA Reset Callback Started", this->getName().c_str());
while(end != std::string::npos) {
@@ -1032,10 +1032,10 @@ CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& step
stepCb(Json::Value("RTN Done: Firmware DM - Session Completed Successfully"));
}
return false;
- } else if(sLine == RSP_ERROR) {
+ } else if(sLine == ICellularRadio::RSP_ERROR) {
result = ERROR;
return false;
- } else if(sLine == RSP_OK) {
+ } else if(sLine == ICellularRadio::RSP_OK) {
//The Device will reboot now, so reset the connection
if(stepCb) {
stepCb(Json::Value("RTN Info: Resetting Radio"));
@@ -1062,7 +1062,7 @@ CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& step
if(next != std::string::npos) {
pos = next;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
}
printTrace("%s| HFA Reset Callback Finished", this->getName().c_str());
@@ -1075,14 +1075,14 @@ CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& step
return result;
}
-CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) {
printTrace("%s| Activation", getName().c_str());
std::string sActivationCmd;
std::string sCarrier;
getCarrier(sCarrier);
- if(sCarrier == VALUE_CARRIER_AERIS) {
+ if(sCarrier == ICellularRadio::VALUE_CARRIER_AERIS) {
if(!jArgs["msid"].isString()) {
printError("%s| Arguments missing \"msid\"", getName().c_str());
@@ -1107,7 +1107,7 @@ CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& step
}
//Set MDN & MSID
- CellularRadio::CODE code;
+ ICellularRadio::CODE code;
code = setMdn(jArgs);
if(code != SUCCESS) {
return code;
@@ -1122,15 +1122,15 @@ CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& step
return SUCCESS;
- } else if(sCarrier == VALUE_CARRIER_VERIZON) {
+ } else if(sCarrier == ICellularRadio::VALUE_CARRIER_VERIZON) {
sActivationCmd = "AT+CDV*22899\r";
- } else if(sCarrier == VALUE_CARRIER_USCELLULAR) {
+ } else if(sCarrier == ICellularRadio::VALUE_CARRIER_USCELLULAR) {
sActivationCmd = "AT+CDV*228\r";
} else {
return NOT_APPLICABLE;
}
- CellularRadio::CODE result = FAILURE;
+ ICellularRadio::CODE result = FAILURE;
std::size_t pos = 0;
std::size_t end = 0;
@@ -1153,7 +1153,7 @@ CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& step
return true;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
printTrace("%s| Activation Reset Callback Started", this->getName().c_str());
while(end != std::string::npos) {
@@ -1162,7 +1162,7 @@ CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& step
printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str());
- if(sLine == RSP_OK) {
+ if(sLine == ICellularRadio::RSP_OK) {
if(stepCb) {
stepCb(Json::Value("Activation Info: Over-the-Air Programming in Process"));
}
@@ -1194,7 +1194,7 @@ CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& step
}
result = ERROR;
return false;
- } else if(sLine == RSP_ERROR) {
+ } else if(sLine == ICellularRadio::RSP_ERROR) {
result = ERROR;
return false;
}
@@ -1203,7 +1203,7 @@ CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& step
if(next != std::string::npos) {
pos = next;
}
- end = allData.find(NL, pos);
+ end = allData.find(ICellularRadio::NL, pos);
}
printTrace("%s| Activation Callback Finished", this->getName().c_str());
@@ -1214,7 +1214,7 @@ CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& step
return result;
}
-CellularRadio::CODE CdmaRadio::getNetworkStatus(Json::Value& jData) {
+ICellularRadio::CODE CdmaRadio::getNetworkStatus(Json::Value& jData) {
printTrace("%s| Get Network Status", getName().c_str());
getCommonNetworkStats(jData);
@@ -1222,11 +1222,11 @@ CellularRadio::CODE CdmaRadio::getNetworkStatus(Json::Value& jData) {
std::string sCarrier;
getCarrier(sCarrier);
- if(sCarrier == VALUE_CARRIER_SPRINT) {
+ if(sCarrier == ICellularRadio::VALUE_CARRIER_SPRINT) {
Json::Value& jDebug = jData["debug"];
std::string sCmd("AT$DEBUG?");
std::string sResult = MTS::Text::trim(sendCommand(sCmd));
- if (sResult.find(RSP_OK) != std::string::npos) {
+ if (sResult.find(ICellularRadio::RSP_OK) != std::string::npos) {
std::vector<std::string> vCategories = MTS::Text::split(sResult, "\r\n\r\n");
for(size_t i = 0 ; i < vCategories.size(); i++) {
std::vector<std::string> vLine = MTS::Text::split(vCategories[i], "\r\n");
diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp
index f89e673..3f0c037 100644
--- a/src/MTS_IO_CellularRadio.cpp
+++ b/src/MTS_IO_CellularRadio.cpp
@@ -18,125 +18,74 @@
*
*/
-#include <mts/MTS_IO_CellularRadio.h>
+#include "mts/MTS_IO_CellularRadio.h"
+
+#include <unistd.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 };
+namespace {
+ typedef struct
+ {
+ const char *name;
+ int32_t low;
+ int32_t high;
+ } *pNameRangeMap, nameRangeMap;
+
+ const unsigned int NUM_GSM_BANDS = 7;
+ const unsigned int NUM_WCDMA_BANDS = 6;
+ const unsigned int NUM_LTE_BANDS = 42;
+
+ // http://niviuk.free.fr/gsm_band.php
+ 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
+ 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
+ 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}
+ };
+}
CellularRadio::CellularRadio(const std::string& sName, const std::string& sRadioPort)
: m_sName(sName)
@@ -164,7 +113,7 @@ bool CellularRadio::initialize(uint32_t iTimeoutMillis) {
}
bool bEnabled;
- CODE eCode = getEcho(bEnabled);
+ ICellularRadio::CODE eCode = getEcho(bEnabled);
if(eCode == SUCCESS && bEnabled) {
printDebug("%s| Disabling 'echo'", m_sName.c_str());
setEcho(false);
@@ -174,20 +123,6 @@ bool CellularRadio::initialize(uint32_t iTimeoutMillis) {
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()) {
@@ -238,211 +173,12 @@ 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) {
+ICellularRadio::CODE CellularRadio::getFirmware(std::string& sFirmware) {
printTrace("%s| Get Firmware", m_sName.c_str());
- sFirmware = VALUE_NOT_SUPPORTED;
+ sFirmware = ICellularRadio::VALUE_NOT_SUPPORTED;
std::string sCmd("AT+CGMR");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t pos = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t pos = sResult.find(ICellularRadio::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;
@@ -459,14 +195,14 @@ CellularRadio::CODE CellularRadio::getFirmware(std::string& sFirmware) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::getFirmwareBuild(std::string& sFirmwareBuild) {
- sFirmwareBuild = VALUE_NOT_SUPPORTED;
+ICellularRadio::CODE CellularRadio::getFirmwareBuild(std::string& sFirmwareBuild) {
+ sFirmwareBuild = ICellularRadio::VALUE_NOT_SUPPORTED;
return FAILURE;
}
-CellularRadio::CODE CellularRadio::getHardware(std::string& sHardware) {
+ICellularRadio::CODE CellularRadio::getHardware(std::string& sHardware) {
printTrace("%s| Get Hardware", m_sName.c_str());
- sHardware = VALUE_NOT_SUPPORTED;
+ sHardware = ICellularRadio::VALUE_NOT_SUPPORTED;
if(m_sFirmware.size() == 0) {
getFirmware(m_sFirmware);
@@ -478,12 +214,12 @@ CellularRadio::CODE CellularRadio::getHardware(std::string& sHardware) {
return FAILURE;
}
-CellularRadio::CODE CellularRadio::getManufacturer(std::string& sManufacturer) {
+ICellularRadio::CODE CellularRadio::getManufacturer(std::string& sManufacturer) {
printTrace("%s| Get Manufacturer", m_sName.c_str());
- sManufacturer = VALUE_NOT_SUPPORTED;
+ sManufacturer = ICellularRadio::VALUE_NOT_SUPPORTED;
std::string sCmd("AT+GMI");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t pos = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t pos = sResult.find(ICellularRadio::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;
@@ -498,12 +234,15 @@ CellularRadio::CODE CellularRadio::getManufacturer(std::string& sManufacturer) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::getImei(std::string& sImei) {
+ICellularRadio::CODE CellularRadio::getImei(std::string& sImei) {
printTrace("%s| Get IMEI", m_sName.c_str());
- sImei = VALUE_NOT_SUPPORTED;
+ sImei = ICellularRadio::VALUE_NOT_SUPPORTED;
+
+ // AT+CGSN execution can take up to 300ms according to the Quectel datasheet. Setting timeout to 500ms just for sure.
std::string sCmd("AT+CGSN");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t pos = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
+ size_t pos = sResult.find(ICellularRadio::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;
@@ -518,17 +257,20 @@ CellularRadio::CODE CellularRadio::getImei(std::string& sImei) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::getMeid(std::string& sMeid) {
+ICellularRadio::CODE CellularRadio::getMeid(std::string& sMeid) {
printTrace("%s| Get MEID", m_sName.c_str());
return getImei(sMeid);
}
-CellularRadio::CODE CellularRadio::getImsi(std::string& sImsi) {
+ICellularRadio::CODE CellularRadio::getImsi(std::string& sImsi) {
printTrace("%s| Get IMSI", m_sName.c_str());
- sImsi = VALUE_NOT_SUPPORTED;
+ sImsi = ICellularRadio::VALUE_NOT_SUPPORTED;
+
+ // AT+CIMI execution can take up to 300ms according to the Quectel datasheet. Setting timeout to 500ms just for sure.
std::string sCmd("AT+CIMI");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t pos = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
+ size_t pos = sResult.find(ICellularRadio::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;
@@ -543,76 +285,65 @@ CellularRadio::CODE CellularRadio::getImsi(std::string& sImsi) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::getSimStatus(std::string& sSimStatus) {
+ICellularRadio::CODE CellularRadio::getSimStatus(std::string& sSimStatus) {
printTrace("%s| Get SIM Status", getName().c_str());
- sSimStatus = VALUE_UNKNOWN;
+ sSimStatus = ICellularRadio::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;
- }
+ICellularRadio::CODE CellularRadio::getSimStatusSummary(Json::Value& jData) {
+ bool bIsSimInserted = false;
+ bool bIsSimLocked = true;
+ int iAttemptsPin = 0;
+ int iAttemptsPuk = 0;
+ std::string sSimLockStatus;
+ ICellularRadio::CODE retCode;
- 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;
+ do {
+ retCode = getIsSimInserted(bIsSimInserted);
+ if (retCode != SUCCESS) {
+ break;
}
- }
- 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;
- }
+ if (!bIsSimInserted) {
+ // There is no left much to do. Return one field only.
+ jData[KEY_IS_SIM_INSERTED] = bIsSimInserted;
+ break;
+ }
- 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;
+ // The following code assumes that the SIM card is inserted
+ retCode = getSimLockStatus(sSimLockStatus);
+ if (retCode != SUCCESS) {
+ break;
}
- printDebug("%s| Service ID: [%d][%s]", m_sName.c_str(), iService, sService.c_str());
- }
- return SUCCESS;
+ bIsSimLocked = (sSimLockStatus != "READY"); // SIM PIN, SIM PUK or other values
+
+ retCode = getSimLockAttempts(iAttemptsPin, iAttemptsPuk);
+ if (retCode != SUCCESS) {
+ break;
+ }
+
+ // Everything fetched successfully. Populate the jData object
+ jData[KEY_IS_SIM_INSERTED] = bIsSimInserted;
+ jData[KEY_IS_SIM_LOCKED] = bIsSimLocked;
+ jData[KEY_SIM_LOCK_STATUS] = sSimLockStatus;
+ jData[KEY_ATTEMPTS_PIN] = iAttemptsPin;
+ jData[KEY_ATTEMPTS_PUK] = iAttemptsPuk;
+ } while (false);
+
+ return retCode;
}
-CellularRadio::CODE CellularRadio::getLac(std::string& sLac) {
+ICellularRadio::CODE CellularRadio::getLac(std::string& sLac) {
Json::Value jData;
printTrace("%s| Get LAC", m_sName.c_str());
- sLac = VALUE_NOT_SUPPORTED;
+ sLac = ICellularRadio::VALUE_NOT_SUPPORTED;
if(getNetworkStatus(jData) == SUCCESS) {
- if(jData.isMember(KEY_LAC)) {
- sLac = jData[KEY_LAC].asString();
+ if(jData.isMember(ICellularRadio::KEY_LAC)) {
+ sLac = jData[ICellularRadio::KEY_LAC].asString();
return SUCCESS;
}
}
@@ -620,12 +351,15 @@ CellularRadio::CODE CellularRadio::getLac(std::string& sLac) {
return FAILURE;
}
-CellularRadio::CODE CellularRadio::getMdn(std::string& sMdn) {
+ICellularRadio::CODE CellularRadio::getMdn(std::string& sMdn) {
printTrace("%s| Get MDN", m_sName.c_str());
- sMdn = VALUE_NOT_SUPPORTED;
+ sMdn = ICellularRadio::VALUE_NOT_SUPPORTED;
+
+ // AT+CNUM execution can take up to 300ms according to the Quectel datasheet. Setting timeout to 500ms just for sure.
std::string sCmd("AT+CNUM");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
+ size_t end = sResult.find(ICellularRadio::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;
@@ -651,7 +385,7 @@ CellularRadio::CODE CellularRadio::getMdn(std::string& sMdn) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::getMsid(std::string& sMsid) {
+ICellularRadio::CODE CellularRadio::getMsid(std::string& sMsid) {
printTrace("%s| Get MSID", m_sName.c_str());
sMsid = "";
@@ -667,25 +401,25 @@ CellularRadio::CODE CellularRadio::getMsid(std::string& sMsid) {
return FAILURE;
}
-CellularRadio::CODE CellularRadio::getType(std::string& sType) {
+ICellularRadio::CODE CellularRadio::getType(std::string& sType) {
printTrace("%s| Get Type", m_sName.c_str());
- sType = VALUE_NOT_SUPPORTED;
+ sType = ICellularRadio::VALUE_NOT_SUPPORTED;
return FAILURE;
}
-CellularRadio::CODE CellularRadio::getCarrier(std::string& sCarrier) {
+ICellularRadio::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();
+ if(jData.isMember(ICellularRadio::KEY_MCC) && jData.isMember(ICellularRadio::KEY_MNC)) {
+ std::string sMcc = jData[ICellularRadio::KEY_MCC].asString();
+ std::string sMnc = jData[ICellularRadio::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();
+ if(jLookup.isMember(ICellularRadio::KEY_CARRIER)) {
+ m_sCarrier = jLookup[ICellularRadio::KEY_CARRIER].asString();
} else {
printWarning("%s| MCC-MNC Lookup did not contain carrier", m_sName.c_str());
return FAILURE;
@@ -703,22 +437,22 @@ CellularRadio::CODE CellularRadio::getCarrier(std::string& sCarrier) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::getTower(std::string& sTower) {
+ICellularRadio::CODE CellularRadio::getTower(std::string& sTower) {
Json::Value jData;
printTrace("%s| Get Tower", m_sName.c_str());
- sTower = VALUE_NOT_SUPPORTED;
+ sTower = ICellularRadio::VALUE_NOT_SUPPORTED;
if(getNetworkStatus(jData) == SUCCESS) {
- if(jData.isMember(KEY_CID)) {
- sTower = jData[KEY_CID].asString();
+ if(jData.isMember(ICellularRadio::KEY_CID)) {
+ sTower = jData[ICellularRadio::KEY_CID].asString();
return SUCCESS;
}
}
return FAILURE;
}
-CellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) {
+ICellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) {
Json::Value jData;
printTrace("%s| Get Time", m_sName.c_str());
@@ -727,8 +461,8 @@ CellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTim
sTimeZone = "";
std::string sCmd("AT+CCLK?");
- std::string sResult = CellularRadio::sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::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;
@@ -793,7 +527,7 @@ CellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTim
return FAILURE;
}
-CellularRadio::CODE CellularRadio::getRoaming(bool& bRoaming) {
+ICellularRadio::CODE CellularRadio::getRoaming(bool& bRoaming) {
Json::Value jData;
printTrace("%s| Get Roaming", m_sName.c_str());
@@ -807,25 +541,13 @@ CellularRadio::CODE CellularRadio::getRoaming(bool& bRoaming) {
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) {
+ICellularRadio::CODE CellularRadio::getSignalStrength(int32_t& rssi) {
printTrace("%s| Get Signal Strength", m_sName.c_str());
+
+ // AT+CSQ execution can take up to 300ms according to the Quectel datasheet. Setting timeout to 500ms just for sure.
std::string sCmd("AT+CSQ");
- std::string sResult = sendCommand(sCmd);
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
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;
@@ -845,53 +567,12 @@ CellularRadio::CODE CellularRadio::getSignalStrength(int32_t& rssi) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::getModemLocation(std::string& sLocation) {
+ICellularRadio::CODE CellularRadio::getModemLocation(std::string&) {
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) {
+ICellularRadio::CODE CellularRadio::getEcho(bool& bEnabled) {
printTrace("%s| Echo Test", m_sName.c_str());
std::string sResult = sendCommand("AT");
if(sResult.size() == 0) {
@@ -907,8 +588,8 @@ CellularRadio::CODE CellularRadio::getEcho(bool& bEnabled) {
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::setEcho(bool bEnabled) {
- CODE eCode = FAILURE;
+ICellularRadio::CODE CellularRadio::setEcho(bool bEnabled) {
+ ICellularRadio::CODE eCode = FAILURE;
if(bEnabled) {
eCode = sendBasicCommand("ATE1");
m_bEchoEnabled = (eCode == SUCCESS ) ? true : m_bEchoEnabled;
@@ -920,7 +601,7 @@ CellularRadio::CODE CellularRadio::setEcho(bool bEnabled) {
return eCode;
}
-CellularRadio::CODE CellularRadio::getStaticInformation(Json::Value& jData) {
+ICellularRadio::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());
@@ -928,268 +609,14 @@ CellularRadio::CODE CellularRadio::getStaticInformation(Json::Value& jData) {
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
+// Get the LAC for the LTE radio that's not in the #RFSTS or +QENG response
std::string CellularRadio::queryLteLac() {
std::string CGREGstring;
std::string originalCGREG;
std::string result;
CGREGstring = queryCGREGstring();
- if (CGREGstring == RSP_ERROR) {
+ if (CGREGstring == ICellularRadio::RSP_ERROR) {
originalCGREG = "0";
} else {
originalCGREG = CGREGstring.at(CGREGstring.find(",") - 1); //Position right before first comma ("+CGREG: 0,1")
@@ -1199,13 +626,13 @@ std::string CellularRadio::queryLteLac() {
setCGREG("2");
CGREGstring = queryCGREGstring();
- if (CGREGstring == RSP_ERROR) {
- result = CellularRadio::VALUE_UNKNOWN;
+ if (CGREGstring == ICellularRadio::RSP_ERROR) {
+ result = ICellularRadio::VALUE_UNKNOWN;
} else {
- size_t start = CGREGstring.find(":") + 1; //Position right after "#RFSTS:"
+ size_t start = CGREGstring.find(":") + 1; //Position right after "+CGREG:"
std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(CGREGstring.substr(start)), ",");
if(vParts.size() < 3) {
- result = CellularRadio::VALUE_UNAVAILABLE;
+ result = ICellularRadio::VALUE_UNAVAILABLE;
} else {
result = MTS::Text::strip(vParts[2], '"');
}
@@ -1220,7 +647,7 @@ 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());
+ printDebug("%s| AT+CGREG=%s returned unexpected response: [%s][%s]", m_sName.c_str(), value.c_str(), sCmd.c_str(), cmdResult.c_str());
}
}
@@ -1228,8 +655,8 @@ 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;
+ printDebug("%s| AT+CGREG? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), cmdResult.c_str());
+ return ICellularRadio::RSP_ERROR;
}
return cmdResult;
}
@@ -1238,51 +665,78 @@ void CellularRadio::getCommonNetworkStats(Json::Value& jData) {
bool bRoaming = false;
if(getRoaming(bRoaming) == SUCCESS) {
- jData[KEY_ROAMING] = bRoaming;
+ jData[ICellularRadio::KEY_ROAMING] = bRoaming;
}
int32_t iRssi;
if(getSignalStrength(iRssi) == SUCCESS) {
- jData[KEY_RSSI] = iRssi;
+ jData[ICellularRadio::KEY_RSSI] = iRssi;
int32_t dBm;
- if(!jData.isMember(KEY_RSSIDBM) && convertSignalStrengthTodBm(iRssi, dBm) == SUCCESS) {
+ if(!jData.isMember(ICellularRadio::KEY_RSSIDBM) && convertSignalStrengthTodBm(iRssi, dBm) == SUCCESS) {
//Add RSSI in dBm format
- jData[KEY_RSSIDBM] = MTS::Text::format(dBm);
+ jData[ICellularRadio::KEY_RSSIDBM] = MTS::Text::format(dBm);
}
}
std::string sService;
if(getService(sService) == SUCCESS) {
- jData[KEY_SERVICE] = sService;
+ jData[ICellularRadio::KEY_SERVICE] = sService;
}
std::string sDate, sTime, sTimeZone;
if(getTime(sDate, sTime, sTimeZone) == SUCCESS) {
- jData[KEY_DATETIME] = sDate + " " + sTime + " GMT" + sTimeZone;
+ jData[ICellularRadio::KEY_DATETIME] = sDate + " " + sTime + " GMT" + sTimeZone;
}
std::string sNetworkReg;
- CellularRadio::REGISTRATION eReg;
+ REGISTRATION eReg;
if (getRegistration(eReg) == SUCCESS) {
if (convertRegistrationToString(eReg, sNetworkReg) == SUCCESS) {
- jData[CellularRadio::KEY_NETWORK_REG] = sNetworkReg;
+ jData[ICellularRadio::KEY_NETWORK_REG] = sNetworkReg;
}
}
}
+ICellularRadio::CODE CellularRadio::getSimLockStatus(std::string& sData)
+{
+ printTrace("%s| Get SIM lock status", m_sName.c_str());
+
+ // SIM card may introduce a delay to AT+CPIN? execution. Setting timeout to 1s as set in PPP chat patches.
+ std::string sCmd("AT+CPIN?");
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 1000);
+
+ const std::string sPrefix = "+CPIN: ";
+ size_t start = sResult.find(sPrefix);
+ size_t end = sResult.rfind(ICellularRadio::RSP_OK);
+
+ if (start == std::string::npos || end == std::string::npos) {
+ printWarning("%s| Unable to get SIM lock status from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ start += sPrefix.size();
+ sData = MTS::Text::trim(sResult.substr(start, end-start));
+ if(sData.size() == 0) {
+ printWarning("%s| Unable to get SIM lock status from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
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) {
+ jData[ICellularRadio::KEY_MIP_ID] = 0;
+ jData[ICellularRadio::KEY_MIP_ENABLED] = false;
+ jData[ICellularRadio::KEY_MIP_NAI] = ICellularRadio::VALUE_UNKNOWN;
+ jData[ICellularRadio::KEY_MIP_HOMEADDRESS] = ICellularRadio::VALUE_UNKNOWN;
+ jData[ICellularRadio::KEY_MIP_PRIMARYHA] = ICellularRadio::VALUE_UNKNOWN;
+ jData[ICellularRadio::KEY_MIP_SECONDARYHA] = ICellularRadio::VALUE_UNKNOWN;
+ jData[ICellularRadio::KEY_MIP_MNAAASPI] = ICellularRadio::VALUE_UNKNOWN;
+ jData[ICellularRadio::KEY_MIP_MNHASPI] = ICellularRadio::VALUE_UNKNOWN;
+ jData[ICellularRadio::KEY_MIP_MNAAASS] = false;
+ jData[ICellularRadio::KEY_MIP_MNHASS] = false;
+}
+
+ICellularRadio::CODE CellularRadio::getRegistration(REGISTRATION& eRegistration) {
std::string sCmd;
std::string sResp;
@@ -1316,168 +770,167 @@ CellularRadio::CODE CellularRadio::getRegistration(REGISTRATION& eRegistration)
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) {
+ICellularRadio::CODE CellularRadio::convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) {
- CODE eCode = FAILURE;
+ ICellularRadio::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;
+ case NOT_REGISTERED: sRegistration = ICellularRadio::VALUE_NOT_REGISTERED; eCode = SUCCESS; break;
+ case REGISTERED: sRegistration = ICellularRadio::VALUE_REGISTERED; eCode = SUCCESS; break;
+ case SEARCHING: sRegistration = ICellularRadio::VALUE_SEARCHING; eCode = SUCCESS; break;
+ case DENIED: sRegistration = ICellularRadio::VALUE_DENIED; eCode = SUCCESS; break;
+ case UNKNOWN: sRegistration = ICellularRadio::VALUE_UNKNOWN; eCode = SUCCESS; break;
+ case ROAMING: sRegistration = ICellularRadio::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());
+ICellularRadio::CODE CellularRadio::unlockSimCard(const Json::Value& jArgs) {
+ printTrace("%s| Unlock the SIM card using PIN code", m_sName.c_str());
- if(!jArgs["mdn"].isString()) {
+ if(!jArgs["pin"].isString()) {
return INVALID_ARGS;
}
- std::string sCmd("AT#SNUM=1,\"");
- sCmd += jArgs["mdn"].asString() + "\"";
+ std::string sCmd = "AT+CPIN=" + jArgs["pin"].asString();
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 5000);
- 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());
+ size_t pos = sResult.find(ICellularRadio::RSP_OK);
+ if (pos == std::string::npos) {
+ printWarning("%s| Failed to unlock the SIM card using command [%s]", m_sName.c_str(), sCmd.c_str());
return FAILURE;
}
return SUCCESS;
}
-CellularRadio::CODE CellularRadio::setMsid(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::validateMsl(const Json::Value&) {
+ printTrace("%s| Validate MSL", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+ICellularRadio::CODE CellularRadio::setMsid(const Json::Value&) {
printTrace("%s| Set MSID", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::getMipProfile(Json::Value& jMipProfile) {
+ICellularRadio::CODE CellularRadio::getMipProfile(Json::Value&) {
printTrace("%s| Get MIP Active Profile", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipActiveProfile(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipActiveProfile(const Json::Value&) {
printTrace("%s| Set MIP Active Profile", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipNai(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipNai(const Json::Value&) {
printTrace("%s| Set MIP NAI", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipHomeIp(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipHomeIp(const Json::Value&) {
printTrace("%s| Set MIP Home IP", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipPrimaryHa(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipPrimaryHa(const Json::Value&) {
printTrace("%s| Set MIP Primary HA", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipSecondaryHa(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipSecondaryHa(const Json::Value&) {
printTrace("%s| Set MIP Secondary HA", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipMnAaaSpi(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipMnAaaSpi(const Json::Value&) {
printTrace("%s| Set MIP MN-AAA SPI", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipMnHaSpi(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipMnHaSpi(const Json::Value&) {
printTrace("%s| Set MIP MN-HA SPI", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipRevTun(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipRevTun(const Json::Value&) {
printTrace("%s| Set MIP Rev Tun", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipMnAaaSs(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipMnAaaSs(const Json::Value&) {
printTrace("%s| Set MIP MN-AAA SS", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setMipMnHaSs(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setMipMnHaSs(const Json::Value&) {
printTrace("%s| Set MIP MN-HA SS", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CellularRadio::updateDc(const Json::Value&, UpdateCb&) {
printTrace("%s| Update Device Configuration", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CellularRadio::updatePrl(const Json::Value&, UpdateCb&) {
printTrace("%s| Update Preferred Roaming List", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CellularRadio::updateFumo(const Json::Value&, UpdateCb&) {
printTrace("%s| Update Firmware Update Management Object", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CellularRadio::resetHfa(const Json::Value&, UpdateCb&) {
printTrace("%s| HFA Reset", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) {
+ICellularRadio::CODE CellularRadio::activate(const Json::Value&, UpdateCb&) {
printTrace("%s| Activation", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::setActiveFirmware(const Json::Value& jArgs) {
+ICellularRadio::CODE CellularRadio::setActiveFirmware(const Json::Value&) {
printTrace("%s| Set Active Firmware Image Number: not applicable", m_sName.c_str());
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::getActiveFirmware(std::string& sFwId) {
+ICellularRadio::CODE CellularRadio::getActiveFirmware(std::string& sFwId) {
printTrace("%s| Get Active Firmware Image Number: not applicable", m_sName.c_str());
- sFwId = VALUE_NOT_SUPPORTED;
+ sFwId = ICellularRadio::VALUE_NOT_SUPPORTED;
return NOT_APPLICABLE;
}
-CellularRadio::CODE CellularRadio::sendBasicCommand(const std::string& sCmd, int32_t iTimeoutMillis, const char& ESC) {
+ICellularRadio::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) {
+ } else if (response.find(ICellularRadio::RSP_OK) != std::string::npos) {
return SUCCESS;
- } else if (response.find(RSP_ERROR) != std::string::npos) {
+ } else if (response.find(ICellularRadio::RSP_ERROR) != std::string::npos) {
return ERROR;
} else {
return FAILURE;
@@ -1485,167 +938,11 @@ CellularRadio::CODE CellularRadio::sendBasicCommand(const std::string& sCmd, int
}
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);
+ return ICellularRadio::sendCommand(m_apIo, sCmd, vBail, 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";
- }
+ return ICellularRadio::sendCommand(m_apIo, sCmd, isNeedMoreData, timeoutMillis, ESC);
}
bool CellularRadio::splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType) {
@@ -1680,84 +977,15 @@ bool CellularRadio::splitAndAssign(const std::string& sLine, const std::string&
}
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;
- }
- }
- }
- }
+ // Assuming that this function is not supported by the modem until overriden.
- return bResult;
+ return false;
}
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;
+ // Assuming that this function is not supported by the modem until overriden.
+ return false;
}
const char *CellularRadio::RadioBandMap::getLTEBand(const int32_t channel)
@@ -1769,7 +997,7 @@ const char *CellularRadio::RadioBandMap::getLTEBand(const int32_t channel)
return EULTRAband[ii].name;
}
}
- return VALUE_UNKNOWN.c_str();
+ return ICellularRadio::VALUE_UNKNOWN;
}
const char *CellularRadio::RadioBandMap::getCDMABand(const int channel)
@@ -1781,7 +1009,7 @@ const char *CellularRadio::RadioBandMap::getCDMABand(const int channel)
return WCDMAband[ii].name;
}
}
- return VALUE_UNKNOWN.c_str();
+ return ICellularRadio::VALUE_UNKNOWN;
}
const char *CellularRadio::RadioBandMap::getGSMBand(const int channel)
@@ -1793,22 +1021,22 @@ const char *CellularRadio::RadioBandMap::getGSMBand(const int channel)
return GSMband[ii].name;
}
}
- return VALUE_UNKNOWN.c_str();
+ return ICellularRadio::VALUE_UNKNOWN;
}
const char *CellularRadio::RadioBandMap::getRadioBandName()
{
- const char *band = CellularRadio::VALUE_UNKNOWN.c_str();
+ const char *band = ICellularRadio::VALUE_UNKNOWN;
- if (m_sRadioType == CellularRadio::VALUE_TYPE_LTE)
+ if (m_sRadioType == ICellularRadio::VALUE_TYPE_LTE)
{
band = getLTEBand(m_iChannel);
}
- else if (m_sRadioType == CellularRadio::VALUE_TYPE_CDMA)
+ else if (m_sRadioType == ICellularRadio::VALUE_TYPE_CDMA)
{
band = getCDMABand(m_iChannel);
}
- else if (m_sRadioType == CellularRadio::VALUE_TYPE_GSM)
+ else if (m_sRadioType == ICellularRadio::VALUE_TYPE_GSM)
{
band = getGSMBand(m_iChannel);
}
@@ -1818,17 +1046,17 @@ const char *CellularRadio::RadioBandMap::getRadioBandName()
const char *CellularRadio::RadioBandMap::getRadioBandName(const std::string &channel, const std::string &radioType)
{
- const char *band = CellularRadio::VALUE_UNKNOWN.c_str();
+ const char *band = ICellularRadio::VALUE_UNKNOWN;
int32_t chan = strtol(channel.c_str(), NULL, 10);
- if (radioType == CellularRadio::VALUE_TYPE_LTE)
+ if (radioType == ICellularRadio::VALUE_TYPE_LTE)
{
band = getLTEBand(chan);
}
- else if (radioType == CellularRadio::VALUE_TYPE_CDMA)
+ else if (radioType == ICellularRadio::VALUE_TYPE_CDMA)
{
band = getCDMABand(chan);
}
- else if (radioType == CellularRadio::VALUE_TYPE_GSM)
+ else if (radioType == ICellularRadio::VALUE_TYPE_GSM)
{
band = getGSMBand(chan);
}
diff --git a/src/MTS_IO_CellularRadioFactory.cpp b/src/MTS_IO_CellularRadioFactory.cpp
index ef87f0e..4ee8756 100644
--- a/src/MTS_IO_CellularRadioFactory.cpp
+++ b/src/MTS_IO_CellularRadioFactory.cpp
@@ -37,6 +37,7 @@
#include <mts/MTS_IO_GE910Radio.h>
#include <mts/MTS_IO_CE910Radio.h>
#include <mts/MTS_IO_DE910Radio.h>
+#include "mts/MTS_IO_EG95Radio.h"
#include <mts/MTS_Logger.h>
using namespace MTS::IO;
@@ -60,9 +61,10 @@ CellularRadioFactory::CellularRadioFactory() {
m_mCreationMap[DE910Radio::MODEL_NAME] = &CellularRadioFactory::createDE910;
m_mCreationMap[CE910Radio::MODEL_NAME] = &CellularRadioFactory::createCE910;
m_mCreationMap[LE866A1JSRadio::MODEL_NAME] = &CellularRadioFactory::createLE866A1JS;
+ m_mCreationMap[EG95Radio::MODEL_NAME] = &CellularRadioFactory::createEG95Radio;
}
-MTS::IO::CellularRadio* CellularRadioFactory::create(const std::string& sModel, const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::create(const std::string& sModel, const std::string& sPort) {
std::string model(sModel);
@@ -87,22 +89,22 @@ 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 ICellularRadio::VALUE_UNKNOWN;
}
//Attempt basic radio communication
- if(CellularRadio::test(apIo) != CellularRadio::SUCCESS) {
+ if(ICellularRadio::test(apIo) != ICellularRadio::SUCCESS) {
printError("CellularRadioFactory| Failed to communicate with radio on port [%s]", sPort.c_str());
apIo->close();
- return CellularRadio::VALUE_UNKNOWN;
+ return ICellularRadio::VALUE_UNKNOWN;
}
//Get model
int count = 0;
- std::string sCmd("ATI4");
+ std::string sCmd("AT+GMM");
std::string sResult;
do {
- sResult = CellularRadio::sendCommand(apIo, sCmd, CellularRadio::DEFAULT_BAIL_STRINGS, 1000, CellularRadio::CR);
+ sResult = ICellularRadio::sendCommand(apIo, sCmd, ICellularRadio::DEFAULT_BAIL_STRINGS, 1000, ICellularRadio::CR);
if (sResult.find("OK") == std::string::npos) {
printDebug("RADIO| Attempting to get radio model [%s] ...", sResult.c_str());
} else {
@@ -114,83 +116,88 @@ 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 ICellularRadio::VALUE_UNKNOWN;
}
- std::string sModel = CellularRadio::extractModelFromResult(sResult);
- printDebug("RADIO| Extracted [%s] from ATI4 query", sModel.c_str());
+ std::string sModel = ICellularRadio::extractModelFromResult(sResult);
+ printDebug("RADIO| Extracted [%s] from AT+GMM query", sModel.c_str());
apIo->close();
return sModel;
}
-CellularRadio* CellularRadioFactory::createHE910D(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createHE910D(const std::string& sPort) const {
return new HE910DRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createHE910EUD(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createHE910EUD(const std::string& sPort) const {
return new HE910EUDRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910NAG(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910NAG(const std::string& sPort) const {
return new LE910NAGRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910C4NF(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910C4NF(const std::string& sPort) const {
return new LE910C4NFRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910NA1(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910NA1(const std::string& sPort) const {
return new LE910NA1Radio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910SVG(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910SVG(const std::string& sPort) const {
return new LE910SVGRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910EUG(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910EUG(const std::string& sPort) const {
return new LE910EUGRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910C4EU(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910C4EU(const std::string& sPort) const {
return new LE910C4EURadio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910EU1(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910EU1(const std::string& sPort) const {
return new LE910EU1Radio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910C1NS(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910C1NS(const std::string& sPort) const {
return new LE910C1NSRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE910C1AP(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createLE910C1AP(const std::string& sPort) const {
return new LE910C1APRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createME910C1NA(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createME910C1NA(const std::string& sPort) const {
return new ME910C1NARadio(sPort);
}
-CellularRadio* CellularRadioFactory::createME910C1NV(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createME910C1NV(const std::string& sPort) const {
return new ME910C1NVRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createME910C1WW(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createME910C1WW(const std::string& sPort) const {
return new ME910C1WWRadio(sPort);
}
-CellularRadio* CellularRadioFactory::createGE910(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createGE910(const std::string& sPort) const {
return new GE910Radio(sPort);
}
-CellularRadio* CellularRadioFactory::createDE910(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createDE910(const std::string& sPort) const {
return new DE910Radio(sPort);
}
-CellularRadio* CellularRadioFactory::createCE910(const std::string& sPort) {
+ICellularRadio* CellularRadioFactory::createCE910(const std::string& sPort) const {
return new CE910Radio(sPort);
}
-CellularRadio* CellularRadioFactory::createLE866A1JS(const std::string &sPort) {
+ICellularRadio* CellularRadioFactory::createLE866A1JS(const std::string &sPort) const {
return new LE866A1JSRadio(sPort);
}
+
+ICellularRadio* CellularRadioFactory::createEG95Radio(const std::string& sPort) const
+{
+ return new EG95Radio(sPort);
+}
diff --git a/src/MTS_IO_DE910Radio.cpp b/src/MTS_IO_DE910Radio.cpp
index eccb3eb..26668f1 100644
--- a/src/MTS_IO_DE910Radio.cpp
+++ b/src/MTS_IO_DE910Radio.cpp
@@ -39,7 +39,7 @@ DE910Radio::DE910Radio(const std::string& sPort)
}
-CellularRadio::CODE DE910Radio::setRxDiversity(const Json::Value& jArgs) {
+ICellularRadio::CODE DE910Radio::setRxDiversity(const Json::Value& jArgs) {
/* Command string for EV3 radios: AT#CRXD= */
if (jArgs["enabled"].asString() != "1" && jArgs["enabled"].asString() != "0")
{
diff --git a/src/MTS_IO_EG95Radio.cpp b/src/MTS_IO_EG95Radio.cpp
new file mode 100644
index 0000000..5c9ed69
--- /dev/null
+++ b/src/MTS_IO_EG95Radio.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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_EG95Radio.h>
+
+using namespace MTS::IO;
+
+const std::string EG95Radio::MODEL_NAME("EG95");
+
+EG95Radio::EG95Radio(const std::string& sPort)
+: QuectelRadio(MODEL_NAME, sPort)
+{
+
+}
+
+EG95Radio::~EG95Radio() {
+
+}
+
+ICellularRadio::CODE EG95Radio::setRxDiversity(const Json::Value& jArgs) {
+ /* Command string for EG95 radios: AT+QCFG="diversity",(0-1) */
+ if (jArgs["enabled"].asString() != "1" && jArgs["enabled"].asString() != "0") {
+ return FAILURE;
+ }
+ std::string sCmd = "AT+QCFG=\"diversity\",";
+ sCmd += jArgs["enabled"].asString();
+
+ return sendBasicCommand(sCmd);
+}
diff --git a/src/MTS_IO_GE910Radio.cpp b/src/MTS_IO_GE910Radio.cpp
index e402b13..61332b5 100644
--- a/src/MTS_IO_GE910Radio.cpp
+++ b/src/MTS_IO_GE910Radio.cpp
@@ -34,12 +34,12 @@ 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)
{
}
-CellularRadio::CODE GE910Radio::setRxDiversity(const Json::Value& jArgs) {
+ICellularRadio::CODE GE910Radio::setRxDiversity(const Json::Value& jArgs) {
/* Command string for GE radios: N/A */
return FAILURE;
}
diff --git a/src/MTS_IO_HE910Radio.cpp b/src/MTS_IO_HE910Radio.cpp
index bc08932..4c0a759 100644
--- a/src/MTS_IO_HE910Radio.cpp
+++ b/src/MTS_IO_HE910Radio.cpp
@@ -32,12 +32,12 @@
using namespace MTS::IO;
HE910Radio::HE910Radio(const std::string& sHE910Model, const std::string& sPort)
-: CellularRadio(sHE910Model, sPort)
+: TelitRadio(sHE910Model, sPort)
{
}
-CellularRadio::CODE HE910Radio::setRxDiversity(const Json::Value& jArgs) {
+ICellularRadio::CODE HE910Radio::setRxDiversity(const Json::Value& jArgs) {
/* Command string for H5 radios: "AT#RXDIV" */
if (jArgs["enabled"].asString() != "1" && jArgs["enabled"].asString() != "0")
{
diff --git a/src/MTS_IO_ICellularRadio.cpp b/src/MTS_IO_ICellularRadio.cpp
new file mode 100644
index 0000000..4e7809e
--- /dev/null
+++ b/src/MTS_IO_ICellularRadio.cpp
@@ -0,0 +1,472 @@
+#include "mts/MTS_IO_ICellularRadio.h"
+
+#include <mts/MTS_Logger.h>
+#include <mts/MTS_Timer.h>
+
+const char MTS::IO::ICellularRadio::ETX = 0x03; //Ends socket connection
+const char MTS::IO::ICellularRadio::DLE = 0x10; //Escapes ETX and DLE within Payload
+const char MTS::IO::ICellularRadio::CR = 0x0D;
+const char MTS::IO::ICellularRadio::NL = 0x0A;
+const char MTS::IO::ICellularRadio::CTRL_Z = 0x1A;
+
+const char *MTS::IO::ICellularRadio::RSP_ERROR = "ERROR";
+const char *MTS::IO::ICellularRadio::RSP_OK = "OK";
+
+
+const char *MTS::IO::ICellularRadio::DEFAULT_RADIO_PORT = "/dev/modem_at1";
+const char *MTS::IO::ICellularRadio::DEFAULT_RADIO_DIR = "/var/run/radio/";
+const char *MTS::IO::ICellularRadio::VALUE_UNKNOWN = "Unknown";
+const char *MTS::IO::ICellularRadio::VALUE_UNAVAILABLE = "Unavailable";
+const char *MTS::IO::ICellularRadio::VALUE_NOT_SUPPORTED = "Not Supported";
+
+const char *MTS::IO::ICellularRadio::VALUE_NOT_REGISTERED = "NOT REGISTERED";
+const char *MTS::IO::ICellularRadio::VALUE_REGISTERED = "REGISTERED";
+const char *MTS::IO::ICellularRadio::VALUE_SEARCHING = "SEARCHING";
+const char *MTS::IO::ICellularRadio::VALUE_DENIED = "DENIED";
+const char *MTS::IO::ICellularRadio::VALUE_ROAMING = "ROAMING";
+
+//Static Data
+const char *MTS::IO::ICellularRadio::KEY_TYPE = "type"; //!< GSM or CDMA
+const char *MTS::IO::ICellularRadio::KEY_CODE = "code"; //!< Product Code : H5, H6, C2, EV3, G3
+const char *MTS::IO::ICellularRadio::KEY_MODEL = "model"; //!< Model : HE910, LE910, CE910, DE910, GE910
+const char *MTS::IO::ICellularRadio::KEY_MANUFACTURER = "manufacturer"; //!< Manufacturer: Telit
+const char *MTS::IO::ICellularRadio::KEY_HARDWARE = "hardware"; //!< Radio Hardware Version
+const char *MTS::IO::ICellularRadio::KEY_FIRMWARE = "firmware"; //!< Radio Firmware Version
+const char *MTS::IO::ICellularRadio::KEY_FIRMWARE_BUILD = "firmwarebuild"; //!< Radio Firmware Build
+
+const char *MTS::IO::ICellularRadio::KEY_CARRIER = "carrier"; //!< Cellular Service Provider = Home Network
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_VERIZON = "Verizon";
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_AERIS = "Aeris";
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_SPRINT = "Sprint";
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_USCELLULAR = "U.S. Cellular";
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_ATT = "AT&T";
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_TMOBILE = "T-Mobile";
+
+const char *MTS::IO::ICellularRadio::KEY_IMEI = "imei"; //!< International Mobile Station Equipment Identity
+const char *MTS::IO::ICellularRadio::KEY_MEID = "meid"; //!< Mobile Equipment Identifier
+const char *MTS::IO::ICellularRadio::KEY_IMSI = "imsi"; //!< International Mobile Subscriber Identity
+const char *MTS::IO::ICellularRadio::KEY_MSID = "msid"; //!< Mobil Station ID / Mobile Identification Number = MSID/MIN = CDMA-Only
+const char *MTS::IO::ICellularRadio::KEY_MDN = "mdn"; //!< Mobile Directory Number : Actual phone number dialed to reach radio
+const char *MTS::IO::ICellularRadio::KEY_ICCID = "iccid"; //!< Integrated Circuit Card Identifier
+const char *MTS::IO::ICellularRadio::KEY_MSL = "msl"; //!< Master Subsidy Lock
+
+//Dynamic Data
+const char *MTS::IO::ICellularRadio::KEY_ROAMING = "roaming"; //!< Indicates whether or not using Home Network
+const char *MTS::IO::ICellularRadio::KEY_DATETIME = "datetime"; //!< Date and Time from tower
+const char *MTS::IO::ICellularRadio::KEY_SERVICE = "service"; //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO]
+const char *MTS::IO::ICellularRadio::KEY_NETWORK = "network"; //!< Cellular Service Provider
+const char *MTS::IO::ICellularRadio::KEY_NETWORK_REG = "netreg"; //!< Network Registration
+const char *MTS::IO::ICellularRadio::KEY_CID = "cid"; //!< Cellular ID = Tower in HEX
+const char *MTS::IO::ICellularRadio::KEY_LAC = "lac"; //!< Location Area Code in HEX
+const char *MTS::IO::ICellularRadio::KEY_RAC = "rac"; //!< Routing Area Code in HEX
+const char *MTS::IO::ICellularRadio::KEY_RSSI = "rssi"; //!< Signal Strength
+const char *MTS::IO::ICellularRadio::KEY_RSSIDBM = "rssidBm"; //!< Signal Strength in dBm
+const char *MTS::IO::ICellularRadio::KEY_MCC = "mcc"; //!< Country Code
+const char *MTS::IO::ICellularRadio::KEY_MNC = "mnc"; //!< Operator Code
+const char *MTS::IO::ICellularRadio::KEY_CHANNEL = "channel"; //!< ARFCN or UARFCN Assigned Radio Channel
+const char *MTS::IO::ICellularRadio::KEY_TXPWR = "txpwr"; //!< Transmit Power
+const char *MTS::IO::ICellularRadio::KEY_PSC = "psc"; //!< Active Primary Synchronization Code = PSC
+const char *MTS::IO::ICellularRadio::KEY_ECIO = "ecio"; //!< Active Ec/Io = chip energy per total wideband power in dBm
+const char *MTS::IO::ICellularRadio::KEY_RSCP = "rscp"; //!< Active RSCP = Received Signal Code Power in dBm
+const char *MTS::IO::ICellularRadio::KEY_DRX = "drx"; //!< Discontinuous reception cycle length = ms
+const char *MTS::IO::ICellularRadio::KEY_MM = "mm"; //!< Mobility Management State
+const char *MTS::IO::ICellularRadio::KEY_RR = "rr"; //!< Radio Resource State
+const char *MTS::IO::ICellularRadio::KEY_NOM = "nom"; //!< Network Operator Mode
+const char *MTS::IO::ICellularRadio::KEY_ABND = "abnd"; //!< Active Band
+const char *MTS::IO::ICellularRadio::KEY_BLER = "bler"; //!< Block Error Rate = percentage
+const char *MTS::IO::ICellularRadio::KEY_SD = "sd"; //!< Service Domain
+const char *MTS::IO::ICellularRadio::KEY_DEBUG = "debug"; //!< Debug Information
+
+const char *MTS::IO::ICellularRadio::KEY_MIP = "mipProfile"; //!< Mobile IP Information
+const char *MTS::IO::ICellularRadio::KEY_MIP_ID = "id"; //!< Mobile IP ID
+const char *MTS::IO::ICellularRadio::KEY_MIP_ENABLED = "enabled"; //!< Mobile IP Enabled/Disabled
+const char *MTS::IO::ICellularRadio::KEY_MIP_NAI = "nai"; //!< Network Access Identifier
+const char *MTS::IO::ICellularRadio::KEY_MIP_HOMEADDRESS = "homeAddress"; //!< Home Address
+const char *MTS::IO::ICellularRadio::KEY_MIP_PRIMARYHA = "primaryAddress"; //!< Primary Home Agent
+const char *MTS::IO::ICellularRadio::KEY_MIP_SECONDARYHA = "secondaryAddress"; //!< Secondary Home Agent
+const char *MTS::IO::ICellularRadio::KEY_MIP_MNAAASPI = "mnAaaSpi"; //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index
+const char *MTS::IO::ICellularRadio::KEY_MIP_MNHASPI = "mnHaSpi"; //!< Mobile Node Home Agent Security Server Parameter Index
+const char *MTS::IO::ICellularRadio::KEY_MIP_REVTUN = "revTun"; //!< Reverse Tunneling Enabled
+const char *MTS::IO::ICellularRadio::KEY_MIP_MNAAASS = "mnAaaSs"; //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret
+const char *MTS::IO::ICellularRadio::KEY_MIP_MNHASS = "mnHaSs"; //!< Mobile Node Home Agent Shared Secret
+
+const char *MTS::IO::ICellularRadio::VALUE_TYPE_GSM = "GSM";
+const char *MTS::IO::ICellularRadio::VALUE_TYPE_LTE = "LTE";
+const char *MTS::IO::ICellularRadio::VALUE_TYPE_CDMA = "CDMA";
+
+const char *MTS::IO::ICellularRadio::KEY_IS_SIM_INSERTED = "isSimInserted"; //!< SIM card insertion indicator. True when a SIM card is inserted
+const char *MTS::IO::ICellularRadio::KEY_IS_SIM_LOCKED = "isSimLocked"; //!< SIM card lock status indicator. True when a SIM card is locked by PIN / PUK / other code
+const char *MTS::IO::ICellularRadio::KEY_SIM_LOCK_STATUS = "lockStatus"; //!< SIM card lock status string. Either "READY", "SIM PIN", "SIM PUK" or other state
+const char *MTS::IO::ICellularRadio::KEY_ATTEMPTS_PIN = "attemptsPin"; //!< The number of attempts left to unlock the SIM card using PIN code
+const char *MTS::IO::ICellularRadio::KEY_ATTEMPTS_PUK = "attemptsPuk"; //!< The number of attempts left to unlock the SIM card using PUK code
+
+const char *MTS::IO::ICellularRadio::VALUE_SD_NO_SERVICE = "NO SERVICE";
+const char *MTS::IO::ICellularRadio::VALUE_SD_CS_ONLY = "CS ONLY";
+const char *MTS::IO::ICellularRadio::VALUE_SD_PS_ONLY = "PS ONLY";
+const char *MTS::IO::ICellularRadio::VALUE_SD_CSPS = "CS+PS";
+
+const char *MTS::IO::ICellularRadio::VALUE_ABND_GSM_850 = "GSM 850";
+const char *MTS::IO::ICellularRadio::VALUE_ABND_GSM_900 = "GSM 900";
+const char *MTS::IO::ICellularRadio::VALUE_ABND_DCS_1800 = "DCS 1800";
+const char *MTS::IO::ICellularRadio::VALUE_ABND_PCS_1900 = "PCS 1900";
+
+const std::vector<std::string> MTS::IO::ICellularRadio::DEFAULT_BAIL_STRINGS = { MTS::IO::ICellularRadio::RSP_OK, MTS::IO::ICellularRadio::RSP_ERROR };
+
+MTS::IO::ICellularRadio::~ICellularRadio()
+{
+}
+
+MTS::IO::ICellularRadio::CODE MTS::IO::ICellularRadio::convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, MTS::IO::ICellularRadio *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 if (sModel.find("EG95") == 0) {
+ if (NULL == radioObject) {
+ sCode = VALUE_NOT_SUPPORTED;
+ eCode = ERROR;
+ } else {
+ std::string sValue;
+ eCode = radioObject->getFirmware(sValue);
+ if (eCode != SUCCESS) {
+ sCode = VALUE_NOT_SUPPORTED;
+ eCode = ERROR;
+ } else if (sValue.find("EG95E") != std::string::npos) {
+ sCode = "LEU7";
+ eCode = SUCCESS;
+ } else if (sValue.find("EG95NA") != std::string::npos) {
+ sCode = "LNA7";
+ eCode = SUCCESS;
+ } else {
+ sCode = VALUE_NOT_SUPPORTED;
+ eCode = ERROR;
+ }
+ }
+ } else {
+ sCode = VALUE_NOT_SUPPORTED;
+ printError("RADIO| Could not identify MTS short code from model. [%s]", sModel.c_str());
+ eCode = ERROR;
+ }
+ return eCode;
+}
+
+MTS::IO::ICellularRadio::CODE MTS::IO::ICellularRadio::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;
+}
+
+MTS::IO::ICellularRadio::CODE MTS::IO::ICellularRadio::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;
+}
+
+MTS::IO::ICellularRadio::CODE MTS::IO::ICellularRadio::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 if (sModel.find("EG95") == 0) {
+ sType = VALUE_TYPE_LTE;
+ 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;
+}
+
+std::string MTS::IO::ICellularRadio::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&, 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 MTS::IO::ICellularRadio::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;
+}
+
+MTS::IO::ICellularRadio::CODE MTS::IO::ICellularRadio::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 MTS::IO::ICellularRadio::extractModelFromResult(const std::string& sResult) {
+ std::string sModel(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";
+ } else if(sResult.find("EG95") != std::string::npos) {
+ sModel = "EG95";
+ }
+ return sModel;
+}
+
+std::string MTS::IO::ICellularRadio::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";
+ }
+}
+
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_LE910C1APRadio.cpp b/src/MTS_IO_LE910C1APRadio.cpp
index 3a560fa..dca5faa 100644
--- a/src/MTS_IO_LE910C1APRadio.cpp
+++ b/src/MTS_IO_LE910C1APRadio.cpp
@@ -30,7 +30,7 @@ LE910C1APRadio::LE910C1APRadio(const std::string& sPort)
}
-CellularRadio::CODE LE910C1APRadio::getCarrier(std::string& sCarrier) {
+ICellularRadio::CODE LE910C1APRadio::getCarrier(std::string& sCarrier) {
sCarrier = "Sprint";
return SUCCESS;
}
diff --git a/src/MTS_IO_LE910C1NSRadio.cpp b/src/MTS_IO_LE910C1NSRadio.cpp
index 6c403a0..907edd7 100644
--- a/src/MTS_IO_LE910C1NSRadio.cpp
+++ b/src/MTS_IO_LE910C1NSRadio.cpp
@@ -39,7 +39,7 @@ LE910C1NSRadio::LE910C1NSRadio(const std::string& sPort)
}
-CellularRadio::CODE LE910C1NSRadio::getCarrier(std::string& sCarrier) {
+ICellularRadio::CODE LE910C1NSRadio::getCarrier(std::string& sCarrier) {
sCarrier = "Sprint";
return SUCCESS;
}
diff --git a/src/MTS_IO_LE910NA1Radio.cpp b/src/MTS_IO_LE910NA1Radio.cpp
index 64583b4..c7341b0 100644
--- a/src/MTS_IO_LE910NA1Radio.cpp
+++ b/src/MTS_IO_LE910NA1Radio.cpp
@@ -38,8 +38,8 @@ LE910NA1Radio::LE910NA1Radio(const std::string& sPort)
}
-CellularRadio::CODE LE910NA1Radio::setActiveFirmware(const Json::Value& jArgs) {
- CellularRadio::CODE rc;
+ICellularRadio::CODE LE910NA1Radio::setActiveFirmware(const Json::Value& jArgs) {
+ ICellularRadio::CODE rc;
// Set command allows enabling a specific firmware image on products
// embedding 2 different firmware images:
@@ -82,9 +82,9 @@ CellularRadio::CODE LE910NA1Radio::setActiveFirmware(const Json::Value& jArgs) {
return sendBasicCommand(sCmd, 5000);
}
-CellularRadio::CODE LE910NA1Radio::getActiveFirmware(std::string& sFwId) {
+ICellularRadio::CODE LE910NA1Radio::getActiveFirmware(std::string& sFwId) {
std::string sCmd;
- CellularRadio::CODE rc;
+ ICellularRadio::CODE rc;
//
// Read command reports the current active firmware image:
// AT#FWSWITCH?
@@ -108,7 +108,7 @@ CellularRadio::CODE LE910NA1Radio::getActiveFirmware(std::string& sFwId) {
sCmd = "AT#FWSWITCH?";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to get active image number from radio using command [%s]",
getName().c_str(),
diff --git a/src/MTS_IO_LE910Radio.cpp b/src/MTS_IO_LE910Radio.cpp
index 76ccae2..ea905a8 100644
--- a/src/MTS_IO_LE910Radio.cpp
+++ b/src/MTS_IO_LE910Radio.cpp
@@ -33,12 +33,12 @@
using namespace MTS::IO;
LE910Radio::LE910Radio(const std::string& sLE910Model, const std::string& sPort)
-: CellularRadio(sLE910Model, sPort)
+: TelitRadio(sLE910Model, sPort)
{
}
-CellularRadio::CODE LE910Radio::setRxDiversity(const Json::Value& jArgs) {
+ICellularRadio::CODE LE910Radio::setRxDiversity(const Json::Value& jArgs) {
/* Command string for LAT1,LVW2,LEU1 radios: "AT#RXDIV=" */
/* Setting needs to append ",1" to the 0/1 value */
if (jArgs["enabled"].asString() != "1" && jArgs["enabled"].asString() != "0")
@@ -49,10 +49,10 @@ CellularRadio::CODE LE910Radio::setRxDiversity(const Json::Value& jArgs) {
sCmd += jArgs["enabled"].asString();
sCmd += ",1";
- return CellularRadio::sendBasicCommand(sCmd);
+ return sendBasicCommand(sCmd);
}
-CellularRadio::CODE LE910Radio::getModemLocation(std::string& sLocation) {
+ICellularRadio::CODE LE910Radio::getModemLocation(std::string& sLocation) {
const std::string& whitespace = " \t";
printTrace("LE910Radio getModemLocation");
std::string sCmd("AT$GPSACP");
diff --git a/src/MTS_IO_LE910SVGRadio.cpp b/src/MTS_IO_LE910SVGRadio.cpp
index 692350d..a43165a 100644
--- a/src/MTS_IO_LE910SVGRadio.cpp
+++ b/src/MTS_IO_LE910SVGRadio.cpp
@@ -39,7 +39,7 @@ LE910SVGRadio::LE910SVGRadio(const std::string& sPort)
}
-CellularRadio::CODE LE910SVGRadio::getCarrier(std::string& sCarrier) {
+ICellularRadio::CODE LE910SVGRadio::getCarrier(std::string& sCarrier) {
sCarrier = "Verizon";
return SUCCESS;
}
diff --git a/src/MTS_IO_ME910C1NVRadio.cpp b/src/MTS_IO_ME910C1NVRadio.cpp
index e9a4874..0af5f24 100644
--- a/src/MTS_IO_ME910C1NVRadio.cpp
+++ b/src/MTS_IO_ME910C1NVRadio.cpp
@@ -53,13 +53,13 @@ ME910C1NVRadio::ME910C1NVRadio(const std::string& sPort)
}
-CellularRadio::CODE ME910C1NVRadio::getCarrier(std::string& sCarrier) {
+ICellularRadio::CODE ME910C1NVRadio::getCarrier(std::string& sCarrier) {
sCarrier = "Verizon";
return SUCCESS;
}
-CellularRadio::CODE ME910C1NVRadio::doGetFirmwareNumbers(std::string &sFirmware, std::string &sFirmwareBuild) {
- CellularRadio::CODE rc = FAILURE;
+ICellularRadio::CODE ME910C1NVRadio::doGetFirmwareNumbers(std::string &sFirmware, std::string &sFirmwareBuild) {
+ ICellularRadio::CODE rc = FAILURE;
rc = getFirmware(sFirmware);
if (rc != SUCCESS){
@@ -74,9 +74,9 @@ CellularRadio::CODE ME910C1NVRadio::doGetFirmwareNumbers(std::string &sFirmware,
return rc;
}
-CellularRadio::CODE ME910C1NVRadio::doFumoReadConfig(const Json::Value& jArgs, Json::Value &jConfig)
+ICellularRadio::CODE ME910C1NVRadio::doFumoReadConfig(const Json::Value& jArgs, Json::Value &jConfig)
{
- CellularRadio::CODE rc = INVALID_ARGS;
+ ICellularRadio::CODE rc = INVALID_ARGS;
std::string sPath;
do
@@ -196,9 +196,9 @@ CellularRadio::CODE ME910C1NVRadio::doFumoReadConfig(const Json::Value& jArgs, J
return rc;
}
-CellularRadio::CODE ME910C1NVRadio::doFumoSetup(const Json::Value &jConfig, UpdateCb& stepCb)
+ICellularRadio::CODE ME910C1NVRadio::doFumoSetup(const Json::Value &jConfig, UpdateCb& stepCb)
{
- CellularRadio::CODE rc = FAILURE;
+ ICellularRadio::CODE rc = FAILURE;
std::string sCmd;
std::string sContextId = jConfig[KEY_FUMO_PDPID].asString();
@@ -215,7 +215,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoSetup(const Json::Value &jConfig, Upda
// AT#SGACT=<cid>,<stat>[,<userId>,<pwd>]
//
sCmd = "AT#SGACT=" + sContextId + ",0";
- rc = CellularRadio::sendBasicCommand(sCmd);
+ rc = sendBasicCommand(sCmd);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: Failed to deactivate PDP context"));
@@ -244,7 +244,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoSetup(const Json::Value &jConfig, Upda
if (!sApn.empty()) {
sCmd += ",\"" + sApn + "\"";
}
- rc = CellularRadio::sendBasicCommand(sCmd, 1000);
+ rc = sendBasicCommand(sCmd, 1000);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: Failed to setup PDP context"));
@@ -267,7 +267,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoSetup(const Json::Value &jConfig, Upda
// less than max packet size (timeout value in hundreds of milliseconds).
//
sCmd = "AT#SCFG=1," + sContextId + ",300,90,600,50";
- rc = CellularRadio::sendBasicCommand(sCmd);
+ rc = sendBasicCommand(sCmd);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: Failed to set connection configuration parameters"));
@@ -279,7 +279,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoSetup(const Json::Value &jConfig, Upda
// Activate PDP context
//
sCmd = "AT#SGACT=" + sContextId + ",1";
- rc = CellularRadio::sendBasicCommand(sCmd, 60 * 1000);
+ rc = sendBasicCommand(sCmd, 60 * 1000);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: Failed to activate PDP context"));
@@ -292,9 +292,9 @@ CellularRadio::CODE ME910C1NVRadio::doFumoSetup(const Json::Value &jConfig, Upda
return rc;
}
-CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, UpdateCb& stepCb)
+ICellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, UpdateCb& stepCb)
{
- CellularRadio::CODE rc = FAILURE;
+ ICellularRadio::CODE rc = FAILURE;
std::string sCmd;
std::string sResult;
@@ -305,7 +305,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
// AT#FTPTO= [<tout>]
// <tout> - time-out in 100 ms units
//
- rc = CellularRadio::sendBasicCommand("AT#FTPTO=2400");
+ rc = sendBasicCommand("AT#FTPTO=2400");
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: Failed to setup connection timeout"));
@@ -322,7 +322,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
sCmd += "\"" + jConfig[KEY_FUMO_ADDRESS].asString() + "\",";
sCmd += "\"" + jConfig[KEY_FUMO_USER].asString() + "\",";
sCmd += "\"" + jConfig[KEY_FUMO_PASSWORD].asString() + "\",1";
- rc = CellularRadio::sendBasicCommand(sCmd, 60 * 1000);
+ rc = sendBasicCommand(sCmd, 60 * 1000);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: Failed to open connection"));
@@ -344,7 +344,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
// 0 - binary
// 1 - ascii
//
- rc = CellularRadio::sendBasicCommand("AT#FTPTYPE=0", 1000);
+ rc = sendBasicCommand("AT#FTPTYPE=0", 1000);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: failed to set file transfer type"));
@@ -363,7 +363,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
sCmd += jConfig[KEY_FUMO_DIR].asString() + "/";
}
sCmd += "\"";
- rc = CellularRadio::sendBasicCommand(sCmd, 60 * 1000);
+ rc = sendBasicCommand(sCmd, 60 * 1000);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: failed to change working directory on the server"));
@@ -380,7 +380,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
//
sCmd = "AT#FTPGETOTA=";
sCmd += "\"" + jConfig[KEY_FUMO_FILE].asString() + "\",1,1";
- CellularRadio::sendBasicCommand(sCmd);
+ sendBasicCommand(sCmd);
//
// Noticed that after successful AT#FTPGETOTA the radio resets the connection.
@@ -396,12 +396,12 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
{
MTS::Thread::sleep(5000);
- rc = CellularRadio::sendBasicCommand("AT");
+ rc = sendBasicCommand("AT");
if (rc == SUCCESS) {
break;
}
- CellularRadio::resetConnection(1);
+ resetConnection(1);
}
oTimer.stop();
@@ -419,7 +419,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
printTrace("RADIO| AT#FTPMSG result [%s]", sResult.c_str());
- if (sResult.find(RSP_OK) == std::string::npos) {
+ if (sResult.find(ICellularRadio::RSP_OK) == std::string::npos) {
rc = FAILURE;
if(stepCb) {
stepCb(Json::Value("FUMO Error: failed to download the firmware file"));
@@ -450,7 +450,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
//
// AT#FTPCLOSE
//
- CellularRadio::CODE rcclose = CellularRadio::sendBasicCommand("AT#FTPCLOSE", 60 * 1000);
+ ICellularRadio::CODE rcclose = sendBasicCommand("AT#FTPCLOSE", 60 * 1000);
if (rcclose != SUCCESS && rc == SUCCESS) {
if(stepCb) {
// Only one "FUMO Error" message should be sent
@@ -468,9 +468,9 @@ CellularRadio::CODE ME910C1NVRadio::doFumoFtp(const Json::Value &jConfig, Update
return rc;
}
-CellularRadio::CODE ME910C1NVRadio::doFumoCleanup(const Json::Value &jConfig, UpdateCb& stepCb)
+ICellularRadio::CODE ME910C1NVRadio::doFumoCleanup(const Json::Value &jConfig, UpdateCb& stepCb)
{
- CellularRadio::CODE rc = FAILURE;
+ ICellularRadio::CODE rc = FAILURE;
std::string sCmd;
std::string sContextId = jConfig[KEY_FUMO_PDPID].asString();
@@ -479,7 +479,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoCleanup(const Json::Value &jConfig, Up
// Deactivate PDP context
//
sCmd = "AT#SGACT=" + sContextId + ",0";
- rc = CellularRadio::sendBasicCommand(sCmd, 10000);
+ rc = sendBasicCommand(sCmd, 10000);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: Failed to deactivate PDP context"));
@@ -488,9 +488,9 @@ CellularRadio::CODE ME910C1NVRadio::doFumoCleanup(const Json::Value &jConfig, Up
return rc;
}
-CellularRadio::CODE ME910C1NVRadio::doFumoApplyFirmware(const Json::Value &jConfig, UpdateCb& stepCb)
+ICellularRadio::CODE ME910C1NVRadio::doFumoApplyFirmware(const Json::Value &jConfig, UpdateCb& stepCb)
{
- CellularRadio::CODE rc = FAILURE;
+ ICellularRadio::CODE rc = FAILURE;
if (jConfig.isMember(KEY_FUMO_DRYRUN)) {
if(stepCb) {
@@ -499,7 +499,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoApplyFirmware(const Json::Value &jConf
return SUCCESS;
}
- rc = CellularRadio::sendBasicCommand("AT#OTAUP=0", 10000);
+ rc = sendBasicCommand("AT#OTAUP=0", 10000);
if (rc != SUCCESS) {
if(stepCb) {
stepCb(Json::Value("FUMO Error: failed to apply the firmware"));
@@ -514,11 +514,11 @@ CellularRadio::CODE ME910C1NVRadio::doFumoApplyFirmware(const Json::Value &jConf
return rc;
}
-CellularRadio::CODE ME910C1NVRadio::doFumoWaitNewFirmware(const Json::Value &jConfig, UpdateCb& stepCb)
+ICellularRadio::CODE ME910C1NVRadio::doFumoWaitNewFirmware(const Json::Value &jConfig, UpdateCb& stepCb)
{
std::string sFirmware;
std::string sFirmwareBuild;
- CellularRadio::CODE rc = FAILURE;
+ ICellularRadio::CODE rc = FAILURE;
if (jConfig.isMember(KEY_FUMO_DRYRUN)) {
if(stepCb) {
@@ -539,7 +539,7 @@ CellularRadio::CODE ME910C1NVRadio::doFumoWaitNewFirmware(const Json::Value &jCo
if (doGetFirmwareNumbers(sFirmware, sFirmwareBuild) != SUCCESS) {
// The radio is probably unavailable
- CellularRadio::resetConnection(100);
+ resetConnection(100);
continue;
}
@@ -570,9 +570,9 @@ CellularRadio::CODE ME910C1NVRadio::doFumoWaitNewFirmware(const Json::Value &jCo
}
-CellularRadio::CODE ME910C1NVRadio::doFumoPerform(const Json::Value &jConfig, UpdateCb& stepCb)
+ICellularRadio::CODE ME910C1NVRadio::doFumoPerform(const Json::Value &jConfig, UpdateCb& stepCb)
{
- CellularRadio::CODE rc = FAILURE;
+ ICellularRadio::CODE rc = FAILURE;
UpdateCb dummyCb;
@@ -606,10 +606,10 @@ CellularRadio::CODE ME910C1NVRadio::doFumoPerform(const Json::Value &jConfig, Up
return rc;
}
-CellularRadio::CODE ME910C1NVRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb)
+ICellularRadio::CODE ME910C1NVRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb)
{
Json::Value jConfig(Json::objectValue);
- CellularRadio::CODE rc = FAILURE;
+ ICellularRadio::CODE rc = FAILURE;
rc = doFumoReadConfig(jArgs, jConfig);
if (rc != SUCCESS) {
diff --git a/src/MTS_IO_ME910C1WWRadio.cpp b/src/MTS_IO_ME910C1WWRadio.cpp
index d26749a..0469d5d 100644
--- a/src/MTS_IO_ME910C1WWRadio.cpp
+++ b/src/MTS_IO_ME910C1WWRadio.cpp
@@ -32,8 +32,8 @@ ME910C1WWRadio::ME910C1WWRadio(const std::string& sPort)
}
-CellularRadio::CODE ME910C1WWRadio::setActiveFirmware(const Json::Value& jArgs) {
- CellularRadio::CODE rc;
+ICellularRadio::CODE ME910C1WWRadio::setActiveFirmware(const Json::Value& jArgs) {
+ ICellularRadio::CODE rc;
// Set command allows enabling a specific firmware image on products
// embedding 2 different firmware images:
@@ -76,9 +76,9 @@ CellularRadio::CODE ME910C1WWRadio::setActiveFirmware(const Json::Value& jArgs)
return sendBasicCommand(sCmd, 5000);
}
-CellularRadio::CODE ME910C1WWRadio::getActiveFirmware(std::string& sFwId) {
+ICellularRadio::CODE ME910C1WWRadio::getActiveFirmware(std::string& sFwId) {
std::string sCmd;
- CellularRadio::CODE rc;
+ ICellularRadio::CODE rc;
//
// Read command reports the current active firmware image:
// AT#FWSWITCH?
@@ -101,7 +101,7 @@ CellularRadio::CODE ME910C1WWRadio::getActiveFirmware(std::string& sFwId) {
sCmd = "AT#FWSWITCH?";
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to get active image number from radio using command [%s]",
getName().c_str(),
diff --git a/src/MTS_IO_ME910Radio.cpp b/src/MTS_IO_ME910Radio.cpp
index 42796e9..2b181d2 100644
--- a/src/MTS_IO_ME910Radio.cpp
+++ b/src/MTS_IO_ME910Radio.cpp
@@ -25,22 +25,22 @@
using namespace MTS::IO;
ME910Radio::ME910Radio(const std::string& sME910Model, const std::string& sPort)
-: CellularRadio(sME910Model, sPort)
+: TelitRadio(sME910Model, sPort)
{
}
-CellularRadio::CODE ME910Radio::setRxDiversity(const Json::Value& jArgs) {
+ICellularRadio::CODE ME910Radio::setRxDiversity(const Json::Value& jArgs) {
return FAILURE;
}
-CellularRadio::CODE ME910Radio::getFirmwareBuild(std::string& sFirmwareBuild) {
+ICellularRadio::CODE ME910Radio::getFirmwareBuild(std::string& sFirmwareBuild) {
std::string sCmd("AT#CFVR");
std::string sResult = sendCommand(sCmd);
- size_t end = sResult.find(RSP_OK);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
if (end == std::string::npos) {
printWarning("%s| Unable to get firmware build number [%s]",
getName().c_str(),
diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp
new file mode 100644
index 0000000..f3227a5
--- /dev/null
+++ b/src/MTS_IO_QuectelRadio.cpp
@@ -0,0 +1,612 @@
+/*
+ * 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_QuectelRadio.h"
+
+#include <mts/MTS_Logger.h>
+#include <mts/MTS_Thread.h>
+#include <mts/MTS_Text.h>
+
+using namespace MTS::IO;
+
+QuectelRadio::QuectelRadio(const std::string& sName, const std::string& sRadioPort)
+: CellularRadio (sName, sRadioPort)
+{
+}
+
+bool QuectelRadio::resetRadio(uint32_t iTimeoutMillis) {
+ printInfo("%s| Rebooting radio", getName().c_str());
+ if(sendBasicCommand("AT+CFUN=1,1") == SUCCESS) {
+ if(iTimeoutMillis > 5000) {
+ MTS::Thread::sleep(5000);
+ iTimeoutMillis -= 5000;
+ }
+ return resetConnection(iTimeoutMillis);
+ }
+
+ return false;
+}
+
+ICellularRadio::CODE QuectelRadio::getModel(std::string& sModel) {
+ printTrace("%s| Get Model", getName().c_str());
+ //Always returns SUCCESS because the model should be m_sName
+ sModel = getName();
+ std::string sCmd("AT+GMM");
+ std::string sResult = sendCommand(sCmd);
+ if (sResult.find("OK") == std::string::npos) {
+ printWarning("%s| Unable to get model from radio. Returning [%s]", getName().c_str(), getName().c_str());
+ return SUCCESS;
+ } else {
+ sModel = extractModelFromResult(sResult);
+ if(sModel.size() == 0) {
+ printWarning("%s| Unable to get model from radio. Returning [%s]", getName().c_str(), getName().c_str());
+ return SUCCESS;
+ }
+ }
+
+ printDebug("%s| Extracted [%s] from [%s] query", getName().c_str(), sModel.c_str(), sCmd.c_str());
+ if(sModel != getName()) {
+ printWarning("%s| Model identified [%s] does not match expected [%s]. Returning [%s]",
+ getName().c_str(), sModel.c_str(), getName().c_str(), sModel.c_str());
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::getIccid(std::string& sIccid) {
+ printTrace("%s| Get ICCID", getName().c_str());
+ sIccid = ICellularRadio::VALUE_NOT_SUPPORTED;
+
+ // AT+QCCID execution can take up to 300ms according to the datasheet. Setting timeout to 500ms just for sure.
+ std::string sCmd("AT+QCCID");
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get ICCID from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("+QCCID:");
+ if(start != std::string::npos) {
+ start += sizeof("+QCCID:");
+ sIccid = MTS::Text::trim(sResult.substr(start, end-start));
+ if(sIccid.size() == 0) {
+ printWarning("%s| Unable to get ICCID from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::getService(std::string& sService) {
+ printTrace("%s| Get Service", getName().c_str());
+ sService = ICellularRadio::VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+COPS?");
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get Service from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find(":") + 1; //Position right after "+COPS:"
+ std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ',');
+
+ int32_t iAccessTechnology;
+
+ // +COPS: <mode>[,<format>[,<oper>][,<Act>]]
+ if (vParts.size() < 4 || !MTS::Text::parse(iAccessTechnology, vParts[3])) {
+ printWarning("%s| Unable to get Service from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ switch(iAccessTechnology) {
+ case 0 : sService = "GPRS" ; break; // GSM
+ case 2 : sService = "WCDMA" ; break; // UTRAN
+ case 3 : sService = "EGPRS" ; break; // GSM W/EGPRS
+ case 4 : sService = "HSDPA" ; break; // UTRAN W/HSDPA
+ case 5 : sService = "WCDMA" ; break; // UTRAN W/HSUPA
+ case 6 : sService = "HSDPA" ; break; // UTRAN W/HSDPA and HSUPA
+ case 7 : sService = "LTE" ; break; // E-UTRAN
+ case 100 : sService = "CDMA" ; break; // CDMA
+
+ default: sService = ICellularRadio::VALUE_UNKNOWN; break;
+ }
+
+ printDebug("%s| Service ID: [%d][%s]", getName().c_str(), iAccessTechnology, sService.c_str());
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::getNetwork(std::string& sNetwork) {
+ /*
+ * TODO: Refactor using MccMncTable once it'll be corrected.
+ *
+ * The proper way to determine the current network is to do that
+ * by MCC and MNC fetched from the `getNetworkStatus` and `AT+QENG` command.
+ * By using MCC and MNC from `AT+QENG` we can fetch the name of the network
+ * reported by a currently connected base station even if the SIM card is
+ * not installed or if we are currently working is a roaming mode.
+ *
+ * Until MccMncTable implementation is not fixed, we are using the name
+ * of a currently selected operator (AT+COPS).
+ */
+ printTrace("%s| Get Network", getName().c_str());
+ sNetwork = ICellularRadio::VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+COPS?");
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
+
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get network name from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ // +COPS: <mode>[, <format>, <oper>,<AcT>]
+ // +COPS: vParts[0],vParts[1],vParts[2],vParts[3]
+ size_t start = sResult.find(":") + 1; //Position right after "+COPS:"
+ std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start)), ",");
+
+ if(vParts.size() > 3) {
+ const std::string sValue = vParts[2];
+
+ // +COPS: 0,0,"CHN-UNICOM UNICOM",7
+ // ^start ^end
+ // +COPS: 0,0,"AT&T",7
+ // ^st ^end
+ size_t start = sValue.find("\"") + 1;
+ size_t end = sValue.find_first_of(" \"", start);
+ sNetwork = sValue.substr(start, end-start);
+ } else {
+ sNetwork = ""; // Not connected to any network
+ }
+
+ return SUCCESS;
+}
+
+/* AT+QENG="servingcell" - Query the information of serving cells
+
+ (GSM network)
+ +QENG:"servingscell",<state>,"GSM",<mcc>,<mnc>,<lac>,<cellid>,<bsic>,<arfcn>,<band>,<rxlev>,<txp>,<rla>,<drx>,<c1>,<c2>,<gprs>,<tch>,<ts>,<ta>,<maio>,<hsn>,<rxlevsub>,<rxlevfull>,<rxqualsub>,<rxqualfull>,<voicecodec>
+
+ (WCDMA network)
+ +QENG:"servingcell",<state>,"WCDMA",<mcc>,<mnc>,<lac>,<cellid>,<uarfcn>,<psc>,<rac>,<rscp>,<ecio>,<phych>,<sf>,<slot>,<speech_code>,<comMod>
+
+ (LTE Network)
+ +QENG:"servingcell",<state>,"LTE",<is_tdd>,<mcc>,<mnc>,<cellid>,<pcid>,<earfcn>,<freq_band_ind>,<ul_bandwidth>,<dl_bandwidth>,<tac>,<rsrp>,<rsrq>,<rssi>,<sinr>,<srxlev>
+
+ The following modes are NOT currently handled:
+ - TD-SCDMA mode;
+ - CDMA mode;
+ - HDR mode;
+ - SRLTE mode.
+
+ In the case of TD-SCDMA mode:
+ +QENG:"servingscell",<state>,"TDSCDMA",<mcc>,<mnc>,<lac>,<cellid>,<pfreq>,<rssi>,<rscp>,<ecio>
+
+ In the case of CDMA mode or CDMA+HDR mode:
+ +QENG:"servingscell",<state>,"CDMA",<mcc>,<mnc>,<lac>,<cellid>,<bcch>,<rxpwr>,<ecio>,<txpwr>
+ [+QENG:"servingscell",<state>,"HDR",<mcc>,<mnc>,<lac>,<cellid>,<bcch>,<rxpwr>,<ecio>,<txpwr>]
+
+ In the case of SRLTE mode:
+ +QENG:"servingscell",<state>,"CDMA",<mcc>,<mnc>,<lac>,<cellid>,<bcch>,<rxpwr>,<ecio>,<txpwr>
+ +QENG:"servingcell",<state>,"LTE",<is_tdd>,<mcc>,<mnc>,<cellid>,<pcid>,<earfcn>,<freq_band_ind>,<ul_bandwidth>,<dl_bandwidth>,<tac>,<rsrp>,<rsrq>,<rssi>,<sinr><srxlev>
+*/
+CellularRadio::CODE QuectelRadio::getNetworkStatus(Json::Value& jData) {
+ const std::string RAT_GSM = "GSM";
+ const std::string RAT_WCDMA = "WCDMA";
+ const std::string RAT_LTE = "LTE";
+
+ int32_t iValue;
+ ACTIVEBAND abnd;
+ SERVICEDOMAIN sd;
+ std::string sValue;
+ std::string sRat; // Radio Access Technology which is currently used
+
+ printTrace("%s| Get Network Status", getName().c_str());
+
+ //Always get common network stats because this should never fail
+ //This way the basic stats are always returned even if AT+QENG fails below
+ getCommonNetworkStats(jData);
+
+ // IMSI is not provided by AT+QENG. Fetch it separately to keep the same interface
+ if (getImsi(sValue) == SUCCESS) {
+ jData[ICellularRadio::KEY_IMSI] = sValue;
+ }
+
+ // Network Name is not explicitly provided by AT+QENG. Fetch it separately to keep the same interface
+ // TODO: Replace with lookup by MCC and MNC once MccMncTable is fixed.
+ if (getNetwork(sValue) == SUCCESS) {
+ jData[ICellularRadio::KEY_NETWORK] = sValue;
+ }
+
+ std::string sCmd;
+ std::string sResult;
+
+ sCmd = "AT+QENG=\"servingcell\"";
+ sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 200);
+ if (sResult.find("+QENG: \"servingcell\"") == std::string::npos) {
+ printDebug("%s| Network Status command returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ printTrace("%s| Network Status:\n%s\n", getName().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 "+QENG:"
+ size_t end = sResult.rfind(ICellularRadio::RSP_OK);
+ std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ",");
+ Json::Value jDebug;
+ Json::Value jQuectelDebug;
+
+ if (vParts.size() < 3) {
+ printDebug("%s| Network Status command reponse is an unknown format: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ printTrace("%s| Network Status:\n%s\n", getName().c_str(), jData.toStyledString().c_str());
+ return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function
+ } else {
+ // UE state and Access technology, Quectel-specific information
+ jQuectelDebug["state"] = vParts[1];
+
+ sRat = MTS::Text::trim(vParts[2], '"');
+ jQuectelDebug["rat"] = sRat;
+ }
+
+ // +QENG:"servingscell",<state>,"GSM",<mcc>,<mnc>,<lac>,<cellid>,<bsic>,<arfcn>,<band>,<rxlev>,<txp>,<rla>,<drx>,<c1>,<c2>,<gprs>,<tch>,<ts>,<ta>,<maio>,<hsn>,<rxlevsub>,<rxlevfull>,<rxqualsub>,<rxqualfull>,<voicecodec>
+ // +QENG: [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13],[14],[15], [16], [17],[18],[19], [20], [21], [22], [23], [24], [25], [26]
+ if (sRat == RAT_GSM) {
+ //Parse as GSM Network Format
+ jData[ICellularRadio::KEY_MCC] = vParts[3];
+ jData[ICellularRadio::KEY_MNC] = vParts[4];
+ jData[ICellularRadio::KEY_LAC] = vParts[5];
+ jData[ICellularRadio::KEY_CID] = vParts[6];
+ jQuectelDebug["bsic"] = vParts[7];
+ jData[ICellularRadio::KEY_CHANNEL] = vParts[8];
+
+ if (convertToActiveBand(vParts[9], abnd) == SUCCESS && convertActiveBandToString(abnd, sValue) == SUCCESS) {
+ jData[ICellularRadio::KEY_ABND] = sValue;
+ }
+
+ jData[ICellularRadio::KEY_RSSIDBM] = vParts[10]; // Values already negative. No need to substract 111 as stated in a datasheet
+ jData[ICellularRadio::KEY_TXPWR] = vParts[11];
+ jQuectelDebug["rla"] = vParts[12];
+ jQuectelDebug["drx"] = vParts[13];
+ jQuectelDebug["c1"] = vParts[14];
+ jQuectelDebug["c2"] = vParts[15];
+ jQuectelDebug["gprs"] = vParts[16];
+ jQuectelDebug["tch"] = vParts[17];
+ jQuectelDebug["ts"] = vParts[18];
+ jQuectelDebug["ta"] = vParts[19];
+ jQuectelDebug["maio"] = vParts[20];
+ jQuectelDebug["hsn"] = vParts[21];
+ jQuectelDebug["rxlevsub"] = vParts[22];
+ jQuectelDebug["rxlevfull"] = vParts[23];
+ jQuectelDebug["rxqualsub"] = vParts[24];
+ jQuectelDebug["rxqualfull"] = vParts[25];
+ jQuectelDebug["voicecodec"] = vParts[26];
+
+ // Service Domain is not provided by AT+QENG. Fetch it separately to keep the same interface
+ if (getServiceDomain(sd) == SUCCESS && convertServiceDomainToString(sd, sValue) == SUCCESS) {
+ jData[ICellularRadio::KEY_SD] = sValue;
+ }
+
+ // The following fields can NOT be fetched for Quectel in GSM mode: RAC, MM, RR, NOM
+
+ jData["quectelDebug"] = jQuectelDebug;
+ }
+
+ // +QENG:"servingcell",<state>,"WCDMA",<mcc>,<mnc>,<lac>,<cellid>,<uarfcn>,<psc>,<rac>,<rscp>,<ecio>,<phych>,<sf>,<slot>,<speech_code>,<comMod>
+ // +QENG: [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12],[13], [14], [15], [16]
+ else if(sRat == RAT_WCDMA) {
+ //Parse as WCDMA Network Format
+ jData[ICellularRadio::KEY_MCC] = vParts[3];
+ jData[ICellularRadio::KEY_MNC] = vParts[4];
+ jData[ICellularRadio::KEY_LAC] = vParts[5];
+ jData[ICellularRadio::KEY_CID] = vParts[6];
+ jData[ICellularRadio::KEY_CHANNEL] = vParts[7];
+ jDebug[ICellularRadio::KEY_PSC] = vParts[8];
+ jData[ICellularRadio::KEY_RAC] = vParts[9];
+ jDebug[ICellularRadio::KEY_RSCP] = vParts[10];
+ jDebug[ICellularRadio::KEY_ECIO] = vParts[11];
+ jQuectelDebug["phych"] = vParts[12];
+ jQuectelDebug["sf"] = vParts[13];
+ jQuectelDebug["slot"] = vParts[14];
+ jQuectelDebug["speechCode"] = vParts[15];
+ jQuectelDebug["comMod"] = vParts[16];
+
+ // The following fields can NOT be fetched for Quectel in WCDMA mode: TXPWR, DRX, MM, RR, NOM, BLER
+
+ // RSSI is not provided by AT+QENG in WCDMA mode. It was filled above by the getCommonNetworkStats
+
+ // Service Domain is not provided by AT+QENG. Fetch it separately to keep the same interface
+ if (getServiceDomain(sd) == SUCCESS && convertServiceDomainToString(sd, sValue) == SUCCESS) {
+ jDebug[ICellularRadio::KEY_SD] = sValue;
+ }
+
+ // BLER is not provided by AT+QENG. Set to constant
+ jDebug[ICellularRadio::KEY_BLER] = "000";
+
+ // Get the radio band given the channel (UARFCN)
+ RadioBandMap radioBandMap(vParts[7], ICellularRadio::VALUE_TYPE_CDMA);
+ jData[ICellularRadio::KEY_ABND] = radioBandMap.getRadioBandName();
+
+ jData["quectelDebug"] = jQuectelDebug;
+ jData[ICellularRadio::KEY_DEBUG] = jDebug;
+ }
+
+ // +QENG:"servingcell",<state>,"LTE",<is_tdd>,<mcc>,<mnc>,<cellid>,<pcid>,<earfcn>,<freq_band_ind>,<ul_bandwidth>,<dl_bandwidth>,<tac>,<rsrp>,<rsrq>,<rssi>,<sinr>,<srxlev>
+ // +QENG: [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17]
+ else if(sRat == RAT_LTE) {
+ //Parse as LTE Network Format
+ jQuectelDebug["isTdd"] = vParts[3];
+ jData[ICellularRadio::KEY_MCC] = vParts[4];
+ jData[ICellularRadio::KEY_MNC] = vParts[5];
+ jData[ICellularRadio::KEY_CID] = vParts[6];
+ jQuectelDebug["pcid"] = vParts[7];
+ jData[ICellularRadio::KEY_CHANNEL] = vParts[8];
+ jQuectelDebug["freqBandInd"] = vParts[9];
+ jQuectelDebug["ulBandwidth"] = vParts[10];
+ jQuectelDebug["dlBandwidth"] = vParts[11];
+ jData["tac"] = vParts[12];
+ jDebug["rsrp"] = vParts[13];
+ jDebug["rsrq"] = vParts[14];
+ jDebug[ICellularRadio::KEY_RSSIDBM] = vParts[15];
+ jQuectelDebug["sinr"] = vParts[16];
+ jQuectelDebug["srxlev"] = vParts[17];
+
+ // Get the radio band given the channel (EARFCN)
+ RadioBandMap radioBandMap(vParts[8], ICellularRadio::VALUE_TYPE_LTE);
+ jData[ICellularRadio::KEY_ABND] = radioBandMap.getRadioBandName();
+
+ // Service Domain is not provided by AT+QENG. Fetch it separately to keep the same interface
+ if (getServiceDomain(sd) == SUCCESS && convertServiceDomainToString(sd, sValue) == SUCCESS) {
+ jDebug[ICellularRadio::KEY_SD] = sValue;
+ }
+
+ // LAC is not provided by AT+QENG in WCDMA mode. Use another command instead
+ jData[ICellularRadio::KEY_LAC] = queryLteLac();
+
+ jData["quectelDebug"] = jQuectelDebug;
+ jData[ICellularRadio::KEY_DEBUG] = jDebug;
+ }
+
+ printTrace("%s| Network Status:\n%s\n", getName().c_str(), jData.toStyledString().c_str());
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& iDbm) {
+ int dbmSteps, minValue, maxValue, rssiOffset;
+ int rawDbm;
+
+ if(iRssi >= 0 && iRssi < 99) {
+ // normal scaling
+ dbmSteps = 2;
+ minValue = -113;
+ maxValue = -51;
+ rssiOffset = 0;
+ } else if(iRssi >= 100 && iRssi < 199) {
+ // TD-SCDMA scaling
+ dbmSteps = 1;
+ minValue = -116;
+ maxValue = -25;
+ rssiOffset = 100;
+ } else {
+ return FAILURE; // invalid, not known or not detectable
+ }
+
+ rawDbm = minValue + ((iRssi - rssiOffset) * dbmSteps);
+ iDbm = std::min(maxValue, rawDbm);
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::convertdBmToSignalStrength(const int32_t& iDBm, int32_t& iRssi) {
+ //Quectel Conversion FOR NORMAL SCALING
+ const int dbmSteps = 2;
+ const int minValue = -113;
+ const int rssiOffset = 0;
+
+ if (iDBm < -113) {
+ iRssi = 0;
+ } else if (iDBm > -51) {
+ iRssi = 31;
+ } else {
+ iRssi = ((iDBm - minValue) / dbmSteps) + rssiOffset;
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::setMdn(const Json::Value& jArgs) {
+ printTrace("%s| Set MDN", getName().c_str());
+ return NOT_APPLICABLE;
+}
+
+ICellularRadio::CODE QuectelRadio::getServiceDomain(ICellularRadio::SERVICEDOMAIN& sd) {
+ printTrace("%s| Get Service Domain", getName().c_str());
+
+ std::string sCmd("AT+QCFG=\"servicedomain\"");
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
+
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get service domain using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ // +QCFG: "servicedomain",<service>
+ size_t start = sResult.find(",") + 1; // Position right after comma
+ std::string sServiceDomain = MTS::Text::trim(sResult.substr(start, end-start));
+ int iValue = -1;
+
+ if (!MTS::Text::parse(iValue, sServiceDomain)) {
+ printWarning("%s| Failed to parse service domain from command output [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ switch (iValue) {
+ case 0: sd = SERVICEDOMAIN::CS_ONLY; break;
+ case 1: sd = SERVICEDOMAIN::PS_ONLY; break;
+ case 2: sd = SERVICEDOMAIN::CSPS; break;
+
+ default: return FAILURE; // Unknown
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::getIsSimInserted(bool& bData) {
+ printTrace("%s| Get SIM insertion status", getName().c_str());
+
+ // AT+QSIMSTAT? execution can take up to 300ms according to the datasheet. Setting timeout to 500ms just for sure.
+ std::string sCmd("AT+QSIMSTAT?");
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
+ const std::string sPrefix = "+QSIMSTAT: ";
+ size_t start = sResult.find(sPrefix);
+ size_t end = sResult.rfind(ICellularRadio::RSP_OK);
+
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get SIM insertion status from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ if (start == std::string::npos) {
+ printDebug("%s| AT+QSIMSTAT? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ // +QSIMSTAT: <enable>,<inserted_status>
+ start += sPrefix.size();
+ std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ',');
+
+ if(vParts.size() != 2) {
+ printWarning("%s| Unable to parse SIM insertion status from response [%s]", getName().c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ if (vParts[1] == "1") { // Inserted
+ bData = true;
+ } else { // Removed or Unknown, before (U)SIM initialization
+ bData = false;
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) {
+ printTrace("%s| Get SIM unlock attempts left", getName().c_str());
+
+ // AT+QPINC execution can take more time that expected. Set timeout to 2s just to be sure.
+ std::string sCmd("AT+QPINC=\"SC\"");
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 2000);
+
+ const std::string sPrefix = "+QPINC: \"SC\",";
+ size_t start = sResult.find(sPrefix);
+ size_t end = sResult.rfind(ICellularRadio::RSP_OK);
+
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get SIM unlock attempts from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ if (start == std::string::npos) {
+ printDebug("%s| AT+QPINC returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ // +QPINC: <facility>,<pincounter>,<pukcounter>
+ // [x] ,[0] ,[1]
+ start += sPrefix.size();
+ std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ',');
+
+ if(vParts.size() != 2) {
+ printWarning("%s| Unable to parse SIM unlock attempts left from response [%s]", getName().c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ if (!MTS::Text::parse(iAttemptsPin, vParts[0])) {
+ printWarning("%s| Unable to parse SIM PIM unlock attempts from response [%s]", getName().c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ if (!MTS::Text::parse(iAttemptsPuk, vParts[1])) {
+ printWarning("%s| Unable to parse SIM PUK unlock attempts from response [%s]", getName().c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::convertToActiveBand(const std::string& sQuectelBand, ICellularRadio::ACTIVEBAND& band) {
+ int iQuectelBand = -1;
+
+ if (!MTS::Text::parse(iQuectelBand, sQuectelBand)) {
+ return FAILURE; // probably "-", other band
+ }
+
+ switch (iQuectelBand) {
+ case 0: band = ACTIVEBAND::DCS_1800; break;
+ case 1: band = ACTIVEBAND::PCS_1900; break;
+
+ default: return FAILURE; // actually, this case should never happen
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::getRadioNetworkMode(RADIO_NETWORK_MODE &mode)
+{
+ // AT+QCFG="nwscanmode" execution can take up to 300ms according to the datasheet. Setting timeout to 500ms just for sure.
+ std::string sCmd("AT+QCFG=\"nwscanmode\"");
+ std::string cmdResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
+ if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) {
+ printDebug("%s| AT+QCFG? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str());
+ return FAILURE;
+ }
+ switch (stoi(MTS::Text::split(cmdResult, ',')[1])) {
+ case 1: mode = ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY; break;
+ case 5: mode = ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY; break;
+ case 0: mode = ICellularRadio::RADIO_NETWORK_MODE_AUTO; break;
+ default: mode = ICellularRadio::RADIO_NETWORK_MODE_UNKNOWN; break;
+ }
+ return SUCCESS;
+}
+
+ICellularRadio::CODE QuectelRadio::setRadioNetworkMode(RADIO_NETWORK_MODE mode)
+{
+ std::string value;
+ switch (mode) {
+ case ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY: value = "1"; break;
+ case ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY: value = "5"; break;
+ case ICellularRadio::RADIO_NETWORK_MODE_AUTO: value = "0"; break;
+ default: return FAILURE;
+ }
+ std::string sCmd("AT+QCFG=\"nwscanmode\",");
+ sCmd += value;
+
+ // AT+QCFG="nwscanmode" execution can take up to 300ms according to the datasheet. Setting timeout to 500ms just for sure.
+ std::string cmdResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+
+ if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) {
+ printDebug("%s| AT+QCFG? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str());
+ return FAILURE;
+ }
+ return SUCCESS;
+}
diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp
new file mode 100644
index 0000000..340c0ac
--- /dev/null
+++ b/src/MTS_IO_TelitRadio.cpp
@@ -0,0 +1,666 @@
+/*
+ * 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_Logger.h>
+#include <mts/MTS_Thread.h>
+#include <mts/MTS_Text.h>
+
+using namespace MTS::IO;
+
+TelitRadio::TelitRadio(const std::string& sName, const std::string& sRadioPort)
+: CellularRadio(sName, sRadioPort)
+{
+}
+
+bool TelitRadio::resetRadio(uint32_t iTimeoutMillis) {
+
+ printInfo("%s| Rebooting radio", getName().c_str());
+ if(sendBasicCommand("AT#REBOOT") == SUCCESS) {
+ if(iTimeoutMillis > 5000) {
+ MTS::Thread::sleep(5000);
+ iTimeoutMillis -= 5000;
+ }
+ return resetConnection(iTimeoutMillis);
+ }
+
+ return false;
+}
+
+
+ICellularRadio::CODE TelitRadio::getModel(std::string& sModel) {
+ printTrace("%s| Get Model", getName().c_str());
+ //Always returns SUCCESS because the model should be m_sName
+ sModel = getName();
+ std::string sCmd("ATI4");
+ std::string sResult = sendCommand(sCmd);
+ if (sResult.find("OK") == std::string::npos) {
+ printWarning("%s| Unable to get model from radio. Returning [%s]", getName().c_str(), getName().c_str());
+ return SUCCESS;
+ } else {
+ sModel = extractModelFromResult(sResult);
+ if(sModel.size() == 0) {
+ printWarning("%s| Unable to get model from radio. Returning [%s]", getName().c_str(), getName().c_str());
+ return SUCCESS;
+ }
+ }
+
+ printDebug("%s| Extracted [%s] from [%s] query", getName().c_str(), sModel.c_str(), sCmd.c_str());
+ if(sModel != getName()) {
+ printWarning("%s| Model identified [%s] does not match expected [%s]. Returning [%s]",
+ getName().c_str(), sModel.c_str(), getName().c_str(), sModel.c_str());
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE TelitRadio::getIccid(std::string& sIccid) {
+ printTrace("%s| Get ICCID", getName().c_str());
+ sIccid = ICellularRadio::VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT#CCID");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get ICCID from radio using command [%s]", getName().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]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
+
+ICellularRadio::CODE TelitRadio::getService(std::string& sService) {
+ printTrace("%s| Get Service", getName().c_str());
+ sService = ICellularRadio::VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT#PSNT?");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(ICellularRadio::RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get Service from radio using command [%s]", getName().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 = ICellularRadio::VALUE_UNKNOWN; break;
+ }
+
+ printDebug("%s| Service ID: [%d][%s]", getName().c_str(), iService, sService.c_str());
+ }
+ return SUCCESS;
+}
+
+ICellularRadio::CODE TelitRadio::getNetwork(std::string& sNetwork) {
+ Json::Value jData;
+
+ printTrace("%s| Get Network", getName().c_str());
+ sNetwork = ICellularRadio::VALUE_NOT_SUPPORTED;
+
+ if(getNetworkStatus(jData) == SUCCESS) {
+ if(jData.isMember(ICellularRadio::KEY_NETWORK)) {
+ sNetwork = jData[ICellularRadio::KEY_NETWORK].asString();
+ return SUCCESS;
+ }
+ }
+ 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> -
+*/
+ICellularRadio::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", getName().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 (getName().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]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ printTrace("%s| Network Status:\n%s\n", getName().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", getName().c_str());
+ printTrace("%s| Network Status:\n%s\n", getName().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]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ printTrace("%s| Network Status:\n%s\n", getName().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]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ printTrace("%s| Network Status:\n%s\n", getName().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[ICellularRadio::KEY_MCC] = MTS::Text::strip(vPLMN[0], '"');
+ jData[ICellularRadio::KEY_MNC] = MTS::Text::strip(vPLMN[1], '"');
+ }
+
+ jData[ICellularRadio::KEY_CHANNEL] = vParts[1];
+ }
+
+ if (vParts.size() == GSM_NETWORK_FORMAT ) {
+ //Parse as GSM Network Format
+ jData[ICellularRadio::KEY_RSSIDBM] = vParts[2];
+ jData[ICellularRadio::KEY_LAC] = vParts[3];
+ jData[ICellularRadio::KEY_RAC] = vParts[4];
+ jData[ICellularRadio::KEY_TXPWR] = vParts[5];
+ jData[ICellularRadio::KEY_MM] = vParts[6];
+ jData[ICellularRadio::KEY_RR] = vParts[7];
+ jData[ICellularRadio::KEY_NOM] = vParts[8];
+ jData[ICellularRadio::KEY_CID] = vParts[9];
+ jData[ICellularRadio::KEY_IMSI] = MTS::Text::strip(vParts[10], '"');
+ jData[ICellularRadio::KEY_NETWORK] = MTS::Text::strip(vParts[11], '"');
+ if(MTS::Text::parse(iValue, vParts[12]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) {
+ jData[ICellularRadio::KEY_SD] = sValue;
+ }
+ if(MTS::Text::parse(iValue, vParts[13]) && convertActiveBandToString((ACTIVEBAND)iValue, sValue) == SUCCESS) {
+ jData[ICellularRadio::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) && (getName().find("ME910C1-WW") == std::string::npos)) {
+ Json::Value jDebug;
+
+ //Parse as WCDMA Network Format
+
+ jDebug[ICellularRadio::KEY_PSC] = vParts[2];
+ jDebug[ICellularRadio::KEY_ECIO] = vParts[3];
+ jDebug[ICellularRadio::KEY_RSCP] = vParts[4];
+
+ jData[ICellularRadio::KEY_RSSIDBM] = vParts[5];
+ jData[ICellularRadio::KEY_LAC] = vParts[6];
+ jData[ICellularRadio::KEY_RAC] = vParts[7];
+
+ jDebug[ICellularRadio::KEY_TXPWR] = vParts[8];
+ jDebug[ICellularRadio::KEY_DRX] = vParts[9];
+ jDebug[ICellularRadio::KEY_MM] = vParts[10];
+ jDebug[ICellularRadio::KEY_RR] = vParts[11];
+ jDebug[ICellularRadio::KEY_NOM] = vParts[12];
+
+ if(vParts[13].size() != 0) {
+ jDebug[ICellularRadio::KEY_BLER] = vParts[13];
+ } else {
+ jDebug[ICellularRadio::KEY_BLER] = "000";
+ }
+
+ jData[ICellularRadio::KEY_CID] = vParts[14];
+ jData[ICellularRadio::KEY_IMSI] = MTS::Text::strip(vParts[15], '"');
+ jData[ICellularRadio::KEY_NETWORK] = MTS::Text::strip(vParts[16], '"');
+
+ // Get the radio band given the channel (UARFCN)
+ RadioBandMap radioBandMap(vParts[1], CellularRadio::ICellularRadio::VALUE_TYPE_CDMA);
+ jData[ICellularRadio::KEY_ABND] = radioBandMap.getRadioBandName();
+
+ if(MTS::Text::parse(iValue, vParts[17]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) {
+ jDebug[ICellularRadio::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[ICellularRadio::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[ICellularRadio::KEY_RAC] = vParts[6];
+ vParts.erase(vParts.begin() + 6);
+ }
+
+ jDebug["rsrp"] = vParts[2];
+ jDebug[ICellularRadio::KEY_RSSIDBM] = vParts[3];
+ jDebug["rsrq"] = vParts[4];
+
+ jData["tac"] = vParts[5];
+ jDebug[ICellularRadio::KEY_TXPWR] = vParts[6];
+ jData[ICellularRadio::KEY_DRX] = vParts[7];
+ jDebug[ICellularRadio::KEY_MM] = vParts[8];
+ jDebug["rrc"] = vParts[9];
+ jData[ICellularRadio::KEY_CID] = MTS::Text::strip(vParts[10], '"');
+ jData[ICellularRadio::KEY_IMSI] = MTS::Text::strip(vParts[11], '"');
+ jData[ICellularRadio::KEY_NETWORK] = MTS::Text::strip(vParts[12], '"');
+
+ // Get the radio band given the channel (EARFCN)
+ RadioBandMap radioBandMap(vParts[1], ICellularRadio::VALUE_TYPE_LTE);
+ jData[ICellularRadio::KEY_ABND] = radioBandMap.getRadioBandName();
+
+ jData[ICellularRadio::KEY_LAC] = queryLteLac();
+
+ if(MTS::Text::parse(iValue, vParts[13]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) {
+ jDebug[ICellularRadio::KEY_SD] = sValue;
+ }
+
+ jData[ICellularRadio::KEY_DEBUG] = jDebug;
+ }
+
+ printTrace("%s| Network Status:\n%s\n", getName().c_str(), jData.toStyledString().c_str());
+ return SUCCESS;
+}
+
+ICellularRadio::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;
+}
+
+ICellularRadio::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;
+}
+
+ICellularRadio::CODE TelitRadio::setMdn(const Json::Value& jArgs) {
+ printTrace("%s| Set MDN", getName().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(ICellularRadio::RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MDN for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+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 = ICellularRadio::VALUE_CARRIER_SPRINT;
+ bResult = true;
+ } else
+ if(cId == '1') {
+ sCarrier = ICellularRadio::VALUE_CARRIER_AERIS;
+ bResult = true;
+ } else
+ if(cId == '2') {
+ sCarrier = ICellularRadio::VALUE_CARRIER_VERIZON;
+ bResult = true;
+ } else
+ if(cId == '3') {
+ sCarrier = ICellularRadio::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;
+
+}
+
+ICellularRadio::CODE TelitRadio::getRadioNetworkMode(RADIO_NETWORK_MODE &mode)
+{
+ std::string sCmd("AT+WS46?");
+ std::string cmdResult = sendCommand(sCmd);
+ if (cmdResult.find("+WS46:") == std::string::npos) {
+ printDebug("%s| AT+WS46? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str());
+ return FAILURE;
+ }
+ switch (stoi(MTS::Text::split(cmdResult, ':')[1])) {
+ case 12: mode = ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY; break;
+ case 22: mode = ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY; break;
+ case 25: mode = ICellularRadio::RADIO_NETWORK_MODE_AUTO; break;
+ default: mode = ICellularRadio::RADIO_NETWORK_MODE_UNKNOWN; break;
+ }
+ return SUCCESS;
+}
+
+ICellularRadio::CODE TelitRadio::setRadioNetworkMode(RADIO_NETWORK_MODE mode)
+{
+ std::string value;
+ switch (mode) {
+ case ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY: value = "12"; break;
+ case ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY: value = "22"; break;
+ case ICellularRadio::RADIO_NETWORK_MODE_AUTO: value = "25"; break;
+ default: return FAILURE;
+ }
+ std::string sCmd("AT+WS46=");
+ sCmd += value;
+ std::string cmdResult = sendCommand(sCmd);
+ if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) {
+ printDebug("%s| AT+WS46? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str());
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+ICellularRadio::CODE TelitRadio::getIsSimInserted(bool& bData) {
+ printTrace("%s| Get SIM insertion status", getName().c_str());
+ std::string sCmd("AT#SIMDET?");
+ std::string sResult = sendCommand(sCmd);
+
+ const std::string sPrefix = "#SIMDET: ";
+ size_t start = sResult.find(sPrefix);
+ size_t end = sResult.rfind(ICellularRadio::RSP_OK);
+
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get SIM insertion status from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ if (start == std::string::npos) {
+ printDebug("%s| AT#SIMDET? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ // #SIMDET: <mode>,<simin>
+ start += sPrefix.size();
+ std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ',');
+
+ if(vParts.size() != 2) {
+ printWarning("%s| Unable to parse SIM insertion status from response [%s]", getName().c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ if (vParts[1] == "1") { // <simin>
+ bData = true;
+ } else {
+ bData = false;
+ }
+
+ return SUCCESS;
+}
+
+ICellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) {
+ std::string sLockStatus;
+ ICellularRadio::CODE retCode;
+
+ retCode = getSimLockStatus(sLockStatus);
+ if (retCode != SUCCESS) {
+ printWarning("%s| Unable determine the number of SIM unlock attempts: SIM lock status is unavailable [%s]", getName().c_str(), sLockStatus.c_str());
+ return retCode;
+ }
+
+ return getSimLockAttempts(iAttemptsPin, iAttemptsPuk, sLockStatus);
+}
+
+ICellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk, const std::string& sLockStatus) {
+ printTrace("%s| Get SIM unlock attempts left", getName().c_str());
+ std::string sCmd("AT#PCT");
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500);
+ std::string sValue;
+ int iValue;
+
+ const std::string sPrefix = "#PCT: ";
+ size_t start = sResult.find(sPrefix);
+ size_t end = sResult.rfind(ICellularRadio::RSP_OK);
+
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get SIM unlock attempts from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ if (start == std::string::npos) {
+ printDebug("%s| AT#PCT? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ // #PCT: <n>
+ start += sPrefix.size();
+ sValue = MTS::Text::trim(sResult.substr(start, end-start));
+
+ if (!MTS::Text::parse(iValue, sValue)) {
+ printWarning("%s| Unable to parse SIM unlock attempts from response [%s]", getName().c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ if (sLockStatus == "READY" || sLockStatus == "SIM PIN") {
+ iAttemptsPin = iValue; // Some PIN attempts left, maximum PUK attempts left
+ iAttemptsPuk = 10;
+ } else {
+ iAttemptsPin = 0; // No PIN attempts left
+ iAttemptsPuk = iValue;
+ }
+
+ return SUCCESS;
+}