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
Diff: SocketInterface.cpp
- Revision:
- 29:b6af04b77a56
- Child:
- 40:4b4306f3d829
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SocketInterface.cpp Mon Oct 27 13:42:26 2014 -0700 @@ -0,0 +1,304 @@ +/** + * ACKme WiConnect Host Library is licensed under the BSD licence: + * + * Copyright (c)2014 ACKme Networks. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include <string.h> +#include "Wiconnect.h" +#include "internal/common.h" +#include "api/StringUtil.h" + +#ifdef WICONNECT_GPIO_IRQ_ENABLED +#include "api/types/SocketIrqHandlerMap.h" +#endif + + +/*************************************************************************************************/ +SocketInterface::SocketInterface(Wiconnect *wiconnect_) +{ + wiconnect = wiconnect_; + serverConnectedClientList = 0; +} + +/*************************************************************************************************/ +SocketInterface::~SocketInterface() +{ +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::connect(WiconnectSocket &socket, SocketType type, const char *host, uint16_t remortPort, uint16_t localPort, const void *args GPIO_IRQ_ARG) +{ + WiconnectResult result; + int32_t handle; + char *cmdBuffer = wiconnect->internalBuffer; + + if(WICONNECT_IS_IDLE()) + { + char gpioOption[8] = ""; + +#ifdef WICONNECT_GPIO_IRQ_ENABLED + if(irqPin != PIN_NC) + { + PinToGpioMapper mapper = wiconnect->pinToGpioMapper; + if(mapper == NULL) + { + return WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL; + } + int8_t gpio = mapper(irqPin); + if(gpio == -1) + { + return WICONNECT_PINNAME_TO_GPIO_NO_MAPPING; + } + else if(!irqHandlers.pinIsRegistered(irqPin)) + { + return WICONNECT_NOT_FOUND; + } + + sprintf(gpioOption, "-g %d ", gpio); + } +#endif + + switch(type) + { + case SOCKET_TYPE_TCP: + sprintf(cmdBuffer, "tcpc %s%s %d", gpioOption, host, remortPort); + break; + + case SOCKET_TYPE_UDP: { + char tmp[16]; + sprintf(cmdBuffer, "udpc %s%s %d %s", gpioOption, host, remortPort, + (localPort != SOCKET_ANY_PORT) ? StringUtil::uint32ToStr(tmp, localPort) : ""); + } break; + + case SOCKET_TYPE_TLS: + sprintf(cmdBuffer, "tlsc %s%s %d %s", gpioOption, host, remortPort, + (args != NULL) ? (char*)args : ""); + break; + + case SOCKET_TYPE_HTTP: { + const HttpSocketArgs *httpArgs = (const HttpSocketArgs*)args; + switch(httpArgs->type) + { + case SOCKET_HTTP_GET: + sprintf(cmdBuffer, "http_get %s%s %s", httpArgs->openOnly ? "-o " : "", + host, + (httpArgs->certName != NULL) ? httpArgs->certName : ""); + break; + + case SOCKET_HTTP_HEAD: + sprintf(cmdBuffer, "http_head %s%s %s", httpArgs->openOnly ? "-o " : "", + host, + (httpArgs->certName != NULL) ? httpArgs->certName : ""); + break; + + case SOCKET_HTTP_POST: + sprintf(cmdBuffer, "http_post %s%s %s %s", httpArgs->openOnly ? "-o " : "", + host, + httpArgs->contextType, + (httpArgs->certName != NULL) ? httpArgs->certName : ""); + break; + + default: + return WICONNECT_BAD_ARG; + } + + } break; + default: + return WICONNECT_BAD_ARG; + } + } + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(cmdBuffer))) + { + if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&handle))) + { + socket.init(handle, type, host, remortPort, localPort); + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::tcpConnect(WiconnectSocket &socket, const char *host, uint16_t remortPort GPIO_IRQ_ARG) +{ + return connect(socket, SOCKET_TYPE_TCP, host, remortPort, SOCKET_ANY_PORT, NULL GPIO_IRQ_PARAM); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::tlsConnect(WiconnectSocket &socket, const char *host, uint16_t remortPort, const char *certFilename GPIO_IRQ_ARG) +{ + return connect(socket, SOCKET_TYPE_TLS, host, remortPort, SOCKET_ANY_PORT, certFilename GPIO_IRQ_PARAM); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::udpConnect(WiconnectSocket &socket, const char *host, uint16_t remortPort, uint16_t localPort GPIO_IRQ_ARG) +{ + return connect(socket, SOCKET_TYPE_UDP, host, remortPort, localPort, NULL GPIO_IRQ_PARAM); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpConnect(WiconnectSocket &socket, const char *url, const HttpSocketArgs *args) +{ +#ifdef WICONNECT_GPIO_IRQ_ENABLED +#define IRQ_NC ,NC +#else +#define IRQ_NC +#endif + return connect(socket, SOCKET_TYPE_HTTP, url, SOCKET_ANY_PORT, SOCKET_ANY_PORT, args IRQ_NC); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpGet(WiconnectSocket &socket, const char *url, bool openOnly, const char *certFilename) +{ + const HttpSocketArgs args = + { + NULL, + certFilename, + openOnly, + SOCKET_HTTP_GET + }; + return httpConnect(socket, url, &args); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpPost(WiconnectSocket &socket, const char *url, const char *contextType, bool openOnly, const char *certFilename) +{ + const HttpSocketArgs args = + { + contextType, + certFilename, + openOnly, + SOCKET_HTTP_POST + }; + return httpConnect(socket, url, &args); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpHead(WiconnectSocket &socket, const char *url, const char *certFilename) +{ + const HttpSocketArgs args = + { + NULL, + certFilename, + false, + SOCKET_HTTP_HEAD + }; + return httpConnect(socket, url, &args); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpAddHeader(WiconnectSocket &socket, const char *key, const char *value) +{ + WiconnectResult result; + char *cmdBuffer = wiconnect->internalBuffer; + + if(WICONNECT_IS_IDLE()) + { + sprintf(cmdBuffer, "http_add_header %d %s %s", socket.getHandle(), key, value); + } + + CHECK_OTHER_COMMAND_EXECUTING(); + + result = wiconnect->sendCommand(cmdBuffer); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpGetStatus(WiconnectSocket &socket, uint32_t *statusCodePtr) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + result = wiconnect->sendCommand("http_read_status %d", socket.getHandle()); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::closeAllSockets() +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + result = wiconnect->sendCommand("close all"); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + +#ifdef WICONNECT_GPIO_IRQ_ENABLED +/*************************************************************************************************/ +WiconnectResult SocketInterface::registerSocketIrqHandler(Pin irqPin, const Callback &handler) +{ + PinToGpioMapper mapper = wiconnect->pinToGpioMapper; + if(irqHandlers.pinIsRegistered(irqPin)) + { + return WICONNECT_DUPLICATE; + } + else if(mapper == NULL) + { + return WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL; + } + int8_t gpio = mapper(irqPin); + if(gpio == -1) + { + return WICONNECT_PINNAME_TO_GPIO_NO_MAPPING; + } + + return irqHandlers.registerHandler(irqPin, handler); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::unregisterSocketIrqHandler(Pin irqPin) +{ + return irqHandlers.unregisterHandler(irqPin); +} +#endif + +/*************************************************************************************************/ +void SocketInterface::socketClosedCallback(const WiconnectSocket *socket) +{ + const uint32_t handleMask = (1 << socket->handle); + if(serverConnectedClientList & handleMask) + { + serverConnectedClientList &= ~handleMask; + } +}