FRDM-K64F, Avnet M14A2A, Grove Shield, to create smart home system. In use with AT&Ts M2x & Flow.

Dependencies:   mbed FXOS8700CQ MODSERIAL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wnc_control.cpp Source File

wnc_control.cpp

00001 /* ===================================================================
00002 Copyright c 2016, AVNET Inc.  
00003 
00004 Licensed under the Apache License, Version 2.0 (the "License"); 
00005 you may not use this file except in compliance with the License.
00006 You may obtain a copy of the License at
00007 
00008    http://www.apache.org/licenses/LICENSE-2.0
00009 
00010 Unless required by applicable law or agreed to in writing, 
00011 software distributed under the License is distributed on an 
00012 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
00013 either express or implied. See the License for the specific 
00014 language governing permissions and limitations under the License.
00015 
00016 ======================================================================== */
00017 
00018 #include "mbed.h"
00019 #include <cctype>
00020 #include <string>
00021 #include "config_me.h"
00022 #include "wnc_control.h"
00023 #include "hardware.h"
00024 
00025 // Outputs detailed WNC command info
00026 #define WNC_CMD_DEBUG_ON
00027 
00028 // Full debug output, longer cmds and extra cellular status checking
00029 #undef WNC_CMD_DEBUG_ON_VERBOSE
00030 
00031 extern string MyServerIpAddress;
00032 extern string MySocketData;
00033 
00034 int reinitialize_mdm(void);
00035 
00036 enum WNC_ERR_e {
00037     WNC_OK =0,
00038     WNC_CMD_ERR = -1,
00039     WNC_NO_RESPONSE = -2,
00040     WNC_CELL_LINK_DOWN = -3,
00041     WNC_EXTERR = -4
00042 };
00043 
00044 // Contains result of last call to send_wnc_cmd(..)
00045 WNC_ERR_e WNC_MDM_ERR = WNC_OK;
00046 
00047 // Contains the RAW WNC UART responses
00048 static string wncStr;
00049 static int socketOpen = 0;
00050 
00051 void software_init_mdm(void)
00052 {
00053  // Temp put here to fix new boards needing init,
00054  //  the check for on the cellular network was preventing the PDNSET from happening!!!!
00055  {  
00056     PUTS("SET APN STRING!\r\n");
00057     string * pRespStr;
00058     string cmd_str("AT%PDNSET=1,");
00059     cmd_str += MY_APN_STR;
00060     cmd_str += ",IP";
00061     at_send_wnc_cmd(cmd_str.c_str(), &pRespStr, 4*WNC_TIMEOUT_MS); // Set APN, cmd seems to take a little longer sometimes
00062  }   
00063 
00064   static bool reportStatus = true;
00065   do
00066   {
00067       PUTS("------------ software_init_mdm! --------->\r\n");
00068       if (check_wnc_ready() == 0)
00069       {
00070           if (reportStatus == false)
00071           {
00072               PUTS("Re-connected to cellular network!\n\r");
00073               reportStatus = true;
00074           }
00075     
00076           // WNC has SIM and registered on network
00077           do
00078           {
00079               WNC_MDM_ERR = WNC_OK;
00080               at_init_wnc();
00081               if (WNC_MDM_ERR == WNC_NO_RESPONSE)
00082               {
00083                   reinitialize_mdm();
00084                   at_init_wnc(true);  // Hard reset occurred so make it go through the software init();
00085               }
00086           } while (WNC_MDM_ERR != WNC_OK);
00087       }
00088       else
00089       {
00090           if (reportStatus == true)
00091           {
00092                PUTS("Not connected to cellular network!\n\r");
00093                reportStatus = false;
00094           }
00095      // Atempt to re-register
00096 //     string * pRespStr;
00097 //     PUTS("Force re-register!\r\n");
00098 //     at_send_wnc_cmd("AT+CFUN=0,0", &pRespStr, WNC_TIMEOUT_MS);
00099 //     wait_ms(31000);
00100 //     at_send_wnc_cmd("AT+CFUN=1,0", &pRespStr, WNC_TIMEOUT_MS);
00101 //     wait_ms(31000);
00102           WNC_MDM_ERR = WNC_CELL_LINK_DOWN;
00103       }
00104   } while (WNC_MDM_ERR != WNC_OK);
00105 }
00106 
00107 void display_modem_firmware_version(void)
00108 {
00109     string * pRespStr;
00110 
00111     PUTS("<-------- WNC Firmware Revision --------\r\n");
00112     at_send_wnc_cmd("ATI", &pRespStr, WNC_TIMEOUT_MS);
00113     PUTS(pRespStr->c_str());
00114     PUTS("\r\n");    
00115     PUTS("--------------------------------------->\r\n");
00116 }
00117 
00118 void resolve_mdm(void)
00119 {
00120     do
00121     {
00122       WNC_MDM_ERR = WNC_OK;
00123       at_dnsresolve_wnc(MY_SERVER_URL, &MyServerIpAddress);
00124       if (WNC_MDM_ERR == WNC_NO_RESPONSE)
00125       {
00126         software_init_mdm();
00127       }
00128       else if (WNC_MDM_ERR == WNC_CMD_ERR)
00129       {
00130         PUTS("Bad URL!!!!!!\r\n");
00131       }
00132     } while (WNC_MDM_ERR != WNC_OK);
00133     
00134     PRINTF("My Server IP: %s\r\n", MyServerIpAddress.c_str());
00135 }
00136 
00137 void sockopen_mdm(void)
00138 {
00139     do
00140     {
00141       WNC_MDM_ERR = WNC_OK;
00142       at_sockopen_wnc(MyServerIpAddress, MY_PORT_STR);
00143       if (WNC_MDM_ERR == WNC_NO_RESPONSE)
00144       {
00145         software_init_mdm();
00146       }
00147       else if (WNC_MDM_ERR == WNC_CMD_ERR)
00148         PUTS("Socket open fail!!!!\r\n");
00149       else
00150         socketOpen = 1;
00151     } while (WNC_MDM_ERR != WNC_OK);
00152 }
00153 
00154 void sockwrite_mdm(const char * s)
00155 {
00156     if (socketOpen == 1)
00157     {
00158     do
00159     {
00160       WNC_MDM_ERR = WNC_OK;
00161       at_sockwrite_wnc(s);
00162       if (WNC_MDM_ERR == WNC_NO_RESPONSE)
00163       {
00164         PUTS("Sock write no response!\r\n");
00165         software_init_mdm();
00166       }
00167       else if (WNC_MDM_ERR == WNC_CMD_ERR)
00168       {
00169         PUTS("Socket Write fail!!!\r\n");
00170         software_init_mdm();
00171       }else if (WNC_MDM_ERR == WNC_EXTERR)
00172       {
00173         PUTS("Socket Disconnected (broken) !!!\r\n");
00174         sockclose_mdm();
00175         sockopen_mdm();
00176         //software_init_mdm();
00177       }
00178     } while (WNC_MDM_ERR != WNC_OK);
00179     }
00180     else
00181       PUTS("Socket is closed for write!\r\n");
00182 }
00183 
00184 unsigned sockread_mdm(string * sockData, int len, int retries)
00185 {
00186     unsigned n = 0;
00187     
00188     if (socketOpen == 1)
00189     {
00190     do
00191     {
00192       WNC_MDM_ERR = WNC_OK;
00193       n = at_sockread_wnc(sockData, len, retries);
00194       if (WNC_MDM_ERR == WNC_NO_RESPONSE)
00195       {
00196         if (n == 0)
00197             software_init_mdm();
00198         else
00199             PUTS("Sock read partial data!!!\r\n");
00200       }
00201       else if (WNC_MDM_ERR == WNC_CMD_ERR)
00202         PUTS("Sock read fail!!!!\r\n");
00203     } while (WNC_MDM_ERR == WNC_NO_RESPONSE);
00204     }
00205     else
00206     {
00207       PUTS("Socket is closed for read\r\n");
00208       sockData->erase();
00209     }
00210       
00211     return (n);
00212 }
00213 
00214 void sockclose_mdm(void)
00215 {
00216     do
00217     {
00218       WNC_MDM_ERR = WNC_OK;
00219       at_sockclose_wnc();
00220       // Assume close happened even if it went bad
00221       // going bad will result in a re-init anyways and if close
00222       // fails we're pretty much in bad state and not much can do
00223       socketOpen = 0;
00224       if (WNC_MDM_ERR == WNC_NO_RESPONSE)
00225       {
00226         software_init_mdm();
00227       }
00228       else if (WNC_MDM_ERR == WNC_CMD_ERR)
00229         PUTS("Sock close fail!!!\r\n");
00230     } while (WNC_MDM_ERR != WNC_OK);
00231 }
00232 
00233 /**                                                                                                                                                          
00234  * C++ version 0.4 char* style "itoa":                                                                                                                       
00235  * Written by Lukas Chmela                                                                                                                                   
00236  * Released under GPLv3.                                                                                                                                     
00237 */
00238  
00239 char* itoa(int value, char* result, int base)                                                                                                          
00240 {                                                                                                                                                        
00241     // check that the base if valid                                                                                                                      
00242     if ( base < 2 || base > 36 ) {                                                                                                                       
00243         *result = '\0';                                                                                                                                  
00244         return result;                                                                                                                                   
00245     }                                                                                                                                                    
00246  
00247     char* ptr = result, *ptr1 = result, tmp_char;                                                                                                        
00248     int tmp_value;                                                                                                                                       
00249  
00250     do {                                                                                                                                                 
00251         tmp_value = value;                                                                                                                               
00252         value /= base;                                                                                                                                   
00253         *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];                             
00254     } while ( value );                                                                                                                                   
00255  
00256     // Apply negative sign                                                                                                                               
00257     if ( tmp_value < 0 )                                                                                                                                 
00258     *ptr++ = '-';                                                                                                                                    
00259     *ptr-- = '\0';                                                                                                                                       
00260  
00261     while ( ptr1 < ptr ) {                                                                                                                               
00262     tmp_char = *ptr;                                                                                                                                 
00263     *ptr-- = *ptr1;                                                                                                                                  
00264     *ptr1++ = tmp_char;                                                                                                                              
00265     }                                                                                                                                                    
00266  
00267     return result;                                                                                                                                       
00268 }
00269 
00270 extern int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len);
00271 
00272 int check_wnc_ready(void)
00273 {
00274     string * pRespStr;
00275     size_t pos;
00276     int regSts;
00277     int cmdRes1, cmdRes2;
00278 
00279 #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00280     PUTS("<-------- Begin Cell Status ------------\r\n");
00281 #endif
00282     cmdRes1 = at_send_wnc_cmd("AT+CSQ", &pRespStr, WNC_TIMEOUT_MS);       // Check RSSI,BER
00283     cmdRes2 = at_send_wnc_cmd("AT+CPIN?", &pRespStr, WNC_TIMEOUT_MS);      // Check if SIM locked
00284     
00285     if ((cmdRes1 != 0) && (cmdRes2 != 0))
00286     {
00287 #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00288         PUTS("------------ WNC No Response! --------->\r\n");
00289 #endif
00290         return (-2);      
00291     }
00292   
00293     // If SIM Card not ready don't bother with commands!
00294     if (pRespStr->find("CPIN: READY") == string::npos)
00295     {
00296 #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00297         PUTS("------------ WNC SIM Problem! --------->\r\n");
00298 #endif
00299         return (-1);
00300     }
00301   
00302     // SIM card OK, now check for signal and cellular network registration
00303     cmdRes1 = at_send_wnc_cmd("AT+CREG?", &pRespStr, WNC_TIMEOUT_MS);      // Check if registered on network
00304     if (pRespStr->size() > 0)
00305     {
00306     pos = pRespStr->find("CREG: ");
00307     if (pos != string::npos)
00308     {
00309         // The registration is the 2nd arg in the comma separated list
00310         *pRespStr = pRespStr->substr(pos+8, 1);
00311         regSts = atoi(pRespStr->c_str());
00312         // 1 - registered home, 5 - registered roaming
00313         if ((regSts != 1) && (regSts != 5))
00314         {
00315 #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00316             PUTS("------------ WNC Cell Link Down! ------>\r\n");
00317 #endif
00318             return (-2);
00319         }
00320     }
00321 
00322 #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00323     PUTS("------------ WNC Ready ---------------->\r\n");
00324 #endif
00325     }
00326     else
00327     {
00328 #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00329         PUTS("------------ CREG No Reply !----------->\r\n");
00330 #endif
00331         return (-2);
00332     }
00333 
00334     return (0);
00335 }
00336 
00337 // Sets a global with failure or success, assumes 1 thread all the time
00338 int send_wnc_cmd(const char * s, string ** r, int ms_timeout)
00339 {
00340   int cmdRes;
00341   
00342   if (check_wnc_ready() < 0)
00343   {
00344      static string noRespStr;
00345 
00346 #ifdef WNC_CMD_DEBUG_ON
00347      PUTS("FAIL send cmd: ");
00348      #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00349      PUTS(s);
00350      PUTS("\r\n");
00351      #else
00352      string truncStr(s, 50);
00353      truncStr += "\r\n";
00354      PUTS(truncStr.c_str());
00355      #endif
00356 #else
00357      PUTS("FAIL send cmd!\r\n");
00358 #endif
00359 
00360      WNC_MDM_ERR = WNC_CELL_LINK_DOWN;
00361      noRespStr.erase();
00362      *r = &noRespStr;
00363      return (-3);
00364   }
00365 
00366 #ifdef WNC_CMD_DEBUG_ON
00367   #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00368   PUTS("[---------- Network Status -------------\r\n");
00369   #endif
00370   string * pRespStr;
00371   at_send_wnc_cmd("AT@SOCKDIAL?", &pRespStr, 5000);
00372   #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00373   PUTS("---------------------------------------]\r\n");
00374   #endif
00375 #endif
00376 
00377   // If WNC ready, send user command
00378   cmdRes = at_send_wnc_cmd(s, r, ms_timeout);
00379   
00380   if (cmdRes == -1)
00381      WNC_MDM_ERR = WNC_CMD_ERR;
00382   
00383   if (cmdRes == -2)
00384      WNC_MDM_ERR = WNC_NO_RESPONSE;
00385      
00386   if (cmdRes == -3) {
00387      WNC_MDM_ERR = WNC_EXTERR;
00388      PRINTF("[[WNC_MDM_ERR = WNC_EXTERR]] \r\n");
00389   }
00390 
00391  if (cmdRes == 0)
00392      WNC_MDM_ERR = WNC_OK;
00393   
00394   return (cmdRes);
00395 }
00396 
00397 int at_send_wnc_cmd(const char * s, string ** r, int ms_timeout)
00398 {
00399    //Eaddy
00400   static const char * rsp_lst[] = { "OK", "ERROR","@EXTERR", "+CME", NULL };
00401   int len;
00402 
00403 #ifdef WNC_CMD_DEBUG_ON
00404   #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00405   
00406   #else
00407   if (strlen(s) > 60)
00408   {
00409       string truncStr(s,57);
00410       truncStr += "...";
00411       PRINTF("Send: <<%s>>\r\n",truncStr.c_str());
00412   }
00413   else
00414   #endif
00415       PRINTF("Send: <<%s>>\r\n",s);
00416 #endif
00417 
00418   int res = mdm_sendAtCmdRsp(s, rsp_lst, ms_timeout, &wncStr, &len);
00419   *r = &wncStr;   // Return a pointer to the static string
00420       
00421   if (res >= 0)
00422   {
00423 
00424 #ifdef WNC_CMD_DEBUG_ON   
00425       PUTS("[");
00426       #ifdef WNC_CMD_DEBUG_ON_VERBOSE
00427       PUTS(wncStr.c_str());
00428       PUTS("]\r\n");
00429       #else
00430       if (wncStr.size() < 51)
00431           PUTS(wncStr.c_str());
00432       else
00433       {
00434           string truncStr = wncStr.substr(0,50) + "...";
00435           PUTS(truncStr.c_str());
00436       }
00437       PUTS("]\r\n");
00438       #endif
00439 #endif
00440 
00441 #if 0
00442       if (res > 0)
00443           return -1;
00444       else
00445           return 0;
00446 #else
00447     //Eaddy added         
00448        if (res == 0) {
00449           /* OK */
00450           return 0;
00451       } else if (res == 2) {
00452           /* @EXTERR */
00453           PRINTF("@EXTERR and res = %d \r\n", res);
00454           return -3;
00455       } else
00456           return -1;
00457 #endif
00458   }
00459   else
00460   {
00461       PUTS("No response from WNC!\n\r");
00462       return -2;
00463   }
00464 }
00465 
00466 
00467 void at_at_wnc(void)
00468 {
00469     string * pRespStr;
00470     send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
00471 }
00472 
00473 void at_init_wnc(bool hardReset)
00474 {
00475   static bool pdnSet = false;
00476   static bool intSet = false;
00477   static bool sockDialSet = false;  
00478   string * pRespStr;
00479   int cmdRes;
00480   
00481   if (hardReset == true)
00482   {
00483       PUTS("Hard Reset!\r\n");
00484       pdnSet = false;
00485       intSet = false;
00486       sockDialSet = false;
00487   }
00488   
00489   PUTS("Start AT init of WNC:\r\n");
00490   // Quick commands below do not need to check cellular connectivity
00491   cmdRes = at_send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS);             // Heartbeat?
00492   cmdRes += at_send_wnc_cmd("ATE0", &pRespStr, WNC_TIMEOUT_MS);           // Echo Off
00493   cmdRes += at_send_wnc_cmd("AT+CMEE=2", &pRespStr, WNC_TIMEOUT_MS);      // 2 - verbose error, 1 - numeric error, 0 - just ERROR
00494   /* Disable unsolicited RRCSTATE responses from interfering with DNS 
00495    * resolution which was introduced with release of the 
00496    * NQ_MPSS_IMA3_v10.58.174043 LTE-M firmware and is a more elegant 
00497    * solution than disabling ALL unsoliceted responses as WNC suggested
00498    * in ticket 2017090085.
00499    */
00500   //cmdRes += at_send_wnc_cmd("AT%NOTIFYEV=\"RRCSTATE\",0", &pRespStr, WNC_TIMEOUT_MS);
00501   cmdRes += at_send_wnc_cmd("AT%NOTIFYEV=\"ALL\",0", &pRespStr, WNC_TIMEOUT_MS);
00502   
00503   // If the simple commands are not working no chance of more complex.
00504   //  I have seen re-trying commands make it worse.
00505   if (cmdRes < 0)
00506   {
00507       // Since I used the at_send_wnc_cmd I am setting the error state based upon
00508       //  the responses.  And since these are simple commands, even if the WNC
00509       //  is saying ERROR, treat it like a no response.
00510       WNC_MDM_ERR = WNC_NO_RESPONSE;
00511       return ;
00512   }
00513   
00514   if (intSet == false)
00515     cmdRes = send_wnc_cmd("AT@INTERNET=1", &pRespStr, WNC_TIMEOUT_MS);
00516   
00517   if (cmdRes == 0)
00518     intSet = true;
00519   else
00520     return ;
00521   
00522   if (pdnSet == false)
00523   {
00524     string cmd_str("AT%PDNSET=1,");
00525     cmd_str += MY_APN_STR;
00526     cmd_str += ",IP";
00527     cmdRes = send_wnc_cmd(cmd_str.c_str(), &pRespStr, 4*WNC_TIMEOUT_MS); // Set APN, cmd seems to take a little longer sometimes
00528   }
00529   
00530   if (cmdRes == 0)
00531     pdnSet = true;
00532   else
00533     return ;
00534   
00535   if (sockDialSet == false)
00536     cmdRes = send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, WNC_TIMEOUT_MS);
00537   
00538   if (cmdRes == 0)
00539     sockDialSet = true;
00540   else
00541     return ;
00542   
00543   PUTS("SUCCESS: AT init of WNC!\r\n");
00544 }
00545 
00546 void at_sockopen_wnc(const string & ipStr, const char * port )
00547 {
00548   string * pRespStr;
00549   send_wnc_cmd("AT@SOCKCREAT=1", &pRespStr, WNC_TIMEOUT_MS);
00550   string cmd_str("AT@SOCKCONN=1,\"");
00551   cmd_str += ipStr;
00552   cmd_str += "\",";
00553   cmd_str += port;
00554   cmd_str += ",30";
00555   int cmd = send_wnc_cmd(cmd_str.c_str(), &pRespStr, 31000);
00556   if (cmd != WNC_OK) {
00557       // Per WNC: re-close even if open fails!
00558       at_sockclose_wnc();
00559   }
00560 }
00561 
00562 void at_sockclose_wnc(void)
00563 {
00564   string * pRespStr;
00565   send_wnc_cmd("AT@SOCKCLOSE=1", &pRespStr, WNC_TIMEOUT_MS);
00566 }
00567 
00568 int at_dnsresolve_wnc(const char * s, string * ipStr)
00569 {
00570   string * pRespStr;
00571   string str(s);
00572   str = "AT@DNSRESVDON=\"" + str + "\"";
00573   if (send_wnc_cmd(str.c_str(), &pRespStr, 60000) == 0)
00574   {
00575     size_t pos_start = pRespStr->find("ON:\"");  // See there are 4 characters in the search string
00576     size_t pos_end = pRespStr->find("\"", (pos_start + 4));
00577     if ((pos_start !=  string::npos) && (pos_end != string::npos))
00578     {
00579         /* The substring identified was indeed located within the returned 
00580          * response.  Adjust the start position ahead by 2 and move the end
00581          * position back by l to narrow the answer down to to the response 
00582          * string contained within the quote bookends -->  ON:"<response>".
00583          */
00584         pos_start += 4;
00585         pos_end -= 1;
00586         
00587         if (pos_end > pos_start)
00588         {
00589           // Make a copy for use later (the source string is re-used)
00590           *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
00591           return 1;
00592         }
00593         else
00594           PUTS("URL Resolve fail, substr Err\r\n");
00595     }
00596     else
00597       PUTS("URL Resolve fail, no quotes\r\n");
00598   }
00599   else
00600     PUTS("URL Resolve fail, WNC cmd fail\r\n");
00601   
00602   *ipStr = "192.168.0.1";
00603   
00604   return -1;
00605 }
00606 
00607 void at_sockwrite_wnc(const char * s)
00608 {
00609   string * pRespStr;
00610   char num2str[6];
00611   size_t sLen = strlen(s);
00612   int res;
00613   if (sLen <= 1500)
00614   {
00615     string cmd_str("AT@SOCKWRITE=1,");
00616     itoa(sLen, num2str, 10);
00617     cmd_str += num2str;
00618     cmd_str += ",\"";
00619     while(*s != '\0')
00620     {
00621       itoa((int)*s++, num2str, 16);
00622       // Always 2-digit ascii hex:
00623       if (strlen(num2str) == 1)
00624       {
00625         num2str[2] = '\0';
00626         num2str[1] = num2str[0];
00627         num2str[0] = '0';
00628       }
00629       cmd_str += num2str;
00630     }
00631     cmd_str += "\"";
00632     res = send_wnc_cmd(cmd_str.c_str(), &pRespStr, 120000);
00633     if (res == -3)
00634         PUTS("sockwrite is disconnect \r\n");
00635   }
00636   else
00637     PUTS("sockwrite Err, string to long\r\n");
00638 }
00639 
00640 unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries = 0)
00641 {
00642   unsigned i, numBytes = 0;
00643   string * pRespStr;
00644   string cmd_str("AT@SOCKREAD=1,");
00645 
00646   // Clean slate
00647   pS->erase();
00648   
00649   if (n <= 1500)
00650   {
00651     char num2str[6];
00652     
00653     itoa(n, num2str, 10);
00654     cmd_str += num2str;
00655     retries += 1;
00656     while (retries--)
00657     {
00658       // Assuming someone is sending then calling this to receive response, invoke
00659       // a pause to give the response some time to come back and then also
00660       // between each retry.
00661       wait_ms(10);
00662       
00663       if (send_wnc_cmd(cmd_str.c_str(), &pRespStr, WNC_TIMEOUT_MS) == 0)
00664       {
00665         size_t pos_start = pRespStr->find("\"")  + 1;
00666         size_t pos_end   = pRespStr->rfind("\"") - 1;
00667       
00668         // Make sure search finds what it's looking for!
00669         if (pos_start != string::npos && pos_end != string::npos)
00670           i = (pos_end - pos_start + 1);  // Num hex chars, 2 per byte
00671         else
00672           i = 0;
00673           
00674         if (i > 0)
00675         {
00676             retries = 1;  // If any data found retry 1 more time to catch data that might be in another
00677                           //  WNC payload
00678             string byte;
00679             while (pos_start < pos_end)
00680             {
00681               byte = pRespStr->substr(pos_start, 2);
00682               *pS += (char)strtol(byte.c_str(), NULL, 16);
00683               pos_start += 2;
00684             }
00685             numBytes += i/2;
00686         }
00687       }
00688       else
00689       {
00690           PUTS("no readsock reply!\r\n");
00691           return (0);
00692       }
00693     }
00694   }
00695   else
00696     PUTS("sockread Err, to many to read\r\n");
00697   
00698   return (numBytes);
00699 }