mirror of https://github.com/ARMmbed/mbed-os.git
commit
e4faeb42a7
|
@ -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];
|
||||
|
@ -357,6 +357,7 @@ 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) {
|
||||
|
@ -364,10 +365,16 @@ int serial_readable(serial_t *obj) {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
|
@ -73,6 +73,11 @@ public:
|
|||
*/
|
||||
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);
|
||||
|
@ -85,7 +90,7 @@ private:
|
|||
bool m_gsm;
|
||||
REGISTRATION_STATE m_registrationState;
|
||||
BEARER m_bearer;
|
||||
|
||||
char m_phoneNumber[16];
|
||||
};
|
||||
|
||||
#endif /* LINKMONITOR_H_ */
|
||||
|
|
|
@ -41,23 +41,24 @@ 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;
|
||||
|
@ -65,15 +66,12 @@ private:
|
|||
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
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
CREGProcessor cregProcessor(m_gsm);
|
||||
// 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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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*/);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,19 @@
|
|||
#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
|
||||
|
@ -92,6 +105,8 @@ public:
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -130,7 +145,7 @@ private:
|
|||
bool m_atOpen; //< Is the interface to the ATCommandsInterface open? true/false
|
||||
protected:
|
||||
bool m_onePort;
|
||||
bool m_gsm;
|
||||
enum { LISA_C200, LISA_U200, SARA_G350, UNKNOWN } m_type;
|
||||
};
|
||||
|
||||
#include "WANDongle.h"
|
||||
|
|
Loading…
Reference in New Issue