David Smart / WiflyInterface Featured

Dependents:   Smart-WiFly-WebServer PUB_WiflyInterface_Demo

Fork of WiflyInterface by mbed official

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 //#define DEBUG "UDPs"      //Debug is disabled by default
00025 
00026 // How to use this debug macro
00027 //
00028 // ...
00029 // INFO("Stuff to show %d", var); // new-line is automatically appended
00030 // [I myfile  23] Stuff to show 23\r\n
00031 //
00032 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
00033 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
00034 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
00035 #define ERR(x, ...)  std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
00036 #else
00037 #define INFO(x, ...)
00038 #define WARN(x, ...)
00039 #define ERR(x, ...)
00040 #endif
00041 
00042 UDPSocket::UDPSocket()
00043 {
00044     endpoint_configured = false;
00045     endpoint_read = false;
00046 }
00047 
00048 int UDPSocket::init(void)
00049 {
00050     wifi->setProtocol(UDP);
00051     wifi->exit();
00052     return 0;
00053 }
00054 
00055 // Server initialization
00056 int UDPSocket::bind(int port)
00057 {
00058     char cmd[17];
00059     
00060     // set local port
00061     sprintf(cmd, "set i l %d\r", port);
00062     if (!wifi->sendCommand(cmd, "AOK"))
00063         return -1;
00064         
00065     // save
00066     if (!wifi->sendCommand("save\r", "Stor", NULL, 5000))
00067         return -1;
00068     
00069     // reboot
00070     wifi->reboot();
00071     
00072     // set udp protocol
00073     wifi->setProtocol(UDP);
00074     
00075     // connect the network
00076     if (wifi->isDHCP()) {
00077         if (!wifi->sendCommand("join\r", "DHCP=ON", NULL, 10000))
00078             return -1;
00079     } else {
00080         if (!wifi->sendCommand("join\r", "Associated", NULL, 10000))
00081             return -1;
00082     }
00083         
00084     // exit
00085     wifi->exit();
00086     wifi->flush();
00087     return 0;
00088 }
00089 
00090 int UDPSocket::join_multicast_group(const char* address) {
00091     return -1;  // unsupported function
00092 }
00093 
00094 int UDPSocket::set_broadcasting(bool broadcast) {
00095     return -1;  // unsupported function
00096 }
00097 
00098 // -1 if unsuccessful, else number of bytes written
00099 int UDPSocket::sendTo(Endpoint &remote, char *packet, int length)
00100 {
00101     Timer tmr;
00102     int idx = 0;
00103     INFO("sendTo(..,..,%d)", length);
00104     confEndpoint(remote);
00105 
00106     tmr.start();
00107     INFO("sendTo %d", tmr.read_ms());
00108     
00109     while ((tmr.read_ms() < _timeout) || _blocking) {
00110 
00111         idx += wifi->send(packet, length);
00112         INFO("  idx: %d", idx);
00113         if (idx == length)
00114             return idx;
00115     }
00116     INFO("  idx; %d @ %d", idx, tmr.read_ms());
00117     return (idx == 0) ? -1 : idx;
00118 }
00119 
00120 // -1 if unsuccessful, else number of bytes received
00121 int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length)
00122 {
00123     Timer tmr;
00124     int idx = 0;
00125     int nb_available = 0;
00126     int time = -1;
00127 
00128     if (_blocking) {
00129         while (1) {
00130             nb_available = wifi->readable();
00131             if (nb_available != 0) {
00132                 break;
00133             }
00134         }
00135     }
00136 
00137     tmr.start();
00138 
00139     while (time < _timeout) {
00140 
00141         nb_available = wifi->readable();
00142         for (int i = 0; i < min(nb_available, length); i++) {
00143             buffer[idx] = wifi->getc();
00144             idx++;
00145         }
00146 
00147         if (idx == length) {
00148             break;
00149         }
00150         
00151         time = tmr.read_ms();
00152     }
00153 
00154     readEndpoint(remote);
00155     return (idx == 0) ? -1 : idx;
00156 }
00157 
00158 bool UDPSocket::confEndpoint(Endpoint & ep)
00159 {
00160     char * host;
00161     char cmd[30];
00162     
00163     WARN("Force endpoint not configured");
00164     endpoint_configured = false;
00165     INFO("confEndpoint config'd: %d", endpoint_configured);
00166     if (!endpoint_configured) {
00167         host = ep.get_address();
00168         if (host[0] != '\0') {
00169             // set host
00170             sprintf(cmd, "set i h %s\r", host);
00171             if (!wifi->sendCommand(cmd, "AOK")) {
00172                 INFO("  confEndPoint false.");
00173                 return false;
00174             }
00175             // set remote port
00176             sprintf(cmd, "set i r %d\r", ep.get_port());
00177             if (!wifi->sendCommand(cmd, "AOK")) {
00178                 INFO("  confEndPoint false.");
00179                 return false;
00180             }
00181             wifi->exit();
00182             endpoint_configured = true;
00183             INFO("  confEndPoint.");
00184             return true;
00185         }
00186     }
00187     INFO("  confEndPoint.");
00188     return true;
00189 }
00190 
00191 bool UDPSocket::readEndpoint(Endpoint & ep)
00192 {
00193     char recv[256];
00194     int begin = 0;
00195     int end = 0;
00196     string str;
00197     string addr;
00198     int port;
00199     if (!endpoint_read) {
00200         if (!wifi->sendCommand("get ip\r", NULL, recv))
00201             return false;
00202         wifi->exit();
00203         str = recv;
00204         begin = str.find("HOST=");
00205         end = str.find("PROTO=");
00206         if (begin != string::npos && end != string::npos) {
00207             str = str.substr(begin + 5, end - begin - 5);
00208             int pos = str.find(":");
00209             if (pos != string::npos) {
00210                 addr = str.substr(0, pos);
00211                 port = atoi(str.substr(pos + 1).c_str());
00212                 ep.set_address(addr.c_str(), port);
00213                 endpoint_read = true;
00214                 wifi->flush();
00215                 return true;
00216             }
00217         }
00218         wifi->flush();
00219     }
00220     return false;
00221 }