Host library for controlling a WiConnect enabled Wi-Fi module.

Dependents:   wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SocketInterface.cpp Source File

SocketInterface.cpp

00001 /**
00002  * ACKme WiConnect Host Library is licensed under the BSD licence: 
00003  * 
00004  * Copyright (c)2014 ACKme Networks.
00005  * All rights reserved. 
00006  * 
00007  * Redistribution and use in source and binary forms, with or without modification, 
00008  * are permitted provided that the following conditions are met: 
00009  * 
00010  * 1. Redistributions of source code must retain the above copyright notice, 
00011  * this list of conditions and the following disclaimer. 
00012  * 2. Redistributions in binary form must reproduce the above copyright notice, 
00013  * this list of conditions and the following disclaimer in the documentation 
00014  * and/or other materials provided with the distribution. 
00015  * 3. The name of the author may not be used to endorse or promote products 
00016  * derived from this software without specific prior written permission. 
00017  * 
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED 
00019  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00020  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
00021  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
00023  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00026  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
00027  * OF SUCH DAMAGE.
00028  */
00029 
00030 #include <string.h>
00031 #include "Wiconnect.h"
00032 #include "internal/common.h"
00033 #include "api/StringUtil.h"
00034 
00035 #ifdef WICONNECT_GPIO_IRQ_ENABLED
00036 #include "api/types/SocketIrqHandlerMap.h"
00037 #endif
00038 
00039 
00040 /*************************************************************************************************/
00041 SocketInterface::SocketInterface(Wiconnect *wiconnect_)
00042 {
00043     wiconnect = wiconnect_;
00044     serverConnectedClientList = 0;
00045 }
00046 
00047 /*************************************************************************************************/
00048 SocketInterface::~SocketInterface()
00049 {
00050 }
00051 
00052 /*************************************************************************************************/
00053 WiconnectResult SocketInterface::connect(WiconnectSocket &socket, SocketType type, const char *host, uint16_t remortPort, uint16_t localPort, const void *args GPIO_IRQ_ARG)
00054 {
00055     WiconnectResult result;
00056     int32_t handle;
00057     char *cmdBuffer = wiconnect->internalBuffer;
00058 
00059     if(WICONNECT_IS_IDLE())
00060     {
00061         char gpioOption[8] = "";
00062 
00063 #ifdef WICONNECT_GPIO_IRQ_ENABLED
00064         if(irqPin != PIN_NC)
00065         {
00066             PinToGpioMapper mapper = wiconnect->pinToGpioMapper;
00067             if(mapper == NULL)
00068             {
00069                 return WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL;
00070             }
00071             int8_t gpio = mapper(irqPin);
00072             if(gpio == -1)
00073             {
00074                 return WICONNECT_PINNAME_TO_GPIO_NO_MAPPING;
00075             }
00076             else if(!irqHandlers.pinIsRegistered(irqPin))
00077             {
00078                 return WICONNECT_NOT_FOUND;
00079             }
00080 
00081             sprintf(gpioOption, "-g %d ", gpio);
00082         }
00083 #endif
00084 
00085         switch(type)
00086         {
00087         case SOCKET_TYPE_TCP:
00088             sprintf(cmdBuffer, "tcpc %s%s %d", gpioOption, host, remortPort);
00089             break;
00090 
00091         case SOCKET_TYPE_UDP: {
00092             char tmp[16];
00093             sprintf(cmdBuffer, "udpc %s%s %d %s", gpioOption, host, remortPort,
00094                                                 (localPort != SOCKET_ANY_PORT) ? StringUtil::uint32ToStr(tmp, localPort) : "");
00095         } break;
00096 
00097         case SOCKET_TYPE_TLS:
00098             sprintf(cmdBuffer, "tlsc %s%s %d %s", gpioOption, host, remortPort,
00099                                                 (args != NULL) ? (char*)args : "");
00100             break;
00101 
00102         case SOCKET_TYPE_HTTP: {
00103             const HttpSocketArgs *httpArgs = (const HttpSocketArgs*)args;
00104             switch(httpArgs->type)
00105             {
00106             case SOCKET_HTTP_GET:
00107                 sprintf(cmdBuffer, "http_get %s%s %s", httpArgs->openOnly ? "-o " : "",
00108                                             host,
00109                                             (httpArgs->certName != NULL) ? httpArgs->certName : "");
00110                 break;
00111 
00112             case SOCKET_HTTP_HEAD:
00113                 sprintf(cmdBuffer, "http_head %s%s %s", httpArgs->openOnly ? "-o " : "",
00114                                             host,
00115                                             (httpArgs->certName != NULL) ? httpArgs->certName : "");
00116                 break;
00117 
00118             case SOCKET_HTTP_POST:
00119                 sprintf(cmdBuffer, "http_post %s%s %s %s", httpArgs->openOnly ? "-o " : "",
00120                                                host,
00121                                                httpArgs->contextType,
00122                                               (httpArgs->certName != NULL) ? httpArgs->certName : "");
00123                 break;
00124 
00125             default:
00126                 return WICONNECT_BAD_ARG;
00127             }
00128 
00129         } break;
00130         default:
00131             return WICONNECT_BAD_ARG;
00132         }
00133     }
00134 
00135     CHECK_OTHER_COMMAND_EXECUTING();
00136 
00137     if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(cmdBuffer)))
00138     {
00139         if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&handle)))
00140         {
00141             socket.init(handle, type, host, remortPort, localPort);
00142         }
00143     }
00144 
00145     CHECK_CLEANUP_COMMAND();
00146 
00147     return result;
00148 }
00149 
00150 /*************************************************************************************************/
00151 WiconnectResult SocketInterface::tcpConnect(WiconnectSocket &socket, const char *host, uint16_t remortPort GPIO_IRQ_ARG)
00152 {
00153     return connect(socket, SOCKET_TYPE_TCP, host, remortPort, SOCKET_ANY_PORT, NULL GPIO_IRQ_PARAM);
00154 }
00155 
00156 /*************************************************************************************************/
00157 WiconnectResult SocketInterface::tlsConnect(WiconnectSocket &socket, const char *host, uint16_t remortPort, const char *certFilename GPIO_IRQ_ARG)
00158 {
00159     return connect(socket, SOCKET_TYPE_TLS, host, remortPort, SOCKET_ANY_PORT, certFilename GPIO_IRQ_PARAM);
00160 }
00161 
00162 /*************************************************************************************************/
00163 WiconnectResult SocketInterface::udpConnect(WiconnectSocket &socket, const char *host, uint16_t remortPort, uint16_t localPort GPIO_IRQ_ARG)
00164 {
00165     return connect(socket, SOCKET_TYPE_UDP, host, remortPort, localPort, NULL GPIO_IRQ_PARAM);
00166 }
00167 
00168 /*************************************************************************************************/
00169 WiconnectResult SocketInterface::httpConnect(WiconnectSocket &socket, const char *url, const HttpSocketArgs *args)
00170 {
00171 #ifdef WICONNECT_GPIO_IRQ_ENABLED
00172 #define IRQ_NC ,NC
00173 #else
00174 #define IRQ_NC
00175 #endif
00176     return connect(socket, SOCKET_TYPE_HTTP, url, SOCKET_ANY_PORT, SOCKET_ANY_PORT, args IRQ_NC);
00177 }
00178 
00179 /*************************************************************************************************/
00180 WiconnectResult SocketInterface::httpGet(WiconnectSocket &socket, const char *url, bool openOnly, const char *certFilename)
00181 {
00182     const HttpSocketArgs args =
00183     {
00184         NULL,
00185         certFilename,
00186         openOnly,
00187         SOCKET_HTTP_GET
00188     };
00189     return httpConnect(socket, url, &args);
00190 }
00191 
00192 /*************************************************************************************************/
00193 WiconnectResult SocketInterface::httpPost(WiconnectSocket &socket, const char *url, const char *contextType, bool openOnly, const char *certFilename)
00194 {
00195     const HttpSocketArgs args =
00196     {
00197         contextType,
00198         certFilename,
00199         openOnly,
00200         SOCKET_HTTP_POST
00201     };
00202     return httpConnect(socket, url, &args);
00203 }
00204 
00205 /*************************************************************************************************/
00206 WiconnectResult SocketInterface::httpHead(WiconnectSocket &socket, const char *url, const char *certFilename)
00207 {
00208     const HttpSocketArgs args =
00209     {
00210         NULL,
00211         certFilename,
00212         false,
00213         SOCKET_HTTP_HEAD
00214     };
00215     return httpConnect(socket, url, &args);
00216 }
00217 
00218 /*************************************************************************************************/
00219 WiconnectResult SocketInterface::httpAddHeader(WiconnectSocket &socket, const char *key, const char *value)
00220 {
00221     WiconnectResult result;
00222     char *cmdBuffer = wiconnect->internalBuffer;
00223 
00224     if(WICONNECT_IS_IDLE())
00225     {
00226         sprintf(cmdBuffer, "http_add_header %d %s %s", socket.getHandle(), key, value);
00227     }
00228 
00229     CHECK_OTHER_COMMAND_EXECUTING();
00230 
00231     result = wiconnect->sendCommand(cmdBuffer);
00232 
00233     CHECK_CLEANUP_COMMAND();
00234 
00235     return result;
00236 }
00237 
00238 /*************************************************************************************************/
00239 WiconnectResult SocketInterface::httpGetStatus(WiconnectSocket &socket, uint32_t *statusCodePtr)
00240 {
00241     WiconnectResult result;
00242 
00243     CHECK_OTHER_COMMAND_EXECUTING();
00244 
00245     result = wiconnect->sendCommand("http_read_status %d", socket.getHandle());
00246 
00247     CHECK_CLEANUP_COMMAND();
00248 
00249     return result;
00250 }
00251 
00252 /*************************************************************************************************/
00253 WiconnectResult SocketInterface::closeAllSockets()
00254 {
00255     WiconnectResult result;
00256 
00257     CHECK_OTHER_COMMAND_EXECUTING();
00258 
00259     result = wiconnect->sendCommand("close all");
00260 
00261     CHECK_CLEANUP_COMMAND();
00262 
00263     return result;
00264 }
00265 
00266 
00267 #ifdef WICONNECT_GPIO_IRQ_ENABLED
00268 /*************************************************************************************************/
00269 WiconnectResult SocketInterface::registerSocketIrqHandler(Pin irqPin, const Callback &handler)
00270 {
00271     PinToGpioMapper mapper = wiconnect->pinToGpioMapper;
00272     if(irqHandlers.pinIsRegistered(irqPin))
00273     {
00274         return WICONNECT_DUPLICATE;
00275     }
00276     else  if(mapper == NULL)
00277     {
00278         return WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL;
00279     }
00280     int8_t gpio = mapper(irqPin);
00281     if(gpio == -1)
00282     {
00283         return WICONNECT_PINNAME_TO_GPIO_NO_MAPPING;
00284     }
00285 
00286     return irqHandlers.registerHandler(irqPin, handler);
00287 }
00288 
00289 /*************************************************************************************************/
00290 WiconnectResult SocketInterface::unregisterSocketIrqHandler(Pin irqPin)
00291 {
00292     return irqHandlers.unregisterHandler(irqPin);
00293 }
00294 #endif
00295 
00296 /*************************************************************************************************/
00297 void SocketInterface::socketClosedCallback(const WiconnectSocket *socket)
00298 {
00299     const uint32_t handleMask = (1 << socket->handle);
00300     if(serverConnectedClientList & handleMask)
00301     {
00302         serverConnectedClientList &= ~handleMask;
00303     }
00304 }