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
Wnc.cpp
00001 #include "Wnc.h" 00002 #include "mbed.h" 00003 #include <cctype> 00004 #include "config_me.h" 00005 #include "SerialBuffered.h" 00006 00007 00008 extern Serial pc; 00009 00010 DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot 00011 DigitalOut mdm_power_on(PTB9); // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem) 00012 DigitalInOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield 00013 00014 DigitalOut mdm_reset(PTC12); // active high 00015 00016 DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active 00017 DigitalOut mdm_uart1_cts(PTD0); 00018 00019 DigitalOut uart1Rts(PTD1); 00020 00021 SerialBuffered mdm(PTD3, PTD2, 512); 00022 00023 int t3412Timer = 4*60*60; 00024 int t3324Timer = 20; 00025 bool powerSave = false; 00026 00027 00028 Wnc::Wnc(void) 00029 { 00030 } 00031 00032 void Wnc::checkPassthrough() 00033 { 00034 if(pc.readable()) 00035 { 00036 if(pc.getc() == '~') 00037 passthrough(); 00038 } 00039 } 00040 00041 00042 void Wnc::passthrough() 00043 { 00044 pc.printf(">>\r\n"); 00045 while(1) 00046 { 00047 char c; 00048 if(pc.readable()) 00049 { 00050 c = pc.getc(); 00051 pc.putc(c); 00052 if(c == '~') 00053 { 00054 pc.printf("exit\r\n"); 00055 break; 00056 } 00057 else if(c == '<') 00058 { 00059 00060 mdm_wakeup_in = 0; 00061 pc.printf("sleep\r\n"); 00062 } 00063 else if(c == '>') 00064 { 00065 mdm_wakeup_in = 1; 00066 pc.printf("wake\r\n"); 00067 } 00068 else if(c == '}') 00069 { 00070 mdm_uart2_rx_boot_mode_sel = 1; 00071 pc.printf("rx hi\r\n"); 00072 } 00073 else if(c == '{') 00074 { 00075 mdm_uart2_rx_boot_mode_sel = 0; 00076 pc.printf("rx low\r\n"); 00077 } 00078 00079 else if(c == '^') 00080 { 00081 pc.printf("reboot\r\n"); 00082 NVIC_SystemReset(); 00083 } 00084 else 00085 { 00086 00087 mdm.putc(c); 00088 } 00089 } 00090 if(mdm.readable()) 00091 pc.putc(mdm.getc()); 00092 } 00093 } 00094 00095 bool Wnc::isPowerSaveOn() 00096 { 00097 return powerSave; 00098 } 00099 00100 void Wnc::resumePowerSave() 00101 { 00102 mdm_wakeup_in = 0; 00103 } 00104 00105 int Wnc::gett3412Timer() 00106 { 00107 return t3412Timer; 00108 } 00109 00110 int Wnc::gett3324Timer() 00111 { 00112 return t3324Timer; 00113 } 00114 00115 char* Wnc::read(int timeout_ms) 00116 { 00117 static char response[3200]; 00118 int len = 0; 00119 char c; 00120 00121 if(timeout_ms > 0) // read until timeout or OK 00122 { 00123 Timer timer; 00124 timer.start(); 00125 while ((len < (3200-1)) && (timer.read_ms() < timeout_ms)) { 00126 if (mdm.readable()) { 00127 c = mdm.getc(); 00128 // replace \r\n to make debug messages more compact 00129 if(c == '\r') c = ' '; 00130 if(c == '\n') c = ' '; 00131 00132 response[len++] = c; 00133 if(len>1 && response[len-2] == 'O' && response[len-1] == 'K') 00134 break; 00135 00136 } 00137 } 00138 } 00139 00140 response[len] = (char)NULL; 00141 pc.printf("{%d %s}\r\n",len,response); 00142 return response; 00143 } 00144 00145 char* Wnc::send(const char *cmd, int timeout_ms) 00146 { 00147 char *reply; 00148 00149 while (mdm.readable()) { 00150 mdm.getc(); 00151 } 00152 00153 int tries = 4; 00154 while(tries > 0) 00155 { 00156 tries--; 00157 pc.printf("\r\n<%s>",cmd); 00158 const char *pt = cmd; 00159 size_t n = strlen(cmd); 00160 while (n--) { 00161 mdm.putc(*pt++); 00162 }; 00163 mdm.putc('\r'); 00164 mdm.putc('\n'); 00165 reply = read(timeout_ms); 00166 if(strlen(reply) > 0 && strstr(reply,"OK") !=0) 00167 break; 00168 checkPassthrough(); 00169 } 00170 return reply; 00171 } 00172 00173 bool Wnc::isModemResponding() 00174 { 00175 char *reply = send("AT",WNC_WAIT_TIME_MS); 00176 if(strlen(reply) > 0 && strstr(reply,"OK") !=0) 00177 return true; 00178 return false; 00179 } 00180 00181 void Wnc::setIn() 00182 { 00183 mdm_wakeup_in.input(); 00184 } 00185 00186 void Wnc::toggleWake() 00187 { 00188 mdm_wakeup_in = 0; 00189 wait_ms(2000); 00190 mdm_wakeup_in = 0; 00191 } 00192 00193 bool Wnc::init(void) { 00194 uart1Rts = 0; 00195 mdm_wakeup_in.output(); 00196 // disable signal level translator (necessary 00197 // for the modem to boot properly) 00198 shield_3v3_1v8_sig_trans_ena = 0; 00199 00200 // Hard reset the modem (doesn't go through 00201 // the signal level translator) 00202 mdm_reset = 1; 00203 00204 // wait a moment for the modem to react 00205 wait_ms(10); 00206 00207 // Let modem boot 00208 mdm_reset = 0; 00209 00210 // wait a moment for the modem to react 00211 wait(1.0); 00212 00213 // power modem on //off 00214 mdm_power_on = 0; //1; 00215 00216 // insure modem boots into normal operating mode 00217 // and does not go to sleep when powered on 00218 mdm_uart2_rx_boot_mode_sel = 1; 00219 mdm_wakeup_in = 1; 00220 00221 // initialze comm with the modem 00222 mdm.baud(115200); 00223 // clear out potential garbage 00224 while (mdm.readable()) 00225 mdm.getc(); 00226 00227 mdm_uart1_cts = 0; 00228 00229 // wait a moment for the modem to react to signal 00230 // conditions while the level translator is disabled 00231 // (sorry, don't have enough information to know 00232 // what exactly the modem is doing with the current 00233 // pin settings) 00234 wait(1.0); 00235 00236 // enable the signal level translator to start 00237 // modem reset process (modem will be powered down) 00238 shield_3v3_1v8_sig_trans_ena = 1; 00239 00240 // Give the modem 60 secons to start responding by 00241 // sending simple 'AT' commands to modem once per second. 00242 Timer timer; 00243 timer.start(); 00244 while (timer.read() < 60) { 00245 SetLedColor(0x1); //red 00246 if(isModemResponding()) 00247 { 00248 SetLedColor(0); 00249 //mdm_uart2_rx_boot_mode_sel = 0; 00250 return true; 00251 } 00252 SetLedColor(0); //off 00253 wait_ms(1000 - (timer.read_ms() % 1000)); 00254 pc.printf("\r%d",timer.read_ms()/1000); 00255 00256 } 00257 return false; 00258 } 00259 int Wnc::secToTau(int time) 00260 { 00261 /* 00262 0 - value is incremented in multiples of 10 minutes 00263 1 - value is incremented in multiples of 1 hour 00264 2 - value is incremented in multiples of 10 hours 00265 3 - value is incremented in multiples of 2 seconds 00266 4 - value is incremented in multiples of 30 seconds 00267 5 - value is incremented in multiples of 1 minute 00268 */ 00269 if(time/2 < 32) 00270 { 00271 return (0x3<<5)+time/2; 00272 } 00273 else if(time/30 < 32) 00274 { 00275 return (0x4<<5)+time/30; 00276 } 00277 else if(time/60 < 32) 00278 { 00279 return (0x5<<5)+time/60; 00280 } 00281 else if(time/3600 < 32) 00282 { 00283 return (0x1<<5)+time/3600; 00284 } 00285 else if(time/36000 < 32) 00286 { 00287 return (0x2<<5)+time/36000; 00288 } 00289 else 00290 return (0x7<<5); 00291 00292 00293 } 00294 int Wnc::secToActivity(int time) 00295 { 00296 /* 00297 0 - value is incremented in multiples of 2 seconds 00298 1 - value is incremented in multiples of 1 minute 00299 2 - value is incremented in multiples of decihours 00300 7 - value indicates that the timer is deactivated. 00301 */ 00302 if(time/2 < 32) 00303 { 00304 return (0x0<<5)+time/2; 00305 } 00306 else if(time/60 < 32) 00307 { 00308 return (0x1<<5)+time/60; 00309 } 00310 else if(time/36000 < 32) 00311 { 00312 return (0x2<<5)+time/36000; 00313 } 00314 else 00315 return (0x7<<5); 00316 00317 } 00318 void Wnc::setPowerSave(bool on,int t3412,int t3324) 00319 { 00320 if(on) 00321 { 00322 t3412Timer = t3412; 00323 t3324Timer = t3324; 00324 int tau = secToTau(t3412); 00325 int activity = secToActivity(t3324); 00326 mdm_wakeup_in = 0; //allow power sleep mode 00327 powerSave = true; 00328 char cmd[32]; 00329 snprintf(cmd,sizeof(cmd),"AT+CPSMS=1,,,%d,%d",tau,activity); 00330 send(cmd, WNC_WAIT_TIME_MS); 00331 } 00332 else 00333 { 00334 mdm_wakeup_in = 1; //disallow power sleep mode 00335 powerSave = false; 00336 send("AT+CPSMS=0", WNC_WAIT_TIME_MS); 00337 } 00338 } 00339 00340 char* Wnc::getIccid() 00341 { 00342 static char iccidBuf[32]; 00343 iccidBuf[0] = NULL; 00344 char* reply = send("AT%CCID",500); 00345 int index = 0; 00346 int begin = -1; 00347 int i = 0; 00348 00349 while (reply[index]) { // While there are more characters to process... 00350 if (begin == -1 && isdigit(reply[index])) { // Upon finding a digit, ... 00351 begin = index; 00352 } 00353 if(begin != -1) 00354 { 00355 if(isdigit(reply[index])) 00356 { 00357 iccidBuf[i++] = reply[index]; 00358 } 00359 else 00360 { 00361 iccidBuf[i++] = NULL; 00362 return iccidBuf; 00363 } 00364 } 00365 index++; 00366 } 00367 return iccidBuf; 00368 } 00369 00370 void Wnc::wakeFromPowerSave() 00371 { 00372 mdm_wakeup_in = 1; 00373 pc.printf("wake from power save\r\n"); 00374 } 00375 00376 bool Wnc::cmdFailed(char* reply,char* msg) 00377 { 00378 if(strstr(reply,"OK") > 0) 00379 return false; 00380 pc.printf("%s\r\n",msg); 00381 return true; 00382 } 00383 00384 bool Wnc::startInternet() 00385 { 00386 char *reply; 00387 reply = send("ATE1",WNC_WAIT_TIME_MS); // Echo ON 00388 char apn [32]; 00389 snprintf(apn,sizeof(apn),"AT%%PDNSET=1,%s,IP",MY_APN_STR); 00390 00391 reply = send(apn, 2*WNC_WAIT_TIME_MS); // Set APN, cmd seems to take a little longer sometimes 00392 if(cmdFailed(reply,"Failed to set APN")) return false; 00393 00394 reply = send("AT%PDNSET?", WNC_WAIT_TIME_MS); 00395 00396 //pc.printf("Wiating ...\r\n"); 00397 //wait(10); 00398 00399 reply = send("AT@INTERNET=1", WNC_WAIT_TIME_MS); // Internet services enabled 00400 if(cmdFailed(reply,"Failed to start INTERNET")) 00401 { 00402 return false; 00403 } 00404 reply = send("AT@SOCKDIAL=1", 4*WNC_WAIT_TIME_MS); 00405 if(cmdFailed(reply,"SOCKDIAL Failed")) 00406 { 00407 // passthrough(); 00408 return false; 00409 } 00410 return true; 00411 } 00412 00413 char* Wnc::ping(char* ip) 00414 { 00415 char cmd[32]; 00416 snprintf(cmd,sizeof(cmd),"AT@PINGREQ=\"%s\"",ip); 00417 return send(cmd,WNC_WAIT_TIME_MS); 00418 } 00419 00420 bool Wnc::connect(char* ip, int port) 00421 { 00422 char *reply; 00423 00424 for(int i = 0;i<2;i++) 00425 { 00426 if(isModemResponding()) 00427 break; 00428 wait(0.5); 00429 } 00430 00431 if(isModemResponding()) 00432 { 00433 reply = send("AT@SOCKCREAT=1", WNC_WAIT_TIME_MS); 00434 if(cmdFailed(reply,"Socket Create Failed")) return false; 00435 } 00436 else 00437 { 00438 pc.printf("Error Modem not responding\r\n"); 00439 return false; 00440 } 00441 00442 00443 char cmd[64]; 00444 00445 snprintf(cmd,sizeof(cmd),"AT@SOCKCONN=1,\"%s\",%d",ip,port); 00446 reply = send(cmd,12*WNC_WAIT_TIME_MS); 00447 if(cmdFailed(reply,"Socket Connect Failed")) return false; 00448 00449 for(int i = 0;i<10;i++) 00450 { 00451 reply = send("AT+CREG?",WNC_WAIT_TIME_MS); 00452 if(strlen(reply) > 0 && strstr(reply,"2,1") != 0) 00453 { 00454 pc.printf("Connected %s\r\n",reply); 00455 return true; 00456 } 00457 else 00458 { 00459 pc.printf("Unconnected %s\r\n",reply); 00460 } 00461 wait(1); 00462 } 00463 return false; 00464 } 00465 00466 void Wnc::disconnect() 00467 { 00468 send("AT@SOCKCLOSE=1", WNC_WAIT_TIME_MS); 00469 } 00470 00471 char* Wnc::encode(int value, char* result, int base) 00472 { 00473 // check that the base if valid 00474 if ( base < 2 || base > 36 ) { 00475 *result = '\0'; 00476 return result; 00477 } 00478 00479 char* ptr = result, *ptr1 = result, tmp_char; 00480 int tmp_value; 00481 00482 do { 00483 tmp_value = value; 00484 value /= base; 00485 *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; 00486 } while ( value ); 00487 00488 // Apply negative sign 00489 if ( tmp_value < 0 ) 00490 *ptr++ = '-'; 00491 *ptr-- = '\0'; 00492 00493 while ( ptr1 < ptr ) { 00494 tmp_char = *ptr; 00495 *ptr-- = *ptr1; 00496 *ptr1++ = tmp_char; 00497 } 00498 return result; 00499 } 00500 00501 bool Wnc::writeSocket(const char * s) 00502 { 00503 00504 char num2str[6]; 00505 size_t sLen = strlen(s); 00506 if (sLen <= 99999) 00507 { 00508 char cmd[sLen*2+32]; 00509 int index = snprintf(cmd,sizeof(cmd),"AT@SOCKWRITE=1,%d,\"",sLen); 00510 00511 while(*s != '\0') 00512 { 00513 encode((int)*s++, num2str, 16); 00514 // Always 2-digit ascii hex: 00515 if (strlen(num2str) == 1) 00516 { 00517 num2str[2] = '\0'; 00518 num2str[1] = num2str[0]; 00519 num2str[0] = '0'; 00520 } 00521 cmd[index++] = num2str[0]; 00522 cmd[index++] = num2str[1]; 00523 } 00524 cmd[index++] = '"'; 00525 cmd[index] = '\0'; 00526 char* reply = send(cmd, WNC_WAIT_TIME_MS); 00527 if(cmdFailed(reply,"Send Failed")) return false; 00528 return true; 00529 } 00530 else 00531 { 00532 pc.puts("sockwrite Err, string to long\r\n"); 00533 return false; 00534 } 00535 00536 } 00537 00538 int Wnc::hex_to_int(char A) 00539 { 00540 return (A > '9')? (A &~ 0x20) - 'A' + 10: (A - '0'); 00541 } 00542 00543 int Wnc::hex_to_ascii(char h, char l) 00544 { 00545 return hex_to_int(h) * 16 + hex_to_int(l); 00546 } 00547 00548 int Wnc::indexOf(char* str, char c) 00549 { 00550 int index = 0; 00551 while(str[index] != 0) 00552 { 00553 if(str[index] == c) 00554 return index; 00555 index++; 00556 } 00557 return -1; 00558 } 00559 00560 char* Wnc::readSocket() 00561 { 00562 00563 static char data[1000]; 00564 int i = 0; 00565 char *reply; 00566 reply = send("AT@SOCKREAD=1,1024",1000); 00567 if(strlen(reply) > 0) 00568 { 00569 int pos_start = indexOf(reply,'"'); 00570 00571 if(pos_start > 0) 00572 { 00573 pos_start+=1; 00574 int length = indexOf(&reply[pos_start],'"'); 00575 00576 if(length > 0) 00577 { 00578 char hi; 00579 char low; 00580 for(i = 0; i < length; i++){ 00581 if(i % 2 != 0){ 00582 low = reply[pos_start++]; 00583 data[i/2] = (char) hex_to_ascii(hi,low); 00584 }else{ 00585 hi = reply[pos_start++]; 00586 } 00587 } 00588 data[length/2] = NULL; 00589 } 00590 } 00591 } 00592 data[i] = NULL; 00593 return data; 00594 } 00595 00596 char* Wnc::resolveDn(const char* name) 00597 { 00598 char cmd[64]; 00599 00600 snprintf(cmd,sizeof(cmd),"AT@DNSRESVDON=\"%s\"",name); 00601 char* reply = send(cmd,12*WNC_WAIT_TIME_MS); 00602 static char ipBuf[32]; 00603 ipBuf[0] = NULL; 00604 int index = 0; 00605 int begin = -1; 00606 int i = 0; 00607 00608 while (reply[index]) { // While there are more characters to process... 00609 if (begin == -1 && isdigit(reply[index])) { // Upon finding a digit, ... 00610 begin = index; 00611 } 00612 if(begin != -1) 00613 { 00614 if(isdigit(reply[index]) || reply[index] == '.') 00615 { 00616 ipBuf[i++] = reply[index]; 00617 } 00618 else 00619 { 00620 ipBuf[i++] = NULL; 00621 return ipBuf; 00622 } 00623 } 00624 index++; 00625 } 00626 return ipBuf; 00627 }
Generated on Tue Jul 12 2022 21:53:53 by
1.7.2
