Connection Manager library for u-blox cellular modules. It manages the modem for keeping data connection always active.

Dependents:   C027_demo_ConnMan

CNLib.cpp

Committer:
msinig
Date:
2016-01-12
Revision:
0:86284a262735

File content as of revision 0:86284a262735:

#include "CNLib.h"
#include "CNUtil.h"
#include "CNManager.h"

#define PROFILE  "0"

int  CNLib::powerOnModem(){
    TRACE("%s enter \r\n", __FUNCTION__);
    int res =  RESP_OK;
    PinName pn MDM_IF( = MDMPWRON, = D4);

#ifdef TARGET_UBLOX_C027
    int i = 20;
    if (pn != NC) {
        INFO("Modem::wakeup\r\n");
        DigitalOut pin(pn, 1);
        while (i--) {
            // SARA-U2/LISA-U2 50..80us
            pin = 0; ::wait_us(50);
            pin = 1; ::wait_ms(10);

            // SARA-G35 >5ms, LISA-C2 > 150ms, LEON-G2 >5ms
            pin = 0; ::wait_ms(150);
            pin = 1; ::wait_ms(100);

            // purge any messages
            purge();

            // check interface
            sendFormated("AT\r\n");
            res = waitFinalResp(NULL,NULL,1000);

            if (RESPOK(res))
                break;
        }
        if (i < 0) {
            ERROR("No Reply from Modem\r\n");
            goto failure;
        }
    }
#endif

    TRACE("%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
    ERROR("%s exit Error code %d\r\n", __FUNCTION__, res);
    return res;
}

int CNLib::initModem()
{
    int res;
    TRACE("CNLib::%s enter \r\n", __FUNCTION__);

    // echo off
    sendFormated("AT E0\r\n");
    res = waitFinalResp();
    if (!RESPOK(res))
        goto failure;
    // enable verbose error messages
    sendFormated("AT+CMEE=2\r\n");
    res = waitFinalResp();
    if (!RESPOK(res))
        goto failure;
    // set baud rate
    sendFormated("AT+IPR=115200\r\n");
    res = waitFinalResp();
    if (!RESPOK(res))
        goto failure;

    // wait some time until baudrate is applied
    wait_ms(200); // SARA-G > 40ms

    // get the manufacturer
    sendFormated("AT+CGMI\r\n");
    res = waitFinalResp(_cbString, _dev.manu);
    if (!RESPOK(res))
        goto failure;
    // get the model identification
    sendFormated("AT+CGMM\r\n");
    res =  waitFinalResp(_cbString, _dev.model);
    if (!RESPOK(res))
       goto failure;
    // get the
    sendFormated("AT+CGMR\r\n");
    res =  waitFinalResp(_cbString, _dev.ver);
    if (!RESPOK(res))
       goto failure;
    // Returns the product serial number, IMEI (International Mobile Equipment Identity)
    sendFormated("AT+CGSN\r\n");
    res =  waitFinalResp(_cbString, _dev.imei);
    if (!RESPOK(res))
        goto failure;
    // enable power saving
    if (_dev.lpm != LPM_DISABLED) {
         // enable power saving (requires flow control, cts at least)
        sendFormated("AT+UPSV=1\r\n");
        res = waitFinalResp();
        if (!RESPOK(res))
            goto failure;
       _dev.lpm = LPM_ACTIVE;
    }
    // identify the module
    sendFormated("ATI\r\n");
    res = waitFinalResp(_cbATI, &_dev.dev );
    if (!RESPOK(res))
        goto failure;
    if (_dev.dev == DEV_UNKNOWN){
        ERROR("CNLib::%s UNKOWN device \r\n", __FUNCTION__);
        goto failure;
    }
    if ((_dev.dev == DEV_LISA_U2) || (_dev.dev == DEV_LEON_G2)) {
       // enable the network identification feature
     sendFormated("AT+UGPIOC=20,2\r\n");
       res = waitFinalResp(NULL,NULL,20000);
       if (!RESPOK(res))
           goto failure;
       }
   else if ((_dev.dev == DEV_SARA_U2) || (_dev.dev == DEV_SARA_U2) || (_dev.dev == DEV_SARA_G35)) {
       // enable the network identification feature
    sendFormated("AT+UGPIOC=16,2\r\n");
       res = waitFinalResp(NULL,NULL,20000);
       if (!RESPOK(res))
           goto failure;
       }
    //enable rat technology unsolicited
    sendFormated("AT+UREG=1\r\n");
    res = waitFinalResp();
    if (!RESPOK(res))
     goto failure;
    // enable the psd registration unsolicited result code
    sendFormated("AT+CGREG=2\r\n");
    res = waitFinalResp();
    if (!RESPOK(res))
        goto failure;
    // enable the network registration unsolicited result code
    sendFormated("AT+CREG=2\r\n");
    res = waitFinalResp();
    if (!RESPOK(res))
     goto failure;
    TRACE("CNLib::%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
    ERROR("CNLib::%s exit Error code %d\r\n", __FUNCTION__, res);
    return res;
}

/*************************************************************************/

int CNLib::_mcbCPIN(int type,  const char* buf, int len, Sim* sim)
{
    int ret = WAIT;
    if (sim) {
        if (type == TYPE_PLUS){
            char s[16];
            if (sscanf(buf, "\r\n+CPIN: %[^\r]\r\n", s) >= 1){
                if (!strcmp("READY", s)){
                    *sim = SIM_READY;
                }
                else if (!strcmp("SIM PIN", s))
                    *sim = SIM_PIN;
                else if (!strcmp("SIM PUK", s))
                     *sim = SIM_PUK;
                     
                     
            }
        } else if (type == TYPE_ERROR_CME) {
                if (strstr(buf, "+CME ERROR: SIM not inserted")){
                     *sim = SIM_MISSING;
                     ret = RESP_OK;
                }
                else if (strstr(buf, "+CME ERROR: incorrect password\r\n")){
                    *sim = WRONG_PIN;
                     ret = RESP_OK;
                }
                else{
                    *sim = SIM_UNKNOWN;
                     ret = RESP_OK;
                }
        }
    }
    return ret;
}

int CNLib::simInit(const char* simpin)
{
    int res;
    TRACE("CNLib::%s Enter \r\n", __FUNCTION__);
    if (simpin == NULL){
        sendFormated("AT+CPIN?\r\n");
    }
    else if (simpin != NULL && *simpin != NULL)
        sendFormated("AT+CPIN=\"%s\"\r\n", simpin);
    res = waitFinalResp(_mcbCPIN, &_dev.sim, 20000);
    if (!RESPOK(res))
        goto failure;

    TRACE("CNLib::%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
    ERROR("CNLib::%s exit Error code %d\r\n", __FUNCTION__, res);
    return res;
 }


int CNLib::getSimInfo(){
    int res;
    // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
    // ICCID is a serial number identifying the SIM.
    sendFormated("AT+CCID\r\n");
    res = waitFinalResp(_cbCCID, _dev.ccid);
    if (res != RESP_OK)
        goto failure;
    // Request IMSI (International Mobile Subscriber Identification)
    sendFormated("AT+CIMI\r\n");
    res = waitFinalResp(_cbString, _dev.imsi);
    if (RESP_OK != res)
        goto failure;
    TRACE("CNLib::%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
    ERROR("CNLib::%s exit Error code %d\r\n", __FUNCTION__, res);
    return res;
}

/*****************************************************************************/

int CNLib::getNetworkInfo()
{
    int res;
    TRACE("CNLib::%s Enter \r\n", __FUNCTION__);
    sendFormated("AT+COPS?\r\n");
    res = waitFinalResp(_cbCOPS, &_net);
    if (!RESPOK(res))
       goto failure;
    TRACE("CNLib::%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
    ERROR("CNLib::%s exit Error code %d\r\n", __FUNCTION__, res);
    return res;
}

int CNLib::setNetAutoReg()
{
    int res;
    TRACE("CNLib::%s Enter \r\n", __FUNCTION__);
    sendFormated("AT+COPS=0\r\n");
    res = waitFinalResp();
    if (!RESPOK(res))
       goto failure;
    TRACE("CNLib::%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
    ERROR("CNLib::%s exit Error code %d\r\n", __FUNCTION__, res);
    return res;
}

/****************************************************************/

int CNLib::getInternalStatusContext()
{
    int res;
    TRACE("CNLib::%s Enter \r\n", __FUNCTION__);

    int context;
    sendFormated("AT+UPSND=" PROFILE ",8\r\n");
    res = waitFinalResp(_cbUPSND, &context);
    if (!RESPOK(res))
        goto failure;
    if (context == 0)
        _ip = NOIP;
    TRACE("CNLib::%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
  TRACE("CNLib::%s exit Error code %d\r\n", __FUNCTION__, res);
  _ip = NOIP;
  return res;
}

int CNLib::disableInternalContext()
{
    int res;
    TRACE("CNLib::%s Enter \r\n", __FUNCTION__);
    _ip = NOIP;
    sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
    res = waitFinalResp(NULL,NULL,40*1000);
    if (!RESPOK(res))
           goto failure;
    TRACE("CNLib::%s exit Ok \r\n", __FUNCTION__);
    return res;

failure:
    ERROR("CNLib::%s exit Error code %d\r\n", __FUNCTION__, res);
    return res;
}