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;