mbed official WiflyInterface (interface for Roving Networks Wifly modules)

Dependents:   Wifly_HelloWorld Websocket_Wifly_HelloWorld RPC_Wifly_HelloWorld HTTPClient_Wifly_HelloWorld ... more

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