1 /* UbloxUSBCDMAModem.cpp */
2 /* Copyright (C) 2012 mbed.org, MIT License
4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in all copies or
11 * substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #define __MODULE__ "UbloxUSBCDMAModem.cpp"
27 #include "UbloxUSBCDMAModem.h"
28 #include "UbloxCDMAModemInitializer.h"
31 #define USE_ONE_PORT 1
33 UbloxUSBCDMAModem::UbloxUSBCDMAModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/, int serial /* 0 */) : m_dongle(),
34 m_stream(m_dongle.getSerial(serial)),
36 m_sms(&m_at), m_ppp(&m_stream),
37 m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_atOpen(false),
38 m_powerGatingPin(powerGatingPin), m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh)
40 USBHost* host = USBHost::getHostInst();
41 m_dongle.addInitializer(new UbloxCDMAModemInitializer(host));
42 if( m_powerGatingPin != NC )
44 power(false); //Dongle will have to be powered on manually
48 class CSSProcessor : public IATCommandsProcessor
51 CSSProcessor() : status(STATUS_REGISTERING)
55 enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK };
56 REGISTERING_STATUS getStatus()
61 virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
67 //if( sscanf(line, "%*d, %c", &r) == 1 )
68 if(sscanf(line, "%*s %c,%2s,%d", &b,bc,&sid)==3)
70 if(strcmp("Z", bc) == 0)
71 status = STATUS_REGISTERING;
77 virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
81 volatile REGISTERING_STATUS status;
84 int UbloxUSBCDMAModem::connect(const char* apn, const char* user, const char* password)
91 m_ppp.setup(user, password, DEFAULT_MSISDN_CDMA);
100 m_smsInit = false; //SMS status reset
101 //m_ussdInit = false; //USSD status reset
102 //m_linkMonitorInit = false; //Link monitor status reset
105 ATCommandsInterface::ATResult result;
110 sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn);
111 ret = m_at.executeSimple(cmd, &result);
112 DBG("Result of command: Err code=%d", ret);
113 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
114 DBG("APN set to %s", apn);
121 m_at.close(); // Closing AT parser
122 m_atOpen = false; //Will need to be reinitialized afterwards
125 DBG("Connecting PPP");
127 ret = m_ppp.connect();
128 DBG("Result of connect: Err code=%d", ret);
133 int UbloxUSBCDMAModem::disconnect()
135 DBG("Disconnecting from PPP");
136 int ret = m_ppp.disconnect();
139 ERR("Disconnect returned %d, still trying to disconnect", ret);
142 //Ugly but leave dongle time to recover
146 ATCommandsInterface::ATResult result;
147 DBG("Starting AT thread");
155 DBG("Trying to hangup");
157 #if 0 //Does not appear to work
161 ret = m_at.executeSimple("+++", &result, 1000);
162 DBG("Result of command: Err code=%d\n", ret);
163 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
164 } while(tries-- && ret);
167 ret = m_at.executeSimple("ATH", &result);
168 DBG("Result of command: Err code=%d\n", ret);
169 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
176 DBG("Result of command: Err code=%d\n", ret);
179 m_at.close(); // Closing AT parser
180 DBG("AT Parser closed, could not complete disconnection");
185 m_at.close(); // Closing AT parser
186 DBG("AT Parser closed");
192 int UbloxUSBCDMAModem::sendSM(const char* number, const char* message)
210 ret = m_sms.send(number, message);
219 int UbloxUSBCDMAModem::getSM(char* number, char* message, size_t maxLength)
237 ret = m_sms.get(number, message, maxLength);
246 int UbloxUSBCDMAModem::getSMCount(size_t* pCount)
264 ret = m_sms.getCount(pCount);
273 ATCommandsInterface* UbloxUSBCDMAModem::getATCommandsInterface()
278 int UbloxUSBCDMAModem::power(bool enable)
280 if( m_powerGatingPin == NC )
282 return NET_INVALID; //A pin name has not been provided in the constructor
285 if(!enable) //Will force components to re-init
290 DigitalOut powerGatingOut(m_powerGatingPin);
291 powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable;
296 bool UbloxUSBCDMAModem::power()
298 if( m_powerGatingPin == NC )
300 return true; //Assume power is always on
303 DigitalOut powerGatingOut(m_powerGatingPin);
304 return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut;
307 int UbloxUSBCDMAModem::init()
309 if( !m_dongleConnected )
313 //Obviously cannot initialize the dongle if it is disconnected...
317 m_dongleConnected = true;
318 while( !m_dongle.connected() )
320 m_dongle.tryConnect();
330 DBG("Starting AT thread if needed");
331 int ret = m_at.open();
337 DBG("Sending initialisation commands");
344 if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAC200)
346 INFO("Using a UBLOX C200 Dongle");
350 WARN("Using an Unknown Dongle");
353 ATCommandsInterface::ATResult result;
355 //Wait for network registration
356 CSSProcessor cssProcessor;
359 DBG("Waiting for network registration");
360 ret = m_at.execute("AT+CSS?", &cssProcessor, &result);
361 DBG("Result of command: Err code=%d\n", ret);
362 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
363 if(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING)
367 } while(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING);
374 int UbloxUSBCDMAModem::cleanup()
376 if(m_ppp.isConnected())
378 WARN("Data connection is still open"); //Try to encourage good behaviour from the user
383 // m_linkMonitorInit = false;
384 //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once
392 m_dongle.disconnect();
393 m_dongleConnected = false;