ThingPlug Test

Dependents:   WizFi310_ThingPlug_Test WizFi310_ThingPlug_Test_P

Fork of WizFi310Interface by WIZnet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WizFi310_msg.cpp Source File

WizFi310_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 WizFi310
00021  */
00022 
00023 #include "WizFi310.h"
00024 
00025 #ifdef CFG_ENABLE_RTOS
00026 #undef WIZ_DBG
00027 #define WIZ_DBG(x, ...)
00028 #endif
00029 
00030 //daniel
00031 char g_asyncbuf[256];
00032 
00033 // This function is operating in ISR. So you can't use debug message.
00034 void WizFi310::recvData ( char c )
00035 {
00036     static int cid, sub, len, count;
00037     static int is_mqtt_data = 0;
00038     char tbf[10];
00039     
00040     switch(_state.mode)
00041     {
00042         case MODE_COMMAND:
00043             switch(c)
00044             {
00045                 case 0:
00046                 case 0x0a:  // LF
00047                 case 0x0d:  // CR
00048                 break;
00049 
00050                 case '{':
00051                 _state.buf->flush();
00052                 _state.mode = MODE_DATA_RX;
00053                 sub = 0;
00054                 break;
00055 
00056                 default:
00057                 _state.buf->flush();
00058                 _state.buf->queue(c);
00059                 _state.mode = MODE_CMDRESP;
00060                 break;
00061             }
00062             break;
00063 
00064         case MODE_CMDRESP:
00065             switch(c)
00066             {
00067                 case 0:
00068                     break;
00069                 case 0x0a: // LF
00070                     break;
00071                 case 0x0d: // CR
00072                     if (_flow == 2) setRts(false);      // block
00073                     _state.mode = MODE_COMMAND;
00074                     parseMessage();
00075                     if (_flow == 2) setRts(true);       // release
00076                     break;
00077                 default:
00078                     _state.buf->queue(c);
00079                     break;
00080             }
00081             break;
00082 
00083         case MODE_DATA_RX:
00084             
00085             switch(sub)
00086             {
00087                 case 0:
00088                 // cid
00089                 if( (c >= '0') && (c <= '9') )
00090                 {
00091                     cid = x2i(c);
00092                 }
00093                 else if ( c == ',' )
00094                 {
00095                     sub++;
00096                     count = 0;
00097                     len = 0;
00098                 }
00099                 //daniel add for mqtt
00100                 else if ( c == 'Q' )
00101                 {
00102                     cid = 0;
00103                     is_mqtt_data = 1;
00104                 }
00105                 //
00106                 else
00107                 {
00108                     _state.mode = MODE_COMMAND;
00109                 }
00110                 break;
00111 
00112             case 1:
00113                 // ip                
00114 //                if ((c >= '0' && c <= '9') || c == '.')
00115                 if (((c >= '0' && c <= '9') || c == '.') && is_mqtt_data == 0 )
00116                 {
00117                     _con[cid].ip[count] = c;
00118                     count++;
00119                 }
00120                 else if( c == ',' )
00121                 {
00122                     _con[cid].ip[count] = '\0';
00123                     _con[cid].port = 0;
00124                     sub++;
00125                 }
00126                 //daniel for mqtt
00127                 else if( is_mqtt_data == 1)
00128                 {
00129                     rcvd_mqtt_topic[count] = c;
00130                     count++;
00131                 }
00132 //              else 
00133                 else if( is_mqtt_data == 0 )
00134                 {
00135                     _state.mode = MODE_COMMAND;
00136                 }
00137                 break;
00138 
00139             case 2:
00140                 // port
00141                 if ( c >= '0' && c <= '9' )
00142                 {
00143                     _con[cid].port = (_con[cid].port * 10) + ( c - '0' );
00144                 }
00145                 else if( c == ',')
00146                 {
00147                     sub++;
00148                     count = 0;
00149                 }
00150                 else
00151                 {
00152                     _state.mode = MODE_COMMAND;
00153                 }
00154                 break;
00155 
00156             case 3:
00157                 // data length
00158                 if ( c >= '0' && c <= '9' )
00159                 {
00160                     //_con[cid].recv_length = (_con[cid].recv_length * 10) + (c - '0');
00161                     len = (len * 10) + (c - '0');
00162                 }
00163                 else if( c == '}' )
00164                 {
00165                     sub++;
00166                     count = 0;
00167                     _con[cid].recv_length = len;
00168                 }
00169                 else
00170                 {
00171                     _state.mode = MODE_COMMAND;
00172                 }
00173                 break;
00174 
00175             default:
00176 
00177                 if(_con[cid].buf != NULL)
00178                 {
00179                     _con[cid].buf->queue(c);
00180                     if(_con[cid].buf->available() > CFG_DATA_SIZE - 16 )
00181                     {
00182                         setRts(false);     // blcok
00183                         _con[cid].received = true;
00184                         WIZ_WARN("buf full");
00185                     }
00186                 }
00187                 _con[cid].recv_length--;
00188                 if(_con[cid].recv_length == 0)
00189                 {
00190                      //WIZ_DBG("recv cid: %d, count : %d, len : %d",cid, count, len);
00191                      //sprintf(tbf, "recv cid: %d, count : %d, len : %d",cid, count, len);
00192                      //strcat(g_asyncbuf, tbf);
00193                     _con[cid].received = true;
00194                     _state.mode = MODE_COMMAND;
00195                 }
00196                 break;
00197             }
00198             break;
00199     }
00200 }
00201 
00202 
00203 //#define MSG_TABLE_NUM 6
00204 //daniel
00205 #define MSG_TABLE_NUM 8
00206 #define RES_TABLE_NUM 7
00207 int WizFi310::parseMessage () {
00208     int i;
00209     char buf[128];
00210 
00211     static const struct MSG_TABLE {
00212         const char msg[24];
00213         void (WizFi310::*func)(const char *);
00214     } msg_table[MSG_TABLE_NUM] = {
00215         {"[OK]",                    &WizFi310::msgOk},
00216         {"[ERROR]",                 &WizFi310::msgError},
00217         {"[ERROR:INVALIDINPUT]",    &WizFi310::msgError},
00218         {"[CONNECT ",               &WizFi310::msgConnect},
00219         {"[DISCONNECT ",            &WizFi310::msgDisconnect},
00220         {"[LISTEN ",                &WizFi310::msgListen},
00221         //daniel
00222         {"[MQTT CONNECT]",               &WizFi310::msgMQTTConnect},
00223         {"[MQTT DISCONNECT]",               &WizFi310::msgMQTTDisconnect},
00224     };
00225     static const struct RES_TABLE{
00226         const Response res;
00227         void (WizFi310::*func)(const char *);
00228     }res_table[RES_TABLE_NUM]={
00229         {RES_NULL,          NULL},
00230         {RES_MACADDRESS,    &WizFi310::resMacAddress},
00231 //      {RES_WJOIN,         &WizFi310::resWJOIN},
00232         {RES_CONNECT,       &WizFi310::resConnect},
00233         {RES_SSEND,         &WizFi310::resSSEND},
00234         {RES_FDNS,          &WizFi310::resFDNS},
00235         {RES_SMGMT,         &WizFi310::resSMGMT},
00236         {RES_WSTATUS,       &WizFi310::resWSTATUS},
00237     };
00238 
00239 
00240     for( i=0; i<sizeof(buf); i++ )
00241     {
00242         if( _state.buf->dequeue(&buf[i]) == false ) break;
00243     }
00244 
00245     buf[i] = '\0';
00246     //strncpy(_state.dbgRespBuf, buf, sizeof(buf) );
00247     //WIZ_DBG("%s\r\n",_state.dbgRespBuf);
00248 
00249     if(_state.res != RES_NULL)
00250     {
00251         for( i=0; i<RES_TABLE_NUM; i++)
00252         {
00253             if(res_table[i].res == _state.res)
00254             {
00255                 //WIZ_DBG("parse res %d '%s'\r\n", i, buf);
00256                 if(res_table[i].func != NULL)
00257                 {
00258                     (this->*(res_table[i].func))(buf);
00259                 }
00260 
00261                 if(res_table[i].res == RES_CONNECT && _state.n < 2)
00262                     return -1;
00263             }
00264         }
00265     }
00266 
00267     for( i=0; i<MSG_TABLE_NUM; i++)
00268     {
00269         if( strncmp(buf, msg_table[i].msg, strlen(msg_table[i].msg)) == 0 )
00270         {
00271             //WIZ_DBG("parse msg '%s'\r\n", buf);
00272             if(msg_table[i].func != NULL)
00273             {
00274                 (this->*(msg_table[i].func))(buf);
00275             }
00276             return 0;
00277         }
00278     }
00279 
00280     return -1;
00281 }
00282 
00283 
00284 void WizFi310::msgOk (const char *buf)
00285 {
00286     _state.ok = true;
00287 }
00288 
00289 void WizFi310::msgError (const char *buf)
00290 {
00291     _state.failure = true;
00292 }
00293 
00294 void WizFi310::msgConnect (const char *buf)
00295 {
00296     int cid;
00297 
00298     if (buf[9] < '0' || buf[9] > '8' || buf[10] != ']') return;
00299 
00300     cid = x2i(buf[9]);
00301 
00302     initCon(cid, true);
00303     _state.cid = cid;
00304     _con[cid].accept = true;
00305     _con[cid].parent = cid;
00306 }
00307 
00308 void WizFi310::msgDisconnect (const char *buf)
00309 {
00310     int cid;
00311 
00312     if(buf[12] < '0' || buf[12] > '8' || buf[13] != ']')    return;
00313 
00314     cid = x2i(buf[12]);
00315     _con[cid].connected = false;
00316 }
00317 
00318 
00319 void WizFi310::msgMQTTConnect (const char *buf)
00320 {
00321     int cid = 0;
00322 
00323     //if (buf[9] < '0' || buf[9] > '8' || buf[10] != ']') return;
00324 
00325     //cid = x2i(buf[9]);
00326     initCon(cid, true);
00327     _state.cid = cid;
00328     _con[cid].accept = true;
00329     _con[cid].parent = cid;
00330     
00331     _con[cid].connected = true;
00332     _state.res = RES_NULL;
00333     _state.ok = true;
00334 }
00335 
00336 void WizFi310::msgMQTTDisconnect (const char *buf)
00337 {
00338     int cid = 0;
00339 
00340     //if(buf[12] < '0' || buf[12] > '8' || buf[13] != ']')    return;
00341 
00342     //cid = x2i(buf[12]);
00343     _con[cid].connected = false;
00344 }
00345 
00346 
00347 void WizFi310::msgListen (const char *buf)
00348 {
00349     int cid;
00350 
00351     if(buf[8] < '0' || buf[8] > '8' || buf[9] != ']')   return;
00352 
00353     cid = x2i(buf[8]);
00354     _state.cid = cid;
00355 }
00356 
00357 void WizFi310::resMacAddress (const char *buf)
00358 {
00359     if( buf[2] == ':' && buf[5] == ':')
00360     {
00361         strncpy(_state.mac, buf, sizeof(_state.mac));
00362         _state.mac[17] = 0;
00363         _state.res = RES_NULL;
00364 
00365         if(strncmp(_state.mac,CFG_DEFAULT_MAC,sizeof(CFG_DEFAULT_MAC)) == 0)
00366             _state.ok = false;
00367         _state.ok = true;
00368     }
00369 }
00370 
00371 void WizFi310::resConnect (const char *buf)
00372 {
00373     int cid;
00374 
00375     if (buf[0] == '[' && buf[1] == 'O' && buf[2] == 'K' && buf[3] == ']')
00376     {
00377         _state.n++;
00378     }
00379     else if( buf[0] == '[' && buf[1] == 'C' && buf[2] == 'O' && buf[3] == 'N' &&
00380               buf[4] == 'N' && buf[5] == 'E' && buf[6] == 'C' && buf[7] == 'T')
00381     {
00382         cid = x2i(buf[9]);
00383         _state.cid = cid;
00384         _state.n++;
00385     }
00386 
00387     if(_state.n >= 2)
00388     {
00389         _state.res = RES_NULL;
00390         _state.ok = true;
00391     }
00392 }
00393 
00394 void WizFi310::resSSEND (const char *buf)
00395 {
00396     if(_state.cid != -1)
00397     {
00398         _state.res = RES_NULL;
00399         _state.ok = true;
00400     }
00401 }
00402 
00403 void WizFi310::resFDNS (const char *buf)
00404 {
00405     int i;
00406 
00407     for(i=0; i<strlen(buf); i++)
00408     {
00409         if( (buf[i] < '0' || buf[i] > '9') && buf[i] != '.' )
00410         {
00411             return;
00412         }
00413     }
00414 
00415     strncpy(_state.resolv, buf, sizeof(_state.resolv));
00416     _state.res = RES_NULL;
00417 }
00418 
00419 void WizFi310::resSMGMT (const char *buf)
00420 {
00421     int cid, i;
00422     char *c;
00423 
00424     if( (buf[0] < '0' || buf[0] > '8') )    return;
00425 
00426     cid = x2i(buf[0]);
00427     if( cid != _state.cid )                 return;
00428 
00429     // IP
00430     c = (char*)(buf+6);
00431     for( i=0; i<16; i++ )
00432     {
00433         if( *(c+i) == ':')
00434         {
00435             _con[cid].ip[i] = '\0';
00436             i++;
00437             break;
00438         }
00439         if( ( *(c+i) < '0' || *(c+i) > '9') && *(c+i) != '.' )  return;
00440         _con[cid].ip[i] = *(c+i);
00441     }
00442 
00443     // Port
00444     c = (c+i);
00445     _con[cid].port = 0;
00446     for( i=0; i<5; i++ )
00447     {
00448         if( *(c+i) == '/')                  break;
00449         if( *(c+i) < '0' || *(c+i) > '9' )  return;
00450 
00451         _con[cid].port = (_con[cid].port * 10) + ( *(c+i) - '0' );
00452     }
00453 
00454     _state.res = RES_NULL;
00455 }
00456 
00457 void WizFi310::resWSTATUS (const char *buf)
00458 {
00459     int idx=0,sep_cnt=0;
00460     int ip_idx=0,gw_idx=0;
00461 
00462     if(_state.n == 0)
00463     {
00464         _state.n++;
00465     }
00466     else if(_state.n == 1)
00467     {
00468         for(idx=0;buf[idx]!='\r';idx++)
00469         {
00470             if(buf[idx] =='/')
00471             {
00472                 sep_cnt++;
00473                 continue;
00474             }
00475 
00476             if( sep_cnt == 2)    // IP Address
00477             {
00478                 _state.ip[ip_idx++] = buf[idx];
00479             }
00480             else if(sep_cnt == 3)
00481             {
00482                 _state.gateway[gw_idx++] = buf[idx];
00483             }
00484         }
00485         _state.ip[ip_idx] = '\0';
00486         _state.gateway[gw_idx] = '\0';
00487         _state.res = RES_NULL;
00488     }
00489 }