/* * Copyright (C) 2015 by Multi-Tech Systems * * This file is part of libmts-io. * * libmts-io is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * libmts-io is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libmts-io. If not, see . * */ /*! \file MTS_IO_LE910Radio.cpp \brief A brief description \date Nov 6, 2014 \author sgodinez A more elaborate description */ #include #include #include using namespace MTS::IO; LE910Radio::LE910Radio(const std::string& sLE910Model, const std::string& sPort) : TelitRadio(sLE910Model, sPort) { } 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") { return FAILURE; } std::string sCmd = "AT#RXDIV="; sCmd += jArgs["enabled"].asString(); sCmd += ",1"; return sendBasicCommand(sCmd); } ICellularRadio::CODE LE910Radio::getModemLocation(std::string& sLocation) { const std::string& whitespace = " \t"; printTrace("LE910Radio getModemLocation"); std::string sCmd("AT$GPSACP"); std::string sResult = sendCommand(sCmd); if (sResult.find("$GPSACP: ") == std::string::npos) { printDebug("AT$GPSACP command returned unexpected response: [%s]", sResult.c_str()); return FAILURE; } printDebug("modem reply: [%s]", sResult.c_str()); size_t start = sResult.find(':'); if (start==std::string::npos) { start = 0; } else { start++; } start = sResult.find_first_not_of(whitespace, start); size_t stop = sResult.find('\n', start); sLocation = sResult.substr(start, stop - start - 1); printDebug("function reply: [%s]", sLocation.c_str()); return SUCCESS; } ICellularRadio::CODE LE910Radio::setUeModeOfOperation(ICellularRadio::UE_MODES_OF_OPERATION mode) { printTrace("%s| Set UE Mode Of Operation", getName().c_str()); std::string sValue; switch (mode) { case ICellularRadio::UE_MODES_OF_OPERATION::PS_MODE1: sValue = "3"; break; case ICellularRadio::UE_MODES_OF_OPERATION::PS_MODE2: sValue = "0"; break; case ICellularRadio::UE_MODES_OF_OPERATION::CS_PS_MODE1: sValue = "1"; break; case ICellularRadio::UE_MODES_OF_OPERATION::CS_PS_MODE2: sValue = "2"; break; default: printError("%s| Set UE Mode Of Operation: invalid argument", getName().c_str()); return INVALID_ARGS; } const int dTimeout = 1000; // ms const std::string sCommand = "AT+CEMODE=" + sValue; return sendBasicCommand(sCommand, dTimeout); } ICellularRadio::CODE LE910Radio::getUeModeOfOperation(ICellularRadio::UE_MODES_OF_OPERATION& mode) { printTrace("%s| Get UE Mode Of Operation", getName().c_str()); const std::string sCommand = "AT+CEMODE?"; const int dTimeout = 1000; // ms std::string sResult = sendCommand(sCommand, ICellularRadio::DEFAULT_BAIL_STRINGS, dTimeout); printTrace("%s| Got response from the radio: %s", getName().c_str(), sResult.c_str()); size_t end = sResult.rfind(ICellularRadio::RSP_OK); if (std::string::npos == end) { printError("%s| Unable to get UE Mode Of Operation from radio using command [%s]", getName().c_str(), sCommand.c_str()); return FAILURE; } const std::string sLabel = "+CEMODE: "; size_t start = sResult.find(sLabel); if (std::string::npos == start) { printError("%s| Unable to get UE Mode Of Operation from radio using command [%s]", getName().c_str(), sCommand.c_str()); return FAILURE; } start += sLabel.length(); const std::string sValue = MTS::Text::trim(sResult.substr(start, end - start)); uint8_t uiValue; if (!MTS::Text::parse(uiValue, sValue)) { printError("%s| Unable to parse CEMODE from response [%s]", getName().c_str(), sResult.c_str()); return FAILURE; } CODE rc; switch (uiValue) { case 0: mode = ICellularRadio::UE_MODES_OF_OPERATION::PS_MODE2; rc = SUCCESS; break; case 1: mode = ICellularRadio::UE_MODES_OF_OPERATION::CS_PS_MODE1; rc = SUCCESS; break; case 2: mode = ICellularRadio::UE_MODES_OF_OPERATION::CS_PS_MODE2; rc = SUCCESS; break; case 3: mode = ICellularRadio::UE_MODES_OF_OPERATION::PS_MODE1; rc = SUCCESS; break; default: printError("%s| Unable to parse CEMODE from response [%s]", getName().c_str(), sResult.c_str()); mode = ICellularRadio::UE_MODES_OF_OPERATION::UNKNOWN_MODE; rc = FAILURE; break; } return rc; } const std::vector& LE910Radio::getDiagCommands(bool bIsSimReady) { // Declare as static to initialize only when used, but cache the results. const static std::vector vCommands { // Radio model and firmware: "AT+CGMI", "AT+CGMM", "AT+CGMR", "AT#SWPKGV", "AT#CFVR", // All carrier profiles that are supported: "AT#FWSWITCH=?", // Current operator profile on the radio side: "AT#FWSWITCH?", "AT+CGSN", // SIM card information: "AT#SIMDET?", "AT#CCID", "AT+CPIN?", "AT#PCT", // Operating mode of the radio: "AT+CFUN?", // Low-level network settings: "AT+WS46?", "AT#RXDIV", "AT#CALLDISA?", "AT+CEMODE?", // Data connection configuration: "AT+CGDCONT?", "AT#PDPAUTH?", // Registration and connection to the tower: "AT+CIND?", "AT+CSQ", "AT+COPS?", "AT+CREG?", "AT+CGREG?", "AT+CEREG?", "AT#RFSTS", "AT#PSNT?", "AT#MONI", // Data connection status: "AT+CGACT?", "AT+CGCONTRDP=1", "AT+CGCONTRDP=2", "AT+CGCONTRDP=3" }; const static std::vector vSimLockedCommands { // Radio model and firmware: "AT+CGMI", "AT+CGMM", "AT+CGMR", "AT#SWPKGV", "AT#CFVR", // All carrier profiles that are supported: "AT#FWSWITCH=?", // Current operator profile on the radio side: "AT#FWSWITCH?", "AT+CGSN", // SIM card information: "AT#SIMDET?", "AT#CCID", "AT+CPIN?", "AT#PCT", // Operating mode of the radio: "AT+CFUN?", // Low-level network settings: "AT+WS46?", "AT#RXDIV", "AT#CALLDISA?", "AT+CEMODE?", // Data connection configuration: "AT+CGDCONT?", "AT#PDPAUTH?", // Registration and connection to the tower. // The same set of commands, but AT#RFSTS is replaced with a dummy command. "AT+CIND?", "AT+CSQ", "AT+COPS?", "AT+CREG?", "AT+CGREG?", "AT+CEREG?", "AT#RFSTS_IGNORED", "AT#PSNT?", "AT#MONI", // Data connection status: "AT+CGACT?", "AT+CGCONTRDP=1", "AT+CGCONTRDP=2", "AT+CGCONTRDP=3" }; // Ignore AT#RFSTS on LE910 radios (mostly legacy ones like LAT1 and LEU1) if // the SIM card is locked by PIN or PUK. Telit Support Portal Case #5069697. if (bIsSimReady) { return vCommands; } else { return vSimLockedCommands; } } const std::vector LE910Radio::getRegistrationCommands() { return { "CREG", "CGREG", "CEREG" }; }