This is library for using WizFi250

Dependents:   WebSocket_WizFi250_HelloWorld IFTTT_WizFi250 AxedaGo-WizFi250 FANARM_AP_udp_server ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WizFi250_msg.cpp Source File

WizFi250_msg.cpp

00001 /*
00002 /* Copyright (C) 2013 gsfan, MIT License
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00005  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00006  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00007  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00008  * furnished to do so, subject to the following conditions:
00009  *
00010  * The above copyright notice and this permission notice shall be included in all copies or
00011  * substantial portions of the Software.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00014  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00015  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00016  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00017  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00018  */
00019 /* Copyright (C) 2014 Wiznet, MIT License
00020  *  port to the Wiznet Module WizFi250
00021  */
00022 
00023 #include "WizFi250.h"
00024 
00025 #ifdef CFG_ENABLE_RTOS
00026 #undef WIZ_DBG
00027 #define WIZ_DBG(x, ...)
00028 #endif
00029 
00030 // This function is operating in ISR. So you can't use debug message.
00031 void WizFi250::recvData ( char c )
00032 {
00033     static int cid, sub, len, count;
00034 
00035     switch(_state.mode)
00036     {
00037         case MODE_COMMAND:
00038             switch(c)
00039             {
00040                 case 0:
00041                 case 0x0a:  // LF
00042                 case 0x0d:  // CR
00043                 break;
00044 
00045                 case '{':
00046                 _state.buf->flush();
00047                 _state.mode = MODE_DATA_RX;
00048                 sub = 0;
00049                 break;
00050 
00051                 default:
00052                 _state.buf->flush();
00053                 _state.buf->queue(c);
00054                 _state.mode = MODE_CMDRESP;
00055                 break;
00056             }
00057             break;
00058 
00059         case MODE_CMDRESP:
00060             switch(c)
00061             {
00062                 case 0:
00063                     break;
00064                 case 0x0a: // LF
00065                     break;
00066                 case 0x0d: // CR
00067                     if (_flow == 2) setRts(false);      // block
00068                     _state.mode = MODE_COMMAND;
00069                     parseMessage();
00070                     if (_flow == 2) setRts(true);       // release
00071                     break;
00072                 default:
00073                     _state.buf->queue(c);
00074                     break;
00075             }
00076             break;
00077 
00078         case MODE_DATA_RX:
00079             switch(sub)
00080             {
00081                 case 0:
00082                 // cid
00083                 if( (c >= '0') && (c <= '9') )
00084                 {
00085                     cid = x2i(c);
00086                 }
00087                 else if ( c == ',' )
00088                 {
00089                     sub++;
00090                     count = 0;
00091                     len = 0;
00092                 }
00093                 else
00094                 {
00095                     _state.mode = MODE_COMMAND;
00096                 }
00097                 break;
00098 
00099             case 1:
00100                 // ip
00101                 if ((c >= '0' && c <= '9') || c == '.')
00102                 {
00103                     _con[cid].ip[count] = c;
00104                     count++;
00105                 }
00106                 else if( c == ',' )
00107                 {
00108                     _con[cid].ip[count] = '\0';
00109                     _con[cid].port = 0;
00110                     sub++;
00111                 }
00112                 else
00113                 {
00114                     _state.mode = MODE_COMMAND;
00115                 }
00116                 break;
00117 
00118             case 2:
00119                 // port
00120                 if ( c >= '0' && c <= '9' )
00121                 {
00122                     _con[cid].port = (_con[cid].port * 10) + ( c - '0' );
00123                 }
00124                 else if( c == ',')
00125                 {
00126                     sub++;
00127                     count = 0;
00128                 }
00129                 else
00130                 {
00131                     _state.mode = MODE_COMMAND;
00132                 }
00133                 break;
00134 
00135             case 3:
00136                 // data length
00137                 if ( c >= '0' && c <= '9' )
00138                 {
00139                     //_con[cid].recv_length = (_con[cid].recv_length * 10) + (c - '0');
00140                     len = (len * 10) + (c - '0');
00141                 }
00142                 else if( c == '}' )
00143                 {
00144                     sub++;
00145                     count = 0;
00146                     _con[cid].recv_length = len;
00147                 }
00148                 else
00149                 {
00150                     _state.mode = MODE_COMMAND;
00151                 }
00152                 break;
00153 
00154             default:
00155                 if(_con[cid].buf != NULL)
00156                 {
00157                     _con[cid].buf->queue(c);
00158                     if(_con[cid].buf->available() > CFG_DATA_SIZE - 16 )
00159                     {
00160                         setRts(false);     // blcok
00161                         _con[cid].received = true;
00162                         WIZ_WARN("buf full");
00163                     }
00164                 }
00165                 _con[cid].recv_length--;
00166                 if(_con[cid].recv_length == 0)
00167                 {
00168                      //WIZ_DBG("recv cid: %d, count : %d, len : %d",cid, count, len);
00169                     _con[cid].received = true;
00170                     _state.mode = MODE_COMMAND;
00171                 }
00172                 break;
00173             }
00174             break;
00175     }
00176 }
00177 
00178 
00179 #define MSG_TABLE_NUM 6
00180 #define RES_TABLE_NUM 7
00181 int WizFi250::parseMessage () {
00182     int i;
00183     char buf[128];
00184 
00185     static const struct MSG_TABLE {
00186         const char msg[24];
00187         void (WizFi250::*func)(const char *);
00188     } msg_table[MSG_TABLE_NUM] = {
00189         {"[OK]",                    &WizFi250::msgOk},
00190         {"[ERROR]",                 &WizFi250::msgError},
00191         {"[ERROR:INVALIDINPUT]",    &WizFi250::msgError},
00192         {"[CONNECT ",               &WizFi250::msgConnect},
00193         {"[DISCONNECT ",            &WizFi250::msgDisconnect},
00194         {"[LISTEN ",                &WizFi250::msgListen},
00195     };
00196     static const struct RES_TABLE{
00197         const Response res;
00198         void (WizFi250::*func)(const char *);
00199     }res_table[RES_TABLE_NUM]={
00200         {RES_NULL,          NULL},
00201         {RES_MACADDRESS,    &WizFi250::resMacAddress},
00202 //      {RES_WJOIN,         &WizFi250::resWJOIN},
00203         {RES_CONNECT,       &WizFi250::resConnect},
00204         {RES_SSEND,         &WizFi250::resSSEND},
00205         {RES_FDNS,          &WizFi250::resFDNS},
00206         {RES_SMGMT,         &WizFi250::resSMGMT},
00207         {RES_WSTATUS,       &WizFi250::resWSTATUS},
00208     };
00209 
00210 
00211     for( i=0; i<sizeof(buf); i++ )
00212     {
00213         if( _state.buf->dequeue(&buf[i]) == false ) break;
00214     }
00215 
00216     buf[i] = '\0';
00217     //strncpy(_state.dbgRespBuf, buf, sizeof(buf) );
00218     //WIZ_DBG("%s\r\n",_state.dbgRespBuf);
00219 
00220     if(_state.res != RES_NULL)
00221     {
00222         for( i=0; i<RES_TABLE_NUM; i++)
00223         {
00224             if(res_table[i].res == _state.res)
00225             {
00226                 //WIZ_DBG("parse res %d '%s'\r\n", i, buf);
00227                 if(res_table[i].func != NULL)
00228                 {
00229                     (this->*(res_table[i].func))(buf);
00230                 }
00231 
00232                 if(res_table[i].res == RES_CONNECT && _state.n < 2)
00233                     return -1;
00234             }
00235         }
00236     }
00237 
00238     for( i=0; i<MSG_TABLE_NUM; i++)
00239     {
00240         if( strncmp(buf, msg_table[i].msg, strlen(msg_table[i].msg)) == 0 )
00241         {
00242             //WIZ_DBG("parse msg '%s'\r\n", buf);
00243             if(msg_table[i].func != NULL)
00244             {
00245                 (this->*(msg_table[i].func))(buf);
00246             }
00247             return 0;
00248         }
00249     }
00250 
00251     return -1;
00252 }
00253 
00254 
00255 void WizFi250::msgOk (const char *buf)
00256 {
00257     _state.ok = true;
00258 }
00259 
00260 void WizFi250::msgError (const char *buf)
00261 {
00262     _state.failure = true;
00263 }
00264 
00265 void WizFi250::msgConnect (const char *buf)
00266 {
00267     int cid;
00268 
00269     if (buf[9] < '0' || buf[9] > '8' || buf[10] != ']') return;
00270 
00271     cid = x2i(buf[9]);
00272 
00273     initCon(cid, true);
00274     _state.cid = cid;
00275     _con[cid].accept = true;
00276     _con[cid].parent = cid;
00277 }
00278 
00279 void WizFi250::msgDisconnect (const char *buf)
00280 {
00281     int cid;
00282 
00283     if(buf[12] < '0' || buf[12] > '8' || buf[13] != ']')    return;
00284 
00285     cid = x2i(buf[12]);
00286     _con[cid].connected = false;
00287 }
00288 
00289 void WizFi250::msgListen (const char *buf)
00290 {
00291     int cid;
00292 
00293     if(buf[8] < '0' || buf[8] > '8' || buf[9] != ']')   return;
00294 
00295     cid = x2i(buf[8]);
00296     _state.cid = cid;
00297 }
00298 
00299 void WizFi250::resMacAddress (const char *buf)
00300 {
00301     if( buf[2] == ':' && buf[5] == ':')
00302     {
00303         strncpy(_state.mac, buf, sizeof(_state.mac));
00304         _state.mac[17] = 0;
00305         _state.res = RES_NULL;
00306 
00307         if(strncmp(_state.mac,CFG_DEFAULT_MAC,sizeof(CFG_DEFAULT_MAC)) == 0)
00308             _state.ok = false;
00309         _state.ok = true;
00310     }
00311 }
00312 
00313 void WizFi250::resConnect (const char *buf)
00314 {
00315     int cid;
00316 
00317     if (buf[0] == '[' && buf[1] == 'O' && buf[2] == 'K' && buf[3] == ']')
00318     {
00319         _state.n++;
00320     }
00321     else if( buf[0] == '[' && buf[1] == 'C' && buf[2] == 'O' && buf[3] == 'N' &&
00322               buf[4] == 'N' && buf[5] == 'E' && buf[6] == 'C' && buf[7] == 'T')
00323     {
00324         cid = x2i(buf[9]);
00325         _state.cid = cid;
00326         _state.n++;
00327     }
00328 
00329     if(_state.n >= 2)
00330     {
00331         _state.res = RES_NULL;
00332         _state.ok = true;
00333     }
00334 }
00335 
00336 void WizFi250::resSSEND (const char *buf)
00337 {
00338     if(_state.cid != -1)
00339     {
00340         _state.res = RES_NULL;
00341         _state.ok = true;
00342     }
00343 }
00344 
00345 void WizFi250::resFDNS (const char *buf)
00346 {
00347     int i;
00348 
00349     for(i=0; i<strlen(buf); i++)
00350     {
00351         if( (buf[i] < '0' || buf[i] > '9') && buf[i] != '.' )
00352         {
00353             return;
00354         }
00355     }
00356 
00357     strncpy(_state.resolv, buf, sizeof(_state.resolv));
00358     _state.res = RES_NULL;
00359 }
00360 
00361 void WizFi250::resSMGMT (const char *buf)
00362 {
00363     int cid, i;
00364     char *c;
00365 
00366     if( (buf[0] < '0' || buf[0] > '8') )    return;
00367 
00368     cid = x2i(buf[0]);
00369     if( cid != _state.cid )                 return;
00370 
00371     // IP
00372     c = (char*)(buf+6);
00373     for( i=0; i<16; i++ )
00374     {
00375         if( *(c+i) == ':')
00376         {
00377             _con[cid].ip[i] = '\0';
00378             i++;
00379             break;
00380         }
00381         if( ( *(c+i) < '0' || *(c+i) > '9') && *(c+i) != '.' )  return;
00382         _con[cid].ip[i] = *(c+i);
00383     }
00384 
00385     // Port
00386     c = (c+i);
00387     _con[cid].port = 0;
00388     for( i=0; i<5; i++ )
00389     {
00390         if( *(c+i) == '/')                  break;
00391         if( *(c+i) < '0' || *(c+i) > '9' )  return;
00392 
00393         _con[cid].port = (_con[cid].port * 10) + ( *(c+i) - '0' );
00394     }
00395 
00396     _state.res = RES_NULL;
00397 }
00398 
00399 void WizFi250::resWSTATUS (const char *buf)
00400 {
00401     int idx=0,sep_cnt=0;
00402     int ip_idx=0,gw_idx=0;
00403 
00404     if(_state.n == 0)
00405     {
00406         _state.n++;
00407     }
00408     else if(_state.n == 1)
00409     {
00410         for(idx=0;buf[idx]!='\r';idx++)
00411         {
00412             if(buf[idx] =='/')
00413             {
00414                 sep_cnt++;
00415                 continue;
00416             }
00417 
00418             if( sep_cnt == 2)    // IP Address
00419             {
00420                 _state.ip[ip_idx++] = buf[idx];
00421             }
00422             else if(sep_cnt == 3)
00423             {
00424                 _state.gateway[gw_idx++] = buf[idx];
00425             }
00426         }
00427         _state.ip[ip_idx] = '\0';
00428         _state.gateway[gw_idx] = '\0';
00429         _state.res = RES_NULL;
00430     }
00431 }