- Added setBaud() function - Added CheckNetworkStatus() function - Improved messaging system

Dependents:   IoT_Ex BatteryModelTester BatteryModelTester

Fork of WiflyInterface by Components

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UDPSocket.cpp Source File

UDPSocket.cpp

00001 /* Copyright (C) 2012 mbed.org, MIT License
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 
00019 #include "UDPSocket.h"
00020 
00021 #include <string>
00022 #include <algorithm>
00023 
00024 UDPSocket::UDPSocket()
00025 {
00026     endpoint_configured = false;
00027     endpoint_read = false;
00028 }
00029 
00030 int UDPSocket::init(void)
00031 {
00032     wifi->setProtocol(UDP);
00033     wifi->exit();
00034     return 0;
00035 }
00036 
00037 
00038 void UDPSocket::setBaud(int baudrate)
00039 {
00040     wifi->setBaud(baudrate);
00041     wifi->exit();
00042     return;
00043 }
00044 
00045 // Server initialization
00046 int UDPSocket::bind(int port)
00047 {
00048     char cmd[17];
00049     
00050     // set local port
00051     sprintf(cmd, "set i l %d\r", port);
00052     if (!wifi->sendCommand(cmd, "AOK"))
00053         return -1;
00054         
00055     // save
00056     if (!wifi->sendCommand("save\r", "Stor"))
00057         return -1;
00058     
00059     // reboot
00060     wifi->reboot();
00061     
00062     // set udp protocol
00063     wifi->setProtocol(UDP);
00064     
00065     // connect the network
00066     if (wifi->isDHCP()) {
00067         if (!wifi->sendCommand("join\r", "DHCP=ON", NULL, 10000))
00068             return -1;
00069     } else {
00070         if (!wifi->sendCommand("join\r", "Associated", NULL, 10000))
00071             return -1;
00072     }
00073         
00074     // exit
00075     wifi->exit();
00076     wifi->flush();
00077     return 0;
00078 }
00079 
00080 // -1 if unsuccessful, else number of bytes written
00081 int UDPSocket::sendTo(Endpoint &remote, char *packet, int length)
00082 {
00083     Timer tmr;
00084     int idx = 0;
00085 
00086     confEndpoint(remote);
00087 
00088     tmr.start();
00089 
00090     while ((tmr.read_ms() < _timeout) || _blocking) {
00091 
00092         idx += wifi->send(packet, length);
00093 
00094         if (idx == length)
00095             return idx;
00096     }
00097     return (idx == 0) ? -1 : idx;
00098 }
00099 
00100 // -1 if unsuccessful, else number of bytes received
00101 int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length)
00102 {
00103     Timer tmr;
00104     int idx = 0;
00105     int nb_available = 0;
00106     int time = -1;
00107 
00108     if (_blocking) {
00109         while (1) {
00110             nb_available = wifi->readable();
00111             if (nb_available != 0) {
00112                 break;
00113             }
00114         }
00115     }
00116 
00117     tmr.start();
00118 
00119     while (time < _timeout) {
00120 
00121         nb_available = wifi->readable();
00122         for (int i = 0; i < min(nb_available, length); i++) {
00123             buffer[idx] = wifi->getc();
00124             idx++;
00125         }
00126 
00127         if (idx == length) {
00128             break;
00129         }
00130         
00131         time = tmr.read_ms();
00132     }
00133 
00134     readEndpoint(remote);
00135     return (idx == 0) ? -1 : idx;
00136 }
00137 
00138 bool UDPSocket::confEndpoint(Endpoint & ep)
00139 {
00140     char * host;
00141     char cmd[30];
00142     if (!endpoint_configured) {
00143         host = ep.get_address();
00144         if (host[0] != '\0') {
00145             // set host
00146             sprintf(cmd, "set i h %s\r", host);
00147             if (!wifi->sendCommand(cmd, "AOK"))
00148                 return false;
00149                 
00150             // set remote port
00151             sprintf(cmd, "set i r %d\r", ep.get_port());
00152             if (!wifi->sendCommand(cmd, "AOK"))
00153                 return false;
00154                 
00155             wifi->exit();
00156             endpoint_configured = true;
00157             return true;
00158         }
00159     }
00160     return true;
00161 }
00162 
00163 bool UDPSocket::readEndpoint(Endpoint & ep)
00164 {
00165     char recv[256];
00166     int begin = 0;
00167     int end = 0;
00168     string str;
00169     string addr;
00170     int port;
00171     if (!endpoint_read) {
00172         if (!wifi->sendCommand("get ip\r", NULL, recv))
00173             return false;
00174         wifi->exit();
00175         str = recv;
00176         begin = str.find("HOST=");
00177         end = str.find("PROTO=");
00178         if (begin != string::npos && end != string::npos) {
00179             str = str.substr(begin + 5, end - begin - 5);
00180             int pos = str.find(":");
00181             if (pos != string::npos) {
00182                 addr = str.substr(0, pos);
00183                 port = atoi(str.substr(pos + 1).c_str());
00184                 ep.set_address(addr.c_str(), port);
00185                 endpoint_read = true;
00186                 wifi->flush();
00187                 return true;
00188             }
00189         }
00190         wifi->flush();
00191     }
00192     return false;
00193 }