Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DISCO_L475VG_IOT01-Sensors-BSP
ISM43362Interface.cpp
00001 /* ISM43362 implementation of NetworkInterfaceAPI 00002 * Copyright (c) STMicroelectronics 2017 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include <string.h> 00018 #include "ISM43362Interface.h" 00019 #include "mbed_debug.h" 00020 00021 // ao activate / de-activate debug 00022 #define ism_debug false 00023 00024 // Various timeouts for different ISM43362 operations 00025 #define ISM43362_CONNECT_TIMEOUT 15000 /* milliseconds */ 00026 #define ISM43362_SEND_TIMEOUT 1000 /* milliseconds */ 00027 #define ISM43362_RECV_TIMEOUT 100 /* milliseconds */ 00028 #define ISM43362_MISC_TIMEOUT 100 /* milliseconds */ 00029 00030 // Tested firmware versions 00031 // Example of versions string returned by the module: 00032 // "ISM43362-M3G-L44-SPI,C3.5.2.3.BETA9,v3.5.2,v1.4.0.rc1,v8.2.1,120000000,Inventek eS-WiFi" 00033 // "ISM43362-M3G-L44-SPI,C3.5.2.2,v3.5.2,v1.4.0.rc1,v8.2.1,120000000,Inventek eS-WiFi" 00034 // Only the first version is checked ! 00035 const char supported_fw_versions[2][15] = {"C3.5.2.3.BETA9", "C3.5.2.2"}; 00036 00037 #define MIN(a,b) (((a)<(b))?(a):(b)) 00038 00039 // ISM43362Interface implementation 00040 ISM43362Interface::ISM43362Interface(PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset, PinName datareadypin, PinName wakeup, bool debug) 00041 : _ism(mosi, miso, sclk, nss, reset, datareadypin, wakeup, debug) 00042 { 00043 memset(_ids, 0, sizeof(_ids)); 00044 memset(_socket_obj, 0, sizeof(_socket_obj)); 00045 memset(_cbs, 0, sizeof(_cbs)); 00046 thread_read_socket.start(callback(this, &ISM43362Interface::socket_check_read)); 00047 } 00048 00049 int ISM43362Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, 00050 uint8_t channel) 00051 { 00052 if (channel != 0) { 00053 return NSAPI_ERROR_UNSUPPORTED; 00054 } 00055 00056 set_credentials(ssid, pass, security); 00057 return connect(); 00058 } 00059 00060 int ISM43362Interface::connect() 00061 { 00062 _mutex.lock(); 00063 const char* read_version; 00064 00065 _ism.setTimeout(ISM43362_MISC_TIMEOUT); 00066 00067 // Check all supported firmware versions 00068 read_version = _ism.get_firmware_version(); 00069 00070 if (!read_version) { 00071 debug_if(ism_debug, "ISM43362: ERROR cannot read firmware version\r\n"); 00072 return NSAPI_ERROR_DEVICE_ERROR; 00073 } 00074 debug_if(ism_debug, "ISM43362: read_version = [%s]\r\n", read_version); 00075 00076 if ((strcmp(read_version, supported_fw_versions[0]) == 0) || (strcmp(read_version, supported_fw_versions[1]) == 0)) { 00077 debug_if(ism_debug, "ISM43362: firmware version is OK\r\n"); 00078 } else { 00079 debug_if(ism_debug, "ISM43362: WARNING this firmware version has not been tested !\r\n"); 00080 } 00081 00082 if (!_ism.dhcp(true)) { 00083 return NSAPI_ERROR_DHCP_FAILURE; 00084 } 00085 00086 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT); 00087 00088 if (!_ism.connect(ap_ssid, ap_pass)) { 00089 return NSAPI_ERROR_NO_CONNECTION; 00090 } 00091 00092 _ism.setTimeout(ISM43362_MISC_TIMEOUT); 00093 if (!_ism.getIPAddress()) { 00094 return NSAPI_ERROR_DHCP_FAILURE; 00095 } 00096 00097 _ism.setTimeout(ISM43362_MISC_TIMEOUT); 00098 _mutex.unlock(); 00099 00100 return NSAPI_ERROR_OK; 00101 } 00102 00103 nsapi_error_t ISM43362Interface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) 00104 { 00105 _mutex.lock(); 00106 if (address->set_ip_address(name)) { 00107 if (version != NSAPI_UNSPEC && address->get_ip_version() != version) { 00108 return NSAPI_ERROR_DNS_FAILURE; 00109 } 00110 00111 return NSAPI_ERROR_OK; 00112 } 00113 00114 char *ipbuff = new char[NSAPI_IP_SIZE]; 00115 int ret = 0; 00116 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT); 00117 if(!_ism.dns_lookup(name, ipbuff)) { 00118 ret = NSAPI_ERROR_DEVICE_ERROR; 00119 } else { 00120 address->set_ip_address(ipbuff); 00121 } 00122 _mutex.unlock(); 00123 00124 delete[] ipbuff; 00125 00126 return ret; 00127 } 00128 00129 int ISM43362Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) 00130 { 00131 _mutex.lock(); 00132 00133 memset(ap_ssid, 0, sizeof(ap_ssid)); 00134 strncpy(ap_ssid, ssid, sizeof(ap_ssid)); 00135 00136 memset(ap_pass, 0, sizeof(ap_pass)); 00137 strncpy(ap_pass, pass, sizeof(ap_pass)); 00138 00139 ap_sec = security; 00140 _mutex.unlock(); 00141 00142 return 0; 00143 } 00144 00145 int ISM43362Interface::set_channel(uint8_t channel) 00146 { 00147 return NSAPI_ERROR_UNSUPPORTED; 00148 } 00149 00150 int ISM43362Interface::disconnect() 00151 { 00152 _mutex.lock(); 00153 00154 _ism.setTimeout(ISM43362_MISC_TIMEOUT); 00155 00156 if (!_ism.disconnect()) { 00157 return NSAPI_ERROR_DEVICE_ERROR; 00158 } 00159 00160 _mutex.unlock(); 00161 00162 return NSAPI_ERROR_OK; 00163 } 00164 00165 const char *ISM43362Interface::get_ip_address() 00166 { 00167 _mutex.lock(); 00168 const char *ret = _ism.getIPAddress(); 00169 _mutex.unlock(); 00170 return ret; 00171 } 00172 00173 const char *ISM43362Interface::get_mac_address() 00174 { 00175 _mutex.lock(); 00176 const char *ret = _ism.getMACAddress(); 00177 _mutex.unlock(); 00178 return ret; 00179 } 00180 00181 const char *ISM43362Interface::get_gateway() 00182 { 00183 _mutex.lock(); 00184 const char *ret = _ism.getGateway(); 00185 _mutex.unlock(); 00186 return ret; 00187 } 00188 00189 const char *ISM43362Interface::get_netmask() 00190 { 00191 _mutex.lock(); 00192 const char *ret = _ism.getNetmask(); 00193 _mutex.unlock(); 00194 return ret; 00195 } 00196 00197 int8_t ISM43362Interface::get_rssi() 00198 { 00199 _mutex.lock(); 00200 int8_t ret = _ism.getRSSI(); 00201 _mutex.unlock(); 00202 return ret; 00203 } 00204 00205 int ISM43362Interface::scan(WiFiAccessPoint *res, unsigned count) 00206 { 00207 _mutex.lock(); 00208 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT); 00209 int ret = _ism.scan(res, count); 00210 _mutex.unlock(); 00211 return ret; 00212 } 00213 00214 struct ISM43362_socket { 00215 int id; 00216 nsapi_protocol_t proto; 00217 volatile bool connected; 00218 SocketAddress addr; 00219 char read_data[1400]; 00220 volatile uint32_t read_data_size; 00221 }; 00222 00223 int ISM43362Interface::socket_open(void **handle, nsapi_protocol_t proto) 00224 { 00225 // Look for an unused socket 00226 int id = -1; 00227 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00228 if (!_ids[i]) { 00229 id = i; 00230 _ids[i] = true; 00231 break; 00232 } 00233 } 00234 00235 if (id == -1) { 00236 return NSAPI_ERROR_NO_SOCKET; 00237 } 00238 _mutex.lock(); 00239 struct ISM43362_socket *socket = new struct ISM43362_socket; 00240 if (!socket) { 00241 return NSAPI_ERROR_NO_SOCKET; 00242 } 00243 socket->id = id; 00244 debug_if(ism_debug, "socket_open, id=%d", socket->id); 00245 memset(socket->read_data, 0, sizeof(socket->read_data)); 00246 socket->addr = 0; 00247 socket->read_data_size = 0; 00248 socket->proto = proto; 00249 socket->connected = false; 00250 *handle = socket; 00251 _mutex.unlock(); 00252 00253 return 0; 00254 } 00255 00256 int ISM43362Interface::socket_close(void *handle) 00257 { 00258 _mutex.lock(); 00259 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00260 debug_if(ism_debug, "socket_close, id=%d", socket->id); 00261 int err = 0; 00262 _ism.setTimeout(ISM43362_MISC_TIMEOUT); 00263 00264 if (!_ism.close(socket->id)) { 00265 err = NSAPI_ERROR_DEVICE_ERROR; 00266 } 00267 00268 socket->connected = false; 00269 _ids[socket->id] = false; 00270 _socket_obj[socket->id] = 0; 00271 _mutex.unlock(); 00272 delete socket; 00273 return err; 00274 } 00275 00276 int ISM43362Interface::socket_bind(void *handle, const SocketAddress &address) 00277 { 00278 return NSAPI_ERROR_UNSUPPORTED; 00279 } 00280 00281 int ISM43362Interface::socket_listen(void *handle, int backlog) 00282 { 00283 return NSAPI_ERROR_UNSUPPORTED; 00284 } 00285 00286 int ISM43362Interface::socket_connect(void *handle, const SocketAddress &addr) 00287 { 00288 _mutex.lock(); 00289 int ret = socket_connect_nolock(handle, addr); 00290 _mutex.unlock(); 00291 return ret; 00292 } 00293 00294 int ISM43362Interface::socket_connect_nolock(void *handle, const SocketAddress &addr) 00295 { 00296 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00297 _ism.setTimeout(ISM43362_CONNECT_TIMEOUT); 00298 const char *proto = (socket->proto == NSAPI_UDP) ? "1" : "0"; 00299 if (!_ism.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) { 00300 return NSAPI_ERROR_DEVICE_ERROR; 00301 } 00302 _ids[socket->id] = true; 00303 _socket_obj[socket->id] = (uint32_t)socket; 00304 socket->connected = true; 00305 return 0; 00306 00307 } 00308 00309 00310 00311 void ISM43362Interface::socket_check_read() 00312 { 00313 while (1) { 00314 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00315 _mutex.lock(); 00316 if (_socket_obj[i] != 0) { 00317 struct ISM43362_socket *socket = (struct ISM43362_socket *)_socket_obj[i]; 00318 /* Check if there is something to read for this socket. But if it */ 00319 /* has already been read : don't read again */ 00320 if ((socket->connected) && (socket->read_data_size == 0) && _cbs[socket->id].callback) { 00321 _ism.setTimeout(1); 00322 /* if no callback is set, no need to read ?*/ 00323 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00324 if (read_amount > 0) { 00325 socket->read_data_size = read_amount; 00326 } else if (read_amount < 0) { 00327 /* Mark donw connection has been lost or closed */ 00328 socket->connected = false; 00329 } 00330 if (read_amount != 0) { 00331 /* There is something to read in this socket*/ 00332 if (_cbs[socket->id].callback) { 00333 _cbs[socket->id].callback(_cbs[socket->id].data); 00334 } 00335 } 00336 } 00337 } 00338 _mutex.unlock(); 00339 } 00340 wait_ms(50); 00341 } 00342 } 00343 00344 int ISM43362Interface::socket_accept(void *server, void **socket, SocketAddress *addr) 00345 { 00346 return NSAPI_ERROR_UNSUPPORTED; 00347 } 00348 00349 int ISM43362Interface::socket_send(void *handle, const void *data, unsigned size) 00350 { 00351 _mutex.lock(); 00352 int ret = socket_send_nolock(handle, data, size); 00353 _mutex.unlock(); 00354 return ret; 00355 } 00356 00357 /* CAREFULL LOCK must be taken before callling this function */ 00358 int ISM43362Interface::socket_send_nolock(void *handle, const void *data, unsigned size) 00359 { 00360 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00361 _ism.setTimeout(ISM43362_SEND_TIMEOUT); 00362 00363 if (size > ES_WIFI_MAX_TX_PACKET_SIZE) { 00364 size = ES_WIFI_MAX_TX_PACKET_SIZE; 00365 } 00366 00367 if (!_ism.send(socket->id, data, size)) { 00368 debug_if(ism_debug, "socket_send ERROR\r\n"); 00369 return NSAPI_ERROR_DEVICE_ERROR; // or WOULD_BLOCK ? 00370 } 00371 00372 return size; 00373 } 00374 00375 int ISM43362Interface::socket_recv(void *handle, void *data, unsigned size) 00376 { 00377 _mutex.lock(); 00378 unsigned recv = 0; 00379 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00380 char *ptr = (char *)data; 00381 00382 debug_if(ism_debug, "[socket_recv] req=%d\r\n", size); 00383 00384 if (!socket->connected) { 00385 _mutex.unlock(); 00386 return NSAPI_ERROR_CONNECTION_LOST; 00387 } 00388 00389 _ism.setTimeout(ISM43362_RECV_TIMEOUT); 00390 00391 if (socket->read_data_size == 0) { 00392 /* if no callback is set, no need to read ?*/ 00393 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00394 if (read_amount > 0) { 00395 socket->read_data_size = read_amount; 00396 } else if (read_amount < 0) { 00397 socket->connected = false; 00398 _mutex.unlock(); 00399 return NSAPI_ERROR_CONNECTION_LOST; 00400 } 00401 } 00402 00403 if (socket->read_data_size != 0) { 00404 debug_if(ism_debug, "read_data_size=%d\r\n", socket->read_data_size); 00405 uint32_t i=0; 00406 while ((i < socket->read_data_size) && (i < size)) { 00407 *ptr++ = socket->read_data[i]; 00408 i++; 00409 } 00410 00411 debug_if(ism_debug, "Copied i bytes=%d, vs %d requestd\r\n", i, size); 00412 recv += i; 00413 00414 if (i >= socket->read_data_size) { 00415 /* All the storeed data has been read, reset buffer */ 00416 memset(socket->read_data, 0, sizeof(socket->read_data)); 00417 socket->read_data_size = 0; 00418 debug_if(ism_debug, "Socket_recv buffer reset\r\n"); 00419 } else { 00420 /* In case there is remaining data in buffer, update socket content 00421 * For now by shift copy of all data (not very efficient to be 00422 * revised */ 00423 while (i < socket->read_data_size) { 00424 socket->read_data[i - size] = socket->read_data[i]; 00425 i++; 00426 } 00427 00428 socket->read_data_size -= size; 00429 } 00430 } else { 00431 debug_if(ism_debug, "Nothing in buffer\r\n"); 00432 } 00433 00434 debug_if(ism_debug, "[socket_recv]read_datasize=%d, recv=%d\r\n", socket->read_data_size, recv); 00435 _mutex.unlock(); 00436 00437 if (recv > 0) { 00438 return recv; 00439 } else { 00440 debug_if(ism_debug, "sock_recv returns WOULD BLOCK\r\n"); 00441 return NSAPI_ERROR_WOULD_BLOCK; 00442 } 00443 } 00444 00445 int ISM43362Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00446 { 00447 _mutex.lock(); 00448 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00449 00450 if (socket->connected && socket->addr != addr) { 00451 _ism.setTimeout(ISM43362_MISC_TIMEOUT); 00452 if (!_ism.close(socket->id)) { 00453 debug_if(ism_debug, "socket_send ERROR\r\n"); 00454 _mutex.unlock(); 00455 return NSAPI_ERROR_DEVICE_ERROR; 00456 } 00457 socket->connected = false; 00458 _ids[socket->id] = false; 00459 _socket_obj[socket->id] = 0; 00460 } 00461 00462 if (!socket->connected) { 00463 int err = socket_connect_nolock(socket, addr); 00464 if (err < 0) { 00465 _mutex.unlock(); 00466 return err; 00467 } 00468 socket->addr = addr; 00469 } 00470 00471 int ret = socket_send_nolock(socket, data, size); 00472 00473 _mutex.unlock(); 00474 00475 return ret; 00476 } 00477 00478 int ISM43362Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00479 { 00480 int ret = socket_recv(handle, data, size); 00481 _mutex.lock(); 00482 if ((ret >= 0) && addr) { 00483 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00484 *addr = socket->addr; 00485 } 00486 _mutex.unlock(); 00487 return ret; 00488 } 00489 00490 void ISM43362Interface::socket_attach(void *handle, void (*cb)(void *), void *data) 00491 { 00492 _mutex.lock(); 00493 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00494 _cbs[socket->id].callback = cb; 00495 _cbs[socket->id].data = data; 00496 _mutex.unlock(); 00497 } 00498 00499 void ISM43362Interface::event() { 00500 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00501 if (_cbs[i].callback) { 00502 _cbs[i].callback(_cbs[i].data); 00503 } 00504 } 00505 }
Generated on Tue Jul 12 2022 23:41:59 by
