diff options
author | Jun Wako <wakojun@gmail.com> | 2015-04-24 16:26:14 +0900 |
---|---|---|
committer | Jun Wako <wakojun@gmail.com> | 2015-04-24 16:26:14 +0900 |
commit | a3d96d3aa96318d339a67de1085e0ae495d57c84 (patch) | |
tree | db85c16d03b52399d6c109eda7ea0341a0de0b1d /tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem | |
parent | 1d5bac21dc6f1425b8ef4bbe7935330c37c3a93e (diff) | |
parent | 1fe4406f374291ab2e86e95a97341fd9c475fcb8 (diff) |
Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8'
Diffstat (limited to 'tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem')
10 files changed, 2389 insertions, 0 deletions
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.cpp b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.cpp new file mode 100644 index 0000000000..6464afc984 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.cpp @@ -0,0 +1,114 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#define __DEBUG__ 4 +#ifndef __MODULE__ +#define __MODULE__ "UbloxCDMAModemInitializer.cpp" +#endif + +#include "core/dbg.h" + +#include <stdint.h> + +#include "UbloxCDMAModemInitializer.h" + +UbloxCDMAModemInitializer::UbloxCDMAModemInitializer(USBHost* pHost) : WANDongleInitializer(pHost) +{ +} + +uint16_t UbloxCDMAModemInitializer::getMSDVid() +{ + return 0x05C6; +} +uint16_t UbloxCDMAModemInitializer::getMSDPid() +{ + return 0x0000; //No MSD mode (presumably) +} + +uint16_t UbloxCDMAModemInitializer::getSerialVid() +{ + return 0x05C6; +} +uint16_t UbloxCDMAModemInitializer::getSerialPid() +{ + return 0x9004; +} + +bool UbloxCDMAModemInitializer::switchMode(USBDeviceConnected* pDev) +{ + return true; +} + +int UbloxCDMAModemInitializer::getSerialPortCount() +{ + return 2; +} + +/*virtual*/ void UbloxCDMAModemInitializer::setVidPid(uint16_t vid, uint16_t pid) +{ + m_currentSerialIntf = 0; + m_currentEndpoint = 0; +} + +/*virtual*/ bool UbloxCDMAModemInitializer::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed +{ + DBG("Interface #%d; Class:%02x; SubClass:%02x; Protocol:%02x", intf_nb, intf_class, intf_subclass, intf_protocol); + + if( intf_class == 0xFF ) { + if( m_currentSerialIntf == 0 || m_currentSerialIntf == 1) { + m_serialIntfMap[m_currentSerialIntf++] = intf_nb; + return true; + } + m_currentSerialIntf++; + } + + return false; +} + +/*virtual*/ bool UbloxCDMAModemInitializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + DBG("USBEndpoint on Interface #%d; Type:%d; Direction:%d Current %d", intf_nb, type, dir, m_currentEndpoint); + if(type == BULK_ENDPOINT) { + if( intf_nb == 1 || intf_nb == 0) { + m_currentEndpoint++; + return true; + } else { + m_currentEndpoint++; + } + } + + /* + if(type == INTERRUPT_ENDPOINT) { + if( intf_nb == 1) { + m_currentEndpoint++; + return true; + } else { + m_currentEndpoint++; + } + } + */ + + return false; +} + + +/*virtual*/ int UbloxCDMAModemInitializer::getType() +{ + return WAN_DONGLE_TYPE_UBLOX_LISAC200; +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.h new file mode 100644 index 0000000000..4836680da2 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef UBLOXCDMAMODEMINITIALIZER_H +#define UBLOXCDMAMODEMINITIALIZER_H + +#include <stdint.h> + +#include "WANDongleInitializer.h" +#include "USBHost.h" +#include "IUSBEnumerator.h" + +enum +{ + WAN_DONGLE_TYPE_UBLOX_LISAC200 = 0xC200, +}; + +class UbloxCDMAModemInitializer : public WANDongleInitializer +{ +public: + UbloxCDMAModemInitializer(USBHost* pHost); + + virtual uint16_t getMSDVid(); + virtual uint16_t getMSDPid(); + + virtual uint16_t getSerialVid(); + virtual uint16_t getSerialPid(); + + virtual bool switchMode(USBDeviceConnected* pDev); + + virtual int getSerialPortCount(); + + virtual void setVidPid(uint16_t vid, uint16_t pid); + + virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed + + virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used + + virtual int getType(); + +private: + + int m_currentSerialIntf; + int m_currentEndpoint; +}; + +#endif + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.cpp b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.cpp new file mode 100644 index 0000000000..e28632593a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.cpp @@ -0,0 +1,131 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "UbloxGSMModemInitializer.h" +#include "core/dbg.h" + +#define __DEBUG__ 0 +#ifndef __MODULE__ +#define __MODULE__ "UbloxGSMModemInitializer.cpp" +#endif + +//----------------------------------------------------------------------- +// mamm, u-blox Modem +//----------------------------------------------------------------------- + +UbloxGSMModemInitializer::UbloxGSMModemInitializer(USBHost* pHost) : WANDongleInitializer(pHost) +{ + +} + +uint16_t UbloxGSMModemInitializer::getMSDVid() { return 0x1546; } +uint16_t UbloxGSMModemInitializer::getMSDPid() { return 0x0000; } + +uint16_t UbloxGSMModemInitializer::getSerialVid() { return 0x1546; } +uint16_t UbloxGSMModemInitializer::getSerialPid() { return 0x1102; } + +bool UbloxGSMModemInitializer::switchMode(USBDeviceConnected* pDev) +{ + for (int i = 0; i < pDev->getNbIntf(); i++) + { + if (pDev->getInterface(i)->intf_class == MSD_CLASS) + { + USBEndpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT); + if ( pEp != NULL ) + { + ERR("MSD descriptor found on device %p, intf %d", (void *)pDev, i); + } + } + } + return false; +} + +#define UBX_SERIALCOUNT 7 + +int UbloxGSMModemInitializer::getSerialPortCount() +{ + return UBX_SERIALCOUNT; +} + +/*virtual*/ void UbloxGSMModemInitializer::setVidPid(uint16_t vid, uint16_t pid) +{ + if( (vid == getSerialVid() ) && ( pid == getSerialPid() ) ) + { + m_hasSwitched = true; + m_currentSerialIntf = 0; + m_endpointsToFetch = UBX_SERIALCOUNT*2; + } + else + { + m_hasSwitched = false; + m_endpointsToFetch = 1; + } +} + +/*virtual*/ bool UbloxGSMModemInitializer::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed +{ + if( m_hasSwitched ) + { + DBG("Interface #%d; Class:%02x; SubClass:%02x; Protocol:%02x", intf_nb, intf_class, intf_subclass, intf_protocol); + if( intf_class == 0x0A ) + { + if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 1) ) + { + m_serialIntfMap[m_currentSerialIntf++] = intf_nb; + return true; + } + m_currentSerialIntf++; + } + } + else + { + if( (intf_nb == 0) && (intf_class == MSD_CLASS) ) + { + return true; + } + } + return false; +} + +/*virtual*/ bool UbloxGSMModemInitializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + if( m_hasSwitched ) + { + DBG("USBEndpoint on Interface #%d; Type:%d; Direction:%d", intf_nb, type, dir); + if( (type == BULK_ENDPOINT) && m_endpointsToFetch ) + { + m_endpointsToFetch--; + return true; + } + } + else + { + if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch ) + { + m_endpointsToFetch--; + return true; + } + } + return false; +} + +/*virtual*/ int UbloxGSMModemInitializer::getType() +{ + return WAN_DONGLE_TYPE_UBLOX_LISAU200; +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.h new file mode 100644 index 0000000000..383c443eb3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef UBLOXGSMMODEMINITIALIZER_H +#define UBLOXGSNMODEMINITIALIZER_H + +#include "WANDongleInitializer.h" + +enum +{ + WAN_DONGLE_TYPE_UBLOX_LISAU200 = 0x0200 +}; + +//----------------------------------------------------------------------- +// mamm, u-blox Modem +//----------------------------------------------------------------------- + +class UbloxGSMModemInitializer : public WANDongleInitializer +{ +public: + UbloxGSMModemInitializer(USBHost* pHost); + + virtual uint16_t getMSDVid(); + virtual uint16_t getMSDPid(); + + virtual uint16_t getSerialVid(); + virtual uint16_t getSerialPid(); + + virtual bool switchMode(USBDeviceConnected* pDev); + + virtual int getSerialPortCount(); + + virtual void setVidPid(uint16_t vid, uint16_t pid); + + virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed + + virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used + + virtual int getType(); + +private: + + bool m_hasSwitched; + int m_currentSerialIntf; + int m_endpointsToFetch; +}; + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp new file mode 100644 index 0000000000..a9fec4cbf0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp @@ -0,0 +1,559 @@ +/* UbloxModem.cpp */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define __DEBUG__ 3 +#ifndef __MODULE__ +#define __MODULE__ "UbloxModem.cpp" +#endif + +#include "core/fwk.h" +#include "sms/GSMSMSInterface.h" +#include "sms/CDMASMSInterface.h" + +#include "UbloxModem.h" + +UbloxModem::UbloxModem(IOStream* atStream, IOStream* pppStream) : + m_at(atStream), // Construct ATCommandsInterface with the AT serial channel + m_CdmaSms(&m_at), // Construct SMSInterface with the ATCommandsInterface + m_GsmSms(&m_at), // Construct SMSInterface with the ATCommandsInterface + m_ussd(&m_at), // Construct USSDInterface with the ATCommandsInterface + m_linkMonitor(&m_at), // Construct LinkMonitor with the ATCommandsInterface + m_ppp(pppStream ? pppStream : atStream), // Construct PPPIPInterface with the PPP serial channel + m_ipInit(false), // PPIPInterface connection is initially down + m_smsInit(false), // SMSInterface starts un-initialised + m_ussdInit(false), // USSDInterface starts un-initialised + m_linkMonitorInit(false), // LinkMonitor subsystem starts un-initialised + m_atOpen(false), // ATCommandsInterface starts in a closed state + m_onePort(pppStream == NULL), + m_type(UNKNOWN) +{ +} + + +genericAtProcessor::genericAtProcessor() +{ + i = 0; + str[0] = '\0'; +} + +const char* genericAtProcessor::getResponse(void) +{ + return str; +} + +int genericAtProcessor::onNewATResponseLine(ATCommandsInterface* pInst, const char* line) +{ + int l = strlen(line); + if (i + l + 2 > sizeof(str)) + return NET_OVERFLOW; + if (i) str[i++] = ','; + strcat(&str[i], line); + i += l; + return OK; +} + +int genericAtProcessor::onNewEntryPrompt(ATCommandsInterface* pInst) +{ + return OK; +} + +class CREGProcessor : public IATCommandsProcessor +{ +public: + CREGProcessor(bool gsm) : status(STATUS_REGISTERING) + { + m_gsm = gsm; + } + enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK, STATUS_FAILED }; + REGISTERING_STATUS getStatus() + { + return status; + } + const char* getAtCommand() + { + return m_gsm ? "AT+CREG?" : "AT+CSS?"; + } +private: + virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line) + { + int r; + if (m_gsm) + { + if( sscanf(line, "+CREG: %*d,%d", &r) == 1 ) + { + status = (r == 1 || r == 5) ? STATUS_OK : + (r == 0 || r == 2) ? STATUS_REGISTERING : + // (r == 3) ? STATUS_FAILED : + STATUS_FAILED; + } + } + else + { + char bc[3] = ""; + if(sscanf(line, "%*s %*c,%2s,%*d",bc)==1) + { + status = (strcmp("Z", bc) == 0) ? STATUS_REGISTERING : STATUS_OK; + } + } + return OK; + } + virtual int onNewEntryPrompt(ATCommandsInterface* pInst) + { + return OK; + } + volatile REGISTERING_STATUS status; + bool m_gsm; +}; + +int UbloxModem::connect(const char* apn, const char* user, const char* password) +{ + if( !m_ipInit ) + { + m_ipInit = true; + m_ppp.init(); + } + m_ppp.setup(user, password, (m_type != LISA_C200) ? DEFAULT_MSISDN_GSM : DEFAULT_MSISDN_CDMA); + + int ret = init(); + if(ret) + { + return ret; + } + + if (m_onePort) + { + m_smsInit = false; //SMS status reset + m_ussdInit = false; //USSD status reset + m_linkMonitorInit = false; //Link monitor status reset + } + + ATCommandsInterface::ATResult result; + + if(apn != NULL) + { + char cmd[48]; + int tries = 30; + sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn); + do //Try 30 times because for some reasons it can fail *a lot* with the K3772-Z dongle + { + ret = m_at.executeSimple(cmd, &result); + DBG("Result of command: Err code=%d", ret); + if(ret) + { + Thread::wait(500); + } + } while(ret && --tries); + DBG("ATResult: AT return=%d (code %d)", result.result, result.code); + DBG("APN set to %s", apn); + } + + //Connect + DBG("Connecting"); + if (m_onePort) + { + m_at.close(); // Closing AT parser + m_atOpen = false; //Will need to be reinitialized afterwards + } + + DBG("Connecting PPP"); + + ret = m_ppp.connect(); + DBG("Result of connect: Err code=%d", ret); + return ret; +} + + +int UbloxModem::disconnect() +{ + DBG("Disconnecting from PPP"); + int ret = m_ppp.disconnect(); + if(ret) + { + ERR("Disconnect returned %d, still trying to disconnect", ret); + } + + //Ugly but leave dongle time to recover + Thread::wait(500); + + if (m_onePort) + { + //ATCommandsInterface::ATResult result; + DBG("Starting AT thread"); + ret = m_at.open(); + if(ret) + { + return ret; + } + } + + DBG("Trying to hangup"); + + if (m_onePort) + { + //Reinit AT parser + ret = m_at.init(false); + DBG("Result of command: Err code=%d\n", ret); + if(ret) + { + m_at.close(); // Closing AT parser + DBG("AT Parser closed, could not complete disconnection"); + return NET_TIMEOUT; + } + + } + return OK; +} + +int UbloxModem::sendSM(const char* number, const char* message) +{ + int ret = init(); + if(ret) + { + return ret; + } + + ISMSInterface* sms; + if (m_type == LISA_C200) sms = &m_CdmaSms; + else sms = &m_GsmSms; + if(!m_smsInit) + { + ret = sms->init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = sms->send(number, message); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxModem::getSM(char* number, char* message, size_t maxLength) +{ + int ret = init(); + if(ret) + { + return ret; + } + + ISMSInterface* sms; + if (m_type == LISA_C200) sms = &m_CdmaSms; + else sms = &m_GsmSms; + if(!m_smsInit) + { + ret = sms->init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = sms->get(number, message, maxLength); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxModem::getSMCount(size_t* pCount) +{ + int ret = init(); + if(ret) + { + return ret; + } + + ISMSInterface* sms; + if (m_type == LISA_C200) sms = &m_CdmaSms; + else sms = &m_GsmSms; + if(!m_smsInit) + { + ret = sms->init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = sms->getCount(pCount); + if(ret) + { + return ret; + } + + return OK; +} + +ATCommandsInterface* UbloxModem::getATCommandsInterface() +{ + return &m_at; +} + +int UbloxModem::init() +{ + if(m_atOpen) + { + return OK; + } + + DBG("Starting AT thread if needed"); + int ret = m_at.open(); + if(ret) + { + return ret; + } + + DBG("Sending initialisation commands"); + ret = m_at.init(false); + if(ret) + { + return ret; + } + + + ATCommandsInterface::ATResult result; + genericAtProcessor atiProcessor; + ret = m_at.execute("ATI", &atiProcessor, &result); + if (OK != ret) + return ret; + const char* info = atiProcessor.getResponse(); + INFO("Modem Identification [%s]", info); + if (strstr(info, "LISA-C200")) { + m_type = LISA_C200; + m_onePort = true; // force use of only one port + } + else if (strstr(info, "LISA-U200")) { + m_type = LISA_U200; + } + else if (strstr(info, "SARA-G350")) { + m_type = SARA_G350; + } + + // enable the network indicator + if (m_type == SARA_G350) { + m_at.executeSimple("AT+UGPIOC=16,2", &result); + } + else if (m_type == LISA_U200) { + m_at.executeSimple("AT+UGPIOC=20,2", &result); + } + else if (m_type == LISA_C200) { + // LISA-C200 02S/22S : GPIO1 do not support network status indication + // m_at.executeSimple("AT+UGPIOC=20,2", &result); + } + INFO("Modem Identification [%s]", info); + + CREGProcessor cregProcessor(m_type != LISA_C200); + //Wait for network registration + do + { + DBG("Waiting for network registration"); + ret = m_at.execute(cregProcessor.getAtCommand(), &cregProcessor, &result); + DBG("Result of command: Err code=%d\n", ret); + DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); + if(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING) + { + Thread::wait(3000); + } + } while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING); + if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED) + { + ERR("Registration denied"); + return NET_AUTH; + } + + m_atOpen = true; + + return OK; +} + +int UbloxModem::cleanup() +{ + if(m_ppp.isConnected()) + { + WARN("Data connection is still open"); //Try to encourage good behaviour from the user + m_ppp.disconnect(); + } + + m_smsInit = false; + m_ussdInit = false; + m_linkMonitorInit = false; + //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once + + if(m_atOpen) + { + m_at.close(); + m_atOpen = false; + } + + return OK; +} + +int UbloxModem::sendUSSD(const char* command, char* result, size_t maxLength) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_ussdInit) + { + ret = m_ussd.init(); + if(ret) + { + return ret; + } + m_ussdInit = true; + } + + ret = m_ussd.send(command, result, maxLength); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegistrationState, LinkMonitor::BEARER* pBearer) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_linkMonitorInit) + { + ret = m_linkMonitor.init(m_type != LISA_C200); + if(ret) + { + return ret; + } + m_linkMonitorInit = true; + } + + ret = m_linkMonitor.getState(pRssi, pRegistrationState, pBearer); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxModem::getPhoneNumber(char* phoneNumber) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_linkMonitorInit) + { + ret = m_linkMonitor.init(m_type != LISA_C200); + if(ret) + { + return ret; + } + m_linkMonitorInit = true; + } + + ret = m_linkMonitor.getPhoneNumber(phoneNumber); + if(ret) + { + return ret; + } + + return OK; +} + +#include "USBHost.h" +#include "UbloxGSMModemInitializer.h" +#include "UbloxCDMAModemInitializer.h" + +UbloxUSBModem::UbloxUSBModem() : + UbloxModem(&m_atStream, &m_pppStream), + m_dongle(), // Construct WANDongle: USB interface with two serial channels to the modem (USBSerialStream objects) + m_atStream(m_dongle.getSerial(1)), // AT commands are sent down one serial channel. + m_pppStream(m_dongle.getSerial(0)), // PPP connections are managed via another serial channel. + m_dongleConnected(false) // Dongle is initially not ready for anything +{ + USBHost* host = USBHost::getHostInst(); + m_dongle.addInitializer(new UbloxGSMModemInitializer(host)); + m_dongle.addInitializer(new UbloxCDMAModemInitializer(host)); +} + +int UbloxUSBModem::init() +{ + if( !m_dongleConnected ) + { + m_dongleConnected = true; + while( !m_dongle.connected() ) + { + m_dongle.tryConnect(); + Thread::wait(10); + } + if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAU200) + { + INFO("Using a u-blox LISA-U200 3G/WCDMA Modem"); + m_type = LISA_U200; + } + else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAC200) + { + INFO("Using a u-blox LISA-C200 CDMA Modem"); + m_type = LISA_C200; + m_onePort = true; + } + else + { + WARN("Using an Unknown Dongle"); + } + } + return UbloxModem::init(); +} + +int UbloxUSBModem::cleanup() +{ + UbloxModem::cleanup(); + m_dongle.disconnect(); + m_dongleConnected = false; + return OK; +} + +UbloxSerModem::UbloxSerModem() : + UbloxModem(&m_atStream, NULL), + m_Serial(P0_15/*MDMTXD*/,P0_16/*MDMRXD*/), + m_atStream(m_Serial) +{ + m_Serial.baud(115200/*MDMBAUD*/); + m_Serial.set_flow_control(SerialBase::RTSCTS, P0_22/*MDMRTS*/, P0_17/*MDMCTS*/); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxModem.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxModem.h new file mode 100644 index 0000000000..dc0e1205a4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxModem.h @@ -0,0 +1,183 @@ +/* VodafoneUSBModem.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UBLOXMODEM_H_ +#define UBLOXMODEM_H_ + +#include "core/fwk.h" + +#include "at/ATCommandsInterface.h" +#include "ip/PPPIPInterface.h" +#include "sms/GSMSMSInterface.h" +#include "sms/CDMASMSInterface.h" +#include "ussd/USSDInterface.h" +#include "link/LinkMonitor.h" +#include "CellularModem.h" + +class genericAtProcessor : public IATCommandsProcessor +{ +public: + genericAtProcessor(); + const char* getResponse(void); +private: + virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line); + virtual int onNewEntryPrompt(ATCommandsInterface* pInst); +protected: + char str[256]; + int i; +}; + +/** u-blox WCDMA modem (LISA-U200) + */ +class UbloxModem: public CellularModem +{ +public: + /** Create u-blox API instance + @param powerGatingPin Optional pin commanding a power gating transistor on the modem's power line + @param powerGatingOnWhenPinHigh true if the pin needs to be high to power the dongle, defaults to true + */ + UbloxModem(IOStream* atStream, IOStream* pppStream); + + //Internet-related functions + + /** Open a 3G internet connection + @return 0 on success, error code on failure + */ + virtual int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL); + + /** Close the internet connection + @return 0 on success, error code on failure + */ + virtual int disconnect(); + + + /** Send a SM + @param number The receiver's phone number + @param message The message to send + @return 0 on success, error code on failure + */ + virtual int sendSM(const char* number, const char* message); + + + /** Receive a SM + @param number Pointer to a buffer to store the sender's phone number (must be at least 17 characters-long, including the sapce for the null-terminating char) + @param message Pointer to a buffer to store the the incoming message + @param maxLength Maximum message length that can be stored in buffer (including null-terminating character) + @return 0 on success, error code on failure + */ + virtual int getSM(char* number, char* message, size_t maxLength); + + /** Get the number of SMs in the incoming box + @param pCount pointer to store the number of unprocessed SMs on + @return 0 on success, error code on failure + */ + virtual int getSMCount(size_t* pCount); + + /** Send a USSD command & wait for its result + @param command The command to send + @param result Buffer in which to store the result + @param maxLength Maximum result length that can be stored in buffer (including null-terminating character) + @return 0 on success, error code on failure + */ + int sendUSSD(const char* command, char* result, size_t maxLength); + + /** Get link state + @param pRssi pointer to store the current RSSI in dBm, between -51 dBm and -113 dBm if known; -51 dBm means -51 dBm or more; -113 dBm means -113 dBm or less; 0 if unknown + @param pRegistrationState pointer to store the current registration state + @param pBearer pointer to store the current bearer + @return 0 on success, error code on failure + */ + int getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegistrationState, LinkMonitor::BEARER* pBearer); + + int getPhoneNumber(char* phoneNumber); + + /** Get the ATCommandsInterface instance + @return Pointer to the ATCommandsInterface instance + */ + virtual ATCommandsInterface* getATCommandsInterface(); + +protected: + /** Initialise dongle. + * The following actions are performed: + * 1) Start AT interface thread + * 2) Wait for network registration + */ + virtual int init(); + + /** De-initialise dongle. + * The following actions are performed: + * 1) Tear down PPP session + * 2) Set SMS,USSD, and LinkMonitor subsystems to un-initialised + * 3) Close the AT commands interface + */ + virtual int cleanup(); + +private: + ATCommandsInterface m_at; //< Interface to AT commands processing + + CDMASMSInterface m_CdmaSms; //< Interface to SMS manager (send/receive etc) + GSMSMSInterface m_GsmSms; //< Interface to SMS manager (send/receive etc) + USSDInterface m_ussd; //< Interface to USSD manager (send etc) + LinkMonitor m_linkMonitor; //< Interface to link monitor (RSSI) + + PPPIPInterface m_ppp; //< Interface to PPP conection manager (IP assignment etc) + + bool m_ipInit; //< Has PPIPInterface object (m_ppp) been initialised? true/false + bool m_smsInit; //< Has SMSInterface object (m_sms) been initialised? true/false + bool m_ussdInit; //< Has USSDInterface object (m_ussd) been initialised? true/false + bool m_linkMonitorInit; //< Has LinkMonitor object (m_linkMonitor) been initialised? true/false + bool m_atOpen; //< Is the interface to the ATCommandsInterface open? true/false +protected: + bool m_onePort; + enum { LISA_C200, LISA_U200, SARA_G350, UNKNOWN } m_type; +}; + +#include "WANDongle.h" +#include "serial/usb/USBSerialStream.h" + +class UbloxUSBModem: public UbloxModem +{ +public: + UbloxUSBModem(); + virtual int init(); + virtual int cleanup(); + virtual int power(bool enable) { return 1; } + +private: + WANDongle m_dongle; //< Interface to USB connected WAN dongle + + USBSerialStream m_atStream; //< Serial interface to AT channel on modem + USBSerialStream m_pppStream; //< Serial interface to PPP channel on modem + + bool m_dongleConnected; //< Is the dongle physically connected (does the USB stack respond)? true/false +}; + +#include "serial/io/IOSerialStream.h" + +class UbloxSerModem: public UbloxModem +{ +public: + UbloxSerModem(); + virtual int power(bool enable) { return 1; } +private: + RawSerial m_Serial; + IOSerialStream m_atStream; //< Serial interface to AT channel on modem +}; + +#endif /* UBLOXMODEM_H_ */ diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.cpp b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.cpp new file mode 100644 index 0000000000..5e4e32a2b5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.cpp @@ -0,0 +1,398 @@ +/* UbloxUSBCDMAModem.cpp */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define __DEBUG__ 4 +#ifndef __MODULE__ +#define __MODULE__ "UbloxUSBCDMAModem.cpp" +#endif + +#include "core/fwk.h" + +#include "UbloxUSBCDMAModem.h" +#include "UbloxCDMAModemInitializer.h" +#include "USBHost.h" + +#define USE_ONE_PORT 1 + +UbloxUSBCDMAModem::UbloxUSBCDMAModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/, int serial /* 0 */) : m_dongle(), +m_stream(m_dongle.getSerial(serial)), +m_at(&m_stream), +m_sms(&m_at), m_ppp(&m_stream), +m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_atOpen(false), +m_powerGatingPin(powerGatingPin), m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh) +{ + USBHost* host = USBHost::getHostInst(); + m_dongle.addInitializer(new UbloxCDMAModemInitializer(host)); + if( m_powerGatingPin != NC ) + { + power(false); //Dongle will have to be powered on manually + } +} + +class CSSProcessor : public IATCommandsProcessor +{ +public: + CSSProcessor() : status(STATUS_REGISTERING) + { + + } + enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK }; + REGISTERING_STATUS getStatus() + { + return status; + } +private: + virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line) + { + char b; + char bc[3] = ""; + int sid = 99999; + + //if( sscanf(line, "%*d, %c", &r) == 1 ) + if(sscanf(line, "%*s %c,%2s,%d", &b,bc,&sid)==3) + { + if(strcmp("Z", bc) == 0) + status = STATUS_REGISTERING; + else + status = STATUS_OK; + } + return OK; + } + virtual int onNewEntryPrompt(ATCommandsInterface* pInst) + { + return OK; + } + volatile REGISTERING_STATUS status; +}; + +int UbloxUSBCDMAModem::connect(const char* apn, const char* user, const char* password) +{ + if( !m_ipInit ) + { + m_ipInit = true; + m_ppp.init(); + } + m_ppp.setup(user, password, DEFAULT_MSISDN_CDMA); + + int ret = init(); + if(ret) + { + return ret; + } + + #if USE_ONE_PORT + m_smsInit = false; //SMS status reset + //m_ussdInit = false; //USSD status reset + //m_linkMonitorInit = false; //Link monitor status reset + #endif + + ATCommandsInterface::ATResult result; + + if(apn != NULL) + { + char cmd[48]; + sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn); + ret = m_at.executeSimple(cmd, &result); + DBG("Result of command: Err code=%d", ret); + DBG("ATResult: AT return=%d (code %d)", result.result, result.code); + DBG("APN set to %s", apn); + } + + + //Connect + DBG("Connecting"); + #if USE_ONE_PORT + m_at.close(); // Closing AT parser + m_atOpen = false; //Will need to be reinitialized afterwards + #endif + + DBG("Connecting PPP"); + + ret = m_ppp.connect(); + DBG("Result of connect: Err code=%d", ret); + return ret; +} + + +int UbloxUSBCDMAModem::disconnect() +{ + DBG("Disconnecting from PPP"); + int ret = m_ppp.disconnect(); + if(ret) + { + ERR("Disconnect returned %d, still trying to disconnect", ret); + } + + //Ugly but leave dongle time to recover + Thread::wait(500); + + #if USE_ONE_PORT + ATCommandsInterface::ATResult result; + DBG("Starting AT thread"); + ret = m_at.open(); + if(ret) + { + return ret; + } + #endif + + DBG("Trying to hangup"); + + #if 0 //Does not appear to work + int tries = 10; + do + { + ret = m_at.executeSimple("+++", &result, 1000); + DBG("Result of command: Err code=%d\n", ret); + DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); + } while(tries-- && ret); + if(!ret) + { + ret = m_at.executeSimple("ATH", &result); + DBG("Result of command: Err code=%d\n", ret); + DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); + } + #endif + + #if USE_ONE_PORT + //Reinit AT parser + ret = m_at.init(); + DBG("Result of command: Err code=%d\n", ret); + if(ret) + { + m_at.close(); // Closing AT parser + DBG("AT Parser closed, could not complete disconnection"); + return NET_TIMEOUT; + } + + #if 0 + m_at.close(); // Closing AT parser + DBG("AT Parser closed"); + #endif + #endif + return OK; +} + +int UbloxUSBCDMAModem::sendSM(const char* number, const char* message) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_smsInit) + { + ret = m_sms.init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = m_sms.send(number, message); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxUSBCDMAModem::getSM(char* number, char* message, size_t maxLength) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_smsInit) + { + ret = m_sms.init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = m_sms.get(number, message, maxLength); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxUSBCDMAModem::getSMCount(size_t* pCount) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_smsInit) + { + ret = m_sms.init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = m_sms.getCount(pCount); + if(ret) + { + return ret; + } + + return OK; +} + +ATCommandsInterface* UbloxUSBCDMAModem::getATCommandsInterface() +{ + return &m_at; +} + +int UbloxUSBCDMAModem::power(bool enable) +{ + if( m_powerGatingPin == NC ) + { + return NET_INVALID; //A pin name has not been provided in the constructor + } + + if(!enable) //Will force components to re-init + { + cleanup(); + } + + DigitalOut powerGatingOut(m_powerGatingPin); + powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable; + + return OK; +} + +bool UbloxUSBCDMAModem::power() +{ + if( m_powerGatingPin == NC ) + { + return true; //Assume power is always on + } + + DigitalOut powerGatingOut(m_powerGatingPin); + return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut; +} + +int UbloxUSBCDMAModem::init() +{ + if( !m_dongleConnected ) + { + if(!power()) + { + //Obviously cannot initialize the dongle if it is disconnected... + ERR("Power is off"); + return NET_INVALID; + } + m_dongleConnected = true; + while( !m_dongle.connected() ) + { + m_dongle.tryConnect(); + Thread::wait(100); + } + } + + if(m_atOpen) + { + return OK; + } + + DBG("Starting AT thread if needed"); + int ret = m_at.open(); + if(ret) + { + return ret; + } + + DBG("Sending initialisation commands"); + ret = m_at.init(); + if(ret) + { + return ret; + } + + if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAC200) + { + INFO("Using a UBLOX C200 Dongle"); + } + else + { + WARN("Using an Unknown Dongle"); + } + + ATCommandsInterface::ATResult result; + + //Wait for network registration + CSSProcessor cssProcessor; + do + { + DBG("Waiting for network registration"); + ret = m_at.execute("AT+CSS?", &cssProcessor, &result); + DBG("Result of command: Err code=%d\n", ret); + DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); + if(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING) + { + Thread::wait(3000); + } + } while(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING); + + m_atOpen = true; + + return OK; +} + +int UbloxUSBCDMAModem::cleanup() +{ + if(m_ppp.isConnected()) + { + WARN("Data connection is still open"); //Try to encourage good behaviour from the user + m_ppp.disconnect(); + } + + m_smsInit = false; +// m_linkMonitorInit = false; + //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once + + if(m_atOpen) + { + m_at.close(); + m_atOpen = false; + } + + m_dongle.disconnect(); + m_dongleConnected = false; + + return OK; +} + + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.h new file mode 100644 index 0000000000..988afb29ad --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.h @@ -0,0 +1,118 @@ +/* UbloxUSBCDMAModem.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UBLOXUSBCDMAMODEM_H_ +#define UBLOXUSBCDMAMODEM_H_ + +#include "core/fwk.h" + +#include "WANDongle.h" +#include "at/ATCommandsInterface.h" +#include "USBSerialStream.h" +#include "ip/PPPIPInterface.h" +#include "sms/CDMASMSInterface.h" +#include "CellularModem.h" + +/** u-blox LISA-C200 modem + */ +class UbloxUSBCDMAModem: public CellularModem +{ +public: + /** Create Sprint USB Modem (Sierra Wireless 598U) API instance + @param powerGatingPin Optional pin commanding a power gating transistor on the modem's power line + @param powerGatingOnWhenPinHigh true if the pin needs to be high to power the dongle, defaults to true + */ + UbloxUSBCDMAModem(PinName powerGatingPin = NC, bool powerGatingOnWhenPinHigh = true, int serial = 0); + + //Internet-related functions + + /** Open a 3G internet connection + @return 0 on success, error code on failure + */ + virtual int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL); + + /** Close the internet connection + @return 0 on success, error code on failure + */ + virtual int disconnect(); + + + /** Send a SM + @param number The receiver's phone number + @param message The message to send + @return 0 on success, error code on failure + */ + virtual int sendSM(const char* number, const char* message); + + + /** Receive a SM + @param number Pointer to a buffer to store the sender's phone number (must be at least 17 characters-long, including the sapce for the null-terminating char) + @param message Pointer to a buffer to store the the incoming message + @param maxLength Maximum message length that can be stored in buffer (including null-terminating character) + @return 0 on success, error code on failure + */ + virtual int getSM(char* number, char* message, size_t maxLength); + + /** Get the number of SMs in the incoming box + @param pCount pointer to store the number of unprocessed SMs on + @return 0 on success, error code on failure + */ + virtual int getSMCount(size_t* pCount); + + /** Get the ATCommandsInterface instance + @return Pointer to the ATCommandsInterface instance + */ + virtual ATCommandsInterface* getATCommandsInterface(); + + /** Switch power on or off + In order to use this function, a pin name must have been entered in the constructor + @param enable true to switch the dongle on, false to switch it off + @return 0 on success, error code on failure + */ + virtual int power(bool enable); + +protected: + bool power(); + + int init(); + int cleanup(); + +private: + WANDongle m_dongle; + + USBSerialStream m_stream; + + ATCommandsInterface m_at; + + CDMASMSInterface m_sms; + + PPPIPInterface m_ppp; + + bool m_dongleConnected; + bool m_ipInit; + bool m_smsInit; + bool m_atOpen; + + PinName m_powerGatingPin; + bool m_powerGatingOnWhenPinHigh; +}; + + +#endif /* UBLOXUSBCDMAMODEM_H_ */ + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.cpp b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.cpp new file mode 100644 index 0000000000..8209dc6a88 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.cpp @@ -0,0 +1,605 @@ +/* UbloxUSBGSMModem.cpp */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define __DEBUG__ 3 +#ifndef __MODULE__ +#define __MODULE__ "UbloxUSBGSMModem.cpp" +#endif + +#include "core/fwk.h" + +#include "UbloxUSBGSMModem.h" +#include "UbloxGSMModemInitializer.h" +#include "USBHost.h" + +UbloxUSBGSMModem::UbloxUSBGSMModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/) : + m_dongle(), // Construct WANDongle: USB interface with two serial channels to the modem (USBSerialStream objects) + m_atStream(m_dongle.getSerial(1)), // AT commands are sent down one serial channel. + m_pppStream(m_dongle.getSerial(0)), // PPP connections are managed via another serial channel. + m_at(&m_atStream), // Construct ATCommandsInterface with the AT serial channel + m_sms(&m_at), // Construct SMSInterface with the ATCommandsInterface + m_ussd(&m_at), // Construct USSDInterface with the ATCommandsInterface + m_linkMonitor(&m_at), // Construct LinkMonitor with the ATCommandsInterface + m_ppp(&m_pppStream), // Construct PPPIPInterface with the PPP serial channel + m_dongleConnected(false), // Dongle is initially not ready for anything + m_ipInit(false), // PPIPInterface connection is initially down + m_smsInit(false), // SMSInterface starts un-initialised + m_ussdInit(false), // USSDInterface starts un-initialised + m_linkMonitorInit(false), // LinkMonitor subsystem starts un-initialised + m_atOpen(false), // ATCommandsInterface starts in a closed state + m_powerGatingPin(powerGatingPin), // set power gating pin + m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh) // set state semantics for power gating pin +{ + USBHost* host = USBHost::getHostInst(); + m_dongle.addInitializer(new UbloxGSMModemInitializer(host)); + if( m_powerGatingPin != NC ) + { + power(false); //Dongle will have to be powered on manually + } +} + +class CREGProcessor : public IATCommandsProcessor +{ +public: + CREGProcessor() : status(STATUS_REGISTERING) + { + + } + enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK, STATUS_FAILED }; + REGISTERING_STATUS getStatus() + { + return status; + } +private: + virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line) + { + int r; + if( sscanf(line, "+CREG: %*d,%d", &r) == 1 ) + { + switch(r) + { + case 1: + case 5: + status = STATUS_OK; + break; + case 0: + case 2: + status = STATUS_REGISTERING; + break; + case 3: + default: + status = STATUS_FAILED; + break; + } + } + return OK; + } + virtual int onNewEntryPrompt(ATCommandsInterface* pInst) + { + return OK; + } + volatile REGISTERING_STATUS status; +}; + +#if 0 +class COPSProcessor : public IATCommandsProcessor +{ +public: + COPSProcessor() : valid(false) + { + network[0] = '\0'; + apn[0] = '\0'; + bearer[0] = '\0'; + } + char* getNetwork() + { + return network; + } + char* getAPN() + { + return apn; + } + char* getBearer() + { + return bearer; + } + bool isValid() + { + return valid; + } +private: + virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line) + { + int networkId; + int bearerId; + int s = sscanf(line, "+COPS: %*d,%*d,\"%d\",%d", &networkId, &bearerId); + if( s == 2 ) + { + switch(networkId) + { + case 23415: + strcpy(network, "Vodafone UK"); + strcpy(apn, "pp.vodafone.co.uk"); + valid = true; + break; + case 20810: + strcpy(network, "SFR FR"); + strcpy(apn, "websfr"); + valid = true; + break; + default: + break; + } + } + else + { + return OK; + } + switch(bearerId) + { + case 0: strcpy(bearer, "GSM"); break; + case 1: strcpy(bearer, "GSM Compact"); break; + case 2: strcpy(bearer, "UTRAN"); break; + case 3: strcpy(bearer, "GSM w/EGPRS"); break; + case 4: strcpy(bearer, "UTRAN w/HSDPA"); break; + case 5: strcpy(bearer, "UTRAN w/HSUPA"); break; + case 6: strcpy(bearer, "UTRAN w/HSDPA and HSUPA"); break; + case 7: strcpy(bearer, "E-UTRAN"); break; + + default: + break; + } + return OK; + } + virtual int onNewEntryPrompt(ATCommandsInterface* pInst) + { + return OK; + } + char network[24]; + char bearer[24]; + char apn[24]; + volatile bool valid; +}; +#endif + +int UbloxUSBGSMModem::connect(const char* apn, const char* user, const char* password) +{ + if( !m_ipInit ) + { + m_ipInit = true; + m_ppp.init(); + } + m_ppp.setup(user, password, DEFAULT_MSISDN_GSM); + + int ret = init(); + if(ret) + { + return ret; + } + + #if USE_ONE_PORT + m_smsInit = false; //SMS status reset + m_ussdInit = false; //USSD status reset + m_linkMonitorInit = false; //Link monitor status reset + #endif + + ATCommandsInterface::ATResult result; + + #if 0 + //Get network info & select corresponding APN + COPSProcessor copsProcessor; + DBG("Get network info & select APN from DB"); + ret = m_at.execute("AT+COPS=,2;+COPS?", &copsProcessor, &result); //Configure to get operator's info in numeric code & get operator's id + DBG("Result of command: Err code=%d", ret); + DBG("ATResult: AT return=%d (code %d)", result.result, result.code); + + if(!copsProcessor.isValid()) + { + WARN("Connected to an unknown network, try to connect with default parameters"); + DBG("Connected with %s", copsProcessor.getBearer()); + } + else + { + DBG("Connected to %s with %s", copsProcessor.getNetwork(), copsProcessor.getBearer()); + char cmd[48]; + int tries = 3; + sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", copsProcessor.getAPN()); + do //Try 3 times because for some reasons it can fail with the K3772-Z dongle + { + ret = m_at.executeSimple(cmd, &result); + DBG("Result of command: Err code=%d", ret); + } while(ret && --tries); + DBG("ATResult: AT return=%d (code %d)", result.result, result.code); + DBG("APN set to %s", copsProcessor.getAPN()); + } + #else + if(apn != NULL) + { + char cmd[48]; + int tries = 30; + sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn); + do //Try 30 times because for some reasons it can fail *a lot* with the K3772-Z dongle + { + ret = m_at.executeSimple(cmd, &result); + DBG("Result of command: Err code=%d", ret); + if(ret) + { + Thread::wait(500); + } + } while(ret && --tries); + DBG("ATResult: AT return=%d (code %d)", result.result, result.code); + DBG("APN set to %s", apn); + } + #endif + + + //Connect + DBG("Connecting"); + #if 0 + ret = m_at.executeSimple("ATDT *99#", &result); + DBG("Result of command: Err code=%d", ret); + DBG("ATResult: AT return=%d (code %d)", result.result, result.code); + #endif + #if USE_ONE_PORT + m_at.close(); // Closing AT parser + m_atOpen = false; //Will need to be reinitialized afterwards + #endif + + #if 0 + DBG("AT Parser closed"); + if( (ret!=NET_MOREINFO) || (result.result != ATCommandsInterface::ATResult::AT_CONNECT)) + { + ERR("Could not connect"); + return ret; //Could not connect + } + #endif + DBG("Connecting PPP"); + + ret = m_ppp.connect(); + DBG("Result of connect: Err code=%d", ret); + return ret; +} + + +int UbloxUSBGSMModem::disconnect() +{ + DBG("Disconnecting from PPP"); + int ret = m_ppp.disconnect(); + if(ret) + { + ERR("Disconnect returned %d, still trying to disconnect", ret); + } + + //Ugly but leave dongle time to recover + Thread::wait(500); + + #if USE_ONE_PORT + ATCommandsInterface::ATResult result; + DBG("Starting AT thread"); + ret = m_at.open(); + if(ret) + { + return ret; + } + #endif + + DBG("Trying to hangup"); + + #if 0 //Does not appear to work + int tries = 10; + do + { + ret = m_at.executeSimple("+++", &result, 1000); + DBG("Result of command: Err code=%d\n", ret); + DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); + } while(tries-- && ret); + if(!ret) + { + ret = m_at.executeSimple("ATH", &result); + DBG("Result of command: Err code=%d\n", ret); + DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); + } + #endif + + #if USE_ONE_PORT + //Reinit AT parser + ret = m_at.init(); + DBG("Result of command: Err code=%d\n", ret); + if(ret) + { + m_at.close(); // Closing AT parser + DBG("AT Parser closed, could not complete disconnection"); + return NET_TIMEOUT; + } + + #if 0 + m_at.close(); // Closing AT parser + DBG("AT Parser closed"); + #endif + #endif + return OK; +} + +int UbloxUSBGSMModem::sendSM(const char* number, const char* message) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_smsInit) + { + ret = m_sms.init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = m_sms.send(number, message); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxUSBGSMModem::getSM(char* number, char* message, size_t maxLength) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_smsInit) + { + ret = m_sms.init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = m_sms.get(number, message, maxLength); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxUSBGSMModem::getSMCount(size_t* pCount) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_smsInit) + { + ret = m_sms.init(); + if(ret) + { + return ret; + } + m_smsInit = true; + } + + ret = m_sms.getCount(pCount); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxUSBGSMModem::sendUSSD(const char* command, char* result, size_t maxLength) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_ussdInit) + { + ret = m_ussd.init(); + if(ret) + { + return ret; + } + m_ussdInit = true; + } + + ret = m_ussd.send(command, result, maxLength); + if(ret) + { + return ret; + } + + return OK; +} + +int UbloxUSBGSMModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegistrationState, LinkMonitor::BEARER* pBearer) +{ + int ret = init(); + if(ret) + { + return ret; + } + + if(!m_linkMonitorInit) + { + ret = m_linkMonitor.init(); + if(ret) + { + return ret; + } + m_linkMonitorInit = true; + } + + ret = m_linkMonitor.getState(pRssi, pRegistrationState, pBearer); + if(ret) + { + return ret; + } + + return OK; +} + + +ATCommandsInterface* UbloxUSBGSMModem::getATCommandsInterface() +{ + return &m_at; +} + +int UbloxUSBGSMModem::power(bool enable) +{ + if( m_powerGatingPin == NC ) + { + return NET_INVALID; //A pin name has not been provided in the constructor + } + + if(!enable) //Will force components to re-init + { + cleanup(); + } + + DigitalOut powerGatingOut(m_powerGatingPin); + powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable; + + return OK; +} + +bool UbloxUSBGSMModem::power() +{ + if( m_powerGatingPin == NC ) + { + return true; //Assume power is always on + } + + DigitalOut powerGatingOut(m_powerGatingPin); + return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut; +} + +int UbloxUSBGSMModem::init() +{ + if( !m_dongleConnected ) + { + if(!power()) + { + //Obviously cannot initialize the dongle if it is disconnected... + ERR("Power is off"); + return NET_INVALID; + } + m_dongleConnected = true; + while( !m_dongle.connected() ) + { + m_dongle.tryConnect(); + Thread::wait(10); + } + } + + if(m_atOpen) + { + return OK; + } + + DBG("Starting AT thread if needed"); + int ret = m_at.open(); + if(ret) + { + return ret; + } + + DBG("Sending initialisation commands"); + ret = m_at.init(); + if(ret) + { + return ret; + } + + if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAU200) + { + INFO("Using a u-blox LISA-U"); + } + else + { + WARN("Using an Unknown Dongle"); + } + + ATCommandsInterface::ATResult result; + + //Wait for network registration + CREGProcessor cregProcessor; + do + { + DBG("Waiting for network registration"); + ret = m_at.execute("AT+CREG?", &cregProcessor, &result); + DBG("Result of command: Err code=%d\n", ret); + DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); + if(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING) + { + Thread::wait(3000); + } + } while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING); + if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED) + { + ERR("Registration denied"); + return NET_AUTH; + } + + m_atOpen = true; + + return OK; +} + +int UbloxUSBGSMModem::cleanup() +{ + if(m_ppp.isConnected()) + { + WARN("Data connection is still open"); //Try to encourage good behaviour from the user + m_ppp.disconnect(); + } + + m_smsInit = false; + m_ussdInit = false; + m_linkMonitorInit = false; + //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once + + if(m_atOpen) + { + m_at.close(); + m_atOpen = false; + } + + m_dongle.disconnect(); + m_dongleConnected = false; + + return OK; +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.h b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.h new file mode 100644 index 0000000000..2cc432a2c2 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.h @@ -0,0 +1,155 @@ +/* VodafoneUSBModem.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UBLOXUSBGSMMODEM_H_ +#define UBLOXUSBGSMMODEM_H_ + +#include "core/fwk.h" + +#include "WANDongle.h" +#include "at/ATCommandsInterface.h" +#include "serial/usb/USBSerialStream.h" +#include "ip/PPPIPInterface.h" +#include "sms/GSMSMSInterface.h" +#include "ussd/USSDInterface.h" +#include "link/LinkMonitor.h" +#include "CellularModem.h" + +/** u-blox WCDMA modem (LISA-U200) + */ +class UbloxUSBGSMModem: public CellularModem +{ +public: + /** Create u-blox API instance + @param powerGatingPin Optional pin commanding a power gating transistor on the modem's power line + @param powerGatingOnWhenPinHigh true if the pin needs to be high to power the dongle, defaults to true + */ + UbloxUSBGSMModem(PinName powerGatingPin = NC, bool powerGatingOnWhenPinHigh = true); + + //Internet-related functions + + /** Open a 3G internet connection + @return 0 on success, error code on failure + */ + virtual int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL); + + /** Close the internet connection + @return 0 on success, error code on failure + */ + virtual int disconnect(); + + + /** Send a SM + @param number The receiver's phone number + @param message The message to send + @return 0 on success, error code on failure + */ + virtual int sendSM(const char* number, const char* message); + + + /** Receive a SM + @param number Pointer to a buffer to store the sender's phone number (must be at least 17 characters-long, including the sapce for the null-terminating char) + @param message Pointer to a buffer to store the the incoming message + @param maxLength Maximum message length that can be stored in buffer (including null-terminating character) + @return 0 on success, error code on failure + */ + virtual int getSM(char* number, char* message, size_t maxLength); + + /** Get the number of SMs in the incoming box + @param pCount pointer to store the number of unprocessed SMs on + @return 0 on success, error code on failure + */ + virtual int getSMCount(size_t* pCount); + + /** Send a USSD command & wait for its result + @param command The command to send + @param result Buffer in which to store the result + @param maxLength Maximum result length that can be stored in buffer (including null-terminating character) + @return 0 on success, error code on failure + */ + int sendUSSD(const char* command, char* result, size_t maxLength); + + /** Get link state + @param pRssi pointer to store the current RSSI in dBm, between -51 dBm and -113 dBm if known; -51 dBm means -51 dBm or more; -113 dBm means -113 dBm or less; 0 if unknown + @param pRegistrationState pointer to store the current registration state + @param pBearer pointer to store the current bearer + @return 0 on success, error code on failure + */ + int getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegistrationState, LinkMonitor::BEARER* pBearer); + + /** Get the ATCommandsInterface instance + @return Pointer to the ATCommandsInterface instance + */ + virtual ATCommandsInterface* getATCommandsInterface(); + + /** Switch power on or off + In order to use this function, a pin name must have been entered in the constructor + @param enable true to switch the dongle on, false to switch it off + @return 0 on success, error code on failure + */ + virtual int power(bool enable); + +protected: + bool power(); //< Turn power to USB dongle ON. + + /** Initialise dongle. + * The following actions are performed: + * 1) Power up + * 2) Establish USB connection to dongle + * 3) Start AT interface thread + * 4) Wait for network registration + */ + int init(); + + /** De-initialise dongle. + * The following actions are performed: + * 1) Tear down PPP session + * 2) Set SMS,USSD, and LinkMonitor subsystems to un-initialised + * 3) Close the AT commands interface + * 4) Tear down the USB connection to dongle + */ + int cleanup(); + +private: + WANDongle m_dongle; //< Interface to USB connected WAN dongle + + USBSerialStream m_atStream; //< Serial interface to AT channel on modem + USBSerialStream m_pppStream; //< Serial interface to PPP channel on modem + + ATCommandsInterface m_at; //< Interface to AT commands processing + + GSMSMSInterface m_sms; //< Interface to SMS manager (send/receive etc) + USSDInterface m_ussd; //< Interface to USSD manager (send etc) + LinkMonitor m_linkMonitor; //< Interface to link monitor (RSSI) + + PPPIPInterface m_ppp; //< Interface to PPP conection manager (IP assignment etc) + + bool m_dongleConnected; //< Is the dongle physically connected (does the USB stack respond)? true/false + bool m_ipInit; //< Has PPIPInterface object (m_ppp) been initialised? true/false + bool m_smsInit; //< Has SMSInterface object (m_sms) been initialised? true/false + bool m_ussdInit; //< Has USSDInterface object (m_ussd) been initialised? true/false + bool m_linkMonitorInit; //< Has LinkMonitor object (m_linkMonitor) been initialised? true/false + bool m_atOpen; //< Is the interface to the ATCommandsInterface open? true/false + + PinName m_powerGatingPin; //< Pin which toggles power gating + bool m_powerGatingOnWhenPinHigh; //< Semantics of power gating (whether high or low toggles power gating) +}; + + +#endif /* UBLOXMODEM_H_ */ |