wifly/socket interface for wifly modules

Dependents:   WiFi neurGAI_WIFI thingspeak thingspeak2

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