leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Committer:
leothedragon
Date:
Tue May 04 08:55:12 2021 +0000
Revision:
0:8f0bb79ddd48
nmn

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leothedragon 0:8f0bb79ddd48 1 /* WizFi310 implementation of NetworkInterfaceAPI
leothedragon 0:8f0bb79ddd48 2 * Copyright (c) 2015 ARM Limited
leothedragon 0:8f0bb79ddd48 3 *
leothedragon 0:8f0bb79ddd48 4 * Licensed under the Apache License, Version 2.0 (the "License");
leothedragon 0:8f0bb79ddd48 5 * you may not use this file except in compliance with the License.
leothedragon 0:8f0bb79ddd48 6 * You may obtain a copy of the License at
leothedragon 0:8f0bb79ddd48 7 *
leothedragon 0:8f0bb79ddd48 8 * http://www.apache.org/licenses/LICENSE-2.0
leothedragon 0:8f0bb79ddd48 9 *
leothedragon 0:8f0bb79ddd48 10 * Unless required by applicable law or agreed to in writing, software
leothedragon 0:8f0bb79ddd48 11 * distributed under the License is distributed on an "AS IS" BASIS,
leothedragon 0:8f0bb79ddd48 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
leothedragon 0:8f0bb79ddd48 13 * See the License for the specific language governing permissions and
leothedragon 0:8f0bb79ddd48 14 * limitations under the License.
leothedragon 0:8f0bb79ddd48 15 */
leothedragon 0:8f0bb79ddd48 16
leothedragon 0:8f0bb79ddd48 17 /**
leothedragon 0:8f0bb79ddd48 18 ******************************************************************************
leothedragon 0:8f0bb79ddd48 19 * @file WizFi310Interface.h
leothedragon 0:8f0bb79ddd48 20 * @author Gateway Team
leothedragon 0:8f0bb79ddd48 21 * @brief Implementation file of the NetworkStack for the WizFi310 WiFi Device
leothedragon 0:8f0bb79ddd48 22 ******************************************************************************
leothedragon 0:8f0bb79ddd48 23 * @attention
leothedragon 0:8f0bb79ddd48 24 *
leothedragon 0:8f0bb79ddd48 25 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
leothedragon 0:8f0bb79ddd48 26 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
leothedragon 0:8f0bb79ddd48 27 * TIME. AS A RESULT, WIZnet SHALL NOT BE HELD LIABLE FOR ANY
leothedragon 0:8f0bb79ddd48 28 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
leothedragon 0:8f0bb79ddd48 29 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
leothedragon 0:8f0bb79ddd48 30 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
leothedragon 0:8f0bb79ddd48 31 *
leothedragon 0:8f0bb79ddd48 32 * <h2><center>&copy; COPYRIGHT 2017 WIZnet Co.,Ltd.</center></h2>
leothedragon 0:8f0bb79ddd48 33 ******************************************************************************
leothedragon 0:8f0bb79ddd48 34 */
leothedragon 0:8f0bb79ddd48 35
leothedragon 0:8f0bb79ddd48 36 #include <string.h>
leothedragon 0:8f0bb79ddd48 37 #include "WizFi310Interface.h"
leothedragon 0:8f0bb79ddd48 38 #include "mbed_trace.h"
leothedragon 0:8f0bb79ddd48 39
leothedragon 0:8f0bb79ddd48 40 #define TRACE_GROUP "WZ__"
leothedragon 0:8f0bb79ddd48 41
leothedragon 0:8f0bb79ddd48 42 using namespace mbed;
leothedragon 0:8f0bb79ddd48 43 // Various timeouts for different WizFi310 operations
leothedragon 0:8f0bb79ddd48 44 #ifndef WIZFI310_CONNECT_TIMEOUT
leothedragon 0:8f0bb79ddd48 45 #define WIZFI310_CONNECT_TIMEOUT 15000
leothedragon 0:8f0bb79ddd48 46 #endif
leothedragon 0:8f0bb79ddd48 47 #ifndef WIZFI310_SEND_TIMEOUT
leothedragon 0:8f0bb79ddd48 48 #define WIZFI310_SEND_TIMEOUT 500
leothedragon 0:8f0bb79ddd48 49 #endif
leothedragon 0:8f0bb79ddd48 50 #ifndef WIZFI310_RECV_TIMEOUT
leothedragon 0:8f0bb79ddd48 51 #define WIZFI310_RECV_TIMEOUT 0
leothedragon 0:8f0bb79ddd48 52 #endif
leothedragon 0:8f0bb79ddd48 53 #ifndef WIZFI310_MISC_TIMEOUT
leothedragon 0:8f0bb79ddd48 54 #define WIZFI310_MISC_TIMEOUT 500
leothedragon 0:8f0bb79ddd48 55 #endif
leothedragon 0:8f0bb79ddd48 56 #ifndef WIZFI310_OPEN_TIMEOUT
leothedragon 0:8f0bb79ddd48 57 #define WIZFI310_OPEN_TIMEOUT 10000
leothedragon 0:8f0bb79ddd48 58 #endif
leothedragon 0:8f0bb79ddd48 59 #ifndef WIZFI310_CLOSE_TIMEOUT
leothedragon 0:8f0bb79ddd48 60 #define WIZFI310_CLOSE_TIMEOUT 500
leothedragon 0:8f0bb79ddd48 61 #endif
leothedragon 0:8f0bb79ddd48 62
leothedragon 0:8f0bb79ddd48 63 #ifndef WIZFI310_MAX_CONNECT_COUNT
leothedragon 0:8f0bb79ddd48 64 #define WIZFI310_MAX_CONNECT 2
leothedragon 0:8f0bb79ddd48 65 #endif
leothedragon 0:8f0bb79ddd48 66
leothedragon 0:8f0bb79ddd48 67 #ifndef WIZFI310_DELAY_MS
leothedragon 0:8f0bb79ddd48 68 #define WIZFI310_DELAY_MS 300
leothedragon 0:8f0bb79ddd48 69 #endif
leothedragon 0:8f0bb79ddd48 70
leothedragon 0:8f0bb79ddd48 71 // =================================================================================================
leothedragon 0:8f0bb79ddd48 72 // helper functions
leothedragon 0:8f0bb79ddd48 73 static const char *sec2str(nsapi_security_t sec)
leothedragon 0:8f0bb79ddd48 74 {
leothedragon 0:8f0bb79ddd48 75 switch (sec) {
leothedragon 0:8f0bb79ddd48 76 case NSAPI_SECURITY_NONE:
leothedragon 0:8f0bb79ddd48 77 return "OPEN";
leothedragon 0:8f0bb79ddd48 78 case NSAPI_SECURITY_WEP:
leothedragon 0:8f0bb79ddd48 79 return "WEP";
leothedragon 0:8f0bb79ddd48 80 case NSAPI_SECURITY_WPA:
leothedragon 0:8f0bb79ddd48 81 return "WPA";
leothedragon 0:8f0bb79ddd48 82 case NSAPI_SECURITY_WPA2:
leothedragon 0:8f0bb79ddd48 83 return "WPA2";
leothedragon 0:8f0bb79ddd48 84 case NSAPI_SECURITY_WPA_WPA2:
leothedragon 0:8f0bb79ddd48 85 return "WPAWPA2";
leothedragon 0:8f0bb79ddd48 86 default:
leothedragon 0:8f0bb79ddd48 87 return "";
leothedragon 0:8f0bb79ddd48 88 }
leothedragon 0:8f0bb79ddd48 89 }
leothedragon 0:8f0bb79ddd48 90
leothedragon 0:8f0bb79ddd48 91 // =================================================================================================
leothedragon 0:8f0bb79ddd48 92 // WizFi310Interface implementation
leothedragon 0:8f0bb79ddd48 93 WizFi310Interface::WizFi310Interface(PinName tx, PinName rx, PinName rts, PinName cts, PinName rst) :
leothedragon 0:8f0bb79ddd48 94 m_wizfi310(tx, rx, rts, cts, rst),
leothedragon 0:8f0bb79ddd48 95 m_mutex("WizFi310Interface")
leothedragon 0:8f0bb79ddd48 96 {
leothedragon 0:8f0bb79ddd48 97 memset(ap_ssid, 0, sizeof(ap_ssid));
leothedragon 0:8f0bb79ddd48 98 memset(ap_pass, 0, sizeof(ap_pass));
leothedragon 0:8f0bb79ddd48 99 ap_sec = NSAPI_SECURITY_NONE;
leothedragon 0:8f0bb79ddd48 100 m_wizfi310.attach(Callback<void(nsapi_connection_status_t)>(this, &WizFi310Interface::link_status_change));
leothedragon 0:8f0bb79ddd48 101 }
leothedragon 0:8f0bb79ddd48 102
leothedragon 0:8f0bb79ddd48 103 void WizFi310Interface::link_status_change(nsapi_connection_status_t status)
leothedragon 0:8f0bb79ddd48 104 {
leothedragon 0:8f0bb79ddd48 105 if (m_on_status_change) {
leothedragon 0:8f0bb79ddd48 106 m_on_status_change(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, status);
leothedragon 0:8f0bb79ddd48 107 }
leothedragon 0:8f0bb79ddd48 108 m_semphr.release();
leothedragon 0:8f0bb79ddd48 109 }
leothedragon 0:8f0bb79ddd48 110
leothedragon 0:8f0bb79ddd48 111 // =================================================================================================
leothedragon 0:8f0bb79ddd48 112 // WiFi network api
leothedragon 0:8f0bb79ddd48 113
leothedragon 0:8f0bb79ddd48 114 nsapi_error_t WizFi310Interface::connect(
leothedragon 0:8f0bb79ddd48 115 const char *ssid,
leothedragon 0:8f0bb79ddd48 116 const char *pass,
leothedragon 0:8f0bb79ddd48 117 nsapi_security_t security,
leothedragon 0:8f0bb79ddd48 118 uint8_t channel)
leothedragon 0:8f0bb79ddd48 119 {
leothedragon 0:8f0bb79ddd48 120 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 121 nsapi_error_t res = set_channel(channel);
leothedragon 0:8f0bb79ddd48 122 if (res == NSAPI_ERROR_OK) {
leothedragon 0:8f0bb79ddd48 123 res = set_credentials(ssid, pass, security);
leothedragon 0:8f0bb79ddd48 124 }
leothedragon 0:8f0bb79ddd48 125 if (res == NSAPI_ERROR_OK) {
leothedragon 0:8f0bb79ddd48 126 res = connect();
leothedragon 0:8f0bb79ddd48 127 }
leothedragon 0:8f0bb79ddd48 128 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 129 return res;
leothedragon 0:8f0bb79ddd48 130 }
leothedragon 0:8f0bb79ddd48 131
leothedragon 0:8f0bb79ddd48 132 nsapi_error_t WizFi310Interface::connect()
leothedragon 0:8f0bb79ddd48 133 {
leothedragon 0:8f0bb79ddd48 134 if (strlen(ap_ssid) == 0) {
leothedragon 0:8f0bb79ddd48 135 return NSAPI_ERROR_PARAMETER;
leothedragon 0:8f0bb79ddd48 136 }
leothedragon 0:8f0bb79ddd48 137 if ((ap_sec != NSAPI_SECURITY_NONE) && ((strlen(ap_pass) == 0) || (strlen(ap_pass) >= 64))) {
leothedragon 0:8f0bb79ddd48 138 return NSAPI_ERROR_PARAMETER;
leothedragon 0:8f0bb79ddd48 139 }
leothedragon 0:8f0bb79ddd48 140 if (m_wizfi310.status() == NSAPI_STATUS_GLOBAL_UP) {
leothedragon 0:8f0bb79ddd48 141 return NSAPI_ERROR_IS_CONNECTED;
leothedragon 0:8f0bb79ddd48 142 } else if (m_wizfi310.status() == NSAPI_STATUS_CONNECTING) {
leothedragon 0:8f0bb79ddd48 143 return NSAPI_ERROR_WOULD_BLOCK;
leothedragon 0:8f0bb79ddd48 144 }
leothedragon 0:8f0bb79ddd48 145
leothedragon 0:8f0bb79ddd48 146 nsapi_error_t res = NSAPI_ERROR_OK;
leothedragon 0:8f0bb79ddd48 147
leothedragon 0:8f0bb79ddd48 148 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 149 if (!m_wizfi310.dhcp(true)) {
leothedragon 0:8f0bb79ddd48 150 res = NSAPI_ERROR_DHCP_FAILURE;
leothedragon 0:8f0bb79ddd48 151 } else {
leothedragon 0:8f0bb79ddd48 152 if (ap_sec == NSAPI_SECURITY_NONE && (strlen(ap_pass) > 0)) {
leothedragon 0:8f0bb79ddd48 153 ap_sec = NSAPI_SECURITY_UNKNOWN;
leothedragon 0:8f0bb79ddd48 154 }
leothedragon 0:8f0bb79ddd48 155
leothedragon 0:8f0bb79ddd48 156 m_semphr.wait(0);
leothedragon 0:8f0bb79ddd48 157 while ((res = m_wizfi310.connect(ap_ssid, ap_pass, sec2str(ap_sec))) == NSAPI_ERROR_WOULD_BLOCK) {
leothedragon 0:8f0bb79ddd48 158 wait_ms(10);
leothedragon 0:8f0bb79ddd48 159 }
leothedragon 0:8f0bb79ddd48 160 if (res == NSAPI_ERROR_IN_PROGRESS) {
leothedragon 0:8f0bb79ddd48 161 do {
leothedragon 0:8f0bb79ddd48 162 // wait for connect
leothedragon 0:8f0bb79ddd48 163 m_semphr.wait();
leothedragon 0:8f0bb79ddd48 164 } while (m_wizfi310.status() == NSAPI_STATUS_CONNECTING);
leothedragon 0:8f0bb79ddd48 165 res = (m_wizfi310.status() == NSAPI_STATUS_DISCONNECTED) ? NSAPI_ERROR_NO_CONNECTION : NSAPI_ERROR_OK;
leothedragon 0:8f0bb79ddd48 166 }
leothedragon 0:8f0bb79ddd48 167 }
leothedragon 0:8f0bb79ddd48 168 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 169
leothedragon 0:8f0bb79ddd48 170 return res;
leothedragon 0:8f0bb79ddd48 171 }
leothedragon 0:8f0bb79ddd48 172
leothedragon 0:8f0bb79ddd48 173 nsapi_error_t WizFi310Interface::set_channel(uint8_t chan)
leothedragon 0:8f0bb79ddd48 174 {
leothedragon 0:8f0bb79ddd48 175 if (chan != 0) {
leothedragon 0:8f0bb79ddd48 176 return NSAPI_ERROR_UNSUPPORTED;
leothedragon 0:8f0bb79ddd48 177 }
leothedragon 0:8f0bb79ddd48 178 return NSAPI_ERROR_OK;
leothedragon 0:8f0bb79ddd48 179 }
leothedragon 0:8f0bb79ddd48 180
leothedragon 0:8f0bb79ddd48 181 int WizFi310Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
leothedragon 0:8f0bb79ddd48 182 {
leothedragon 0:8f0bb79ddd48 183 if ((ssid == NULL) || (strlen(ssid) == 0)) {
leothedragon 0:8f0bb79ddd48 184 return NSAPI_ERROR_PARAMETER;
leothedragon 0:8f0bb79ddd48 185 }
leothedragon 0:8f0bb79ddd48 186 if ((security != NSAPI_SECURITY_NONE) && ((pass == NULL) || (strlen(pass) == 0) || (strlen(pass) >= 64))) {
leothedragon 0:8f0bb79ddd48 187 return NSAPI_ERROR_PARAMETER;
leothedragon 0:8f0bb79ddd48 188 }
leothedragon 0:8f0bb79ddd48 189
leothedragon 0:8f0bb79ddd48 190 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 191 memset(ap_ssid, 0, sizeof(ap_ssid));
leothedragon 0:8f0bb79ddd48 192 strncpy(ap_ssid, ssid, sizeof(ap_ssid));
leothedragon 0:8f0bb79ddd48 193
leothedragon 0:8f0bb79ddd48 194 memset(ap_pass, 0, sizeof(ap_pass));
leothedragon 0:8f0bb79ddd48 195 if (pass != NULL) {
leothedragon 0:8f0bb79ddd48 196 strncpy(ap_pass, pass, sizeof(ap_pass));
leothedragon 0:8f0bb79ddd48 197 }
leothedragon 0:8f0bb79ddd48 198
leothedragon 0:8f0bb79ddd48 199 ap_sec = security;
leothedragon 0:8f0bb79ddd48 200 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 201
leothedragon 0:8f0bb79ddd48 202 return NSAPI_ERROR_OK;
leothedragon 0:8f0bb79ddd48 203 }
leothedragon 0:8f0bb79ddd48 204
leothedragon 0:8f0bb79ddd48 205 int WizFi310Interface::disconnect()
leothedragon 0:8f0bb79ddd48 206 {
leothedragon 0:8f0bb79ddd48 207 nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
leothedragon 0:8f0bb79ddd48 208
leothedragon 0:8f0bb79ddd48 209 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 210 if (m_wizfi310.status() != NSAPI_STATUS_DISCONNECTED) {
leothedragon 0:8f0bb79ddd48 211 m_semphr.wait(0);
leothedragon 0:8f0bb79ddd48 212 while ((err = m_wizfi310.disconnect()) == NSAPI_ERROR_WOULD_BLOCK) {
leothedragon 0:8f0bb79ddd48 213 wait_ms(10);
leothedragon 0:8f0bb79ddd48 214 }
leothedragon 0:8f0bb79ddd48 215 if (err == NSAPI_ERROR_IN_PROGRESS) {
leothedragon 0:8f0bb79ddd48 216 while (m_wizfi310.status() != NSAPI_STATUS_DISCONNECTED) {
leothedragon 0:8f0bb79ddd48 217 m_semphr.wait();
leothedragon 0:8f0bb79ddd48 218 err = NSAPI_ERROR_OK;
leothedragon 0:8f0bb79ddd48 219 }
leothedragon 0:8f0bb79ddd48 220 }
leothedragon 0:8f0bb79ddd48 221 }
leothedragon 0:8f0bb79ddd48 222 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 223 return err;
leothedragon 0:8f0bb79ddd48 224 }
leothedragon 0:8f0bb79ddd48 225
leothedragon 0:8f0bb79ddd48 226 nsapi_connection_status_t WizFi310Interface::get_connection_status() const
leothedragon 0:8f0bb79ddd48 227 {
leothedragon 0:8f0bb79ddd48 228 return m_wizfi310.status();
leothedragon 0:8f0bb79ddd48 229 }
leothedragon 0:8f0bb79ddd48 230
leothedragon 0:8f0bb79ddd48 231 const char *WizFi310Interface::get_ip_address()
leothedragon 0:8f0bb79ddd48 232 {
leothedragon 0:8f0bb79ddd48 233 return m_wizfi310.get_ip_address();
leothedragon 0:8f0bb79ddd48 234 }
leothedragon 0:8f0bb79ddd48 235
leothedragon 0:8f0bb79ddd48 236 int8_t WizFi310Interface::get_rssi()
leothedragon 0:8f0bb79ddd48 237 {
leothedragon 0:8f0bb79ddd48 238 return 0;
leothedragon 0:8f0bb79ddd48 239 }
leothedragon 0:8f0bb79ddd48 240
leothedragon 0:8f0bb79ddd48 241 void WizFi310Interface::attach(Callback<void(nsapi_event_t, intptr_t)> status_cb)
leothedragon 0:8f0bb79ddd48 242 {
leothedragon 0:8f0bb79ddd48 243 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 244 m_on_status_change = status_cb;
leothedragon 0:8f0bb79ddd48 245 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 246 }
leothedragon 0:8f0bb79ddd48 247
leothedragon 0:8f0bb79ddd48 248 nsapi_size_or_error_t WizFi310Interface::scan(WiFiAccessPoint *res, nsapi_size_t count)
leothedragon 0:8f0bb79ddd48 249 {
leothedragon 0:8f0bb79ddd48 250 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 251 m_scan_ctx.res = res;
leothedragon 0:8f0bb79ddd48 252 m_scan_ctx.count = count;
leothedragon 0:8f0bb79ddd48 253 m_scan_ctx.idx = 0;
leothedragon 0:8f0bb79ddd48 254
leothedragon 0:8f0bb79ddd48 255 m_semphr.wait(0);
leothedragon 0:8f0bb79ddd48 256 nsapi_error_t err = m_wizfi310.scan(Callback<void(nsapi_wifi_ap_t *)>(this, &WizFi310Interface::scan_ap));
leothedragon 0:8f0bb79ddd48 257 if (err == NSAPI_ERROR_IN_PROGRESS) {
leothedragon 0:8f0bb79ddd48 258 m_semphr.wait();
leothedragon 0:8f0bb79ddd48 259 }
leothedragon 0:8f0bb79ddd48 260
leothedragon 0:8f0bb79ddd48 261 uint32_t total = m_scan_ctx.idx;
leothedragon 0:8f0bb79ddd48 262 if ((count != 0) && (count < total)) {
leothedragon 0:8f0bb79ddd48 263 total = count;
leothedragon 0:8f0bb79ddd48 264 }
leothedragon 0:8f0bb79ddd48 265 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 266 return total;
leothedragon 0:8f0bb79ddd48 267 }
leothedragon 0:8f0bb79ddd48 268
leothedragon 0:8f0bb79ddd48 269 void WizFi310Interface::scan_ap(nsapi_wifi_ap_t *ap)
leothedragon 0:8f0bb79ddd48 270 {
leothedragon 0:8f0bb79ddd48 271 if (ap == NULL) {
leothedragon 0:8f0bb79ddd48 272 m_semphr.release();
leothedragon 0:8f0bb79ddd48 273 return;
leothedragon 0:8f0bb79ddd48 274 }
leothedragon 0:8f0bb79ddd48 275 if (m_scan_ctx.idx < m_scan_ctx.count) {
leothedragon 0:8f0bb79ddd48 276 m_scan_ctx.res[m_scan_ctx.idx] = WiFiAccessPoint(*ap);
leothedragon 0:8f0bb79ddd48 277 }
leothedragon 0:8f0bb79ddd48 278 m_scan_ctx.idx += 1;
leothedragon 0:8f0bb79ddd48 279 }
leothedragon 0:8f0bb79ddd48 280
leothedragon 0:8f0bb79ddd48 281 // =================================================================================================
leothedragon 0:8f0bb79ddd48 282 // Socket API
leothedragon 0:8f0bb79ddd48 283 nsapi_error_t WizFi310Interface::socket_open(void **handle, nsapi_protocol_t proto)
leothedragon 0:8f0bb79ddd48 284 {
leothedragon 0:8f0bb79ddd48 285 tr_debug("socket_open(%p, %d)", handle, proto);
leothedragon 0:8f0bb79ddd48 286 if (handle == NULL) {
leothedragon 0:8f0bb79ddd48 287 tr_debug("socket_open()=%d,--", NSAPI_ERROR_PARAMETER);
leothedragon 0:8f0bb79ddd48 288 return NSAPI_ERROR_PARAMETER;
leothedragon 0:8f0bb79ddd48 289 }
leothedragon 0:8f0bb79ddd48 290
leothedragon 0:8f0bb79ddd48 291 // Look for an unused socket
leothedragon 0:8f0bb79ddd48 292 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 293 // limit the number of active socket to WIZFI310_SOCKET_COUNT
leothedragon 0:8f0bb79ddd48 294 if (m_socket_count == WIZFI310_SOCKET_COUNT) {
leothedragon 0:8f0bb79ddd48 295 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 296 tr_debug("socket_open()=%d,--", NSAPI_ERROR_NO_SOCKET);
leothedragon 0:8f0bb79ddd48 297 return NSAPI_ERROR_NO_SOCKET;
leothedragon 0:8f0bb79ddd48 298 }
leothedragon 0:8f0bb79ddd48 299
leothedragon 0:8f0bb79ddd48 300 struct wizfi310_socket *socket = new (std::nothrow) struct wizfi310_socket(m_wizfi310, proto);
leothedragon 0:8f0bb79ddd48 301 if (!socket) {
leothedragon 0:8f0bb79ddd48 302 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 303 tr_debug("socket_open()=%d,--", NSAPI_ERROR_NO_MEMORY);
leothedragon 0:8f0bb79ddd48 304 return NSAPI_ERROR_NO_MEMORY;
leothedragon 0:8f0bb79ddd48 305 }
leothedragon 0:8f0bb79ddd48 306 m_socket_count += 1;
leothedragon 0:8f0bb79ddd48 307 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 308
leothedragon 0:8f0bb79ddd48 309 *handle = socket;
leothedragon 0:8f0bb79ddd48 310 tr_debug("socket_open()=0,%p", socket);
leothedragon 0:8f0bb79ddd48 311
leothedragon 0:8f0bb79ddd48 312 return 0;
leothedragon 0:8f0bb79ddd48 313 }
leothedragon 0:8f0bb79ddd48 314
leothedragon 0:8f0bb79ddd48 315 int WizFi310Interface::socket_bind(void *handle, const SocketAddress &address)
leothedragon 0:8f0bb79ddd48 316 {
leothedragon 0:8f0bb79ddd48 317 return NSAPI_ERROR_UNSUPPORTED;
leothedragon 0:8f0bb79ddd48 318 }
leothedragon 0:8f0bb79ddd48 319
leothedragon 0:8f0bb79ddd48 320 int WizFi310Interface::socket_listen(void *handle, int backlog)
leothedragon 0:8f0bb79ddd48 321 {
leothedragon 0:8f0bb79ddd48 322 return NSAPI_ERROR_UNSUPPORTED;
leothedragon 0:8f0bb79ddd48 323 }
leothedragon 0:8f0bb79ddd48 324
leothedragon 0:8f0bb79ddd48 325 int WizFi310Interface::socket_connect(void *handle, const SocketAddress &addr)
leothedragon 0:8f0bb79ddd48 326 {
leothedragon 0:8f0bb79ddd48 327 struct wizfi310_socket *socket = (struct wizfi310_socket *)handle;
leothedragon 0:8f0bb79ddd48 328 if (addr.get_ip_version() != NSAPI_IPv4) {
leothedragon 0:8f0bb79ddd48 329 return NSAPI_ERROR_UNSUPPORTED;
leothedragon 0:8f0bb79ddd48 330 }
leothedragon 0:8f0bb79ddd48 331
leothedragon 0:8f0bb79ddd48 332 tr_debug("socket_connect(%p, %s:%u)", handle, addr.get_ip_address(), addr.get_port());
leothedragon 0:8f0bb79ddd48 333 socket->op_mtx.lock();
leothedragon 0:8f0bb79ddd48 334 nsapi_error_t res = NSAPI_ERROR_DEVICE_ERROR;
leothedragon 0:8f0bb79ddd48 335 if (socket->id >= 0) {
leothedragon 0:8f0bb79ddd48 336 if (socket->connected) {
leothedragon 0:8f0bb79ddd48 337 res = NSAPI_ERROR_IS_CONNECTED;
leothedragon 0:8f0bb79ddd48 338 } else {
leothedragon 0:8f0bb79ddd48 339 res = NSAPI_ERROR_ALREADY;
leothedragon 0:8f0bb79ddd48 340 }
leothedragon 0:8f0bb79ddd48 341 } else {
leothedragon 0:8f0bb79ddd48 342 socket->addr = addr;
leothedragon 0:8f0bb79ddd48 343 const char *proto = (socket->proto == NSAPI_UDP) ? "UCN" : "TCN";
leothedragon 0:8f0bb79ddd48 344 int id = NSAPI_ERROR_WOULD_BLOCK;
leothedragon 0:8f0bb79ddd48 345 while (id == NSAPI_ERROR_WOULD_BLOCK) {
leothedragon 0:8f0bb79ddd48 346 id = m_wizfi310.open(proto, addr.get_ip_address(), addr.get_port(), socket_event, socket);
leothedragon 0:8f0bb79ddd48 347 if (id == NSAPI_ERROR_WOULD_BLOCK) {
leothedragon 0:8f0bb79ddd48 348 wait_ms(1000);
leothedragon 0:8f0bb79ddd48 349 } else if (id < 0) {
leothedragon 0:8f0bb79ddd48 350 res = id;
leothedragon 0:8f0bb79ddd48 351 } else {
leothedragon 0:8f0bb79ddd48 352 socket->id = id;
leothedragon 0:8f0bb79ddd48 353 res = NSAPI_ERROR_IN_PROGRESS;
leothedragon 0:8f0bb79ddd48 354 }
leothedragon 0:8f0bb79ddd48 355 }
leothedragon 0:8f0bb79ddd48 356 }
leothedragon 0:8f0bb79ddd48 357 socket->op_mtx.unlock();
leothedragon 0:8f0bb79ddd48 358 tr_debug("socket_connect(%p,...)=(%d)%d", handle, socket->id, res);
leothedragon 0:8f0bb79ddd48 359 return res;
leothedragon 0:8f0bb79ddd48 360 }
leothedragon 0:8f0bb79ddd48 361
leothedragon 0:8f0bb79ddd48 362 int WizFi310Interface::socket_accept(void *server, void **socket, SocketAddress *addr)
leothedragon 0:8f0bb79ddd48 363 {
leothedragon 0:8f0bb79ddd48 364 return NSAPI_ERROR_UNSUPPORTED;
leothedragon 0:8f0bb79ddd48 365 }
leothedragon 0:8f0bb79ddd48 366
leothedragon 0:8f0bb79ddd48 367 int WizFi310Interface::socket_send(void *handle, const void *data, unsigned size)
leothedragon 0:8f0bb79ddd48 368 {
leothedragon 0:8f0bb79ddd48 369 tr_debug("socket_send(%p, %p, %u)", handle, data, size);
leothedragon 0:8f0bb79ddd48 370 if (size == 0) {
leothedragon 0:8f0bb79ddd48 371 return 0;
leothedragon 0:8f0bb79ddd48 372 }
leothedragon 0:8f0bb79ddd48 373 struct wizfi310_socket *socket = (struct wizfi310_socket *)handle;
leothedragon 0:8f0bb79ddd48 374 socket->op_mtx.lock();
leothedragon 0:8f0bb79ddd48 375 if (!socket->connected) {
leothedragon 0:8f0bb79ddd48 376 socket->op_mtx.unlock();
leothedragon 0:8f0bb79ddd48 377 return NSAPI_ERROR_NO_CONNECTION;
leothedragon 0:8f0bb79ddd48 378 }
leothedragon 0:8f0bb79ddd48 379 nsapi_error_t res;
leothedragon 0:8f0bb79ddd48 380 do {
leothedragon 0:8f0bb79ddd48 381 socket->semphr.wait(0);
leothedragon 0:8f0bb79ddd48 382 res = m_wizfi310.send(socket->id, data, size);
leothedragon 0:8f0bb79ddd48 383 if (res == NSAPI_ERROR_WOULD_BLOCK) {
leothedragon 0:8f0bb79ddd48 384 wait_ms(10);
leothedragon 0:8f0bb79ddd48 385 }
leothedragon 0:8f0bb79ddd48 386 } while (res == NSAPI_ERROR_WOULD_BLOCK);
leothedragon 0:8f0bb79ddd48 387 if (res == NSAPI_ERROR_IN_PROGRESS) {
leothedragon 0:8f0bb79ddd48 388 socket->semphr.wait();
leothedragon 0:8f0bb79ddd48 389 res = size;
leothedragon 0:8f0bb79ddd48 390 }
leothedragon 0:8f0bb79ddd48 391 socket->op_mtx.unlock();
leothedragon 0:8f0bb79ddd48 392 tr_debug("socket_send(%p, %p, %u)=%d", handle, data, size, res);
leothedragon 0:8f0bb79ddd48 393 return res;
leothedragon 0:8f0bb79ddd48 394 }
leothedragon 0:8f0bb79ddd48 395
leothedragon 0:8f0bb79ddd48 396 int WizFi310Interface::socket_recv(void *handle, void *data, unsigned size)
leothedragon 0:8f0bb79ddd48 397 {
leothedragon 0:8f0bb79ddd48 398 tr_debug("socket_recv(%p, %p, %u)", handle, data, size);
leothedragon 0:8f0bb79ddd48 399 struct wizfi310_socket *s = (struct wizfi310_socket *)handle;
leothedragon 0:8f0bb79ddd48 400 int32_t read = NSAPI_ERROR_WOULD_BLOCK;
leothedragon 0:8f0bb79ddd48 401 Packet *p = NULL;
leothedragon 0:8f0bb79ddd48 402
leothedragon 0:8f0bb79ddd48 403 s->state_mtx.lock();
leothedragon 0:8f0bb79ddd48 404 if (s->first != NULL) {
leothedragon 0:8f0bb79ddd48 405 p = s->first;
leothedragon 0:8f0bb79ddd48 406
leothedragon 0:8f0bb79ddd48 407 uint32_t plen = p->len();
leothedragon 0:8f0bb79ddd48 408 read = p->consume((char *)data, size);
leothedragon 0:8f0bb79ddd48 409 tr_debug("%d: f: %p l: %p; read: %lu/%lu", __LINE__, s->first, s->last, read, plen);
leothedragon 0:8f0bb79ddd48 410 (void)plen;
leothedragon 0:8f0bb79ddd48 411 if (p->len() == 0) {
leothedragon 0:8f0bb79ddd48 412 s->first = p->next();
leothedragon 0:8f0bb79ddd48 413 if (s->first == NULL) {
leothedragon 0:8f0bb79ddd48 414 s->last = NULL;
leothedragon 0:8f0bb79ddd48 415 } else {
leothedragon 0:8f0bb79ddd48 416 p->set_next(NULL); // detach head from the rest
leothedragon 0:8f0bb79ddd48 417 }
leothedragon 0:8f0bb79ddd48 418 delete p;
leothedragon 0:8f0bb79ddd48 419
leothedragon 0:8f0bb79ddd48 420 // TODO: we need a way to signal the driver that we made some space for further reception
leothedragon 0:8f0bb79ddd48 421 }
leothedragon 0:8f0bb79ddd48 422 tr_debug("%d: f: %p l: %p", __LINE__, s->first, s->last);
leothedragon 0:8f0bb79ddd48 423 } else if (!s->connected) {
leothedragon 0:8f0bb79ddd48 424 read = 0;
leothedragon 0:8f0bb79ddd48 425 }
leothedragon 0:8f0bb79ddd48 426 s->state_mtx.unlock();
leothedragon 0:8f0bb79ddd48 427 tr_debug("socket_recv(%p, %p, %u)=%ld", s, data, size, read);
leothedragon 0:8f0bb79ddd48 428 return read;
leothedragon 0:8f0bb79ddd48 429 }
leothedragon 0:8f0bb79ddd48 430
leothedragon 0:8f0bb79ddd48 431 int WizFi310Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
leothedragon 0:8f0bb79ddd48 432 {
leothedragon 0:8f0bb79ddd48 433 if (addr.get_ip_version() != NSAPI_IPv4) {
leothedragon 0:8f0bb79ddd48 434 return NSAPI_ERROR_PARAMETER;
leothedragon 0:8f0bb79ddd48 435 }
leothedragon 0:8f0bb79ddd48 436 nsapi_error_t res;
leothedragon 0:8f0bb79ddd48 437
leothedragon 0:8f0bb79ddd48 438 tr_debug("socket_sendto(%p, %s:%hu, %p, %u)", handle, addr.get_ip_address(), (uint16_t)addr.get_port(), data, size);
leothedragon 0:8f0bb79ddd48 439 struct wizfi310_socket *socket = (struct wizfi310_socket *)handle;
leothedragon 0:8f0bb79ddd48 440 socket->op_mtx.lock();
leothedragon 0:8f0bb79ddd48 441 if (socket->connected && socket->addr != addr) {
leothedragon 0:8f0bb79ddd48 442 socket->close();
leothedragon 0:8f0bb79ddd48 443 }
leothedragon 0:8f0bb79ddd48 444 res = socket_connect(socket, addr);
leothedragon 0:8f0bb79ddd48 445 if ((res == NSAPI_ERROR_IN_PROGRESS) || (res == NSAPI_ERROR_ALREADY) || (res == NSAPI_ERROR_IS_CONNECTED)) {
leothedragon 0:8f0bb79ddd48 446 if (!socket->connected) {
leothedragon 0:8f0bb79ddd48 447 socket->semphr.wait();
leothedragon 0:8f0bb79ddd48 448 }
leothedragon 0:8f0bb79ddd48 449 if (!socket->connected) {
leothedragon 0:8f0bb79ddd48 450 res = NSAPI_ERROR_NO_CONNECTION;
leothedragon 0:8f0bb79ddd48 451 } else {
leothedragon 0:8f0bb79ddd48 452 res = socket_send(socket, data, size);
leothedragon 0:8f0bb79ddd48 453 }
leothedragon 0:8f0bb79ddd48 454 }
leothedragon 0:8f0bb79ddd48 455 socket->op_mtx.unlock();
leothedragon 0:8f0bb79ddd48 456 return res;
leothedragon 0:8f0bb79ddd48 457 }
leothedragon 0:8f0bb79ddd48 458 int WizFi310Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
leothedragon 0:8f0bb79ddd48 459 {
leothedragon 0:8f0bb79ddd48 460 tr_debug("socket_recvfrom(%p, %p, %u)", handle, data, size);
leothedragon 0:8f0bb79ddd48 461 struct wizfi310_socket *socket = (struct wizfi310_socket *)handle;
leothedragon 0:8f0bb79ddd48 462 int ret = socket_recv(socket, data, size);
leothedragon 0:8f0bb79ddd48 463 if (ret >= 0 && addr) {
leothedragon 0:8f0bb79ddd48 464 *addr = socket->addr;
leothedragon 0:8f0bb79ddd48 465 }
leothedragon 0:8f0bb79ddd48 466
leothedragon 0:8f0bb79ddd48 467 return ret;
leothedragon 0:8f0bb79ddd48 468 }
leothedragon 0:8f0bb79ddd48 469
leothedragon 0:8f0bb79ddd48 470 nsapi_error_t WizFi310Interface::socket_close(void *handle)
leothedragon 0:8f0bb79ddd48 471 {
leothedragon 0:8f0bb79ddd48 472 struct wizfi310_socket *socket = (struct wizfi310_socket *)handle;
leothedragon 0:8f0bb79ddd48 473 tr_debug("socket_close(%p)", handle);
leothedragon 0:8f0bb79ddd48 474
leothedragon 0:8f0bb79ddd48 475 m_mutex.lock();
leothedragon 0:8f0bb79ddd48 476 socket->close();
leothedragon 0:8f0bb79ddd48 477 m_socket_count -= 1;
leothedragon 0:8f0bb79ddd48 478 m_mutex.unlock();
leothedragon 0:8f0bb79ddd48 479 delete socket;
leothedragon 0:8f0bb79ddd48 480
leothedragon 0:8f0bb79ddd48 481 return NSAPI_ERROR_OK;
leothedragon 0:8f0bb79ddd48 482 }
leothedragon 0:8f0bb79ddd48 483 void WizFi310Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
leothedragon 0:8f0bb79ddd48 484 {
leothedragon 0:8f0bb79ddd48 485 tr_debug("socket_attach(%p, %p, %p)", handle, callback, data);
leothedragon 0:8f0bb79ddd48 486 struct wizfi310_socket *socket = (struct wizfi310_socket *)handle;
leothedragon 0:8f0bb79ddd48 487 socket->state_mtx.lock();
leothedragon 0:8f0bb79ddd48 488 socket->cbk = callback;
leothedragon 0:8f0bb79ddd48 489 socket->data = data;
leothedragon 0:8f0bb79ddd48 490 socket->state_mtx.unlock();
leothedragon 0:8f0bb79ddd48 491 }
leothedragon 0:8f0bb79ddd48 492
leothedragon 0:8f0bb79ddd48 493 void WizFi310Interface::socket_event(void *ctx, WizFi310::socket_event_t type, WizFi310::socket_event_data_t &data)
leothedragon 0:8f0bb79ddd48 494 {
leothedragon 0:8f0bb79ddd48 495 struct wizfi310_socket *s = (struct wizfi310_socket *)ctx;
leothedragon 0:8f0bb79ddd48 496 tr_debug("socket_event(%p, %s)", ctx, WizFi310::event2str(type));
leothedragon 0:8f0bb79ddd48 497 s->state_mtx.lock();
leothedragon 0:8f0bb79ddd48 498 switch (type) {
leothedragon 0:8f0bb79ddd48 499 case WizFi310::EventConnected: {
leothedragon 0:8f0bb79ddd48 500 s->connected = true;
leothedragon 0:8f0bb79ddd48 501 s->semphr.release();
leothedragon 0:8f0bb79ddd48 502 break;
leothedragon 0:8f0bb79ddd48 503 }
leothedragon 0:8f0bb79ddd48 504 case WizFi310::EventDataReceived: {
leothedragon 0:8f0bb79ddd48 505 tr_debug("%d: Data received: %p (f:%p l:%p)", __LINE__, data.data_received.packet, s->first, s->last);
leothedragon 0:8f0bb79ddd48 506 if (s->last == NULL) {
leothedragon 0:8f0bb79ddd48 507 s->last = data.data_received.packet;
leothedragon 0:8f0bb79ddd48 508 s->first = s->last;
leothedragon 0:8f0bb79ddd48 509 } else {
leothedragon 0:8f0bb79ddd48 510 s->last->set_next(data.data_received.packet);
leothedragon 0:8f0bb79ddd48 511 s->last = data.data_received.packet;
leothedragon 0:8f0bb79ddd48 512 }
leothedragon 0:8f0bb79ddd48 513 tr_debug("%d: f: %p l: %p", __LINE__, s->first, s->last);
leothedragon 0:8f0bb79ddd48 514 break;
leothedragon 0:8f0bb79ddd48 515 }
leothedragon 0:8f0bb79ddd48 516 case WizFi310::EventDataSent: {
leothedragon 0:8f0bb79ddd48 517 s->semphr.release();
leothedragon 0:8f0bb79ddd48 518 break;
leothedragon 0:8f0bb79ddd48 519 }
leothedragon 0:8f0bb79ddd48 520 case WizFi310::EventDisconnected: {
leothedragon 0:8f0bb79ddd48 521 s->connected = false;
leothedragon 0:8f0bb79ddd48 522 s->id = -1;
leothedragon 0:8f0bb79ddd48 523 // TODO: on recv transfer the packet owner ship to this layer as we may be disconnected before those data are actually read.
leothedragon 0:8f0bb79ddd48 524 // This would also remove the need of the WizFi310::recv method.
leothedragon 0:8f0bb79ddd48 525 s->semphr.release();
leothedragon 0:8f0bb79ddd48 526 break;
leothedragon 0:8f0bb79ddd48 527 }
leothedragon 0:8f0bb79ddd48 528 default: {
leothedragon 0:8f0bb79ddd48 529 // tr_error("Unknown event %d", type);
leothedragon 0:8f0bb79ddd48 530 break;
leothedragon 0:8f0bb79ddd48 531 }
leothedragon 0:8f0bb79ddd48 532 }
leothedragon 0:8f0bb79ddd48 533 if (s->cbk) {
leothedragon 0:8f0bb79ddd48 534 s->cbk(s->data);
leothedragon 0:8f0bb79ddd48 535 }
leothedragon 0:8f0bb79ddd48 536 s->state_mtx.unlock();
leothedragon 0:8f0bb79ddd48 537 }
leothedragon 0:8f0bb79ddd48 538
leothedragon 0:8f0bb79ddd48 539 void WizFi310Interface::wizfi310_socket::close()
leothedragon 0:8f0bb79ddd48 540 {
leothedragon 0:8f0bb79ddd48 541 // no lock required here as no other thread shall access this object as it is freed.
leothedragon 0:8f0bb79ddd48 542 state_mtx.lock();
leothedragon 0:8f0bb79ddd48 543 int id = this->id;
leothedragon 0:8f0bb79ddd48 544 this->id = -1;
leothedragon 0:8f0bb79ddd48 545 state_mtx.unlock();
leothedragon 0:8f0bb79ddd48 546 if (id >= 0) {
leothedragon 0:8f0bb79ddd48 547 wifi.close(id);
leothedragon 0:8f0bb79ddd48 548 }
leothedragon 0:8f0bb79ddd48 549 }
leothedragon 0:8f0bb79ddd48 550
leothedragon 0:8f0bb79ddd48 551 WizFi310Interface::wizfi310_socket::~wizfi310_socket()
leothedragon 0:8f0bb79ddd48 552 {
leothedragon 0:8f0bb79ddd48 553 close();
leothedragon 0:8f0bb79ddd48 554 if (first != NULL) {
leothedragon 0:8f0bb79ddd48 555 delete first;
leothedragon 0:8f0bb79ddd48 556 }
leothedragon 0:8f0bb79ddd48 557 }
leothedragon 0:8f0bb79ddd48 558
leothedragon 0:8f0bb79ddd48 559 #ifdef MBED_CONF_WIZFI310_PROVIDE_DEFAULT
leothedragon 0:8f0bb79ddd48 560
leothedragon 0:8f0bb79ddd48 561 WiFiInterface *WiFiInterface::get_default_instance()
leothedragon 0:8f0bb79ddd48 562 {
leothedragon 0:8f0bb79ddd48 563 static WizFi310Interface wizfi;
leothedragon 0:8f0bb79ddd48 564 return &wizfi;
leothedragon 0:8f0bb79ddd48 565 }
leothedragon 0:8f0bb79ddd48 566
leothedragon 0:8f0bb79ddd48 567 #endif