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

Dependents:   C027_demo_ConnMan

CNData.cpp

Committer:
msinig
Date:
2016-01-12
Revision:
0:86284a262735
Child:
1:29ad1d1ac1f9

File content as of revision 0:86284a262735:

#include "CNData.h"
#include "CNLib.h"
#include "CNUtil.h"

//! Data Connection State
typedef enum {
    DATA_UNDEFINED,         //!< undefined
    DATA_UP,                //!< data is up
    DATA_DOWN,              //!< data is down
} DataState;

#define IS_DATA_CONNECTED(s) (s == DATA_UP)
#define IS_DATA_DISCONNECTED(s) (s == DATA_DOWN)
#define HAS_DATA_ATTACHED(st, newSt) (st == DATA_DOWN && newSt == DATA_UP)
#define HAS_DATA_DEATTACHED(st, newSt) (newSt== DATA_DOWN && st == DATA_UP)

static DataState state = DATA_UNDEFINED;       //!<data state
static CNTimer tmDataRetry;                    //!<timer for data retry
static CNTimer tmDataPullStatus;               //!<timer for data pull status
static bool dataIsEnable;                      //!<data is enabled

static char dapn[20];              //!<apn  of the network provider
static char dusername[10];         //!<user name text string for the authentication phase
static char dpassword[10];         //!<password text string for the authentication phase
static MDMParser::Auth auth;       //!<authentication mode (CHAP,PAP,NONE or DETECT)

void cnDataInit(){
    state =  DATA_DOWN;
    dataIsEnable = false;
    tmDataPullStatus.setExpireTimeout(TIMEOUT_CHECK_STATUS_DATA_CONNECITION);
    tmDataRetry.setExpireTimeout(TIMEOUT_RETRY_DATA_CONNECTION);
    memset(dapn, 0, sizeof(dapn));
    memset(dusername, 0, sizeof(dusername));
    memset(dpassword, 0, sizeof(dpassword));
    auth = MDMParser::AUTH_DETECT;
}

void cnDataEnable(bool enabled){
    dataIsEnable = enabled;
}

void cnDataReset(){
    TRACE("%s enter \r\n", __FUNCTION__);
    state =  DATA_DOWN;
    dataIsEnable = false;
    tmDataRetry.stop();
}

void cnDataSetupApn(const char* apn,const char* username,const char* password)
{
    TRACE("%s enter \r\n", __FUNCTION__);    
    if (apn)
        strncpy(dapn, apn, sizeof(apn));        
    if (username)
        strncpy(dusername, username, sizeof(username));
    if (password)
        strncpy(dpassword, password, sizeof(password));    
}

CNResp cnDataLoop(CNLib* const lib, RegStatus regStatus,DataConnStatus* const dataStatus)
{
    DataState newState = DATA_UNDEFINED;
    *dataStatus = DATA_NO_CHANGES;
    MDMParser::IP ip;
    char *apn, *username, *password;

    //enable data connection
    if (dataIsEnable && IS_DATA_DISCONNECTED(state) && regStatus == REG_REGISTERED){
        if (!tmDataRetry.isOn() || tmDataRetry.isExpired()){
            INFO("%s: Trying to bring up Data\r\n", __FUNCTION__);
            apn = (dapn[0]=='\0') ? NULL : dapn;
            username = (dusername[0]=='\0') ? NULL : dusername;
            password = (dpassword[0]=='\0') ? NULL : dpassword;            
            ip = lib->join(apn, username, password, auth);
            newState = (ip != NOIP)? DATA_UP : DATA_DOWN;
            //check result of data activation call
            if (IS_DATA_DISCONNECTED(newState)){
                INFO("%s: Data has not been successfully activated\r\n", __FUNCTION__);
                tmDataRetry.start();
            }
            else if (IS_DATA_CONNECTED(newState)){
                INFO("%s: Data has been activated successfully\r\n", __FUNCTION__);
                tmDataRetry.stop();
            }
        }
    }
    //disable data
    else if (IS_DATA_CONNECTED(state) && (!dataIsEnable || regStatus == REG_NOT_REGISTERED)){
        INFO("%s: Disable data\n", __FUNCTION__);
        lib->disableInternalContext();
        newState = DATA_DOWN;
    }
    //pull internal context status
    else if (tmDataPullStatus.isExpired() && IS_DATA_CONNECTED(state)){
        INFO("%s: Polling Status..\r\n", __FUNCTION__);
        lib->getInternalStatusContext();
        if (lib->getIpAddress() == NOIP)  newState = DATA_DOWN;
            else newState = DATA_UP;
    }
    //data id attached
    if (HAS_DATA_ATTACHED(state, newState)){
        INFO("%s: Notify data is up\r\n", __FUNCTION__);
        *dataStatus = DATA_IS_CONNECTED;
        tmDataRetry.stop();
        tmDataPullStatus.start();
    }
    //data is detached
    if (HAS_DATA_DEATTACHED(state, newState)){
        INFO("%s: Notify data is down\r\n", __FUNCTION__);
        *dataStatus = DATA_IS_DISCONNECTED;
        tmDataPullStatus.stop();
    }
    //dump info
    if (getUtilDebugLevel() > 1 && ( HAS_DATA_ATTACHED(state, newState) ||  HAS_DATA_DEATTACHED(state, newState))){
        INFO("CNM Data Dump\r\n");
        const char* txtState[] = { "Undefined", "Up", "Down"};
        if (newState < sizeof(txtState)/sizeof(*txtState) && newState != DATA_UNDEFINED)
            INFO("  State is now:  %s\r\n", txtState[newState]);
        INFO("  Data is enabled: %s, has Data Attached: %s, has Data Detached: %s\r\n", BOOLTOSTR(dataIsEnable),\
                BOOLTOSTR(HAS_DATA_ATTACHED(state, newState)), BOOLTOSTR(HAS_DATA_DEATTACHED(state, newState)));
        INFO("  Timer for Data Retry:  %d, Timer for Check Data %d \r\n", tmDataRetry.getRetryContunter(), \
                tmDataPullStatus.getRetryContunter());
        if (lib->getIpAddress() != NOIP)
            lib->dumpIp(lib->getIpAddress());
    }
    //update status
    if (newState != DATA_UNDEFINED)
            state = newState;

    return RES_OK;;
}