Skip to content

Update of cellular modem #195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ serial_t stdio_uart;
struct serial_global_data_s {
uint32_t serial_irq_id;
gpio_t sw_rts, sw_cts;
uint8_t rx_irq_set_flow, rx_irq_set_api;
uint8_t count, rx_irq_set_flow, rx_irq_set_api;
};

static struct serial_global_data_s uart_data[UART_NUM];
Expand Down Expand Up @@ -357,17 +357,24 @@ int serial_getc(serial_t *obj) {
void serial_putc(serial_t *obj, int c) {
while (!serial_writable(obj));
obj->uart->THR = c;
uart_data[obj->index].count++;
}

int serial_readable(serial_t *obj) {
return obj->uart->LSR & 0x01;
}

int serial_writable(serial_t *obj) {
int isWritable = 1;
if (NC != uart_data[obj->index].sw_cts.pin)
return (gpio_read(&uart_data[obj->index].sw_cts) == 0) && (obj->uart->LSR & 0x40); //If flow control: writable if CTS low + UART done
else
return obj->uart->LSR & 0x20; //No flow control: writable if space in holding register
isWritable = (gpio_read(&uart_data[obj->index].sw_cts) == 0) && (obj->uart->LSR & 0x40);
else {
if (obj->uart->LSR & 0x20)
uart_data[obj->index].count = 0;
else if (uart_data[obj->index].count >= 16)
isWritable = 0;
}
return isWritable;
}

void serial_clear(serial_t *obj) {
Expand Down
18 changes: 11 additions & 7 deletions libraries/net/cellular/CellularModem/at/ATCommandsInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ using std::memmove;
#include "ATCommandsInterface.h"

ATCommandsInterface::ATCommandsInterface(IOStream* pStream) :
m_pStream(pStream), m_open(false), m_env2AT(), m_AT2Env(), m_processingMtx(),
m_pStream(pStream), m_open(false), m_transactionState(IDLE), m_env2AT(), m_AT2Env(), m_processingMtx(),
m_processingThread(&ATCommandsInterface::staticCallback, this, (osPriority)AT_THREAD_PRIORITY, 4*192),
m_eventsMgmtMtx(), m_eventsProcessingMtx()
{
Expand Down Expand Up @@ -270,6 +270,7 @@ int ATCommandsInterface::executeInternal(const char* command, IATCommandsProcess
} while(msgResult != AT_TIMEOUT);

WARN("Command returned no message");
WARN("Command \"%s\" returned no message", command);
return NET_TIMEOUT;
}
DBG("Command returned with message %d", *msg);
Expand All @@ -285,6 +286,7 @@ int ATCommandsInterface::executeInternal(const char* command, IATCommandsProcess
if(ret != OK)
{
WARN("Command returned AT result %d with code %d", m_transactionResult.result, m_transactionResult.code);
WARN("Command \"%s\" returned AT result %d with code %d", command, m_transactionResult.result, m_transactionResult.code);
}

DBG("Command returned successfully");
Expand Down Expand Up @@ -751,12 +753,13 @@ void ATCommandsInterface::enableEvents()
{
m_eventsHandlers[i]->onDispatchStart();
//Enable this kind of events
if(m_eventsHandlers[i]->getEventsEnableCommand() != NULL)
const char* cmd = m_eventsHandlers[i]->getEventsEnableCommand();
if(cmd != NULL)
{
int ret = executeInternal(m_eventsHandlers[i]->getEventsEnableCommand(), this, NULL); //Execute enable command
int ret = executeInternal(cmd, this, NULL); //Execute enable command
if(ret)
{
WARN("Events enabling command failed");
WARN("Events enabling command \"%s\" failed", cmd);
}
}
}
Expand All @@ -775,12 +778,13 @@ void ATCommandsInterface::disableEvents()
{
m_eventsHandlers[i]->onDispatchStart();
//Disable this kind of events
if(m_eventsHandlers[i]->getEventsDisableCommand() != NULL)
const char* cmd = m_eventsHandlers[i]->getEventsDisableCommand();
if(cmd != NULL)
{
int ret = executeInternal(m_eventsHandlers[i]->getEventsDisableCommand(), this, NULL); //Execute disable command
int ret = executeInternal(cmd, this, NULL); //Execute disable command
if(ret)
{
WARN("Events disabling command failed");
WARN("Events disabling command \"%s\" failed", cmd);
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions libraries/net/cellular/CellularModem/link/LinkMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ int LinkMonitor::init(bool gsm)
/*virtual*/ int LinkMonitor::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
{
DBG("Line is %s", line);
char n[32] = "";
char s[32] = "";
int v;
if( sscanf(line, "+CREG: %*d,%d", &v) >= 1 ) //Reg state is valid
{
Expand Down Expand Up @@ -127,6 +129,13 @@ int LinkMonitor::init(bool gsm)
m_rssi = -113 + 2*v;
}
}
else if ( (sscanf(line, "+CNUM: \"%[^\"]\",\"%[^\"]\",%d", n, s, &v) == 3) ||
(sscanf(line, "+CNUM: \"\",\"%[^\"]\",%d", s, &v) == 2) )
{
if (*s && ((v == 145/*number includes + */) || (v == 129/*otherwise*/))) {
strcpy(m_phoneNumber, s);
}
}
return OK;
}

Expand All @@ -150,3 +159,17 @@ int LinkMonitor::getState(int* pRssi, REGISTRATION_STATE* pRegistrationState, BE
*pBearer = m_bearer;
return OK;
}

int LinkMonitor::getPhoneNumber(char* phoneNumber)
{
*m_phoneNumber = '\0';
if (m_gsm) {
int ret = m_pIf->execute("AT+CNUM", this, NULL, DEFAULT_TIMEOUT);
if(ret != OK)
{
return NET_PROTOCOL;
}
}
strcpy(phoneNumber, m_phoneNumber);
return OK;
}
7 changes: 6 additions & 1 deletion libraries/net/cellular/CellularModem/link/LinkMonitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class LinkMonitor : protected IATCommandsProcessor
*/
int getState(int* pRssi, REGISTRATION_STATE* pRegistrationState, BEARER* pBearer);

/** Get my phone number
@param phoneNumber pointer to store the current phoneNumber
@return 0 on success, error code on failure
*/
int getPhoneNumber(char* phoneNumber);
protected:
//IATCommandsProcessor
virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line);
Expand All @@ -85,7 +90,7 @@ class LinkMonitor : protected IATCommandsProcessor
bool m_gsm;
REGISTRATION_STATE m_registrationState;
BEARER m_bearer;

char m_phoneNumber[16];
};

#endif /* LINKMONITOR_H_ */
133 changes: 87 additions & 46 deletions libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,39 +41,37 @@ UbloxModem::UbloxModem(IOStream* atStream, IOStream* pppStream) :
m_linkMonitorInit(false), // LinkMonitor subsystem starts un-initialised
m_atOpen(false), // ATCommandsInterface starts in a closed state
m_onePort(pppStream == NULL),
m_gsm(true)
m_type(UNKNOWN)
{
}


class AtiProcessor : public IATCommandsProcessor
{
public:
AtiProcessor()
{
genericAtProcessor::genericAtProcessor()
{
i = 0;
str[0] = '\0';
}
const char* getInfo(void) { return str; }
private:
virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
{
}

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;
}
virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
{
}

int genericAtProcessor::onNewEntryPrompt(ATCommandsInterface* pInst)
{
return OK;
}
protected:
char str[256];
int i;
};
}

class CREGProcessor : public IATCommandsProcessor
{
Expand Down Expand Up @@ -130,7 +128,7 @@ int UbloxModem::connect(const char* apn, const char* user, const char* password)
m_ipInit = true;
m_ppp.init();
}
m_ppp.setup(user, password, m_gsm ? DEFAULT_MSISDN_GSM : DEFAULT_MSISDN_CDMA);
m_ppp.setup(user, password, (m_type != LISA_C200) ? DEFAULT_MSISDN_GSM : DEFAULT_MSISDN_CDMA);

int ret = init();
if(ret)
Expand Down Expand Up @@ -231,8 +229,8 @@ int UbloxModem::sendSM(const char* number, const char* message)
}

ISMSInterface* sms;
if (m_gsm) sms = &m_GsmSms;
else sms = &m_CdmaSms;
if (m_type == LISA_C200) sms = &m_CdmaSms;
else sms = &m_GsmSms;
if(!m_smsInit)
{
ret = sms->init();
Expand Down Expand Up @@ -261,8 +259,8 @@ int UbloxModem::getSM(char* number, char* message, size_t maxLength)
}

ISMSInterface* sms;
if (m_gsm) sms = &m_GsmSms;
else sms = &m_CdmaSms;
if (m_type == LISA_C200) sms = &m_CdmaSms;
else sms = &m_GsmSms;
if(!m_smsInit)
{
ret = sms->init();
Expand Down Expand Up @@ -291,8 +289,8 @@ int UbloxModem::getSMCount(size_t* pCount)
}

ISMSInterface* sms;
if (m_gsm) sms = &m_GsmSms;
else sms = &m_CdmaSms;
if (m_type == LISA_C200) sms = &m_CdmaSms;
else sms = &m_GsmSms;
if(!m_smsInit)
{
ret = sms->init();
Expand Down Expand Up @@ -337,25 +335,40 @@ int UbloxModem::init()
{
return ret;
}



ATCommandsInterface::ATResult result;
AtiProcessor atiProcessor;
do
{
ret = m_at.execute("ATI", &atiProcessor, &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
}
while (ret != OK);
{
const char* info = atiProcessor.getInfo();
DBG("Modem Identification [%s]", info);
if (strstr(info, "LISA-C200"))
{
m_gsm = false; // it is CDMA modem
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_gsm);
CREGProcessor cregProcessor(m_type != LISA_C200);
//Wait for network registration
do
{
Expand Down Expand Up @@ -438,8 +451,7 @@ int UbloxModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegis

if(!m_linkMonitorInit)
{
ret = m_linkMonitor.init();
ret = m_linkMonitor.init(m_gsm);
ret = m_linkMonitor.init(m_type != LISA_C200);
if(ret)
{
return ret;
Expand All @@ -456,6 +468,33 @@ int UbloxModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegis
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"
Expand Down Expand Up @@ -485,11 +524,12 @@ int UbloxUSBModem::init()
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_gsm = false;
m_type = LISA_C200;
m_onePort = true;
}
else
Expand All @@ -510,9 +550,10 @@ int UbloxUSBModem::cleanup()

UbloxSerModem::UbloxSerModem() :
UbloxModem(&m_atStream, NULL),
m_Serial(P0_15,P0_16),
m_Serial(P0_15/*MDMTXD*/,P0_16/*MDMRXD*/),
m_atStream(m_Serial)
{
m_Serial.baud(115200);
m_Serial.baud(115200/*MDMBAUD*/);
m_Serial.set_flow_control(SerialBase::RTSCTS, P0_22/*MDMRTS*/, P0_17/*MDMCTS*/);
}

Loading