Rick McConney
/
TCPSend
TCP send example
Fork of StarterKit 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