Implementation of the WifiPlusClick hardware module.

Dependents:   WifiPlusKlickExample

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Wifi.cpp Source File

Wifi.cpp

00001 /* Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 #include "mbed.h"
00019 #include "Wifi.h"
00020 #include "DnsQuery.h"
00021 
00022 #define DEBUG
00023 #include "debug.h"
00024 
00025 #define LOBYTE(x)       ((x)&0xFF)
00026 #define HIBYTE(x)       (((x)>>8)&0xFF)
00027 
00028 static Wifi::RX_STATE_t   state = Wifi::Idle;
00029 static int ResponseType = 0;
00030 static int DataLen = 0;
00031 static int DataPtr = 0;
00032 
00033 Wifi* Wifi::_Wifi = NULL;
00034   
00035 
00036 Wifi::Wifi(PinName tx, PinName rx, PinName rst)
00037     : m_wifi(tx, rx), m_reset(rst), m_msgReceived(false), m_ackReceived(false), m_bWifiConnected(false), m_WifiConnectionError(NoFailure), m_lastError(NoError)
00038     , m_bScanResultsReady(false), m_NumLastScanResults(0)
00039 {
00040     _Wifi = this;
00041     m_reset = 1;
00042     m_wifi.baud(115200);
00043     m_wifi.format(8, Serial::None, 2);
00044 
00045     m_buffer = new char [1024];
00046 
00047     if (m_buffer == NULL) {
00048         ERR("Failed to allocate buffer !");
00049         error("WIFI");
00050     }
00051     
00052     m_wifi.attach(this, &Wifi::rx_int);
00053 }
00054 
00055 void Wifi::Reset()
00056 {
00057     m_reset = 0;
00058     wait(0.2);
00059     m_msgReceived = 0;
00060     m_ackReceived = false;
00061     m_bWifiConnected = false;
00062     m_WifiConnectionError = NoFailure;
00063     state = Idle;
00064     m_reset = 1;
00065     wait(0.2);
00066 }
00067 
00068 void Wifi::SendCommand(CMD_MSG_t cmd, int msgDataLen1, char* pData1, int msgDataLen2, char* pData2)
00069 {
00070     //  Wifi Plus Click has little endian format (means LSB comes first)
00071     //  btw. MBED is also little endian format
00072     //  Send Header
00073     m_wifi.putc(0x55);
00074     m_wifi.putc(0xAA);
00075     //  Send Message Command
00076     m_wifi.putc( LOBYTE((short)cmd) );
00077     m_wifi.putc( HIBYTE((short)cmd) );
00078     //  Send Message Data1 Length
00079     m_wifi.putc( LOBYTE((short)msgDataLen1+msgDataLen2) );
00080     m_wifi.putc( HIBYTE((short)msgDataLen1+msgDataLen2) );
00081     
00082     //  Send Data1
00083     if ((msgDataLen1 > 0) && (pData1 != NULL)) {
00084         for (int i = 0 ; i < msgDataLen1 ; i++) {
00085             m_wifi.putc(pData1[i]);
00086         }
00087     }
00088     //  Send Data2
00089     if ((msgDataLen2 > 0) && (pData2 != NULL)) {
00090         for (int i = 0 ; i < msgDataLen2 ; i++) {
00091             m_wifi.putc(pData2[i]);
00092         }
00093     }
00094     
00095     //  Reset Acknowledge Recevied flag
00096     m_ackReceived = false;
00097     m_lastError = NoError;
00098     //  Send Trailer
00099     m_wifi.putc(0x45);
00100 }
00101     
00102 void Wifi::rx_int()
00103 {
00104     char c = m_wifi.getc();
00105 
00106     switch (state) {
00107         case    Idle:
00108             if (c == 0x55) {
00109                 state = Header1_received;
00110             } else {
00111                 if (c == 0x00) {
00112                     m_ackReceived = true;
00113                     INFO("ACK");
00114                 } else {
00115                     INFO("c = 0x%02x", c);
00116                 }
00117             }
00118             break;
00119         case    Header1_received:
00120             if (c == 0xAA) {
00121                 state = Header2_received;
00122                 ResponseType = 0;
00123                 DataLen = 0;
00124             } else {
00125                 if (c == 0x55) {
00126                     state = Header1_received;
00127                 } else {
00128                     state = Idle;
00129                 }
00130             }
00131             break;
00132         case    Header2_received:
00133             ResponseType = c;
00134             state = MessageType_low_received;
00135             break;
00136         case    MessageType_low_received:
00137             ResponseType |= (((short)c)<<8);
00138             state = MessageType_high_received;
00139             break;
00140         case    MessageType_high_received:
00141             DataLen = c;
00142             state = DataLen_low_received;
00143             break;
00144         case    DataLen_low_received:
00145             DataLen |= (((short)c)<<8);
00146             if (DataLen == 0) {
00147                 state = Awaiting_trailer;
00148             } else {
00149                 DataPtr = 0;
00150                 state = Data_receiving;
00151             }
00152             break;
00153         case    Data_receiving:
00154             m_buffer[DataPtr++] = c;
00155             if (DataPtr == DataLen) {
00156                 state = Awaiting_trailer;
00157             }
00158             break;
00159         case Awaiting_trailer:
00160             if (c != 0x45) {
00161                 ERR("Trailer information received is incorrect !");
00162                 ERR("Full Message : ");
00163                 ERR("Response Type : 0x%02x", ResponseType);
00164                 for ( int i = 0; i < DataPtr++ ; i++) {
00165                     ERR ("0x%02x", m_buffer[i]);
00166                 }
00167                 ERR("Trailer : 0x%02x", c);
00168             } else {
00169                 //  Complete Message received, so submit it for processing
00170                 SubmitResponse((RSP_MSG_t)ResponseType, DataLen);
00171             }
00172             state = Idle;
00173             break;
00174         default:
00175             state = Idle;
00176     }
00177 }
00178 
00179 void Wifi::SubmitResponse(RSP_MSG_t rsp, int msgLen)
00180 {
00181     //  Check if Event was received
00182     if (rsp == EVENT_MSG) {
00183         INFO("EVENT !!!!");
00184         switch( m_buffer[0] ) {
00185             case Event_IP_Address_Assigned :
00186                 //  IP Address assigned, set the IP Address
00187                 m_ipAddress.sin_addr.o1 = m_buffer[2];
00188                 m_ipAddress.sin_addr.o2 = m_buffer[3];
00189                 m_ipAddress.sin_addr.o3 = m_buffer[4];
00190                 m_ipAddress.sin_addr.o4 = m_buffer[5];
00191                 INFO("NEW IPADDRESS SET !");
00192                 return;
00193             case Event_WiFi_Connection_Status_Changed :
00194                 if ((m_buffer[1] == 1) || (m_buffer[1] == 4)) {
00195                     m_bWifiConnected = true;
00196                     m_WifiConnectionError = NoFailure;
00197                     INFO("EVENT      WIFI CONNECTED !");
00198                     DigitalOut led2(LED2);
00199                     led2 = 1;
00200                 } else {
00201                     DigitalOut led2(LED2);
00202                     led2 = 0;
00203                     m_bWifiConnected = false;
00204                     m_WifiConnectionError = (CONN_ERROR_t)m_buffer[2];
00205                     if (m_buffer[1] != 2) {
00206                         m_WifiConnectionError = (CONN_ERROR_t)((char)m_WifiConnectionError+20);
00207                         DigitalOut led3(LED3);
00208                         led3 = 1;
00209                         
00210                     }
00211                     INFO("EVENT     WIFI DISCONNECTED !");
00212                 }
00213                 return;
00214             case Event_Error_Event :
00215                 INFO("ERROR EVENT %d (%d, %d, %d, %d) !", *((short*)&m_buffer[2]), m_buffer[4], m_buffer[5], m_buffer[6], m_buffer[7]);
00216                 m_lastError = (ERR_t)*((short*)&m_buffer[2]);
00217                 return ;
00218             case Event_WiFi_Scan_Results_Ready :
00219                 m_NumLastScanResults = m_buffer[1];
00220                 INFO("SCAN RESULTS (#%d) READY !", m_NumLastScanResults);
00221                 m_bScanResultsReady = true;
00222                 return ;
00223             default:
00224                 INFO("EVT %d", m_buffer[0])
00225                 break;
00226         }
00227     } 
00228 
00229     if (m_msgReceived) {
00230         ERR("BUFFER FULL !");
00231     }
00232     m_msgResponse = rsp;
00233     m_msgDataLen = msgLen;
00234     m_msgReceived = true;
00235     INFO("Message received (%d)", rsp);
00236 }
00237 
00238 
00239 bool Wifi::WaitMessage(RSP_MSG_t msg, int timeout)
00240 {
00241     Timer t;
00242     
00243     t.start();
00244     
00245     while(t.read_ms() < timeout) {
00246         if (m_msgReceived) {
00247             //  Successfully received a message
00248             if (m_msgResponse == msg) {
00249                 //  Successfull received correct message
00250                 m_msgReceived = false;
00251                 return true;
00252             } else {
00253                 //  Not the message we wanted to hear, so wait for next one
00254                 m_msgReceived = false;
00255             }
00256         }
00257     }
00258     
00259     //  Timeout
00260     return false;
00261 }
00262 
00263 bool Wifi::WaitEvent(EVT_MSG_t evt, int timeout)
00264 {
00265     Timer t;
00266     
00267     t.start();
00268     
00269     while(t.read_ms() < timeout) {
00270         if (m_msgReceived) {
00271             //  Successfully received a message
00272             if ((m_msgResponse == EVENT_MSG) && (m_buffer[0] == evt)) {
00273                 //  Successfull received correct message
00274                 m_msgReceived = false;
00275                 return true;
00276             } else {
00277                 //  Not the message or eventwe wanted to hear, so wait for next one
00278                 m_msgReceived = false;
00279             }
00280         }
00281     }
00282     
00283     //  Timeout
00284     return false;
00285 }
00286 
00287 bool Wifi::WaitAck(int timeout)
00288 {
00289     Timer t;
00290     
00291     t.start();
00292     
00293     while(t.read_ms() < timeout) {
00294         if (m_ackReceived) {
00295             INFO("ACK after %d ms", t.read_ms());
00296             m_ackReceived = false;
00297             return true;
00298         }
00299     }
00300     
00301     return false;
00302 }
00303 
00304 
00305 
00306 
00307 bool Wifi::ResetMsg()
00308 {
00309     bool bRetVal = false;
00310     
00311     INFO("SENDING RESET_MSG");
00312     SendCommand(RESET_MSG, 0, NULL);
00313 
00314     if (WaitMessage (ACK_MSG, 1000)) {
00315         //  Now wait for the Startup Event
00316         
00317         if (WaitEvent (Event_Startup_Event, 10000)) {
00318             //  Startup Event received
00319             bRetVal = true;
00320             INFO("Successfully Reset the device !");
00321             INFO("Startup condition : 0x%02d", m_buffer[1]);
00322         } else {
00323             ERR("Did not receive a startup event from device after reset !");
00324         }
00325     } else {
00326         ERR("Did not get acknowledge from WifiPlusClick Board !");
00327     }
00328     
00329     return bRetVal;
00330 }
00331 
00332 bool Wifi::GetVersionMsg(char &sw_ver_lo, char &sw_ver_hi, char &rad_ver_lo, char &rad_ver_hi)
00333 {
00334     bool bRetVal = false;
00335     
00336     INFO("SENDING GET_VERSION_MSG");
00337     SendCommand(GET_VERSION_MSG, 0, NULL);
00338     
00339     if (WaitAck (1000)) {
00340         //  Now wait for the asynchroneous Startup Event
00341         
00342         if (WaitEvent (Event_Startup_Event, 2000)) {
00343             //  Startup Event received
00344             bRetVal = true;
00345             sw_ver_hi = m_buffer[3];
00346             sw_ver_lo = m_buffer[2];
00347             rad_ver_hi = m_buffer[5];
00348             rad_ver_lo = m_buffer[4];
00349         } else {
00350             ERR("Did not receive an answer event from device after GET_VERSION_MSG !");
00351         }
00352     } else {
00353         ERR("Did not get acknowledge from WifiPlusClick Board !");
00354     }
00355     
00356     return bRetVal;
00357 }
00358 
00359 bool Wifi::GpioMsg(GPIO_IDX_t pin, GPIO_OP_t operation, GPIO_RES_t &result)
00360 {
00361     char buf[2] = { (char)pin, (char)operation };
00362     bool bRetVal = false;
00363     
00364     INFO("SENDING GPIO_MSG");
00365     SendCommand(GPIO_MSG, 2, buf);
00366     
00367     if (WaitMessage (GPIO_RESPONSE_MSG, 1000)) {
00368         bRetVal = true;
00369         result = (GPIO_RES_t)m_buffer[1];
00370     } else {
00371         ERR("Did not get answer from device after GPIO_MSG !");
00372     }
00373     
00374     return bRetVal;
00375 }
00376 
00377 bool Wifi::SetIpAddress(bool bUseDHCP, IPADDRESS_t *ipAddress)
00378 {
00379     bool bRetVal = false;
00380     char buf[18] = {255, (bUseDHCP ? 0 : 1), 0};
00381             
00382     if (!bUseDHCP) {
00383         if ( ipAddress == NULL) {
00384             ERR("Invalid argument, ipAdress is NULL !");
00385             return false;
00386         }
00387         memcpy( &buf[2], (void*)ipAddress, 16 );
00388     } else {
00389         memset( &buf[2], 0, 16);
00390     }
00391     
00392     INFO("SENDING SET_IP_ADDRESS_MSG");
00393     SendCommand(SET_IP_ADDRESS_MSG, 18, buf);
00394     
00395     if (WaitMessage (ACK_MSG, 1000)) {
00396         bRetVal = true;
00397     } else {
00398         ERR("Did not get acknowledge after SET_IP_ADDRESS_MSG !");
00399     }
00400     
00401     return bRetVal;
00402 }
00403 
00404 bool Wifi::SetSubnetMask(IPADDRESS_t *NetworkMask)
00405 {
00406     bool bRetVal = false;
00407     
00408     if (NetworkMask == NULL)
00409         return false;
00410         
00411     INFO("SENDING SET_NETWORK_MASK_MSG");
00412     SendCommand(SET_NETWORK_MASK_MSG, 16, NetworkMask->sin_addr.o);
00413     
00414     if (WaitMessage (ACK_MSG, 1000)) {
00415         bRetVal = true;
00416     } else {
00417         ERR("Did not get acknowledge after SET_NETWORK_MASK_MSG !");
00418     }
00419     
00420     return bRetVal;
00421 }
00422 
00423 bool Wifi::SetGatewayIpAddress(IPADDRESS_t *IPAddress)
00424 {
00425     bool bRetVal = false;
00426     
00427     if (IPAddress == NULL)
00428         return false;
00429         
00430     INFO("SENDING SET_GATEWAY_IP_ADDRESS");
00431     SendCommand(SET_GATEWAY_IP_ADDRESS_MSG, 16, IPAddress->sin_addr.o);
00432     
00433     if (WaitMessage (ACK_MSG, 1000)) {
00434         bRetVal = true;
00435     } else {
00436         ERR("Did not get acknowledge after SET_GATEWAY_IP_ADDRESS_MSG !");
00437     }
00438     
00439     return bRetVal;
00440 }
00441 
00442 bool Wifi::GetNetworkStatus(char *MacAddress, IPADDRESS_t *IPAddress, IPADDRESS_t *NetworkMask, IPADDRESS_t *GatewayAddress, NET_STAT_t &stat)
00443 {
00444     bool bRetVal = false;
00445     
00446     INFO("SENDING GET_NETWORK_STATUS_MSG");
00447     SendCommand(GET_NETWORK_STATUS_MSG, 0, NULL);
00448     
00449     if (WaitMessage (NETWORK_STATUS_RESPONSE_MSG, 1000)) {
00450         if (MacAddress != NULL) {
00451             memcpy (MacAddress, &m_buffer[1], 6);
00452         }
00453         if (IPAddress != NULL) {
00454             memcpy( IPAddress, &m_buffer[7], 4);
00455         }
00456         if (NetworkMask != NULL) {
00457             memcpy( NetworkMask, &m_buffer[23], 4);
00458         }
00459         if (GatewayAddress != NULL) {
00460             memcpy( GatewayAddress, &m_buffer[39], 4);
00461         }
00462         stat = (NET_STAT_t)m_buffer[55];
00463         bRetVal = true;
00464     } else {
00465         ERR("Did not get Response after GET_NETWORK_STATUS_MSG !");
00466     }
00467     
00468     return bRetVal;
00469 }
00470 
00471 bool Wifi::SetMACAddress( char MACAddress[6])
00472 {
00473     bool bRetVal = false;
00474     
00475     INFO("SENDING SET_MACADDRESS_MSG");
00476     SendCommand(SET_MACADDRESS_MSG, 6, MACAddress);
00477     
00478     if (WaitMessage (ACK_MSG, 1000)) {
00479         bRetVal = true;
00480     } else {
00481         ERR("Did not get acknowledge after SET_MACADDRESS_MSG !");
00482     }
00483     
00484     return bRetVal;
00485 }
00486 
00487 bool Wifi::SetARPTime(unsigned short ARPTime)
00488 {
00489     char buf[2] = { ARPTime&0xFF, (ARPTime>>8)&0xFF };
00490     
00491     bool bRetVal = false;
00492     
00493     INFO("SENDING SET_ARP_TIME_MSG");
00494     SendCommand(SET_ARP_TIME_MSG, 2, buf);
00495     
00496     if (WaitMessage (ACK_MSG, 1000)) {
00497         bRetVal = true;
00498     } else {
00499         ERR("Did not get acknowledge after SET_ARP_TIME_MSG !");
00500     }
00501     
00502     return bRetVal;
00503 }
00504 
00505 bool Wifi::SetNetworkMode(char ProfileNum, NETW_MODE_t NetMode)
00506 {
00507     char buf[2] = { ProfileNum, (char)NetMode };
00508     bool bRetVal = false;
00509     
00510     INFO("SENDING SET_CP_NETWORK_MODE_MSG");
00511     SendCommand(SET_CP_NETWORK_MODE_MSG, 2, buf);
00512     
00513     if (WaitMessage (ACK_MSG, 1000)) {
00514         bRetVal = true;
00515     } else {
00516         ERR("Did not get acknowledge after SET_CP_NETWORK_MODE_MSG !");
00517     }
00518     
00519     return bRetVal;
00520 }
00521 
00522 bool Wifi::SetPowerSaveMode(POWERSAVE_MODE_t pwrsave, short DTIM_Listen)
00523 {
00524     bool bRetVal = false;
00525     char buf[4] = { (char)pwrsave, 0, LOBYTE(DTIM_Listen), HIBYTE(DTIM_Listen) };
00526     
00527     INFO("SENDING SET_POWER_SAVE_MODE_MSG");
00528     SendCommand(SET_POWER_SAVE_MODE_MSG, 4, buf);
00529     
00530     if (WaitMessage(ACK_MSG, 1000)) {
00531         bRetVal = true;
00532     } else {
00533         ERR("Did not get acknowledge after SET_POWER_SAVE_MODE_MSG !");
00534     }
00535     
00536     return bRetVal;
00537 }
00538 
00539 
00540 bool Wifi::SetSSID(char Profile, const char* ssid)
00541 {
00542     bool bRetVal = false;
00543     char len = strlen(ssid);
00544     char buf[2] = { Profile, len };
00545     
00546     if (len <= 32 ) {        
00547         INFO("SENDING SET_CP_SSID_MSG");
00548         SendCommand(SET_CP_SSID_MSG, 2, buf, len, (char*)ssid);
00549         
00550         if (WaitMessage (ACK_MSG, 10000)) {
00551             if (m_lastError != NoError) {
00552                 ERR("Failed to set SSID with error code %d", m_lastError);
00553                 m_lastError = NoError;
00554             } else {
00555                 bRetVal = true;
00556             }
00557         } else {
00558             ERR("Did not get acknowledge after SET_CP_SSID_MSG !");
00559         }
00560     } else {
00561         ERR("SSID is too long !");
00562     }
00563     
00564     return bRetVal;
00565 }
00566 
00567 bool Wifi::SetRegionalDomain(DOMAIN_COUNTRY_CODE_t dcode)
00568 {
00569     bool bRetVal = false;
00570     char buf[2] = { (char)dcode, 0 };
00571     
00572     INFO("SENDING SET_REGIONAL_DOMAIN_MSG");
00573     SendCommand(SET_REGIONAL_DOMAIN_MSG, 2, buf);
00574     
00575     if (WaitMessage (ACK_MSG, 1000)) {
00576         bRetVal = true;
00577     } else {
00578         ERR("Did not get acknowledge after SET_REGIONAL_DOMAIN_MSG !");
00579     }
00580     
00581     return bRetVal;
00582 }
00583 
00584 bool Wifi::SetChannelList(char numListItems, char *ListItems)
00585 {
00586     bool bRetVal = false;
00587     char buf[2] = { numListItems, 0 };
00588         
00589     INFO("SENDING SET_CHANNEL_LIST_MSG");
00590     SendCommand(SET_CHANNEL_LIST_MSG, 2, buf, numListItems, ListItems);
00591     
00592     if (WaitMessage (ACK_MSG, 1000)) {
00593         bRetVal = true;
00594     } else {
00595         ERR("Did not get acknowledge after SET_CHANNEL_LIST_MSG !");
00596     }
00597     
00598     return bRetVal;
00599 }
00600 
00601 bool Wifi::SetRetryCount(char infrastructureRetryCount, char adhocRetryCount)
00602 {
00603     bool bRetVal = false;
00604     char buf[2] = { infrastructureRetryCount, adhocRetryCount };
00605     
00606     INFO("SENDING SET_LIST_RETRY_COUNT_MSG");
00607     SendCommand(SET_LIST_RETRY_COUNT_MSG, 2, buf);
00608     
00609     if (WaitMessage (ACK_MSG, 1000)) {
00610         bRetVal = true;
00611     } else {
00612         ERR("Did not get acknowledge after SET_LIST_RETRY_COUNT_MSG !");
00613     }
00614     
00615     return bRetVal;
00616 }
00617 
00618 bool Wifi::SetSecurityOpen(char Profile)
00619 {
00620     bool bRetVal = false;
00621     char buf[2] = { Profile, 0 };
00622     
00623     INFO("SENDING SET_CP_SECURITY_OPEN_MSG");
00624     SendCommand(SET_CP_SECURITY_OPEN_MSG, 2, buf);
00625     
00626     if (WaitMessage (ACK_MSG, 1000)) {
00627         bRetVal = true;
00628     } else {
00629         ERR("Did not get acknowledge after SET_CP_SECURITY_OPEN_MSG !");
00630     }
00631     
00632     return bRetVal;
00633 }
00634 
00635 bool Wifi::SetSecurityWEP40(char Profile, bool bSharedKey, char DefaultWEPKeyIdx, char SecurityKeys[20])
00636 {
00637     bool bRetVal = false;
00638     char buf[4];
00639     
00640     buf[0] = Profile;
00641     buf[1] = bSharedKey ? 1 : 0;
00642     buf[2] = DefaultWEPKeyIdx;
00643     
00644     INFO("SENDING SET_CP_SECURITY_WEP40_MSG");
00645     SendCommand(SET_CP_SECURITY_WEP40_MSG, 4, buf, 20, SecurityKeys);
00646     
00647     if (WaitMessage (ACK_MSG, 1000)) {
00648         bRetVal = true;
00649     } else {
00650         ERR("Did not get acknowledge after SET_CP_SECURITY_WEP40_MSG !");
00651     }
00652     
00653     return bRetVal;
00654 }
00655 
00656 bool Wifi::SetSecurityWEP104(char Profile, bool bSharedKey, char DefaultWEPKeyIdx, char SecurityKeys[52])
00657 {
00658     bool bRetVal = false;
00659     char buf[4];
00660     
00661     buf[0] = Profile;
00662     buf[1] = bSharedKey ? 1 : 0;
00663     buf[2] = DefaultWEPKeyIdx;
00664     
00665     INFO("SENDING SET_CP_SECURITY_WEP104_MSG");
00666     SendCommand(SET_CP_SECURITY_WEP104_MSG, 4, buf, 52, SecurityKeys);
00667     
00668     if (WaitMessage (ACK_MSG, 1000)) {
00669         bRetVal = true;
00670     } else {
00671         ERR("Did not get acknowledge after SET_CP_SECURITY_WEP104_MSG !");
00672     }
00673     
00674     return bRetVal;
00675 }
00676 
00677 bool Wifi::SetSecurityWPA(char Profile, WPA_SECURITY_t sec, int len, const char* secKeyOrPSK)
00678 {
00679     bool bRetVal = false;
00680     char buf[4];
00681     if ((secKeyOrPSK == NULL) || (*secKeyOrPSK == 0))
00682         return false;
00683             
00684     if (buf != NULL) {
00685         buf[0] = Profile;
00686         buf[1] = sec;
00687         buf[2] = 0;
00688         buf[3] = len;
00689         
00690         INFO("SENDING SET_CP_SECURITY_WPA_MSG");
00691         SendCommand(SET_CP_SECURITY_WPA_MSG, 4, buf, len, (char*)secKeyOrPSK);
00692         
00693         if (WaitMessage (ACK_MSG, 1000)) {
00694             bRetVal = true;
00695         } else {
00696             ERR("Did not get acknowledge after SET_CP_SECURITY_WPA_MSG !");
00697         }
00698     } else {
00699         ERR("Out of memory error in SetCPSecurityWPA !");
00700     }
00701     
00702     return bRetVal;
00703 }
00704 
00705 bool Wifi::GetWPAKey(char Profile, char Key[32])
00706 {
00707     bool bRetVal = false;
00708     char buf[2] = { Profile, 0 };
00709     
00710     INFO("SENDING GET_CP_WPAKEY_MSG");
00711     SendCommand(GET_CP_WPAKEY_MSG, 2, buf);
00712     
00713     if (WaitMessage (WPAKEY_RESPONSE_MSG, 1000)) {
00714         bRetVal = true;
00715         memcpy(Key, m_buffer, 32);
00716     } else {
00717         ERR("Did not get answer from device !");
00718     }
00719     
00720     return bRetVal;
00721 }
00722 
00723 bool Wifi::ScanStartMsg(char Profile)
00724 {
00725     bool bRetVal = false;
00726     
00727     if (m_bWifiConnected) {
00728         ERR("Can not start scan while Wifi is connected !");
00729     } else {
00730         char buf[2] = { Profile, 0 };
00731         
00732         INFO("SENDING SCAN_START_MSG");
00733         m_bScanResultsReady = false;
00734         m_NumLastScanResults = 0;
00735         SendCommand(SCAN_START_MSG, 2, buf);
00736         
00737         if (WaitMessage (ACK_MSG, 1000)) {
00738             bRetVal = true;
00739         } else {
00740             ERR("Did not get acknowledge after SCAN_START_MSG !");
00741         }
00742     }
00743     
00744     return bRetVal;
00745 }
00746 
00747 bool Wifi::ScanGetResults(char index, char ssid[32], AP_CONFIG_t &apCfg, short &beaconInterval, short &ATIMWindow, char &RSSI, NETW_MODE_t &bssType, char &channelNo)
00748 {
00749     bool bRetVal = false;
00750     
00751     if (!m_bScanResultsReady) {
00752         ERR("No scan results !");
00753     } else {
00754         if (index >= m_NumLastScanResults) {
00755             ERR ("No more scan results !");
00756         } else {
00757             char buf[2] = { index, 0 };
00758             
00759             INFO("SENDING SCAN_GET_RESULTS_MSG");
00760             SendCommand(SCAN_GET_RESULTS_MSG, 2, buf);
00761             
00762             if (WaitMessage (SCAN_RESULT_MSG, 1000)) {
00763                 bRetVal = true;
00764                 memcpy(ssid, &m_buffer[7], m_buffer[6]);
00765                 memcpy(&apCfg, &m_buffer[39], 1);
00766                 beaconInterval = *(short*)&m_buffer[40];
00767                 ATIMWindow = *(short*)&m_buffer[42];
00768                 RSSI = m_buffer[52];
00769                 bssType = (NETW_MODE_t)m_buffer[55];
00770                 channelNo = m_buffer[56];
00771             } else {
00772                 ERR("Did not receive message after SCAN_GET_RESULTS_MSG !");
00773             }
00774         }
00775     }
00776     
00777     return bRetVal;
00778 }
00779 
00780 bool Wifi::Connect(char Profile)
00781 {
00782     bool bRetVal = false;
00783     
00784     if (m_bWifiConnected) {
00785         ERR("WIFI is already connected !");
00786     } else {
00787         char buf[2] = { Profile, 0 };
00788         
00789         INFO("SENDING WIFI_CONNECT_MSG");
00790         SendCommand(WIFI_CONNECT_MSG, 2, buf);
00791         
00792         if (WaitMessage (ACK_MSG, 1000)) {
00793             bRetVal = true;
00794         } else {
00795             ERR("Did not get any acknowledge after WIFI_CONNECT_MSG !");
00796         }
00797     }
00798     
00799     return bRetVal;
00800 }
00801 
00802 bool Wifi::Disconnect()
00803 {
00804     bool bRetVal = false;
00805     
00806     if (!m_bWifiConnected) {
00807         ERR("WIFI is not yet connected !");
00808     } else {        
00809         INFO("SENDING WIFI_DISCONNECT_MSG");
00810         SendCommand(WIFI_DISCONNECT_MSG, 0, NULL);
00811         
00812         if (WaitMessage (ACK_MSG, 1000)) {
00813             bRetVal = true;
00814         } else {
00815             ERR("Did not get any acknowledge after WIFI_DISCONNECT_MSG !");
00816         }
00817         
00818    }
00819     
00820     return bRetVal;
00821 }
00822 
00823 
00824 bool Wifi::SocketAllocate(char nTCPSvr, char nTCPClnt, unsigned short TCPSvrRxBuf, unsigned short TCPSvrTxBuf, unsigned short TCPClntRxBuf, unsigned short TCPClntTxBuf)
00825 {
00826     bool bRetVal = false;
00827     __packed struct _sendBuf {
00828         char _nTcpSvr;
00829         char _nTcpClnt;
00830         unsigned short _TcpSvrRxBuf, _TcpSvrTxBuf, _TcpClntRxBuf, _TcpClntTxBuf;
00831     } buf = { nTCPSvr, nTCPClnt, TCPSvrRxBuf, TCPSvrTxBuf, TCPClntRxBuf, TCPClntTxBuf };
00832     
00833     INFO("SENDING SOCKET_ALLOCATE_MSG");
00834     SendCommand(SOCKET_ALLOCATE_MSG, sizeof(buf), (char*)&buf);
00835     
00836     if (WaitMessage (SOCKET_ALLOCATE_RESPONSE_MSG, 2000)) {
00837         if (m_buffer[0] == 0) {
00838             bRetVal = true;
00839         } else if (m_buffer[0] == 0xFF) {
00840             ERR("Too many sockets requested in SOCKET_ALLOCATE_MSG !");
00841         } else  if (m_buffer[0] == 0xFE) {
00842             ERR("Too much buffer requested in SOCKET_ALLOCATE_MSG !");
00843         } else {
00844             ERR("Unknown error in SOCKET_ALLOCATE_MSG !");
00845         }
00846     } else {
00847         ERR("Did not get expected message SOCKET_ALLOCATE_RESPONSE_MSG !");
00848     }
00849     
00850     return bRetVal;
00851 }
00852 
00853 
00854 
00855 SOCKET_HANDLE_t Wifi::SocketCreate( SOCKET_TYPE_t sockType )
00856 {
00857     char sockHandle = InvalidSocketHandle;
00858     char buf[2] = { sockType, 0 };
00859     
00860     INFO("SENDING SOCKET_CREATE_MSG");
00861     SendCommand(SOCKET_CREATE_MSG, 2, buf);
00862     
00863     if (WaitMessage (SOCKET_CREATE_RESPONSE_MSG, 1000)) {
00864         sockHandle = (SOCKET_HANDLE_t)m_buffer[0];
00865         if (m_buffer[0] == 254) {
00866             ERR("Invalid socket handle received after SOCKET_CREATE_MSG !");
00867         } else if (m_buffer[0] == 255) {
00868             ERR("Unknown socket type specified in call to SOCKET_CREATE_MSG !");
00869         } else {
00870             INFO("Valid socket handle received !");
00871         }
00872     } else {
00873         ERR("Did not get expected response after SOCKET_CREATE_MSG !");
00874     }
00875     
00876     return (SOCKET_HANDLE_t)sockHandle;
00877 }
00878 
00879 bool Wifi::SocketClose(SOCKET_HANDLE_t hSock)
00880 {
00881     bool bRetVal = false;
00882     char buf[2] = { hSock, 0 };
00883 
00884     INFO("SENDING SOCKET_CLOSE_MSG");
00885     m_lastError = NoError;
00886     SendCommand(SOCKET_CLOSE_MSG, 2, buf);
00887     
00888     if (WaitMessage (ACK_MSG, 1000)) {
00889         wait(0.1);
00890         if (m_lastError != NoError) {
00891             bRetVal = false;
00892         } else {
00893             bRetVal = true;
00894         }                
00895     } else {
00896         ERR("Did not get expected acknowledge message after SOCKET_CLOSE_MSG !");
00897     }
00898     
00899     return bRetVal;
00900 }
00901 
00902 bool Wifi::SocketBind(SOCKET_HANDLE_t hSock, int Port)
00903 {
00904     bool bRetVal = false;
00905     char buf[4] = { LOBYTE(Port), HIBYTE(Port), hSock, 0 };
00906 
00907     INFO("SENDING SOCKET_BIND_MSG");
00908     SendCommand(SOCKET_BIND_MSG, 4, buf);
00909     
00910     if (WaitMessage (SOCKET_BIND_RESPONSE_MSG, 1000)) {
00911         if (m_buffer[2] == 0) {
00912             bRetVal = true;
00913         } else {
00914             ERR("Bind operation return non-zero result !");
00915         }
00916     } else {
00917         ERR("Did not get expected acknowledge message after SOCKET_CLOSE_MSG !");
00918     }
00919     
00920     return bRetVal;
00921 }
00922 
00923 bool Wifi::SocketListen(SOCKET_HANDLE_t hSock, int& Backlog)
00924 {
00925     bool bRetVal = false;
00926     char buf[2] = { hSock, Backlog };
00927     
00928     INFO("SENDING SOCKET_LISTEN_MSG");
00929     SendCommand(SOCKET_LISTEN_MSG, 2, buf);
00930     
00931     if (WaitMessage (SOCKET_LISTEN_RESPONSE_MSG, 1000)) {
00932         Backlog = m_buffer[1];
00933         if (m_buffer[0] != 255) {
00934             if (m_buffer[0] != 254) {
00935                 bRetVal = true;
00936             } else {
00937                 ERR("SOCKET Listen failed because a socket connection is currently in progress !");
00938             }
00939         } else {
00940             ERR("Socket Listen failed because the socket is already connected !");
00941         }
00942     } else {
00943         ERR("Did not get expected acknowledge message after SOCKET_LISTEN_RESPONSE !");
00944     }
00945 
00946     return bRetVal;
00947 }
00948 
00949 bool Wifi::SocketAccept(SOCKET_HANDLE_t hSock, SOCKET_HANDLE_t &client, int &remotePort, IPADDRESS_t &remoteAddress)
00950 {
00951     bool bRetVal = false;
00952     char buf[2] = { hSock, 0 };
00953     
00954     INFO("SENDING SOCKET_ACCEPT_MSG");
00955     SendCommand(SOCKET_ACCEPT_MSG, 2, buf);
00956     
00957     if (WaitMessage (SOCKET_ACCEPT_RESPONSE_MSG, 1000)) {
00958         client = (SOCKET_HANDLE_t)m_buffer[0];
00959         remotePort = m_buffer[1] + ((int)m_buffer[2])<<8;
00960         memcpy(&remoteAddress, (const void*)&m_buffer[3], 4);
00961         bRetVal = true;
00962     } else {
00963         ERR("Did not get expected response after SOCKET_ACCEPT_MSG !");
00964     }
00965     
00966     return bRetVal;
00967 }
00968 
00969 SOCKET_HANDLE_t Wifi::SocketConnect(SOCKET_HANDLE_t hSock, IPADDRESS_t *IpAddress, int Port)
00970 {
00971     SOCKET_HANDLE_t bRetVal = InvalidSocketHandle;
00972     char buf[4] = { hSock, 0, LOBYTE(Port), HIBYTE(Port) };
00973     
00974     INFO("SENDING SOCKET_CONNECT_MSG");
00975     SendCommand(SOCKET_CONNECT_MSG, 4, buf, 16, (char*)IpAddress);
00976     
00977     if (WaitMessage (SOCKET_CONNECT_RESPONSE_MSG, 1000)) {
00978         bRetVal = (SOCKET_HANDLE_t)m_buffer[0];
00979     } else {
00980         ERR("Did not get expected response after SOCKET_CONNECT_MSG !");
00981     }
00982     
00983     return bRetVal;
00984 }
00985 
00986 int Wifi::SocketSend(SOCKET_HANDLE_t hSock, char* data, int length)
00987 {
00988     int nRetVal = -1;
00989     char buf[4] = { hSock, 0, LOBYTE(length), HIBYTE(length) };
00990     
00991     INFO("SENDING SOCKET_SEND_MSG");
00992     SendCommand(SOCKET_SEND_MSG, 4, buf, length, data);
00993     
00994     if (WaitMessage (SOCKET_SEND_RESPONSE_MSG, 1000)) {
00995         nRetVal = m_buffer[0] + ((int)m_buffer[1])<<8;
00996     } else {
00997         ERR("Did not get expected response after SOCKET_SEND_MSG !");
00998     }
00999     
01000     return nRetVal;
01001 }
01002 
01003 int Wifi::SocketRecv(SOCKET_HANDLE_t hSock, char* data, int length)
01004 {
01005     int nRetVal = -1;
01006     char buf[4] = { hSock, 0, LOBYTE(length), HIBYTE(length) };
01007     
01008     INFO("SENDING SOCKET_RECV_MSG");
01009     SendCommand(SOCKET_RECV_MSG, 4, buf);
01010     
01011     if (WaitMessage (SOCKET_RECV_RESPONSE_MSG, 1000)) {
01012         nRetVal = m_buffer[2] + ((int)m_buffer[3])<<8;
01013         memcpy(data, &m_buffer[4], nRetVal);
01014     } else {
01015         ERR("Did not get expected response after SOCKET_RECV_MSG !");
01016     }
01017     
01018     return nRetVal;
01019 }
01020 
01021 int Wifi::SocketSendTo(SOCKET_HANDLE_t hSock, IPADDRESS_t* remoteAddress, int remotePort, char *data, int length)
01022 {
01023     int nRetVal = -1;
01024     char buf[22] = { hSock, 0, LOBYTE(remotePort), HIBYTE(remotePort) };
01025     
01026     memcpy(&buf[4], remoteAddress, 16);
01027     buf[20] = LOBYTE(length);
01028     buf[21] = HIBYTE(length);
01029     INFO("SENDING SOCKET_SEND_TO_MSG");
01030     SendCommand(SOCKET_SEND_TO_MSG, 22, buf, length, data);
01031     
01032     if (WaitMessage (SOCKET_SEND_TO_RESPONSE_MSG, 1000)) {
01033         nRetVal = m_buffer[0] + (((int)m_buffer[1])<<8);
01034     } else {
01035         ERR("Did not get expected response after SOCKET_SEND_TO_MSG !");
01036     }
01037     
01038     return nRetVal;
01039 }
01040 
01041 int Wifi::SocketRecvFrom(SOCKET_HANDLE_t hSock, IPADDRESS_t *remoteAddress, int *port, char *data, int length)
01042 {
01043     int nRetVal = -1;
01044     char buf[4] = { hSock, 0, LOBYTE(length), HIBYTE(length) };
01045     
01046     INFO("SENDING SOCKET_RECV_FROM_MSG");
01047     SendCommand(SOCKET_RECV_FROM_MSG, 4, buf);
01048 
01049     if (WaitMessage (SOCKET_RECV_FROM_RESPONSE_MSG, 1000)) {
01050         if (port != NULL)
01051             *port = m_buffer[2] + (((int)m_buffer[3])<<8);
01052         if (remoteAddress != NULL)
01053             memcpy(remoteAddress, &m_buffer[4], 4);
01054         nRetVal = m_buffer[20] + (((int)m_buffer[21])<<8);
01055         
01056         memcpy(data, &m_buffer[22], nRetVal > length ? length : nRetVal);
01057         if (nRetVal > length) {
01058             INFO("Socket received %d bytes on port %d which is more than the %d provided by buffer !", nRetVal, *port, length);
01059         }
01060     } else {
01061         ERR("Did not get expected response after SOCKET_RECV_FROM_MSG !");
01062     }
01063     
01064     return nRetVal;
01065 }
01066 
01067 
01068 int Wifi::gethostbyname(const char* host, IPADDRESS_t *IpAddress)
01069 {
01070     //  First issue a get network status message to retrieve the gateway address. The gateway will be used as the DNS.
01071     IPADDRESS_t GatewayIP;
01072     NET_STAT_t     netStat;
01073     
01074     if (IpAddress == NULL)
01075         return -1;
01076     
01077     //  Get the gateway ip address for use as DNS server
01078     if (!GetNetworkStatus(NULL, NULL, NULL, &GatewayIP, netStat)) {
01079         return -1;
01080     }
01081     INFO("Using gateway on %d.%d.%d.%d as DNS !", GatewayIP.sin_addr.o1, GatewayIP.sin_addr.o2, GatewayIP.sin_addr.o3, GatewayIP.sin_addr.o4);        
01082     //  Now create the DNS query
01083     DnsQuery    dns(this, &GatewayIP);
01084     
01085     if( !dns.gethostbyname(host, *IpAddress) ) {
01086         ERR("Failed to get host by name !");
01087         return -1;
01088     }
01089     
01090     return 0;
01091 }
01092 
01093 int Wifi::convert(const char* hostip, IPADDRESS_t *ipAddress)
01094 {
01095     if ((hostip == NULL) || (ipAddress == NULL))
01096         return -1;
01097         
01098     int nCnt = 0;
01099     int val = 0;
01100     while(*hostip != 0) {
01101         if (*hostip != '.') {
01102             val = val*10 + (*hostip)-'0';
01103         } else {
01104             if (nCnt > 3)
01105                 return -1;
01106             ipAddress->sin_addr.o[nCnt++] = val;
01107             val = 0;
01108         }
01109     }
01110     ipAddress->sin_addr.o[nCnt++] = val;
01111 
01112     return 0;
01113 }