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.
wifi-ism43362/ISM43362Interface.cpp@0:5738799d7a56, 2020-10-28 (annotated)
- Committer:
- axelhwang
- Date:
- Wed Oct 28 07:42:46 2020 +0000
- Revision:
- 0:5738799d7a56
Push
Who changed what in which revision?
| User | Revision | Line number | New 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 | } |