Pathfindr / Mbed OS mbed-os-PF-UWBBEACON_v1_dev

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

modem.cpp

Committer:
pathfindr
Date:
2018-12-17
Revision:
17:ba55c026b1d6
Parent:
16:3bf5f1a5f869
Child:
19:22261767c87a

File content as of revision 17:ba55c026b1d6:

#include "modem.h"

Modem::Modem(PinName tx, PinName rx, PinName cts, PinName rts, PinName pwrkey, PinName vreg_en):  _uart(tx,rx,115200), _pwrkey(pwrkey), _vreg_en(vreg_en)
{
    GLOBAL_requireSoftReset = true;  //TODO: this can be removed when uart sleep issue resolved
}

void Modem::flushSerial(void)
{ 
    char char1 = 0;
    while (_uart.readable()) { 
        char1 = _uart.getc();
    } 
    return;
}

void Modem::ATsendCMD(char* cmd) 
{ 
    flushSerial();
    _uart.puts(cmd);
    _uart.puts("\r"); 
}

bool Modem::ATwaitForWord(char* word, uint32_t timeout) 
{
    int targetIndex = 0;
    bool havefullmatch = false;
    char captured[32];
    memset (captured,0,sizeof(captured));
    Timer t;
    t.start();
    uint32_t startmillis = t.read_ms();
    uint32_t runtime = 0;
    while(!havefullmatch && runtime < timeout) {
        runtime = (t.read_ms() - startmillis);
        if(_uart.readable()) { 
            char c = _uart.getc();
            if (c != word[targetIndex]) { //no match, reset
                targetIndex = 0; 
            }
            if (c == word[targetIndex]) { //we have a match
                captured[targetIndex] = c;
                targetIndex ++;
                //check for full match
                if (  strcmp(word, captured) == 0  ) {
                    havefullmatch = true;
                }
            }
        }
    }
    t.stop();
    t.reset();
    ThisThread::sleep_for(500);
    if (havefullmatch) {
        return true;
    } else {
        return false;
    }
}

bool Modem::on(void) 
{
    _vreg_en = 1;
    Thread::wait(500);
    _pwrkey = 0;
    Thread::wait(1500);
    _pwrkey = 1;
    if (ATwaitForWord("RDY",10000)) {
        //TURN OFF ECHO
        ATsendCMD("ATE0");
        ATwaitForWord("OK",5000);
        return true;
    } else {
        return false;   
    }
}

void Modem::off(bool soft) 
{
    if (soft) {
        ATsendCMD("AT+QPOWD=0");
        ATwaitForWord("OK\r",5000);
    }
    _vreg_en = 0;
}

long long Modem::getIMEI() 
{
    long long imei = 0;
    char ATinBuffer[32];
    ATsendCMD("AT+GSN");
    ATwaitForWord("\n",5000);
    _uart.scanf("%s", ATinBuffer);
    imei = atoll(ATinBuffer);
    flushSerial();
    return imei;
}

bool Modem::registerOnNetwork(int maxAttempts, uint32_t timeout) 
{
    int attempt = 0;
    Timer t;
    t.start();
    //TRY X NUMBER OF TIMES
    while (attempt <= maxAttempts) {
        attempt ++;
        t.reset();
        uint32_t startmillis = t.read_ms();
        uint32_t runtime = 0;
        while(!GLOBAL_registeredOnNetwork && runtime < timeout) {
            runtime = (t.read_ms() - startmillis);
            Thread::wait(1000);
            ATsendCMD("AT+CREG?");
            if (ATwaitForWord("+CREG: 0,5",5000)) {
                flushSerial();
                GLOBAL_registeredOnNetwork = true;
            };
        }
        if (!GLOBAL_registeredOnNetwork) {
            off(true);
            on();   
        }
    }
    t.stop();
    flushSerial();
    if (GLOBAL_registeredOnNetwork) {
        return true;
    } else {
        return false;   
    }
}

bool Modem::USSDsend(char* message, int maxAttempts) 
{
    bool sent = false;
    int attempt = 0;
    //TRY X NUMBER OF TIMES
    while (!sent && attempt <= maxAttempts) {
        attempt ++;
        char bytestosend[160];
        snprintf(bytestosend, sizeof(bytestosend), "AT+CUSD=1,\"#469*%s#\"", message);
        ATsendCMD(bytestosend);
        if (ATwaitForWord("+CUSD: 0",10000)) {
            flushSerial();
            sent = true;
        };
    }
    if (sent) {
        return true;
    } else {
        return false;   
    }
}

char* Modem::USSDreceive(int messageIndex) 
{
    bool received = false;
    uint32_t timeout = 15000;
    int bufferIndex = 0;
    int USSDmessageIndex = 0;
    char ATinBuffer[180];
    int matchCount = 0;
    Timer t;
    t.start();
    //TRY UNTIL TIMEOUT
    uint32_t startmillis = t.read_ms();
    uint32_t runtime = 0;
    while(!received && runtime < timeout) {
        runtime = (t.read_ms() - startmillis);
        if (ATwaitForWord("+CUSD: 0",5000)) {
            led1 = 0;
            if ( (matchCount = _uart.scanf(",\"%d#%[^#]",USSDmessageIndex,ATinBuffer) ) > 0 ) {
                //DEBUG("got:%s \n",ATinBuffer);
                if (USSDmessageIndex == messageIndex) {
                    //NEED TO GET THIS WORKING SO WE KNOW WE ARE DEALING WITH THE RIGT MESSAGE
                    //MOVE THE BELOW INTO THIS IF STAEMEBNTS
                }
                led1 = 1;
                received = true;
            }
        }
    }
    flushSerial();
    if (received) {
        return ATinBuffer;
    } else {
        return "err";   
    }
}


char* Modem::USSDmessage(char* message, bool needResponse, int maxAttempts, char* api) 
{  
    uint8_t messageIndex = 1;
    bool result;
    int messageLength = strlen(message);
    if (messageLength > USSD_MAXLENGTH) {
        char message_failsafe[100];
        snprintf(message_failsafe,sizeof(message_failsafe),"(%s,im:%lld,z:TOOBIG,c:%d)\0",api,messageIndex,GLOBAL_imei,messageIndex);
        result = USSDsend(message_failsafe, maxAttempts);
    } else {
        result = USSDsend(message, maxAttempts);
    }
    if (result) {
        if (needResponse) {
            char* response = USSDreceive(messageIndex);
            if (response != "err") {
                return response;
            } else {
                return "sendonly";
            }
        } else {
            return "ok";   
        } 
    } else {
        return "err";   
    }
}

Modem::~Modem(){};