Axel Hwang / Mbed OS ProjetIOT
Committer:
axelhwang
Date:
Wed Oct 28 07:42:46 2020 +0000
Revision:
0:5738799d7a56
Push

Who changed what in which revision?

UserRevisionLine numberNew contents of line
axelhwang 0:5738799d7a56 1 /* ISM43362 implementation of NetworkInterfaceAPI
axelhwang 0:5738799d7a56 2 * Copyright (c) STMicroelectronics 2017
axelhwang 0:5738799d7a56 3 *
axelhwang 0:5738799d7a56 4 * Licensed under the Apache License, Version 2.0 (the "License");
axelhwang 0:5738799d7a56 5 * you may not use this file except in compliance with the License.
axelhwang 0:5738799d7a56 6 * You may obtain a copy of the License at
axelhwang 0:5738799d7a56 7 *
axelhwang 0:5738799d7a56 8 * http://www.apache.org/licenses/LICENSE-2.0
axelhwang 0:5738799d7a56 9 *
axelhwang 0:5738799d7a56 10 * Unless required by applicable law or agreed to in writing, software
axelhwang 0:5738799d7a56 11 * distributed under the License is distributed on an "AS IS" BASIS,
axelhwang 0:5738799d7a56 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
axelhwang 0:5738799d7a56 13 * See the License for the specific language governing permissions and
axelhwang 0:5738799d7a56 14 * limitations under the License.
axelhwang 0:5738799d7a56 15 */
axelhwang 0:5738799d7a56 16
axelhwang 0:5738799d7a56 17 #include <string.h>
axelhwang 0:5738799d7a56 18 #include "ISM43362Interface.h"
axelhwang 0:5738799d7a56 19 #include "mbed_debug.h"
axelhwang 0:5738799d7a56 20
axelhwang 0:5738799d7a56 21 // ao activate / de-activate debug
axelhwang 0:5738799d7a56 22 #define ism_debug false
axelhwang 0:5738799d7a56 23
axelhwang 0:5738799d7a56 24 // Various timeouts for different ISM43362 operations
axelhwang 0:5738799d7a56 25 #define ISM43362_CONNECT_TIMEOUT 15000 /* milliseconds */
axelhwang 0:5738799d7a56 26 #define ISM43362_SEND_TIMEOUT 1000 /* milliseconds */
axelhwang 0:5738799d7a56 27 #define ISM43362_RECV_TIMEOUT 100 /* milliseconds */
axelhwang 0:5738799d7a56 28 #define ISM43362_MISC_TIMEOUT 100 /* milliseconds */
axelhwang 0:5738799d7a56 29
axelhwang 0:5738799d7a56 30 // Tested firmware versions
axelhwang 0:5738799d7a56 31 // Example of versions string returned by the module:
axelhwang 0:5738799d7a56 32 // "ISM43362-M3G-L44-SPI,C3.5.2.3.BETA9,v3.5.2,v1.4.0.rc1,v8.2.1,120000000,Inventek eS-WiFi"
axelhwang 0:5738799d7a56 33 // "ISM43362-M3G-L44-SPI,C3.5.2.2,v3.5.2,v1.4.0.rc1,v8.2.1,120000000,Inventek eS-WiFi"
axelhwang 0:5738799d7a56 34 // Only the first version is checked !
axelhwang 0:5738799d7a56 35 const char supported_fw_versions[2][15] = {"C3.5.2.3.BETA9", "C3.5.2.2"};
axelhwang 0:5738799d7a56 36
axelhwang 0:5738799d7a56 37 #define MIN(a,b) (((a)<(b))?(a):(b))
axelhwang 0:5738799d7a56 38
axelhwang 0:5738799d7a56 39 // ISM43362Interface implementation
axelhwang 0:5738799d7a56 40 ISM43362Interface::ISM43362Interface(PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset, PinName datareadypin, PinName wakeup, bool debug)
axelhwang 0:5738799d7a56 41 : _ism(mosi, miso, sclk, nss, reset, datareadypin, wakeup, debug)
axelhwang 0:5738799d7a56 42 {
axelhwang 0:5738799d7a56 43 memset(_ids, 0, sizeof(_ids));
axelhwang 0:5738799d7a56 44 memset(_socket_obj, 0, sizeof(_socket_obj));
axelhwang 0:5738799d7a56 45 memset(_cbs, 0, sizeof(_cbs));
axelhwang 0:5738799d7a56 46 thread_read_socket.start(callback(this, &ISM43362Interface::socket_check_read));
axelhwang 0:5738799d7a56 47 }
axelhwang 0:5738799d7a56 48
axelhwang 0:5738799d7a56 49 int ISM43362Interface::connect(const char *ssid, const char *pass, nsapi_security_t security,
axelhwang 0:5738799d7a56 50 uint8_t channel)
axelhwang 0:5738799d7a56 51 {
axelhwang 0:5738799d7a56 52 if (channel != 0) {
axelhwang 0:5738799d7a56 53 return NSAPI_ERROR_UNSUPPORTED;
axelhwang 0:5738799d7a56 54 }
axelhwang 0:5738799d7a56 55
axelhwang 0:5738799d7a56 56 set_credentials(ssid, pass, security);
axelhwang 0:5738799d7a56 57 return connect();
axelhwang 0:5738799d7a56 58 }
axelhwang 0:5738799d7a56 59
axelhwang 0:5738799d7a56 60 int ISM43362Interface::connect()
axelhwang 0:5738799d7a56 61 {
axelhwang 0:5738799d7a56 62 _mutex.lock();
axelhwang 0:5738799d7a56 63 const char* read_version;
axelhwang 0:5738799d7a56 64
axelhwang 0:5738799d7a56 65 _ism.setTimeout(ISM43362_MISC_TIMEOUT);
axelhwang 0:5738799d7a56 66
axelhwang 0:5738799d7a56 67 // Check all supported firmware versions
axelhwang 0:5738799d7a56 68 read_version = _ism.get_firmware_version();
axelhwang 0:5738799d7a56 69
axelhwang 0:5738799d7a56 70 if (!read_version) {
axelhwang 0:5738799d7a56 71 debug_if(ism_debug, "ISM43362: ERROR cannot read firmware version\r\n");
axelhwang 0:5738799d7a56 72 return NSAPI_ERROR_DEVICE_ERROR;
axelhwang 0:5738799d7a56 73 }
axelhwang 0:5738799d7a56 74 debug_if(ism_debug, "ISM43362: read_version = [%s]\r\n", read_version);
axelhwang 0:5738799d7a56 75
axelhwang 0:5738799d7a56 76 if ((strcmp(read_version, supported_fw_versions[0]) == 0) || (strcmp(read_version, supported_fw_versions[1]) == 0)) {
axelhwang 0:5738799d7a56 77 debug_if(ism_debug, "ISM43362: firmware version is OK\r\n");
axelhwang 0:5738799d7a56 78 } else {
axelhwang 0:5738799d7a56 79 debug_if(ism_debug, "ISM43362: WARNING this firmware version has not been tested !\r\n");
axelhwang 0:5738799d7a56 80 }
axelhwang 0:5738799d7a56 81
axelhwang 0:5738799d7a56 82 if (!_ism.dhcp(true)) {
axelhwang 0:5738799d7a56 83 return NSAPI_ERROR_DHCP_FAILURE;
axelhwang 0:5738799d7a56 84 }
axelhwang 0:5738799d7a56 85
axelhwang 0:5738799d7a56 86 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT);
axelhwang 0:5738799d7a56 87
axelhwang 0:5738799d7a56 88 if (!_ism.connect(ap_ssid, ap_pass)) {
axelhwang 0:5738799d7a56 89 return NSAPI_ERROR_NO_CONNECTION;
axelhwang 0:5738799d7a56 90 }
axelhwang 0:5738799d7a56 91
axelhwang 0:5738799d7a56 92 _ism.setTimeout(ISM43362_MISC_TIMEOUT);
axelhwang 0:5738799d7a56 93 if (!_ism.getIPAddress()) {
axelhwang 0:5738799d7a56 94 return NSAPI_ERROR_DHCP_FAILURE;
axelhwang 0:5738799d7a56 95 }
axelhwang 0:5738799d7a56 96
axelhwang 0:5738799d7a56 97 _ism.setTimeout(ISM43362_MISC_TIMEOUT);
axelhwang 0:5738799d7a56 98 _mutex.unlock();
axelhwang 0:5738799d7a56 99
axelhwang 0:5738799d7a56 100 return NSAPI_ERROR_OK;
axelhwang 0:5738799d7a56 101 }
axelhwang 0:5738799d7a56 102
axelhwang 0:5738799d7a56 103 nsapi_error_t ISM43362Interface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version)
axelhwang 0:5738799d7a56 104 {
axelhwang 0:5738799d7a56 105 _mutex.lock();
axelhwang 0:5738799d7a56 106 if (address->set_ip_address(name)) {
axelhwang 0:5738799d7a56 107 if (version != NSAPI_UNSPEC && address->get_ip_version() != version) {
axelhwang 0:5738799d7a56 108 return NSAPI_ERROR_DNS_FAILURE;
axelhwang 0:5738799d7a56 109 }
axelhwang 0:5738799d7a56 110
axelhwang 0:5738799d7a56 111 return NSAPI_ERROR_OK;
axelhwang 0:5738799d7a56 112 }
axelhwang 0:5738799d7a56 113
axelhwang 0:5738799d7a56 114 char *ipbuff = new char[NSAPI_IP_SIZE];
axelhwang 0:5738799d7a56 115 int ret = 0;
axelhwang 0:5738799d7a56 116 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT);
axelhwang 0:5738799d7a56 117 if(!_ism.dns_lookup(name, ipbuff)) {
axelhwang 0:5738799d7a56 118 ret = NSAPI_ERROR_DEVICE_ERROR;
axelhwang 0:5738799d7a56 119 } else {
axelhwang 0:5738799d7a56 120 address->set_ip_address(ipbuff);
axelhwang 0:5738799d7a56 121 }
axelhwang 0:5738799d7a56 122 _mutex.unlock();
axelhwang 0:5738799d7a56 123
axelhwang 0:5738799d7a56 124 delete[] ipbuff;
axelhwang 0:5738799d7a56 125
axelhwang 0:5738799d7a56 126 return ret;
axelhwang 0:5738799d7a56 127 }
axelhwang 0:5738799d7a56 128
axelhwang 0:5738799d7a56 129 int ISM43362Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
axelhwang 0:5738799d7a56 130 {
axelhwang 0:5738799d7a56 131 _mutex.lock();
axelhwang 0:5738799d7a56 132
axelhwang 0:5738799d7a56 133 memset(ap_ssid, 0, sizeof(ap_ssid));
axelhwang 0:5738799d7a56 134 strncpy(ap_ssid, ssid, sizeof(ap_ssid));
axelhwang 0:5738799d7a56 135
axelhwang 0:5738799d7a56 136 memset(ap_pass, 0, sizeof(ap_pass));
axelhwang 0:5738799d7a56 137 strncpy(ap_pass, pass, sizeof(ap_pass));
axelhwang 0:5738799d7a56 138
axelhwang 0:5738799d7a56 139 ap_sec = security;
axelhwang 0:5738799d7a56 140 _mutex.unlock();
axelhwang 0:5738799d7a56 141
axelhwang 0:5738799d7a56 142 return 0;
axelhwang 0:5738799d7a56 143 }
axelhwang 0:5738799d7a56 144
axelhwang 0:5738799d7a56 145 int ISM43362Interface::set_channel(uint8_t channel)
axelhwang 0:5738799d7a56 146 {
axelhwang 0:5738799d7a56 147 return NSAPI_ERROR_UNSUPPORTED;
axelhwang 0:5738799d7a56 148 }
axelhwang 0:5738799d7a56 149
axelhwang 0:5738799d7a56 150 int ISM43362Interface::disconnect()
axelhwang 0:5738799d7a56 151 {
axelhwang 0:5738799d7a56 152 _mutex.lock();
axelhwang 0:5738799d7a56 153
axelhwang 0:5738799d7a56 154 _ism.setTimeout(ISM43362_MISC_TIMEOUT);
axelhwang 0:5738799d7a56 155
axelhwang 0:5738799d7a56 156 if (!_ism.disconnect()) {
axelhwang 0:5738799d7a56 157 return NSAPI_ERROR_DEVICE_ERROR;
axelhwang 0:5738799d7a56 158 }
axelhwang 0:5738799d7a56 159
axelhwang 0:5738799d7a56 160 _mutex.unlock();
axelhwang 0:5738799d7a56 161
axelhwang 0:5738799d7a56 162 return NSAPI_ERROR_OK;
axelhwang 0:5738799d7a56 163 }
axelhwang 0:5738799d7a56 164
axelhwang 0:5738799d7a56 165 const char *ISM43362Interface::get_ip_address()
axelhwang 0:5738799d7a56 166 {
axelhwang 0:5738799d7a56 167 _mutex.lock();
axelhwang 0:5738799d7a56 168 const char *ret = _ism.getIPAddress();
axelhwang 0:5738799d7a56 169 _mutex.unlock();
axelhwang 0:5738799d7a56 170 return ret;
axelhwang 0:5738799d7a56 171 }
axelhwang 0:5738799d7a56 172
axelhwang 0:5738799d7a56 173 const char *ISM43362Interface::get_mac_address()
axelhwang 0:5738799d7a56 174 {
axelhwang 0:5738799d7a56 175 _mutex.lock();
axelhwang 0:5738799d7a56 176 const char *ret = _ism.getMACAddress();
axelhwang 0:5738799d7a56 177 _mutex.unlock();
axelhwang 0:5738799d7a56 178 return ret;
axelhwang 0:5738799d7a56 179 }
axelhwang 0:5738799d7a56 180
axelhwang 0:5738799d7a56 181 const char *ISM43362Interface::get_gateway()
axelhwang 0:5738799d7a56 182 {
axelhwang 0:5738799d7a56 183 _mutex.lock();
axelhwang 0:5738799d7a56 184 const char *ret = _ism.getGateway();
axelhwang 0:5738799d7a56 185 _mutex.unlock();
axelhwang 0:5738799d7a56 186 return ret;
axelhwang 0:5738799d7a56 187 }
axelhwang 0:5738799d7a56 188
axelhwang 0:5738799d7a56 189 const char *ISM43362Interface::get_netmask()
axelhwang 0:5738799d7a56 190 {
axelhwang 0:5738799d7a56 191 _mutex.lock();
axelhwang 0:5738799d7a56 192 const char *ret = _ism.getNetmask();
axelhwang 0:5738799d7a56 193 _mutex.unlock();
axelhwang 0:5738799d7a56 194 return ret;
axelhwang 0:5738799d7a56 195 }
axelhwang 0:5738799d7a56 196
axelhwang 0:5738799d7a56 197 int8_t ISM43362Interface::get_rssi()
axelhwang 0:5738799d7a56 198 {
axelhwang 0:5738799d7a56 199 _mutex.lock();
axelhwang 0:5738799d7a56 200 int8_t ret = _ism.getRSSI();
axelhwang 0:5738799d7a56 201 _mutex.unlock();
axelhwang 0:5738799d7a56 202 return ret;
axelhwang 0:5738799d7a56 203 }
axelhwang 0:5738799d7a56 204
axelhwang 0:5738799d7a56 205 int ISM43362Interface::scan(WiFiAccessPoint *res, unsigned count)
axelhwang 0:5738799d7a56 206 {
axelhwang 0:5738799d7a56 207 _mutex.lock();
axelhwang 0:5738799d7a56 208 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT);
axelhwang 0:5738799d7a56 209 int ret = _ism.scan(res, count);
axelhwang 0:5738799d7a56 210 _mutex.unlock();
axelhwang 0:5738799d7a56 211 return ret;
axelhwang 0:5738799d7a56 212 }
axelhwang 0:5738799d7a56 213
axelhwang 0:5738799d7a56 214 struct ISM43362_socket {
axelhwang 0:5738799d7a56 215 int id;
axelhwang 0:5738799d7a56 216 nsapi_protocol_t proto;
axelhwang 0:5738799d7a56 217 volatile bool connected;
axelhwang 0:5738799d7a56 218 SocketAddress addr;
axelhwang 0:5738799d7a56 219 char read_data[1400];
axelhwang 0:5738799d7a56 220 volatile uint32_t read_data_size;
axelhwang 0:5738799d7a56 221 };
axelhwang 0:5738799d7a56 222
axelhwang 0:5738799d7a56 223 int ISM43362Interface::socket_open(void **handle, nsapi_protocol_t proto)
axelhwang 0:5738799d7a56 224 {
axelhwang 0:5738799d7a56 225 // Look for an unused socket
axelhwang 0:5738799d7a56 226 int id = -1;
axelhwang 0:5738799d7a56 227 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) {
axelhwang 0:5738799d7a56 228 if (!_ids[i]) {
axelhwang 0:5738799d7a56 229 id = i;
axelhwang 0:5738799d7a56 230 _ids[i] = true;
axelhwang 0:5738799d7a56 231 break;
axelhwang 0:5738799d7a56 232 }
axelhwang 0:5738799d7a56 233 }
axelhwang 0:5738799d7a56 234
axelhwang 0:5738799d7a56 235 if (id == -1) {
axelhwang 0:5738799d7a56 236 return NSAPI_ERROR_NO_SOCKET;
axelhwang 0:5738799d7a56 237 }
axelhwang 0:5738799d7a56 238 _mutex.lock();
axelhwang 0:5738799d7a56 239 struct ISM43362_socket *socket = new struct ISM43362_socket;
axelhwang 0:5738799d7a56 240 if (!socket) {
axelhwang 0:5738799d7a56 241 return NSAPI_ERROR_NO_SOCKET;
axelhwang 0:5738799d7a56 242 }
axelhwang 0:5738799d7a56 243 socket->id = id;
axelhwang 0:5738799d7a56 244 debug_if(ism_debug, "socket_open, id=%d", socket->id);
axelhwang 0:5738799d7a56 245 memset(socket->read_data, 0, sizeof(socket->read_data));
axelhwang 0:5738799d7a56 246 socket->addr = 0;
axelhwang 0:5738799d7a56 247 socket->read_data_size = 0;
axelhwang 0:5738799d7a56 248 socket->proto = proto;
axelhwang 0:5738799d7a56 249 socket->connected = false;
axelhwang 0:5738799d7a56 250 *handle = socket;
axelhwang 0:5738799d7a56 251 _mutex.unlock();
axelhwang 0:5738799d7a56 252
axelhwang 0:5738799d7a56 253 return 0;
axelhwang 0:5738799d7a56 254 }
axelhwang 0:5738799d7a56 255
axelhwang 0:5738799d7a56 256 int ISM43362Interface::socket_close(void *handle)
axelhwang 0:5738799d7a56 257 {
axelhwang 0:5738799d7a56 258 _mutex.lock();
axelhwang 0:5738799d7a56 259 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle;
axelhwang 0:5738799d7a56 260 debug_if(ism_debug, "socket_close, id=%d", socket->id);
axelhwang 0:5738799d7a56 261 int err = 0;
axelhwang 0:5738799d7a56 262 _ism.setTimeout(ISM43362_MISC_TIMEOUT);
axelhwang 0:5738799d7a56 263
axelhwang 0:5738799d7a56 264 if (!_ism.close(socket->id)) {
axelhwang 0:5738799d7a56 265 err = NSAPI_ERROR_DEVICE_ERROR;
axelhwang 0:5738799d7a56 266 }
axelhwang 0:5738799d7a56 267
axelhwang 0:5738799d7a56 268 socket->connected = false;
axelhwang 0:5738799d7a56 269 _ids[socket->id] = false;
axelhwang 0:5738799d7a56 270 _socket_obj[socket->id] = 0;
axelhwang 0:5738799d7a56 271 _mutex.unlock();
axelhwang 0:5738799d7a56 272 delete socket;
axelhwang 0:5738799d7a56 273 return err;
axelhwang 0:5738799d7a56 274 }
axelhwang 0:5738799d7a56 275
axelhwang 0:5738799d7a56 276 int ISM43362Interface::socket_bind(void *handle, const SocketAddress &address)
axelhwang 0:5738799d7a56 277 {
axelhwang 0:5738799d7a56 278 return NSAPI_ERROR_UNSUPPORTED;
axelhwang 0:5738799d7a56 279 }
axelhwang 0:5738799d7a56 280
axelhwang 0:5738799d7a56 281 int ISM43362Interface::socket_listen(void *handle, int backlog)
axelhwang 0:5738799d7a56 282 {
axelhwang 0:5738799d7a56 283 return NSAPI_ERROR_UNSUPPORTED;
axelhwang 0:5738799d7a56 284 }
axelhwang 0:5738799d7a56 285
axelhwang 0:5738799d7a56 286 int ISM43362Interface::socket_connect(void *handle, const SocketAddress &addr)
axelhwang 0:5738799d7a56 287 {
axelhwang 0:5738799d7a56 288 _mutex.lock();
axelhwang 0:5738799d7a56 289 int ret = socket_connect_nolock(handle, addr);
axelhwang 0:5738799d7a56 290 _mutex.unlock();
axelhwang 0:5738799d7a56 291 return ret;
axelhwang 0:5738799d7a56 292 }
axelhwang 0:5738799d7a56 293
axelhwang 0:5738799d7a56 294 int ISM43362Interface::socket_connect_nolock(void *handle, const SocketAddress &addr)
axelhwang 0:5738799d7a56 295 {
axelhwang 0:5738799d7a56 296 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle;
axelhwang 0:5738799d7a56 297 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT);
axelhwang 0:5738799d7a56 298 const char *proto = (socket->proto == NSAPI_UDP) ? "1" : "0";
axelhwang 0:5738799d7a56 299 if (!_ism.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) {
axelhwang 0:5738799d7a56 300 return NSAPI_ERROR_DEVICE_ERROR;
axelhwang 0:5738799d7a56 301 }
axelhwang 0:5738799d7a56 302 _ids[socket->id] = true;
axelhwang 0:5738799d7a56 303 _socket_obj[socket->id] = (uint32_t)socket;
axelhwang 0:5738799d7a56 304 socket->connected = true;
axelhwang 0:5738799d7a56 305 return 0;
axelhwang 0:5738799d7a56 306
axelhwang 0:5738799d7a56 307 }
axelhwang 0:5738799d7a56 308
axelhwang 0:5738799d7a56 309
axelhwang 0:5738799d7a56 310
axelhwang 0:5738799d7a56 311 void ISM43362Interface::socket_check_read()
axelhwang 0:5738799d7a56 312 {
axelhwang 0:5738799d7a56 313 while (1) {
axelhwang 0:5738799d7a56 314 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) {
axelhwang 0:5738799d7a56 315 _mutex.lock();
axelhwang 0:5738799d7a56 316 if (_socket_obj[i] != 0) {
axelhwang 0:5738799d7a56 317 struct ISM43362_socket *socket = (struct ISM43362_socket *)_socket_obj[i];
axelhwang 0:5738799d7a56 318 /* Check if there is something to read for this socket. But if it */
axelhwang 0:5738799d7a56 319 /* has already been read : don't read again */
axelhwang 0:5738799d7a56 320 if ((socket->connected) && (socket->read_data_size == 0) && _cbs[socket->id].callback) {
axelhwang 0:5738799d7a56 321 _ism.setTimeout(1);
axelhwang 0:5738799d7a56 322 /* if no callback is set, no need to read ?*/
axelhwang 0:5738799d7a56 323 int read_amount = _ism.check_recv_status(socket->id, socket->read_data);
axelhwang 0:5738799d7a56 324 if (read_amount > 0) {
axelhwang 0:5738799d7a56 325 socket->read_data_size = read_amount;
axelhwang 0:5738799d7a56 326 } else if (read_amount < 0) {
axelhwang 0:5738799d7a56 327 /* Mark donw connection has been lost or closed */
axelhwang 0:5738799d7a56 328 socket->connected = false;
axelhwang 0:5738799d7a56 329 }
axelhwang 0:5738799d7a56 330 if (read_amount != 0) {
axelhwang 0:5738799d7a56 331 /* There is something to read in this socket*/
axelhwang 0:5738799d7a56 332 if (_cbs[socket->id].callback) {
axelhwang 0:5738799d7a56 333 _cbs[socket->id].callback(_cbs[socket->id].data);
axelhwang 0:5738799d7a56 334 }
axelhwang 0:5738799d7a56 335 }
axelhwang 0:5738799d7a56 336 }
axelhwang 0:5738799d7a56 337 }
axelhwang 0:5738799d7a56 338 _mutex.unlock();
axelhwang 0:5738799d7a56 339 }
axelhwang 0:5738799d7a56 340 wait_ms(50);
axelhwang 0:5738799d7a56 341 }
axelhwang 0:5738799d7a56 342 }
axelhwang 0:5738799d7a56 343
axelhwang 0:5738799d7a56 344 int ISM43362Interface::socket_accept(void *server, void **socket, SocketAddress *addr)
axelhwang 0:5738799d7a56 345 {
axelhwang 0:5738799d7a56 346 return NSAPI_ERROR_UNSUPPORTED;
axelhwang 0:5738799d7a56 347 }
axelhwang 0:5738799d7a56 348
axelhwang 0:5738799d7a56 349 int ISM43362Interface::socket_send(void *handle, const void *data, unsigned size)
axelhwang 0:5738799d7a56 350 {
axelhwang 0:5738799d7a56 351 _mutex.lock();
axelhwang 0:5738799d7a56 352 int ret = socket_send_nolock(handle, data, size);
axelhwang 0:5738799d7a56 353 _mutex.unlock();
axelhwang 0:5738799d7a56 354 return ret;
axelhwang 0:5738799d7a56 355 }
axelhwang 0:5738799d7a56 356
axelhwang 0:5738799d7a56 357 /* CAREFULL LOCK must be taken before callling this function */
axelhwang 0:5738799d7a56 358 int ISM43362Interface::socket_send_nolock(void *handle, const void *data, unsigned size)
axelhwang 0:5738799d7a56 359 {
axelhwang 0:5738799d7a56 360 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle;
axelhwang 0:5738799d7a56 361 _ism.setTimeout(ISM43362_SEND_TIMEOUT);
axelhwang 0:5738799d7a56 362
axelhwang 0:5738799d7a56 363 if (size > ES_WIFI_MAX_TX_PACKET_SIZE) {
axelhwang 0:5738799d7a56 364 size = ES_WIFI_MAX_TX_PACKET_SIZE;
axelhwang 0:5738799d7a56 365 }
axelhwang 0:5738799d7a56 366
axelhwang 0:5738799d7a56 367 if (!_ism.send(socket->id, data, size)) {
axelhwang 0:5738799d7a56 368 debug_if(ism_debug, "socket_send ERROR\r\n");
axelhwang 0:5738799d7a56 369 return NSAPI_ERROR_DEVICE_ERROR; // or WOULD_BLOCK ?
axelhwang 0:5738799d7a56 370 }
axelhwang 0:5738799d7a56 371
axelhwang 0:5738799d7a56 372 return size;
axelhwang 0:5738799d7a56 373 }
axelhwang 0:5738799d7a56 374
axelhwang 0:5738799d7a56 375 int ISM43362Interface::socket_recv(void *handle, void *data, unsigned size)
axelhwang 0:5738799d7a56 376 {
axelhwang 0:5738799d7a56 377 _mutex.lock();
axelhwang 0:5738799d7a56 378 unsigned recv = 0;
axelhwang 0:5738799d7a56 379 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle;
axelhwang 0:5738799d7a56 380 char *ptr = (char *)data;
axelhwang 0:5738799d7a56 381
axelhwang 0:5738799d7a56 382 debug_if(ism_debug, "[socket_recv] req=%d\r\n", size);
axelhwang 0:5738799d7a56 383
axelhwang 0:5738799d7a56 384 if (!socket->connected) {
axelhwang 0:5738799d7a56 385 _mutex.unlock();
axelhwang 0:5738799d7a56 386 return NSAPI_ERROR_CONNECTION_LOST;
axelhwang 0:5738799d7a56 387 }
axelhwang 0:5738799d7a56 388
axelhwang 0:5738799d7a56 389 _ism.setTimeout(ISM43362_RECV_TIMEOUT);
axelhwang 0:5738799d7a56 390
axelhwang 0:5738799d7a56 391 if (socket->read_data_size == 0) {
axelhwang 0:5738799d7a56 392 /* if no callback is set, no need to read ?*/
axelhwang 0:5738799d7a56 393 int read_amount = _ism.check_recv_status(socket->id, socket->read_data);
axelhwang 0:5738799d7a56 394 if (read_amount > 0) {
axelhwang 0:5738799d7a56 395 socket->read_data_size = read_amount;
axelhwang 0:5738799d7a56 396 } else if (read_amount < 0) {
axelhwang 0:5738799d7a56 397 socket->connected = false;
axelhwang 0:5738799d7a56 398 _mutex.unlock();
axelhwang 0:5738799d7a56 399 return NSAPI_ERROR_CONNECTION_LOST;
axelhwang 0:5738799d7a56 400 }
axelhwang 0:5738799d7a56 401 }
axelhwang 0:5738799d7a56 402
axelhwang 0:5738799d7a56 403 if (socket->read_data_size != 0) {
axelhwang 0:5738799d7a56 404 debug_if(ism_debug, "read_data_size=%d\r\n", socket->read_data_size);
axelhwang 0:5738799d7a56 405 uint32_t i=0;
axelhwang 0:5738799d7a56 406 while ((i < socket->read_data_size) && (i < size)) {
axelhwang 0:5738799d7a56 407 *ptr++ = socket->read_data[i];
axelhwang 0:5738799d7a56 408 i++;
axelhwang 0:5738799d7a56 409 }
axelhwang 0:5738799d7a56 410
axelhwang 0:5738799d7a56 411 debug_if(ism_debug, "Copied i bytes=%d, vs %d requestd\r\n", i, size);
axelhwang 0:5738799d7a56 412 recv += i;
axelhwang 0:5738799d7a56 413
axelhwang 0:5738799d7a56 414 if (i >= socket->read_data_size) {
axelhwang 0:5738799d7a56 415 /* All the storeed data has been read, reset buffer */
axelhwang 0:5738799d7a56 416 memset(socket->read_data, 0, sizeof(socket->read_data));
axelhwang 0:5738799d7a56 417 socket->read_data_size = 0;
axelhwang 0:5738799d7a56 418 debug_if(ism_debug, "Socket_recv buffer reset\r\n");
axelhwang 0:5738799d7a56 419 } else {
axelhwang 0:5738799d7a56 420 /* In case there is remaining data in buffer, update socket content
axelhwang 0:5738799d7a56 421 * For now by shift copy of all data (not very efficient to be
axelhwang 0:5738799d7a56 422 * revised */
axelhwang 0:5738799d7a56 423 while (i < socket->read_data_size) {
axelhwang 0:5738799d7a56 424 socket->read_data[i - size] = socket->read_data[i];
axelhwang 0:5738799d7a56 425 i++;
axelhwang 0:5738799d7a56 426 }
axelhwang 0:5738799d7a56 427
axelhwang 0:5738799d7a56 428 socket->read_data_size -= size;
axelhwang 0:5738799d7a56 429 }
axelhwang 0:5738799d7a56 430 } else {
axelhwang 0:5738799d7a56 431 debug_if(ism_debug, "Nothing in buffer\r\n");
axelhwang 0:5738799d7a56 432 }
axelhwang 0:5738799d7a56 433
axelhwang 0:5738799d7a56 434 debug_if(ism_debug, "[socket_recv]read_datasize=%d, recv=%d\r\n", socket->read_data_size, recv);
axelhwang 0:5738799d7a56 435 _mutex.unlock();
axelhwang 0:5738799d7a56 436
axelhwang 0:5738799d7a56 437 if (recv > 0) {
axelhwang 0:5738799d7a56 438 return recv;
axelhwang 0:5738799d7a56 439 } else {
axelhwang 0:5738799d7a56 440 debug_if(ism_debug, "sock_recv returns WOULD BLOCK\r\n");
axelhwang 0:5738799d7a56 441 return NSAPI_ERROR_WOULD_BLOCK;
axelhwang 0:5738799d7a56 442 }
axelhwang 0:5738799d7a56 443 }
axelhwang 0:5738799d7a56 444
axelhwang 0:5738799d7a56 445 int ISM43362Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
axelhwang 0:5738799d7a56 446 {
axelhwang 0:5738799d7a56 447 _mutex.lock();
axelhwang 0:5738799d7a56 448 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle;
axelhwang 0:5738799d7a56 449
axelhwang 0:5738799d7a56 450 if (socket->connected && socket->addr != addr) {
axelhwang 0:5738799d7a56 451 _ism.setTimeout(ISM43362_MISC_TIMEOUT);
axelhwang 0:5738799d7a56 452 if (!_ism.close(socket->id)) {
axelhwang 0:5738799d7a56 453 debug_if(ism_debug, "socket_send ERROR\r\n");
axelhwang 0:5738799d7a56 454 _mutex.unlock();
axelhwang 0:5738799d7a56 455 return NSAPI_ERROR_DEVICE_ERROR;
axelhwang 0:5738799d7a56 456 }
axelhwang 0:5738799d7a56 457 socket->connected = false;
axelhwang 0:5738799d7a56 458 _ids[socket->id] = false;
axelhwang 0:5738799d7a56 459 _socket_obj[socket->id] = 0;
axelhwang 0:5738799d7a56 460 }
axelhwang 0:5738799d7a56 461
axelhwang 0:5738799d7a56 462 if (!socket->connected) {
axelhwang 0:5738799d7a56 463 int err = socket_connect_nolock(socket, addr);
axelhwang 0:5738799d7a56 464 if (err < 0) {
axelhwang 0:5738799d7a56 465 _mutex.unlock();
axelhwang 0:5738799d7a56 466 return err;
axelhwang 0:5738799d7a56 467 }
axelhwang 0:5738799d7a56 468 socket->addr = addr;
axelhwang 0:5738799d7a56 469 }
axelhwang 0:5738799d7a56 470
axelhwang 0:5738799d7a56 471 int ret = socket_send_nolock(socket, data, size);
axelhwang 0:5738799d7a56 472
axelhwang 0:5738799d7a56 473 _mutex.unlock();
axelhwang 0:5738799d7a56 474
axelhwang 0:5738799d7a56 475 return ret;
axelhwang 0:5738799d7a56 476 }
axelhwang 0:5738799d7a56 477
axelhwang 0:5738799d7a56 478 int ISM43362Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
axelhwang 0:5738799d7a56 479 {
axelhwang 0:5738799d7a56 480 int ret = socket_recv(handle, data, size);
axelhwang 0:5738799d7a56 481 _mutex.lock();
axelhwang 0:5738799d7a56 482 if ((ret >= 0) && addr) {
axelhwang 0:5738799d7a56 483 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle;
axelhwang 0:5738799d7a56 484 *addr = socket->addr;
axelhwang 0:5738799d7a56 485 }
axelhwang 0:5738799d7a56 486 _mutex.unlock();
axelhwang 0:5738799d7a56 487 return ret;
axelhwang 0:5738799d7a56 488 }
axelhwang 0:5738799d7a56 489
axelhwang 0:5738799d7a56 490 void ISM43362Interface::socket_attach(void *handle, void (*cb)(void *), void *data)
axelhwang 0:5738799d7a56 491 {
axelhwang 0:5738799d7a56 492 _mutex.lock();
axelhwang 0:5738799d7a56 493 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle;
axelhwang 0:5738799d7a56 494 _cbs[socket->id].callback = cb;
axelhwang 0:5738799d7a56 495 _cbs[socket->id].data = data;
axelhwang 0:5738799d7a56 496 _mutex.unlock();
axelhwang 0:5738799d7a56 497 }
axelhwang 0:5738799d7a56 498
axelhwang 0:5738799d7a56 499 void ISM43362Interface::event() {
axelhwang 0:5738799d7a56 500 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) {
axelhwang 0:5738799d7a56 501 if (_cbs[i].callback) {
axelhwang 0:5738799d7a56 502 _cbs[i].callback(_cbs[i].data);
axelhwang 0:5738799d7a56 503 }
axelhwang 0:5738799d7a56 504 }
axelhwang 0:5738799d7a56 505 }