From d0d44766593cc81c616e88a216428b6cb03b3333 Mon Sep 17 00:00:00 2001 From: mazgch Date: Mon, 9 Dec 2013 21:22:02 +0100 Subject: [PATCH 1/6] adding support for serial port --- .../CellularModem/at/ATCommandsInterface.cpp | 35 +- .../CellularModem/at/ATCommandsInterface.h | 2 +- .../CellularModem/ip/PPPIPInterface.cpp | 47 +- .../CellularModem/ip/PPPIPInterface.h | 9 +- .../serial/io/IOSerialStream.cpp | 253 ++++++++++ .../serial/io/IOSerialStream.h | 72 +++ .../serial/usb/USBSerialStream.h | 3 +- .../UbloxCDMAModemInitializer.cpp | 2 +- .../UbloxUSBModem/UbloxCDMAModemInitializer.h | 2 +- .../UbloxGSMModemInitializer.cpp | 2 +- .../UbloxUSBModem/UbloxGSMModemInitializer.h | 2 +- .../net/cellular/UbloxUSBModem/UbloxModem.cpp | 470 ++++++++++++++++++ .../net/cellular/UbloxUSBModem/UbloxModem.h | 168 +++++++ .../UbloxUSBModem/UbloxUSBCDMAModem.cpp | 6 +- .../UbloxUSBModem/UbloxUSBGSMModem.cpp | 6 +- 15 files changed, 1021 insertions(+), 58 deletions(-) create mode 100644 libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.cpp create mode 100644 libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.h create mode 100644 libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp create mode 100644 libraries/net/cellular/UbloxUSBModem/UbloxModem.h diff --git a/libraries/net/cellular/CellularModem/at/ATCommandsInterface.cpp b/libraries/net/cellular/CellularModem/at/ATCommandsInterface.cpp index e101a8171f..90be0c2e65 100644 --- a/libraries/net/cellular/CellularModem/at/ATCommandsInterface.cpp +++ b/libraries/net/cellular/CellularModem/at/ATCommandsInterface.cpp @@ -63,30 +63,33 @@ int ATCommandsInterface::open() } //Initialize AT link & start events processing -int ATCommandsInterface::init() +int ATCommandsInterface::init(bool reset /* = true*/) { - DBG("Sending ATZ E1 V1"); //Lock transaction mutex m_transactionMtx.lock(); - //Should we flush m_pStream at this point ??? - int err; - int tries = 5; - do + if (reset) { - err = executeInternal("ATZ E1 V1", this, NULL, 3000); //Enable echo and verbosity - if(err && tries) + DBG("Sending ATZ E1 V1"); + //Should we flush m_pStream at this point ??? + int err; + int tries = 5; + do { - WARN("No response, trying again"); - Thread::wait(1000); //Give dongle time to recover + err = executeInternal("ATZ E1 V1", this, NULL, 3000); //Enable echo and verbosity + if(err && tries) + { + WARN("No response, trying again"); + Thread::wait(1000); //Give dongle time to recover + } + } while(err && tries--); + if( err ) + { + ERR("Sending ATZ E1 V1 returned with err code %d", err); + m_transactionMtx.unlock(); + return err; } - } while(err && tries--); - if( err ) - { - ERR("Sending ATZ E1 V1 returned with err code %d", err); - m_transactionMtx.unlock(); - return err; } //Enable events handling and execute events enabling commands diff --git a/libraries/net/cellular/CellularModem/at/ATCommandsInterface.h b/libraries/net/cellular/CellularModem/at/ATCommandsInterface.h index 129eedf8cf..8334df8957 100644 --- a/libraries/net/cellular/CellularModem/at/ATCommandsInterface.h +++ b/libraries/net/cellular/CellularModem/at/ATCommandsInterface.h @@ -77,7 +77,7 @@ public: int open(); //Initialize AT link - int init(); + int init(bool reset = true); //Close connection int close(); diff --git a/libraries/net/cellular/CellularModem/ip/PPPIPInterface.cpp b/libraries/net/cellular/CellularModem/ip/PPPIPInterface.cpp index f71afea65b..1766868ff5 100644 --- a/libraries/net/cellular/CellularModem/ip/PPPIPInterface.cpp +++ b/libraries/net/cellular/CellularModem/ip/PPPIPInterface.cpp @@ -50,22 +50,15 @@ extern "C" { #include "netif/ppp/ppp.h" } -PPPIPInterface::PPPIPInterface(IOStream* pStream, const char* msisdn) : LwIPInterface(), m_linkStatusSphre(1), m_pppErrCode(0), m_pStream(pStream), m_streamAvail(true), m_pppd(-1) +PPPIPInterface::PPPIPInterface(IOStream* pStream) : LwIPInterface(), m_linkStatusSphre(1), m_pppErrCode(0), m_pStream(pStream), m_streamAvail(true), m_pppd(-1) { - m_connectCmd = new char[strlen(CONNECT_CMD_PREFIX) + strlen(msisdn) + strlen(CONNECT_CMD_SUFFIX) + 1]; - sprintf(m_connectCmd, "%s%s%s", CONNECT_CMD_PREFIX, msisdn, CONNECT_CMD_SUFFIX); - m_expectedResp = new char[strlen(m_connectCmd) + strlen(EXPECTED_RESP_SUFFIX) + 1]; - sprintf(m_expectedResp, "%s%s", m_connectCmd, EXPECTED_RESP_SUFFIX); - m_expectedRespDatarate = new char[strlen(m_connectCmd) + strlen(EXPECTED_RESP_DATARATE_SUFFIX) + 1]; - sprintf(m_expectedRespDatarate, "%s%s", m_connectCmd, EXPECTED_RESP_DATARATE_SUFFIX); m_linkStatusSphre.wait(); } + + /*virtual*/ PPPIPInterface::~PPPIPInterface() { - delete m_connectCmd; - delete m_expectedResp; - delete m_expectedRespDatarate; } /*virtual*/ int PPPIPInterface::init() //Init PPP-specific stuff, create the right bindings, etc @@ -78,10 +71,11 @@ PPPIPInterface::PPPIPInterface(IOStream* pStream, const char* msisdn) : LwIPInte return OK; } -int PPPIPInterface::setup(const char* user, const char* pw) +int PPPIPInterface::setup(const char* user, const char* pw, const char* msisdn) { DBG("Configuring PPP authentication method"); pppSetAuth(PPPAUTHTYPE_ANY, user, pw); + m_msisdn = msisdn; DBG("Done"); return OK; } @@ -89,22 +83,22 @@ int PPPIPInterface::setup(const char* user, const char* pw) /*virtual*/ int PPPIPInterface::connect() { int ret; + char cmd[32]; + int cmdLen; char buf[32]; size_t len; DBG("Trying to connect with PPP"); cleanupLink(); - DBG("Sending %s", m_connectCmd); - - ret = m_pStream->write((uint8_t*)m_connectCmd, strlen(m_connectCmd), osWaitForever); + cmdLen = sprintf(cmd, "%s%s%s", CONNECT_CMD_PREFIX, m_msisdn, CONNECT_CMD_SUFFIX); + DBG("Sending %s", cmd); + ret = m_pStream->write((uint8_t*)cmd, cmdLen, osWaitForever); if( ret != OK ) { return NET_UNKNOWN; } - DBG("Expect %s", m_expectedResp); - len = 0; size_t readLen; ret = m_pStream->read((uint8_t*)buf + len, &readLen, EXPECTED_RESP_MIN_LEN, 10000); @@ -128,16 +122,21 @@ int PPPIPInterface::setup(const char* user, const char* pw) DBG("Got %s[len %d]", buf, len); int datarate = 0; - if( (sscanf(buf, m_expectedRespDatarate, &datarate ) != 1) && (strcmp(m_expectedResp, buf) != 0) ) + strcpy(&cmd[cmdLen], EXPECTED_RESP_DATARATE_SUFFIX); + if( (sscanf(buf, cmd, &datarate ) != 1)) { - //Discard buffer - do //Clear buf + strcpy(&cmd[cmdLen], EXPECTED_RESP_SUFFIX); + if (strcmp(cmd, buf) != 0) { - ret = m_pStream->read((uint8_t*)buf, &len, 32, 0); - } while( (ret == OK) && (len > 0) ); - return NET_CONN; - } - + //Discard buffer + do //Clear buf + { + ret = m_pStream->read((uint8_t*)buf, &len, 32, 0); + } while( (ret == OK) && (len > 0) ); + return NET_CONN; + } + } + DBG("Transport link open"); if(datarate != 0) { diff --git a/libraries/net/cellular/CellularModem/ip/PPPIPInterface.h b/libraries/net/cellular/CellularModem/ip/PPPIPInterface.h index eba30e9461..2d24009dcd 100644 --- a/libraries/net/cellular/CellularModem/ip/PPPIPInterface.h +++ b/libraries/net/cellular/CellularModem/ip/PPPIPInterface.h @@ -40,11 +40,11 @@ using namespace rtos; class PPPIPInterface : public LwIPInterface { public: - PPPIPInterface(IOStream* pStream, const char* msisdn); + PPPIPInterface(IOStream* pStream); virtual ~PPPIPInterface(); int init(); //Init PPP-specific stuff, create the right bindings, etc - int setup(const char* user, const char* pw); //Setup authentication + int setup(const char* user, const char* pw, const char* msisdn); //Setup authentication virtual int connect(); virtual int disconnect(); @@ -57,16 +57,13 @@ private: IOStream* m_pStream; //Serial stream bool m_streamAvail; + const char* m_msisdn; int m_pppd; friend u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); friend u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); friend void sio_read_abort(sio_fd_t fd); - - char* m_connectCmd; - char* m_expectedResp; - char* m_expectedRespDatarate; }; #endif /* PPPIPINTERFACE_H_ */ diff --git a/libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.cpp b/libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.cpp new file mode 100644 index 0000000000..2a05c1c2c4 --- /dev/null +++ b/libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.cpp @@ -0,0 +1,253 @@ +/* IOSerialStream.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__ 0 //Maximum verbosity +#ifndef __MODULE__ +#define __MODULE__ "IOSerialStream.cpp" +#endif + +#include "core/fwk.h" + +#include + +#include "IOSerialStream.h" + +#define UART_X ((LPC_UART_TypeDef *)(UART_1)) + +IOSerialStream::IOSerialStream(mbed::RawSerial& serial) : m_serial(serial), m_serialTxFifoEmpty(true), +m_availableSphre(1), m_spaceSphre(1), m_inBuf(), m_outBuf() +{ + m_availableSphre.wait(); + m_spaceSphre.wait(); + //Attach interrupts + m_serial.attach(this, &IOSerialStream::readable, mbed::SerialBase::RxIrq); + m_serial.attach(this, &IOSerialStream::writeable, mbed::SerialBase::TxIrq); +} + +/*virtual*/ IOSerialStream::~IOSerialStream() +{ + m_serial.attach(NULL, mbed::SerialBase::RxIrq); + m_serial.attach(NULL, mbed::SerialBase::TxIrq); +} + +//0 for non-blocking (returns immediately), osWaitForever for infinite blocking +/*virtual*/ int IOSerialStream::read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout/*=osWaitForever*/) +{ + DBG("Trying to read at most %d chars", maxLength); + int ret = waitAvailable(timeout); + if(ret) + { + WARN("Error %d while waiting for incoming data", ret); + return ret; + } + int readLen = MIN( available(), maxLength ); + *pLength = readLen; + setupReadableISR(false); + while(readLen--) + { + m_inBuf.dequeue(buf); + buf++; + } + setupReadableISR(true); + DBG("Read %d chars successfully", *pLength); + return OK; +} + +/*virtual*/ size_t IOSerialStream::available() +{ + setupReadableISR(false); //m_inBuf.available() is not reentrant + size_t len = m_inBuf.available(); + setupReadableISR(true); + return len; +} + +/*virtual*/ int IOSerialStream::waitAvailable(uint32_t timeout/*=osWaitForever*/) //Wait for data to be available +{ + int ret; + if(available()) //Is data already available? + { + m_availableSphre.wait(0); //Clear the queue as data is available + return OK; + } + + DBG("Waiting for data availability %d ms (-1 is infinite)", timeout); + ret = m_availableSphre.wait(timeout); //Wait for data to arrive or for abort + if(ret <= 0) + { + DBG("Timeout"); + return NET_TIMEOUT; + } + if(!available()) //Even if abort has been called, return that data is available + { + DBG("Aborted"); + return NET_INTERRUPTED; + } + DBG("Finished waiting"); + m_availableSphre.wait(0); //Clear the queue as data is available + return OK; +} + +/*virtual*/ int IOSerialStream::abortRead() //Abort current reading (or waiting) operation +{ + if( !available() ) //If there is data pending, no need to abort + { + m_availableSphre.release(); //Force exiting the waiting state; kludge to pass a RC directly + } + else + { + DBG("Serial is readable"); ; + } + return OK; +} + +void IOSerialStream::setupReadableISR(bool en) +{ + if(en) + { + UART_X->IER |= 1 << 0; + } + else + { + UART_X->IER &= ~(1 << 0); + } +} + +void IOSerialStream::readable() //Callback from m_serial when new data is available +{ + do + { + m_inBuf.queue(m_serial.getc()); + } while(m_serial.readable()); + m_availableSphre.release(); //Force exiting the waiting state +} + +//0 for non-blocking (returns immediately), osWaitForever for infinite blocking +/*virtual*/ int IOSerialStream::write(uint8_t* buf, size_t length, uint32_t timeout/*=osWaitForever*/) +{ + DBG("Trying to write %d chars", length); + int ret = waitSpace(timeout); + if(ret) + { + WARN("Error %d while waiting for space", ret); + return ret; + } + DBG("Writing %d chars", length); + setupWriteableISR(false); + while(length) + { + m_outBuf.queue(*buf); + buf++; + length--; + if(length && !space()) + { + DBG("Waiting to write remaining %d chars", length); + setupWriteableISR(true); + ret = waitSpace(timeout); + if(ret) + { + WARN("Error %d while waiting for space", ret); + return ret; + } + setupWriteableISR(false); + } + } + //If m_serial tx fifo is empty we need to manually tx a byte in order to trigger the interrupt + if( m_outBuf.available() && m_serialTxFifoEmpty ) + { + m_serialTxFifoEmpty = false; + uint8_t c; + m_outBuf.dequeue(&c); + m_serial.putc((char)c); + } + setupWriteableISR(true); + DBG("Write successful"); + return OK; +} + +/*virtual*/ size_t IOSerialStream::space() +{ + setupWriteableISR(false); //m_outBuf.available() is not reentrant + size_t len = CIRCBUF_SIZE - m_outBuf.available(); + setupWriteableISR(true); + return len; +} + +/*virtual*/ int IOSerialStream::waitSpace(uint32_t timeout/*=osWaitForever*/) //Wait for space to be available +{ + int ret; + if(space()) //Is still space already left? + { + m_spaceSphre.wait(0); //Clear the queue as space is available + return OK; + } + + DBG("Waiting for data space %d ms (-1 is infinite)", timeout); + ret = m_spaceSphre.wait(timeout); //Wait for space to be made or for abort + if(ret <= 0) + { + DBG("Timeout"); + return NET_TIMEOUT; + } + if(!space()) //Even if abort has been called, return that space is available + { + DBG("Aborted"); + return NET_INTERRUPTED; + } + m_spaceSphre.wait(0); //Clear the queue as space is available + return OK; +} + +/*virtual*/ int IOSerialStream::abortWrite() //Abort current writing (or waiting) operation +{ + if( !space() ) //If there is space left, no need to abort + { + m_spaceSphre.release(); //Force exiting the waiting state + } + return OK; +} + +void IOSerialStream::setupWriteableISR(bool en) +{ + if(en) + { + UART_X->IER |= 1 << 1; + } + else + { + UART_X->IER &= ~(1 << 1); + } +} + +void IOSerialStream::writeable() //Callback from m_serial when new space is available +{ + if(m_outBuf.isEmpty()) + { + m_serialTxFifoEmpty = true; + } + else + { + while(m_serial.writeable() && !m_outBuf.isEmpty()) + { + uint8_t c; + m_outBuf.dequeue(&c); + m_serial.putc((char)c); + } + } + m_spaceSphre.release(); //Force exiting the waiting state +} diff --git a/libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.h b/libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.h new file mode 100644 index 0000000000..7e9ef89d05 --- /dev/null +++ b/libraries/net/cellular/CellularUSBModem/serial/io/IOSerialStream.h @@ -0,0 +1,72 @@ +/* IOSerialStream.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 IOSERIALSTREAM_H_ +#define IOSERIALSTREAM_H_ + +#include "core/fwk.h" + +#include "RawSerial.h" + +#include "rtos.h" +#include "core/MtxCircBuffer.h" + +/** Input Serial Stream for physical serial interfaces (UART...) +This class is not thread-safe, except for the *Abort() methods that can be called by any thread/ISR +*/ +class IOSerialStream : public IOStream +{ +public: + enum { CIRCBUF_SIZE = 255 }; + IOSerialStream(mbed::RawSerial& serial); + /*virtual*/ ~IOSerialStream(); + + //0 for non-blocking (returns immediately), osWaitForever for infinite blocking + virtual int read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout=osWaitForever); + virtual size_t available(); + virtual int waitAvailable(uint32_t timeout=osWaitForever); //Wait for data to be available + virtual int abortRead(); //Abort current reading (or waiting) operation + + + //0 for non-blocking (returns immediately), osWaitForever for infinite blocking + virtual int write(uint8_t* buf, size_t length, uint32_t timeout=osWaitForever); + virtual size_t space(); + virtual int waitSpace(uint32_t timeout=osWaitForever); //Wait for space to be available + virtual int abortWrite(); //Abort current writing (or waiting) operation + +private: + + mbed::RawSerial& m_serial; + volatile bool m_serialTxFifoEmpty; + + void setupReadableISR(bool en); + void readable(); //Callback from m_serial when new data is available + + Semaphore m_availableSphre; //Used for signalling + + void setupWriteableISR(bool en); + void writeable(); //Callback from m_serial when new space is available + + Semaphore m_spaceSphre; //Used for signalling + + MtxCircBuffer m_inBuf; + MtxCircBuffer m_outBuf; + +}; + +#endif /* IOSERIALSTREAM_H_ */ diff --git a/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h b/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h index 1af5f019db..854570e22f 100644 --- a/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h +++ b/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h @@ -32,10 +32,11 @@ /* Input Serial Stream for USB virtual serial ports interfaces This class is not thread-safe, except for the *Abort() methods that can be called by any thread/ISR */ -#define CIRCBUF_SIZE 127 + class USBSerialStream : public IOStream, IUSBHostSerialListener { public: + enum { CIRCBUF_SIZE = 127 } USBSerialStream(IUSBHostSerial& serial); /*virtual*/ ~USBSerialStream(); diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.cpp index d0a1e52c99..6464afc984 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.cpp +++ b/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.cpp @@ -109,6 +109,6 @@ int UbloxCDMAModemInitializer::getSerialPortCount() /*virtual*/ int UbloxCDMAModemInitializer::getType() { - return WAN_DONGLE_TYPE_UBLOXC200; + return WAN_DONGLE_TYPE_UBLOX_LISAC200; } diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.h b/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.h index cccec7f8ec..4836680da2 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.h +++ b/libraries/net/cellular/UbloxUSBModem/UbloxCDMAModemInitializer.h @@ -27,7 +27,7 @@ enum { - WAN_DONGLE_TYPE_UBLOXC200 + WAN_DONGLE_TYPE_UBLOX_LISAC200 = 0xC200, }; class UbloxCDMAModemInitializer : public WANDongleInitializer diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.cpp index a3a89313db..e28632593a 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.cpp +++ b/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.cpp @@ -126,6 +126,6 @@ int UbloxGSMModemInitializer::getSerialPortCount() /*virtual*/ int UbloxGSMModemInitializer::getType() { - return WAN_DONGLE_TYPE_UBX; + return WAN_DONGLE_TYPE_UBLOX_LISAU200; } diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.h b/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.h index a1e9e038b4..383c443eb3 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.h +++ b/libraries/net/cellular/UbloxUSBModem/UbloxGSMModemInitializer.h @@ -23,7 +23,7 @@ enum { - WAN_DONGLE_TYPE_UBX + WAN_DONGLE_TYPE_UBLOX_LISAU200 = 0x0200 }; //----------------------------------------------------------------------- diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp new file mode 100644 index 0000000000..7118adb5d2 --- /dev/null +++ b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp @@ -0,0 +1,470 @@ +/* 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_gsm(true) +{ +} + +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_gsm ? 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_gsm) sms = &m_GsmSms; + else sms = &m_CdmaSms; + 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_gsm) sms = &m_GsmSms; + else sms = &m_CdmaSms; + 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_gsm) sms = &m_GsmSms; + else sms = &m_CdmaSms; + 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; + CREGProcessor cregProcessor(m_gsm); + //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(); + if(ret) + { + return ret; + } + m_linkMonitorInit = true; + } + + ret = m_linkMonitor.getState(pRssi, pRegistrationState, pBearer); + 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"); + } + else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAC200) + { + INFO("Using a u-blox LISA-C200 CDMA Modem"); + m_gsm = false; + } + 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,P0_16), + m_atStream(m_Serial) +{ + m_Serial.baud(115200); +} + diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxModem.h b/libraries/net/cellular/UbloxUSBModem/UbloxModem.h new file mode 100644 index 0000000000..5515ff29f2 --- /dev/null +++ b/libraries/net/cellular/UbloxUSBModem/UbloxModem.h @@ -0,0 +1,168 @@ +/* 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" + +/** 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); + + /** 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 + bool m_onePort; +protected: + bool m_gsm; +}; + +#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/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.cpp index eb7be36fe6..5e4e32a2b5 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.cpp +++ b/libraries/net/cellular/UbloxUSBModem/UbloxUSBCDMAModem.cpp @@ -33,7 +33,7 @@ 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, DEFAULT_MSISDN_CDMA), +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) { @@ -88,7 +88,7 @@ int UbloxUSBCDMAModem::connect(const char* apn, const char* user, const char* pa m_ipInit = true; m_ppp.init(); } - m_ppp.setup(user, password); + m_ppp.setup(user, password, DEFAULT_MSISDN_CDMA); int ret = init(); if(ret) @@ -341,7 +341,7 @@ int UbloxUSBCDMAModem::init() return ret; } - if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOXC200) + if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAC200) { INFO("Using a UBLOX C200 Dongle"); } diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.cpp index 56ceacc63e..8209dc6a88 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.cpp +++ b/libraries/net/cellular/UbloxUSBModem/UbloxUSBGSMModem.cpp @@ -36,7 +36,7 @@ UbloxUSBGSMModem::UbloxUSBGSMModem(PinName powerGatingPin /*= NC*/, bool powerGa 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, DEFAULT_MSISDN_GSM), // Construct PPPIPInterface with the PPP serial channel + 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 @@ -185,7 +185,7 @@ int UbloxUSBGSMModem::connect(const char* apn, const char* user, const char* pas m_ipInit = true; m_ppp.init(); } - m_ppp.setup(user, password); + m_ppp.setup(user, password, DEFAULT_MSISDN_GSM); int ret = init(); if(ret) @@ -543,7 +543,7 @@ int UbloxUSBGSMModem::init() return ret; } - if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBX) + if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAU200) { INFO("Using a u-blox LISA-U"); } From ea42c3b72688c788274f8634f5e3e8789bf35eb5 Mon Sep 17 00:00:00 2001 From: mazgch Date: Mon, 9 Dec 2013 21:28:56 +0100 Subject: [PATCH 2/6] typo --- .../net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h b/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h index 854570e22f..97cf3c6860 100644 --- a/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h +++ b/libraries/net/cellular/CellularUSBModem/serial/usb/USBSerialStream.h @@ -36,7 +36,7 @@ This class is not thread-safe, except for the *Abort() methods that can be calle class USBSerialStream : public IOStream, IUSBHostSerialListener { public: - enum { CIRCBUF_SIZE = 127 } + enum { CIRCBUF_SIZE = 127 }; USBSerialStream(IUSBHostSerial& serial); /*virtual*/ ~USBSerialStream(); From d5da33236719b74494e8fc4ee215c9a085eb7fb6 Mon Sep 17 00:00:00 2001 From: mazgch Date: Mon, 9 Dec 2013 21:48:01 +0100 Subject: [PATCH 3/6] only use one port with CDMA at the moment. --- libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp | 1 + libraries/net/cellular/UbloxUSBModem/UbloxModem.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp index 7118adb5d2..c5111a2bc9 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp +++ b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp @@ -443,6 +443,7 @@ int UbloxUSBModem::init() { INFO("Using a u-blox LISA-C200 CDMA Modem"); m_gsm = false; + m_onePort = false; } else { diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxModem.h b/libraries/net/cellular/UbloxUSBModem/UbloxModem.h index 5515ff29f2..153942785c 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxModem.h +++ b/libraries/net/cellular/UbloxUSBModem/UbloxModem.h @@ -128,8 +128,8 @@ private: 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 - bool m_onePort; protected: + bool m_onePort; bool m_gsm; }; From 44c2e02e51ad3a1eed1aaa25381212d6310f8ea7 Mon Sep 17 00:00:00 2001 From: mazgch Date: Mon, 9 Dec 2013 22:04:21 +0100 Subject: [PATCH 4/6] - add support for MultiPort Serial Devices - allow to configure the debug level of the USB stack --- libraries/USBHost/USBHost/USBHostConf.h | 2 +- libraries/USBHost/USBHost/dbg.h | 25 +- .../USBHost/USBHostSerial/USBHostSerial.cpp | 321 +++++++++++++----- .../USBHost/USBHostSerial/USBHostSerial.h | 125 +++++-- 4 files changed, 356 insertions(+), 117 deletions(-) diff --git a/libraries/USBHost/USBHost/USBHostConf.h b/libraries/USBHost/USBHost/USBHostConf.h index b0d9ff76b8..d5515edc3b 100644 --- a/libraries/USBHost/USBHost/USBHostConf.h +++ b/libraries/USBHost/USBHost/USBHostConf.h @@ -49,7 +49,7 @@ #define USBHOST_MOUSE 1 /* -* Enable USBHostSerial +* Enable USBHostSerial or USBHostMultiSerial (if set > 1) */ #define USBHOST_SERIAL 1 diff --git a/libraries/USBHost/USBHost/dbg.h b/libraries/USBHost/USBHost/dbg.h index 950e61f830..33deb48437 100644 --- a/libraries/USBHost/USBHost/dbg.h +++ b/libraries/USBHost/USBHost/dbg.h @@ -18,17 +18,35 @@ #define USB_DEBUG_H //Debug is disabled by default -#define DEBUG 0 +#define DEBUG 3 /*INFO,ERR,WARN*/ #define DEBUG_TRANSFER 0 #define DEBUG_EP_STATE 0 #define DEBUG_EVENT 0 -#if (DEBUG) +#if (DEBUG > 3) #define USB_DBG(x, ...) std::printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); #else #define USB_DBG(x, ...) #endif +#if (DEBUG > 2) +#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); +#else +#define USB_INFO(x, ...) +#endif + +#if (DEBUG > 1) +#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); +#else +#define USB_WARN(x, ...) +#endif + +#if (DEBUG > 0) +#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); +#else +#define USB_ERR(x, ...) +#endif + #if (DEBUG_TRANSFER) #define USB_DBG_TRANSFER(x, ...) std::printf("[USB_TRANSFER: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); #else @@ -41,9 +59,6 @@ #define USB_DBG_EVENT(x, ...) #endif -#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); #endif diff --git a/libraries/USBHost/USBHostSerial/USBHostSerial.cpp b/libraries/USBHost/USBHostSerial/USBHostSerial.cpp index 52db31a4bb..0737180030 100644 --- a/libraries/USBHost/USBHostSerial/USBHostSerial.cpp +++ b/libraries/USBHost/USBHostSerial/USBHostSerial.cpp @@ -20,27 +20,17 @@ #include "dbg.h" -#define SET_LINE_CODING 0x20 +#define CHECK_INTERFACE(cls,subcls,proto) \ + (((cls == 0xFF) && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */ || \ + ((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ ) -USBHostSerial::USBHostSerial(): circ_buf() { +#if (USBHOST_SERIAL <= 1) + +USBHostSerial::USBHostSerial() +{ host = USBHost::getHostInst(); - size_bulk_in = 0; - size_bulk_out = 0; - init(); -} - -void USBHostSerial::init() { - dev = NULL; - bulk_in = NULL; - bulk_out = NULL; + ports_found = 0; dev_connected = false; - serial_intf = -1; - serial_device_found = false; - line_coding.baudrate = 9600; - line_coding.data_bits = 8; - line_coding.parity = None; - line_coding.stop_bits = 1; - circ_buf.flush(); } bool USBHostSerial::connected() @@ -48,49 +38,219 @@ bool USBHostSerial::connected() return dev_connected; } +void USBHostSerial::disconnect(void) +{ + ports_found = 0; + dev = NULL; +} + bool USBHostSerial::connect() { - if (dev_connected) { - return true; + if (dev) + { + for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) + { + USBDeviceConnected* d = host->getDevice(i); + if (dev == d) + return true; + } + disconnect(); } - for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { - if ((dev = host->getDevice(i)) != NULL) { + for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) + { + USBDeviceConnected* d = host->getDevice(i); + if (d != NULL) { - USB_DBG("Trying to connect serial device\r\n"); - - if(host->enumerate(dev, this)) + USB_DBG("Trying to connect serial device \r\n"); + if(host->enumerate(d, this)) break; - if (serial_device_found) { - bulk_in = dev->getEndpoint(serial_intf, BULK_ENDPOINT, IN); - bulk_out = dev->getEndpoint(serial_intf, BULK_ENDPOINT, OUT); - - if (!bulk_in || !bulk_out) - break; - - USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf); - dev->setName("Serial", serial_intf); - host->registerDriver(dev, serial_intf, this, &USBHostSerial::init); - - baud(9600); - - size_bulk_in = bulk_in->getSize(); - size_bulk_out = bulk_out->getSize(); - - bulk_in->attach(this, &USBHostSerial::rxHandler); - bulk_out->attach(this, &USBHostSerial::txHandler); - - host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); - dev_connected = true; - return true; + USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN); + USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT); + if (bulk_in && bulk_out) + { + USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out); + dev = d; } } } - init(); + return dev != NULL; +} + +/*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid) +{ + // we don't check VID/PID for MSD driver +} + +/*virtual*/ bool USBHostSerial::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 ((ports_found < USBHOST_MAXSERIAL) && + CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) { + port_intf = intf_nb; + ports_found = true; + return true; + } return false; } -void USBHostSerial::rxHandler() { +/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + if (ports_found && (intf_nb == port_intf)) { + if (type == BULK_ENDPOINT) + return true; + } + return false; +} + +#else // (USBHOST_SERIAL > 1) + +//------------------------------------------------------------------------------ + +USBHostMultiSerial::USBHostMultiSerial() +{ + host = USBHost::getHostInst(); + dev = NULL; + memset(ports, NULL, sizeof(ports)); + ports_found = 0; + dev_connected = false; +} + +USBHostMultiSerial::~USBHostMultiSerial() +{ + disconnect(); +} + +bool USBHostMultiSerial::connected() +{ + return dev_connected; +} + +void USBHostMultiSerial::disconnect(void) +{ + for (int port = 0; port < USBHOST_SERIAL; port ++) + { + if (ports[port]) + { + delete ports[port]; + ports[port] = NULL; + } + } + ports_found = 0; + dev = NULL; +} + +bool USBHostMultiSerial::connect() { + + if (dev) + { + for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) + { + USBDeviceConnected* d = host->getDevice(i); + if (dev == d) + return true; + } + disconnect(); + } + for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) + { + USBDeviceConnected* d = host->getDevice(i); + if (d != NULL) { + + USB_DBG("Trying to connect serial device \r\n"); + if(host->enumerate(d, this)) + break; + + for (int port = 0; port < ports_found; port ++) + { + USBEndpoint* bulk_in = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN); + USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT); + if (bulk_in && bulk_out) + { + ports[port] = new USBHostSerialPort(); + if (ports[port]) + { + ports[port]->connect(host,d,port_intf[port],bulk_in, bulk_out); + dev = d; + } + } + } + } + } + return dev != NULL; +} + +/*virtual*/ void USBHostMultiSerial::setVidPid(uint16_t vid, uint16_t pid) +{ + // we don't check VID/PID for MSD driver +} + +/*virtual*/ bool USBHostMultiSerial::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 ((ports_found < USBHOST_SERIAL) && + CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) { + port_intf[ports_found++] = intf_nb; + return true; + } + return false; +} + +/*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) { + if (type == BULK_ENDPOINT) + return true; + } + return false; +} + +#endif + +//------------------------------------------------------------------------------ + +#define SET_LINE_CODING 0x20 + +USBHostSerialPort::USBHostSerialPort(): circ_buf() +{ + init(); +} + +void USBHostSerialPort::init(void) +{ + host = NULL; + dev = NULL; + serial_intf = NULL; + size_bulk_in = 0; + size_bulk_out = 0; + bulk_in = NULL; + bulk_out = NULL; + line_coding.baudrate = 9600; + line_coding.data_bits = 8; + line_coding.parity = None; + line_coding.stop_bits = 1; + circ_buf.flush(); +} + +void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev, + uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out) +{ + host = _host; + dev = _dev; + serial_intf = _serial_intf; + bulk_in = _bulk_in; + bulk_out = _bulk_out; + + USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf); + dev->setName("Serial", serial_intf); + host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init); + //baud(9600); + size_bulk_in = bulk_in->getSize(); + size_bulk_out = bulk_out->getSize(); + bulk_in->attach(this, &USBHostSerialPort::rxHandler); + bulk_out->attach(this, &USBHostSerialPort::txHandler); + host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); +} + +void USBHostSerialPort::rxHandler() { if (bulk_in) { int len = bulk_in->getLengthTransferred(); if (bulk_in->getState() == USB_TYPE_IDLE) { @@ -103,7 +263,7 @@ void USBHostSerial::rxHandler() { } } -void USBHostSerial::txHandler() { +void USBHostSerialPort::txHandler() { if (bulk_out) { if (bulk_out->getState() == USB_TYPE_IDLE) { tx.call(); @@ -111,7 +271,7 @@ void USBHostSerial::txHandler() { } } -int USBHostSerial::_putc(int c) { +int USBHostSerialPort::_putc(int c) { if (bulk_out) { if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) { return 1; @@ -120,12 +280,12 @@ int USBHostSerial::_putc(int c) { return -1; } -void USBHostSerial::baud(int baudrate) { +void USBHostSerialPort::baud(int baudrate) { line_coding.baudrate = baudrate; format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits); } -void USBHostSerial::format(int bits, Parity parity, int stop_bits) { +void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) { line_coding.data_bits = bits; line_coding.parity = parity; line_coding.stop_bits = (stop_bits == 1) ? 0 : 2; @@ -137,7 +297,7 @@ void USBHostSerial::format(int bits, Parity parity, int stop_bits) { 0, serial_intf, (uint8_t *)&line_coding, 7); } -int USBHostSerial::_getc() { +int USBHostSerialPort::_getc() { uint8_t c = 0; if (bulk_in == NULL) { init(); @@ -148,37 +308,36 @@ int USBHostSerial::_getc() { return c; } +int USBHostSerialPort::writeBuf(const char* b, int s) +{ + int c = 0; + if (bulk_out) + { + while (c < s) + { + int i = (s < size_bulk_out) ? s : size_bulk_out; + if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK) + c += i; + } + } + return s; +} -uint8_t USBHostSerial::available() { +int USBHostSerialPort::readBuf(char* b, int s) +{ + int i = 0; + if (bulk_in) + { + for (i = 0; i < s; ) + b[i++] = getc(); + } + return i; +} + +uint8_t USBHostSerialPort::available() { return circ_buf.available(); } -/*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid) -{ - // we don't check VID/PID for MSD driver -} -/*virtual*/ bool USBHostSerial::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 ((serial_intf == -1) && - (intf_class == SERIAL_CLASS) && - (intf_subclass == 0x00) && - (intf_protocol == 0x00)) { - serial_intf = intf_nb; - return true; - } - return false; -} - -/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used -{ - if (intf_nb == serial_intf) { - if (type == BULK_ENDPOINT) { - serial_device_found = true; - return true; - } - } - return false; -} #endif diff --git a/libraries/USBHost/USBHostSerial/USBHostSerial.h b/libraries/USBHost/USBHostSerial/USBHostSerial.h index 8e386c42fd..53466da249 100644 --- a/libraries/USBHost/USBHostSerial/USBHostSerial.h +++ b/libraries/USBHost/USBHostSerial/USBHostSerial.h @@ -28,12 +28,12 @@ /** * A class to communicate a USB virtual serial port */ -class USBHostSerial : public IUSBEnumerator, public Stream { +class USBHostSerialPort : public Stream { public: /** * Constructor */ - USBHostSerial(); + USBHostSerialPort(); enum IrqType { RxIrq, @@ -48,20 +48,9 @@ public: Space }; - /** - * Check if a virtual serial port is connected - * - * @returns true if a serial device is connected - */ - bool connected(); - - /** - * Try to connect a serial device - * - * @return true if connection was successful - */ - bool connect(); - + void connect(USBHost* _host, USBDeviceConnected * _dev, + uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out); + /** * Check the number of bytes available. * @@ -111,34 +100,29 @@ public: /** Set the transmission format used by the Serial port * * @param bits The number of bits in a word (default = 8) - * @param parity The parity used (USBHostSerial::None, USBHostSerial::Odd, USBHostSerial::Even, USBHostSerial::Mark, USBHostSerial::Space; default = USBHostSerial::None) + * @param parity The parity used (USBHostSerialPort::None, USBHostSerialPort::Odd, USBHostSerialPort::Even, USBHostSerialPort::Mark, USBHostSerialPort::Space; default = USBHostSerialPort::None) * @param stop The number of stop bits (1 or 2; default = 1) */ - void format(int bits = 8, Parity parity = USBHostSerial::None, int stop_bits = 1); - + void format(int bits = 8, Parity parity = USBHostSerialPort::None, int stop_bits = 1); + virtual int writeBuf(const char* b, int s); + virtual int readBuf(char* b, int s); protected: - //From IUSBEnumerator - 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 _getc(); virtual int _putc(int c); private: USBHost * host; USBDeviceConnected * dev; + USBEndpoint * bulk_in; USBEndpoint * bulk_out; uint32_t size_bulk_in; uint32_t size_bulk_out; - bool dev_connected; - void init(); - MtxCircBuffer circ_buf; + MtxCircBuffer circ_buf; uint8_t buf[64]; @@ -156,11 +140,92 @@ private: FunctionPointer rx; FunctionPointer tx; - int serial_intf; - bool serial_device_found; - + uint8_t serial_intf; }; +#if (USBHOST_SERIAL <= 1) + +class USBHostSerial : public IUSBEnumerator, public USBHostSerialPort +{ +public: + USBHostSerial(); + + /** + * Try to connect a serial device + * + * @return true if connection was successful + */ + bool connect(); + + void disconnect(); + + /** + * Check if a any serial port is connected + * + * @returns true if a serial device is connected + */ + bool connected(); + +protected: + USBHost* host; + USBDeviceConnected* dev; + uint8_t port_intf; + int ports_found; + + //From IUSBEnumerator + 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 + +private: + bool dev_connected; +}; + +#else // (USBHOST_SERIAL > 1) + +class USBHostMultiSerial : public IUSBEnumerator { +public: + USBHostMultiSerial(); + virtual ~USBHostMultiSerial(); + + USBHostSerialPort* getPort(int port) + { + return port < USBHOST_SERIAL ? ports[port] : NULL; + } + + /** + * Try to connect a serial device + * + * @return true if connection was successful + */ + bool connect(); + + void disconnect(); + + /** + * Check if a any serial port is connected + * + * @returns true if a serial device is connected + */ + bool connected(); + +protected: + USBHost* host; + USBDeviceConnected* dev; + USBHostSerialPort* ports[USBHOST_SERIAL]; + uint8_t port_intf[USBHOST_SERIAL]; + int ports_found; + + //From IUSBEnumerator + 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 + +private: + bool dev_connected; +}; +#endif // (USBHOST_SERIAL <= 1) + #endif #endif From 20776dbaa5d0cab1ca32c5d953bbe8c21bed3cdd Mon Sep 17 00:00:00 2001 From: mazgch Date: Mon, 9 Dec 2013 23:43:51 +0100 Subject: [PATCH 5/6] fixed the comparison --- libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp index c5111a2bc9..7bfed72e85 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp +++ b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp @@ -40,7 +40,7 @@ UbloxModem::UbloxModem(IOStream* atStream, IOStream* pppStream) : 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_onePort(pppStream == NULL), m_gsm(true) { } From 6a9083527e116efad023905191c834a35d3561c1 Mon Sep 17 00:00:00 2001 From: mazgch Date: Tue, 10 Dec 2013 15:25:08 +0100 Subject: [PATCH 6/6] CDMA currently only uses one CDC --- .../net/cellular/UbloxUSBModem/UbloxModem.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp index 7bfed72e85..055cb28570 100644 --- a/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp +++ b/libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp @@ -313,19 +313,19 @@ int UbloxModem::init() //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); - } + 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; + ERR("Registration denied"); + return NET_AUTH; } m_atOpen = true; @@ -443,7 +443,7 @@ int UbloxUSBModem::init() { INFO("Using a u-blox LISA-C200 CDMA Modem"); m_gsm = false; - m_onePort = false; + m_onePort = true; } else { @@ -466,6 +466,6 @@ UbloxSerModem::UbloxSerModem() : m_Serial(P0_15,P0_16), m_atStream(m_Serial) { - m_Serial.baud(115200); + m_Serial.baud(115200); }