Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of AvnetATT_shape_hackathon by
Diff: Wnc.cpp
- Revision:
- 42:8500f0cb2ea5
- Child:
- 43:3979ea0a2df3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Wnc.cpp	Fri Oct 07 17:01:22 2016 +0000
@@ -0,0 +1,508 @@
+#include "Wnc.h"
+#include "mbed.h"
+#include <cctype>
+#include <string>
+#include "config_me.h"
+#include "SerialBuffered.h"
+
+
+extern Serial pc;
+
+DigitalOut  mdm_uart2_rx_boot_mode_sel(PTC17);  // on powerup, 0 = boot mode, 1 = normal boot
+DigitalOut  mdm_power_on(PTB9);                 // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem)
+DigitalInOut  mdm_wakeup_in(PTC2);                // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield
+
+DigitalOut  mdm_reset(PTC12);                   // active high      
+
+DigitalOut  shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active
+DigitalOut  mdm_uart1_cts(PTD0);
+
+SerialBuffered mdm(PTD3, PTD2, 512);
+
+bool powerSave = false;
+
+Wnc::Wnc(void)
+{
+}
+
+void Wnc::checkPassthrough()
+{
+    if(pc.readable())
+    {
+        if(pc.getc() == '~')
+        passthrough();
+    }
+}
+               
+
+void Wnc::passthrough()
+{
+    pc.printf(">>\r\n");
+    while(1)
+    {
+        char c;
+        if(pc.readable())
+        {
+            c =  pc.getc();
+            pc.putc(c);
+            if(c == '~')
+            {
+                pc.printf("exit\r\n");
+                 break;
+            }
+            else if(c == '<')
+            {
+                
+                 mdm_wakeup_in = 0;
+                 pc.printf("sleep\r\n");
+            }
+            else if(c == '>')
+            {
+                 mdm_wakeup_in = 1;
+                 pc.printf("wake\r\n");
+            }
+            else if(c == '^')
+            {
+                pc.printf("reboot\r\n");
+                NVIC_SystemReset();
+            }
+            else
+            {
+               
+                mdm.putc(c);
+            }
+        }
+        if(mdm.readable())
+            pc.putc(mdm.getc());
+    }
+}
+
+bool Wnc::isPowerSaveOn()
+{
+    return powerSave;
+}
+
+void Wnc::resumePowerSave()
+{
+    mdm_wakeup_in = 0;
+}
+
+char* Wnc::read(int timeout_ms)
+{
+    static char response[3200]; 
+    int len = 0;
+    
+    if(timeout_ms > 0) // read until timeout or OK
+    {
+        Timer timer;
+        timer.start();
+        while ((len < (3200-1)) && (timer.read_ms() < timeout_ms)) {
+            if (mdm.readable()) {
+                response[len++] = mdm.getc();
+                if(len>1 && response[len-2] == 'O' && response[len-1] == 'K')
+                    break;
+            }
+        }
+    }
+ 
+    response[len] = (char)NULL;
+    pc.printf("{%s}\r\n",response);
+    return response;
+}
+
+char* Wnc::send(const char *cmd, int timeout_ms)
+{
+    char* reply;
+        
+    int tries = 4;
+    while(tries > 0)
+    {
+        tries--;        
+        pc.printf("\r\n<%s>",cmd);
+        const char *pt = cmd;
+        size_t n = strlen(cmd);
+        while (n--) {
+            mdm.putc(*pt++);
+        };
+        mdm.putc('\r');
+        mdm.putc('\n');
+        reply = read(timeout_ms);
+        if(strlen(reply) > 0 && strstr(reply,"OK") !=0)
+            break; 
+        checkPassthrough();
+    }
+    return reply;
+}
+
+bool Wnc::isModemResponding()
+{    
+    char *reply = send("AT",WNC_WAIT_TIME_MS);
+    if(strlen(reply) > 0 && strstr(reply,"OK") !=0)
+        return true;
+    return false;
+}
+
+void Wnc::setIn()
+{
+    mdm_wakeup_in.input();
+}
+
+void Wnc::toggleWake()
+{
+    mdm_wakeup_in = 0;
+    wait_ms(2000);  
+    mdm_wakeup_in = 0; 
+}
+
+int Wnc::init(void) {
+    mdm_wakeup_in.output();
+    // disable signal level translator (necessary
+    // for the modem to boot properly)
+    shield_3v3_1v8_sig_trans_ena = 0;
+
+    // Hard reset the modem (doesn't go through
+    // the signal level translator)
+    mdm_reset = 1;
+    
+   // wait a moment for the modem to react
+    wait_ms(10);
+    
+    // Let modem boot
+    mdm_reset = 0;
+    
+    // wait a moment for the modem to react
+    wait(1.0);
+    
+    // power modem on //off
+    mdm_power_on = 0; //1;
+    
+    // insure modem boots into normal operating mode
+    // and does not go to sleep when powered on
+    mdm_uart2_rx_boot_mode_sel = 1;
+    mdm_wakeup_in = 1;
+    
+    // initialze comm with the modem
+    mdm.baud(115200);
+    // clear out potential garbage
+    while (mdm.readable())
+      mdm.getc();
+
+    mdm_uart1_cts = 0;
+    
+    // wait a moment for the modem to react to signal
+    // conditions while the level translator is disabled
+    // (sorry, don't have enough information to know
+    // what exactly the modem is doing with the current
+    // pin settings)
+    wait(1.0);
+
+    // enable the signal level translator to start
+    // modem reset process (modem will be powered down)
+    shield_3v3_1v8_sig_trans_ena = 1;
+    
+    // Give the modem 60 secons to start responding by
+    // sending simple 'AT' commands to modem once per second.
+    Timer timer;
+    timer.start();
+    while (timer.read() < 60) {
+        SetLedColor(0x1); //red     
+        if(isModemResponding())
+        {
+            SetLedColor(0);
+            return true; 
+        }
+        SetLedColor(0); //off
+        wait_ms(1000 - (timer.read_ms() % 1000));
+        pc.printf("\r%d",timer.read_ms()/1000);
+         
+    }
+    return false;       
+}
+int Wnc::secToTau(int time)
+{
+    /*
+    0 - value is incremented in multiples of 10 minutes
+    1 - value is incremented in multiples of 1 hour
+    2 - value is incremented in multiples of 10 hours
+    3 - value is incremented in multiples of 2 seconds
+    4 - value is incremented in multiples of 30 seconds
+    5 - value is incremented in multiples of 1 minute
+*/
+    if(time/2 < 32)
+    {
+        return (0x3<<5)+time/2;
+    }
+    else if(time/30 < 32)
+    {
+        return (0x4<<5)+time/30;
+    }
+    else if(time/60 < 32)
+    {
+        return (0x5<<5)+time/60;
+    }
+    else if(time/3600 < 32)
+    {
+        return (0x1<<5)+time/3600;
+    }
+    else if(time/36000 < 32)
+    {
+        return (0x2<<5)+time/36000;
+    }
+    else
+        return (0x7<<5);
+        
+
+}
+int Wnc::secToActivity(int time)
+{
+    /*
+    0 - value is incremented in multiples of 2 seconds
+    1 - value is incremented in multiples of 1 minute
+    2 - value is incremented in multiples of decihours
+    7 - value indicates that the timer is deactivated.
+    */
+    if(time/2 < 32)
+    {
+        return (0x0<<5)+time/2;
+    }
+    else if(time/60 < 32)
+    {
+        return (0x1<<5)+time/60;
+    }
+    else if(time/36000 < 32)
+    {
+        return (0x2<<5)+time/36000;
+    }
+    else
+        return (0x7<<5);
+
+}    
+void Wnc::setPowerSave(bool on,int t3412,int t3324)
+{
+    if(on)
+    {
+        int tau = secToTau(t3412);
+        int activity = secToActivity(t3324);
+        mdm_wakeup_in = 0; //allow power sleep mode
+        powerSave = true;
+        char cmd[32];
+        sprintf(cmd,"AT+CPSMS=1,,,%d,%d",tau,activity);
+        send(cmd,  WNC_WAIT_TIME_MS);
+    }
+    else
+    {
+        mdm_wakeup_in = 1; //disallow power sleep mode
+        powerSave = false;
+        send("AT+CPSMS=0",  WNC_WAIT_TIME_MS);
+    }
+}
+
+char* Wnc::getIccid()
+{
+    static char iccidBuf[32];
+    iccidBuf[0] = NULL;
+    char* reply = send("AT%CCID",500);
+    int index = 0;
+    int begin = -1;
+    int i = 0;
+
+    while (reply[index]) { // While there are more characters to process...
+        if (begin == -1 && isdigit(reply[index])) { // Upon finding a digit, ...
+            begin = index;
+        }
+        if(begin != -1)
+        { 
+            if(isdigit(reply[index]))
+            { 
+                iccidBuf[i++] = reply[index];
+            }
+            else
+            {
+                iccidBuf[i++] = NULL;
+                return iccidBuf;
+            }
+        }
+        index++;
+    }
+    return iccidBuf;
+}
+
+void Wnc::wakeFromPowerSave()
+{
+    char *reply;
+    mdm_wakeup_in = 1;
+    reply = send("AT+CFUN=1", WNC_WAIT_TIME_MS);
+    reply = send("AT%CMATT=1",  WNC_WAIT_TIME_MS);
+    wait(2); // wait to attach
+    reply = send("AT+CREG?",  WNC_WAIT_TIME_MS);
+    reply = send("AT@INTERNET=1",  WNC_WAIT_TIME_MS);  // Internet services enabled
+    reply = send("AT@SOCKDIAL=1",  WNC_WAIT_TIME_MS);
+    
+
+}
+
+void Wnc::startInternet()
+{
+  char *reply;
+  reply = send("ATE1",WNC_WAIT_TIME_MS);           // Echo ON
+  char apn [32];
+  sprintf(apn,"AT%%PDNSET=1,%s,IP",MY_APN_STR);
+
+  reply = send(apn, 2*WNC_WAIT_TIME_MS); // Set APN, cmd seems to take a little longer sometimes
+  reply = send("AT+CREG?",  WNC_WAIT_TIME_MS);
+  reply = send("AT@INTERNET=1",  WNC_WAIT_TIME_MS);  // Internet services enabled
+  reply = send("AT@SOCKDIAL=1",  WNC_WAIT_TIME_MS);
+}
+
+char* Wnc::ping(char* ip)
+{
+    char cmd[32];
+    sprintf(cmd,"AT@PINGREQ=\"%s\"",ip);
+    return send(cmd,WNC_WAIT_TIME_MS);
+}
+// AT@SOCKCONN=1,"108.244.165.22",5005"
+bool Wnc::connect(char* ip, int port)
+{
+  char *reply;
+
+    reply = send("AT@SOCKCREAT=1", WNC_WAIT_TIME_MS);
+    if(strlen(reply) == 0 || strstr(reply,"OK") ==0)
+        return false;
+    char cmd[32];
+    sprintf(cmd,"AT@SOCKCONN=1,\"%s\",%d",ip,port);
+    reply = send(cmd,WNC_WAIT_TIME_MS);
+    if(strlen(reply) == 0 || strstr(reply,"OK") ==0)
+        return false;
+    return true;
+}
+
+void Wnc::disconnect()
+{
+     send("AT@SOCKCLOSE=1", WNC_WAIT_TIME_MS);
+}
+
+char* Wnc::encode(int value, char* result, int base)                                                                                                          
+{                                                                                                                                                        
+    // check that the base if valid                                                                                                                      
+    if ( base < 2 || base > 36 ) {                                                                                                                       
+        *result = '\0';                                                                                                                                  
+        return result;                                                                                                                                   
+    }                                                                                                                                                    
+ 
+    char* ptr = result, *ptr1 = result, tmp_char;                                                                                                        
+    int tmp_value;                                                                                                                                       
+ 
+    do {                                                                                                                                                 
+        tmp_value = value;                                                                                                                               
+        value /= base;                                                                                                                                   
+        *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];                             
+    } while ( value );                                                                                                                                   
+ 
+    // Apply negative sign                                                                                                                               
+    if ( tmp_value < 0 )                                                                                                                                 
+    *ptr++ = '-';                                                                                                                                    
+    *ptr-- = '\0';                                                                                                                                       
+ 
+    while ( ptr1 < ptr ) {                                                                                                                               
+    tmp_char = *ptr;                                                                                                                                 
+    *ptr-- = *ptr1;                                                                                                                                  
+    *ptr1++ = tmp_char;                                                                                                                              
+    }                                                                                                                                                    
+    return result;                                                                                                                                       
+}
+
+char* Wnc::writeSocket(const char * s)
+{
+
+  char *reply;
+  char num2str[6];
+  size_t sLen = strlen(s);
+  if (sLen <= 99999)
+  {
+
+    string cmd_str("AT@SOCKWRITE=1,");
+    encode(sLen, num2str, 10);
+    cmd_str += num2str;
+    cmd_str += ",\"";
+    while(*s != '\0')
+    {
+      encode((int)*s++, num2str, 16);
+      // Always 2-digit ascii hex:
+      if (strlen(num2str) == 1)
+      {
+        num2str[2] = '\0';
+        num2str[1] = num2str[0];
+        num2str[0] = '0';
+      }
+      cmd_str += num2str;
+    }
+    cmd_str += "\"";
+    reply = send(cmd_str.c_str(), WNC_WAIT_TIME_MS);
+  }
+  else
+    pc.puts("sockwrite Err, string to long\r\n");
+  return NULL;
+}
+
+int Wnc::hex_to_int(char c){
+    if(c >=97)
+        c=c-32;
+    int first = c / 16 - 3;
+    int second = c % 16;
+    int result = first*10 + second;
+    if(result > 9) result--;
+    return result;
+}
+
+int Wnc::hex_to_ascii(char h, char l){
+        int high = hex_to_int(h) * 16;
+        int low = hex_to_int(l);
+        return high+low;       
+}
+
+int Wnc::indexOf(char* str, char c)
+{
+    int index = 0;
+    while(str[index] != 0)
+    {
+        if(str[index] == c)
+            return index;
+        index++;
+    }
+    return -1;
+}
+
+char* Wnc::readSocket()
+{
+
+     static char data[1000];
+     int i = 0;
+     char *reply;
+     reply = send("AT@SOCKREAD=1,1024",1000);
+     if(strlen(reply) > 0)
+     {
+        int pos_start = indexOf(reply,'"');
+ 
+        if(pos_start > 0)
+        {
+            pos_start+=1;
+            int length  = indexOf(&reply[pos_start],'"');
+
+            if(length > 0)
+            {
+                char hi;
+                char low;
+                for(i = 0; i < length; i++){
+                    if(i % 2 != 0){
+                        low = reply[pos_start++];
+                        data[i/2] = (char) hex_to_ascii(hi,low);
+                    }else{
+                        hi = reply[pos_start++];
+                    }
+                }
+            }
+        }
+    }
+    data[i] = NULL;
+    return data;
+}
\ No newline at end of file
    