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.
ISM43362Interface.cpp
00001 /* ISM43362 implementation of NetworkInterfaceAPI 00002 * Copyright (c) STMicroelectronics 2018 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 // Product ID,FW Revision,API Revision,Stack Revision,RTOS Revision,CPU Clock,Product Name 00022 #define LATEST_FW_VERSION_NUMBER "C3.5.2.5" // ISM43362-M3G-L44-SPI,C3.5.2.5.STM,v3.5.2,v1.4.0.rc1,v8.2.1,120000000,Inventek eS-WiFi 00023 00024 // activate / de-activate debug 00025 #define ism_interface_debug 0 00026 00027 #define MIN(a,b) (((a)<(b))?(a):(b)) 00028 00029 // ISM43362Interface implementation 00030 ISM43362Interface::ISM43362Interface(bool debug) 00031 : _ism(MBED_CONF_ISM43362_WIFI_MOSI, MBED_CONF_ISM43362_WIFI_MISO, MBED_CONF_ISM43362_WIFI_SCLK, MBED_CONF_ISM43362_WIFI_NSS, MBED_CONF_ISM43362_WIFI_RESET, MBED_CONF_ISM43362_WIFI_DATAREADY, MBED_CONF_ISM43362_WIFI_WAKEUP, debug) 00032 { 00033 _ism_debug = ism_interface_debug || debug; 00034 memset(_ids, 0, sizeof(_ids)); 00035 memset(_socket_obj, 0, sizeof(_socket_obj)); 00036 memset(_cbs, 0, sizeof(_cbs)); 00037 memset(ap_ssid, 0, sizeof(ap_ssid)); 00038 memset(ap_pass, 0, sizeof(ap_pass)); 00039 ap_sec = ISM_SECURITY_UNKNOWN; 00040 00041 thread_read_socket.start(callback(this, &ISM43362Interface::socket_check_read)); 00042 00043 _mutex.lock(); 00044 00045 // Check all supported firmware versions 00046 _FwVersion = _ism.get_firmware_version(); 00047 00048 if (!_FwVersion) { 00049 error("ISM43362Interface: ERROR cannot read firmware version\r\n"); 00050 } 00051 00052 debug_if(_ism_debug, "ISM43362Interface: read_version = %lu\r\n", _FwVersion); 00053 /* FW Revision should be with format "CX.X.X.X" with X as a single digit */ 00054 if ( (_FwVersion < 1000) || (_FwVersion > 9999) ) { 00055 debug_if(_ism_debug, "ISM43362Interface: read_version issue\r\n"); 00056 } 00057 00058 #if TARGET_DISCO_L475VG_IOT01A 00059 if (_FwVersion < ParseNumber(LATEST_FW_VERSION_NUMBER, NULL)) { 00060 debug_if(_ism_debug, "ISM43362Interface: please update FW\r\n"); 00061 } 00062 #endif 00063 00064 _mutex.unlock(); 00065 } 00066 00067 int ISM43362Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, 00068 uint8_t channel) 00069 { 00070 if (channel != 0) { 00071 return NSAPI_ERROR_UNSUPPORTED; 00072 } 00073 00074 nsapi_error_t credentials_status = set_credentials(ssid, pass, security); 00075 if (credentials_status) { 00076 return credentials_status; 00077 } 00078 00079 return connect(); 00080 } 00081 00082 int ISM43362Interface::connect() 00083 { 00084 if (strlen(ap_ssid) == 0) { 00085 return NSAPI_ERROR_NO_SSID; 00086 } 00087 00088 _mutex.lock(); 00089 00090 if (!_ism.dhcp(true)) { 00091 _mutex.unlock(); 00092 return NSAPI_ERROR_DHCP_FAILURE; 00093 } 00094 00095 int connect_status = _ism.connect(ap_ssid, ap_pass, ap_sec); 00096 debug_if(_ism_debug, "ISM43362Interface: connect_status %d\n", connect_status); 00097 00098 if (connect_status != NSAPI_ERROR_OK) { 00099 _mutex.unlock(); 00100 return connect_status; 00101 } 00102 00103 if (!_ism.getIPAddress()) { 00104 _mutex.unlock(); 00105 return NSAPI_ERROR_DHCP_FAILURE; 00106 } 00107 00108 _mutex.unlock(); 00109 00110 return NSAPI_ERROR_OK; 00111 } 00112 00113 nsapi_error_t ISM43362Interface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) 00114 { 00115 if (strlen(name) == 0) { 00116 return NSAPI_ERROR_NO_SOCKET; 00117 } 00118 00119 _mutex.lock(); 00120 if (address->set_ip_address(name)) { 00121 if (version != NSAPI_UNSPEC && address->get_ip_version() != version) { 00122 _mutex.unlock(); 00123 return NSAPI_ERROR_DNS_FAILURE; 00124 } 00125 00126 _mutex.unlock(); 00127 return NSAPI_ERROR_OK; 00128 } 00129 00130 char *ipbuff = new char[NSAPI_IP_SIZE]; 00131 int ret = 0; 00132 if (!_ism.dns_lookup(name, ipbuff)) { 00133 ret = NSAPI_ERROR_DEVICE_ERROR; 00134 } else { 00135 address->set_ip_address(ipbuff); 00136 } 00137 _mutex.unlock(); 00138 00139 delete[] ipbuff; 00140 00141 return ret; 00142 } 00143 00144 int ISM43362Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) 00145 { 00146 if ((strlen(ssid) == 0) || (strlen(ssid) > 32)) { 00147 return NSAPI_ERROR_PARAMETER; 00148 } 00149 00150 if ((security != NSAPI_SECURITY_NONE) && (strcmp(pass, "") == 0)) { 00151 return NSAPI_ERROR_PARAMETER; 00152 } 00153 00154 if (strlen(pass) > 63) { 00155 return NSAPI_ERROR_PARAMETER; 00156 } 00157 00158 _mutex.lock(); 00159 memset(ap_ssid, 0, sizeof(ap_ssid)); 00160 strncpy(ap_ssid, ssid, sizeof(ap_ssid)); 00161 00162 memset(ap_pass, 0, sizeof(ap_pass)); 00163 strncpy(ap_pass, pass, sizeof(ap_pass)); 00164 00165 switch (security) { 00166 case NSAPI_SECURITY_NONE: 00167 ap_sec = ISM_SECURITY_NONE; 00168 break; 00169 case NSAPI_SECURITY_WEP: 00170 ap_sec = ISM_SECURITY_WEP; 00171 break; 00172 case NSAPI_SECURITY_WPA: 00173 ap_sec = ISM_SECURITY_WPA; 00174 break; 00175 case NSAPI_SECURITY_WPA2: 00176 ap_sec = ISM_SECURITY_WPA2; 00177 break; 00178 case NSAPI_SECURITY_WPA_WPA2: 00179 ap_sec = ISM_SECURITY_WPA_WPA2; 00180 break; 00181 default: 00182 ap_sec = ISM_SECURITY_UNKNOWN; 00183 break; 00184 } 00185 _mutex.unlock(); 00186 00187 return NSAPI_ERROR_OK; 00188 } 00189 00190 int ISM43362Interface::set_channel(uint8_t channel) 00191 { 00192 return NSAPI_ERROR_UNSUPPORTED; 00193 } 00194 00195 int ISM43362Interface::disconnect() 00196 { 00197 _mutex.lock(); 00198 00199 if (!_ism.disconnect()) { 00200 _mutex.unlock(); 00201 return NSAPI_ERROR_DEVICE_ERROR; 00202 } 00203 00204 _mutex.unlock(); 00205 00206 return NSAPI_ERROR_OK; 00207 } 00208 00209 const char *ISM43362Interface::get_ip_address() 00210 { 00211 _mutex.lock(); 00212 const char *ret = _ism.getIPAddress(); 00213 _mutex.unlock(); 00214 return ret; 00215 } 00216 00217 const char *ISM43362Interface::get_mac_address() 00218 { 00219 _mutex.lock(); 00220 const char *ret = _ism.getMACAddress(); 00221 _mutex.unlock(); 00222 return ret; 00223 } 00224 00225 const char *ISM43362Interface::get_gateway() 00226 { 00227 _mutex.lock(); 00228 const char *ret = _ism.getGateway(); 00229 _mutex.unlock(); 00230 return ret; 00231 } 00232 00233 const char *ISM43362Interface::get_netmask() 00234 { 00235 _mutex.lock(); 00236 const char *ret = _ism.getNetmask(); 00237 _mutex.unlock(); 00238 return ret; 00239 } 00240 00241 int8_t ISM43362Interface::get_rssi() 00242 { 00243 _mutex.lock(); 00244 int8_t ret = _ism.getRSSI(); 00245 _mutex.unlock(); 00246 return ret; 00247 } 00248 00249 int ISM43362Interface::scan(WiFiAccessPoint *res, unsigned count) 00250 { 00251 _mutex.lock(); 00252 int ret = _ism.scan(res, count); 00253 _mutex.unlock(); 00254 return ret; 00255 } 00256 00257 struct ISM43362_socket { 00258 int id; 00259 nsapi_protocol_t proto; 00260 volatile bool connected; 00261 SocketAddress addr; 00262 char read_data[1400]; 00263 volatile uint32_t read_data_size; 00264 }; 00265 00266 int ISM43362Interface::socket_open(void **handle, nsapi_protocol_t proto) 00267 { 00268 // Look for an unused socket 00269 int id = -1; 00270 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00271 if (!_ids[i]) { 00272 id = i; 00273 _ids[i] = true; 00274 break; 00275 } 00276 } 00277 00278 if (id == -1) { 00279 return NSAPI_ERROR_NO_SOCKET; 00280 } 00281 _mutex.lock(); 00282 struct ISM43362_socket *socket = new struct ISM43362_socket; 00283 if (!socket) { 00284 _mutex.unlock(); 00285 return NSAPI_ERROR_NO_SOCKET; 00286 } 00287 socket->id = id; 00288 debug_if(_ism_debug, "ISM43362Interface: socket_open, id=%d\n", socket->id); 00289 memset(socket->read_data, 0, sizeof(socket->read_data)); 00290 socket->addr = 0; 00291 socket->read_data_size = 0; 00292 socket->proto = proto; 00293 socket->connected = false; 00294 *handle = socket; 00295 _mutex.unlock(); 00296 00297 return 0; 00298 } 00299 00300 int ISM43362Interface::socket_close(void *handle) 00301 { 00302 _mutex.lock(); 00303 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00304 debug_if(_ism_debug, "ISM43362Interface: socket_close, id=%d\n", socket->id); 00305 int err = 0; 00306 00307 if (!_ism.close(socket->id)) { 00308 err = NSAPI_ERROR_DEVICE_ERROR; 00309 } 00310 00311 socket->connected = false; 00312 _ids[socket->id] = false; 00313 _socket_obj[socket->id] = 0; 00314 _mutex.unlock(); 00315 delete socket; 00316 return err; 00317 } 00318 00319 int ISM43362Interface::socket_bind(void *handle, const SocketAddress &address) 00320 { 00321 return NSAPI_ERROR_UNSUPPORTED; 00322 } 00323 00324 int ISM43362Interface::socket_listen(void *handle, int backlog) 00325 { 00326 return NSAPI_ERROR_UNSUPPORTED; 00327 } 00328 00329 int ISM43362Interface::socket_connect(void *handle, const SocketAddress &addr) 00330 { 00331 _mutex.lock(); 00332 int ret = socket_connect_nolock(handle, addr); 00333 _mutex.unlock(); 00334 return ret; 00335 } 00336 00337 int ISM43362Interface::socket_connect_nolock(void *handle, const SocketAddress &addr) 00338 { 00339 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00340 const char *proto = (socket->proto == NSAPI_UDP) ? "1" : "0"; 00341 if (!_ism.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) { 00342 return NSAPI_ERROR_DEVICE_ERROR; 00343 } 00344 _ids[socket->id] = true; 00345 _socket_obj[socket->id] = (uint32_t)socket; 00346 socket->connected = true; 00347 return 0; 00348 00349 } 00350 00351 00352 00353 void ISM43362Interface::socket_check_read() 00354 { 00355 while (1) { 00356 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00357 _mutex.lock(); 00358 if (_socket_obj[i] != 0) { 00359 struct ISM43362_socket *socket = (struct ISM43362_socket *)_socket_obj[i]; 00360 /* Check if there is something to read for this socket. But if it */ 00361 /* has already been read : don't read again */ 00362 if ((socket->connected) && (socket->read_data_size == 0) && _cbs[socket->id].callback) { 00363 /* if no callback is set, no need to read ?*/ 00364 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00365 // debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d read_amount %d \r\n", i, read_amount); 00366 if (read_amount > 0) { 00367 socket->read_data_size = read_amount; 00368 } else if (read_amount < 0) { 00369 /* Mark donw connection has been lost or closed */ 00370 debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d closed\r\n", i, read_amount); 00371 socket->connected = false; 00372 } 00373 if (read_amount != 0) { 00374 /* There is something to read in this socket*/ 00375 if (_cbs[socket->id].callback) { 00376 _cbs[socket->id].callback(_cbs[socket->id].data); 00377 } 00378 } 00379 } 00380 } 00381 _mutex.unlock(); 00382 } 00383 wait_ms(50); 00384 } 00385 } 00386 00387 int ISM43362Interface::socket_accept(void *server, void **socket, SocketAddress *addr) 00388 { 00389 return NSAPI_ERROR_UNSUPPORTED; 00390 } 00391 00392 int ISM43362Interface::socket_send(void *handle, const void *data, unsigned size) 00393 { 00394 _mutex.lock(); 00395 int ret = socket_send_nolock(handle, data, size); 00396 _mutex.unlock(); 00397 return ret; 00398 } 00399 00400 /* CAREFULL LOCK must be taken before callling this function */ 00401 int ISM43362Interface::socket_send_nolock(void *handle, const void *data, unsigned size) 00402 { 00403 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00404 00405 if (size > ES_WIFI_MAX_TX_PACKET_SIZE) { 00406 size = ES_WIFI_MAX_TX_PACKET_SIZE; 00407 } 00408 00409 if (!_ism.send(socket->id, data, size)) { 00410 debug_if(_ism_debug, "ISM43362Interface: socket_send ERROR\r\n"); 00411 return NSAPI_ERROR_DEVICE_ERROR; // or WOULD_BLOCK ? 00412 } 00413 00414 return size; 00415 } 00416 00417 int ISM43362Interface::socket_recv(void *handle, void *data, unsigned size) 00418 { 00419 _mutex.lock(); 00420 unsigned recv = 0; 00421 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00422 char *ptr = (char *)data; 00423 00424 // debug_if(_ism_debug, "ISM43362Interface socket_recv: req=%d read_data_size=%d connected %d\r\n", size, socket->read_data_size, socket->connected); 00425 00426 if (!socket->connected) { 00427 _mutex.unlock(); 00428 return NSAPI_ERROR_CONNECTION_LOST; 00429 } 00430 00431 if (socket->read_data_size == 0) { 00432 /* if no callback is set, no need to read ?*/ 00433 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00434 if (read_amount > 0) { 00435 socket->read_data_size = read_amount; 00436 } else if (read_amount < 0) { 00437 socket->connected = false; 00438 debug_if(_ism_debug, "ISM43362Interface socket_recv: socket closed\r\n"); 00439 _mutex.unlock(); 00440 return NSAPI_ERROR_CONNECTION_LOST; 00441 } 00442 } 00443 00444 if (socket->read_data_size != 0) { 00445 // debug_if(_ism_debug, "ISM43362Interface socket_recv: read_data_size=%d\r\n", socket->read_data_size); 00446 uint32_t i = 0; 00447 while ((i < socket->read_data_size) && (i < size)) { 00448 *ptr++ = socket->read_data[i]; 00449 i++; 00450 } 00451 00452 recv += i; 00453 00454 if (i >= socket->read_data_size) { 00455 /* All the storeed data has been read, reset buffer */ 00456 memset(socket->read_data, 0, sizeof(socket->read_data)); 00457 socket->read_data_size = 0; 00458 // debug_if(_ism_debug, "ISM43362Interface: Socket_recv buffer reset\r\n"); 00459 } else { 00460 /* In case there is remaining data in buffer, update socket content 00461 * For now by shift copy of all data (not very efficient to be 00462 * revised */ 00463 while (i < socket->read_data_size) { 00464 socket->read_data[i - size] = socket->read_data[i]; 00465 i++; 00466 } 00467 00468 socket->read_data_size -= size; 00469 } 00470 } 00471 // else { 00472 // debug_if(_ism_debug, "ISM43362Interface socket_recv: Nothing in buffer\r\n"); 00473 // } 00474 00475 _mutex.unlock(); 00476 00477 if (recv > 0) { 00478 debug_if(_ism_debug, "ISM43362Interface socket_recv: recv=%d\r\n", recv); 00479 return recv; 00480 } else { 00481 debug_if(_ism_debug, "ISM43362Interface socket_recv: returns WOULD BLOCK\r\n"); 00482 return NSAPI_ERROR_WOULD_BLOCK; 00483 } 00484 } 00485 00486 int ISM43362Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00487 { 00488 _mutex.lock(); 00489 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00490 00491 if (socket->connected && socket->addr != addr) { 00492 if (!_ism.close(socket->id)) { 00493 debug_if(_ism_debug, "ISM43362Interface: socket_sendto ERROR\r\n"); 00494 _mutex.unlock(); 00495 return NSAPI_ERROR_DEVICE_ERROR; 00496 } 00497 socket->connected = false; 00498 _ids[socket->id] = false; 00499 _socket_obj[socket->id] = 0; 00500 } 00501 00502 if (!socket->connected) { 00503 int err = socket_connect_nolock(socket, addr); 00504 if (err < 0) { 00505 _mutex.unlock(); 00506 return err; 00507 } 00508 socket->addr = addr; 00509 } 00510 00511 int ret = socket_send_nolock(socket, data, size); 00512 00513 _mutex.unlock(); 00514 00515 return ret; 00516 } 00517 00518 int ISM43362Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00519 { 00520 int ret = socket_recv(handle, data, size); 00521 _mutex.lock(); 00522 if ((ret >= 0) && addr) { 00523 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00524 *addr = socket->addr; 00525 } 00526 _mutex.unlock(); 00527 return ret; 00528 } 00529 00530 void ISM43362Interface::socket_attach(void *handle, void (*cb)(void *), void *data) 00531 { 00532 _mutex.lock(); 00533 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00534 _cbs[socket->id].callback = cb; 00535 _cbs[socket->id].data = data; 00536 _mutex.unlock(); 00537 } 00538 00539 void ISM43362Interface::event() 00540 { 00541 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00542 if (_cbs[i].callback) { 00543 _cbs[i].callback(_cbs[i].data); 00544 } 00545 } 00546 } 00547 00548 #if MBED_CONF_ISM43362_PROVIDE_DEFAULT 00549 00550 WiFiInterface *WiFiInterface::get_default_instance() { 00551 static ISM43362Interface ism; 00552 return &ism; 00553 } 00554 00555 #endif
Generated on Tue Jul 12 2022 16:24:13 by
1.7.2