|
| 1 | +/* |
| 2 | + * Copyright 2018-2020 Cypress Semiconductor Corporation |
| 3 | + * SPDX-License-Identifier: Apache-2.0 |
| 4 | + * |
| 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | + * you may not use this file except in compliance with the License. |
| 7 | + * You may obtain a copy of the License at |
| 8 | + * |
| 9 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | + * |
| 11 | + * Unless required by applicable law or agreed to in writing, software |
| 12 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | + * See the License for the specific language governing permissions and |
| 15 | + * limitations under the License. |
| 16 | + */ |
| 17 | + |
| 18 | +#include <cstring> |
| 19 | +#include <algorithm> |
| 20 | +#include <vector> |
| 21 | +#include "SclSTAInterface.h" |
| 22 | +#include "nsapi.h" |
| 23 | +#include "lwipopts.h" |
| 24 | +#include "lwip/etharp.h" |
| 25 | +#include "lwip/ethip6.h" |
| 26 | +#include "rtos.h" |
| 27 | +#include "scl_emac.h" |
| 28 | +#include "scl_ipc.h" |
| 29 | +#include "mbed_wait_api.h" |
| 30 | + |
| 31 | + |
| 32 | +/** @file |
| 33 | + * Provides SCL interface functions to be used with WiFiInterface or NetworkInterface Objects |
| 34 | + */ |
| 35 | + |
| 36 | +struct scl_tx_nw_credentials { |
| 37 | + nsapi_security_t network_security_type; |
| 38 | + int ssid_len; |
| 39 | + int pass_len; |
| 40 | + const char *network_ssid; |
| 41 | + const char *network_passphrase; |
| 42 | +} scl_tx_nw_credentials_t; |
| 43 | + |
| 44 | +network_params_t network_parameter; |
| 45 | + |
| 46 | +int scl_toerror(scl_result_t res) |
| 47 | +{ |
| 48 | + switch (res) { |
| 49 | + case SCL_SUCCESS: |
| 50 | + return NSAPI_ERROR_OK; |
| 51 | + case SCL_UNSUPPORTED: |
| 52 | + return NSAPI_ERROR_UNSUPPORTED; |
| 53 | + case SCL_BADARG: |
| 54 | + return NSAPI_ERROR_PARAMETER; |
| 55 | + case SCL_INVALID_JOIN_STATUS: |
| 56 | + return NSAPI_ERROR_NO_CONNECTION; |
| 57 | + case SCL_BUFFER_UNAVAILABLE_PERMANENT: |
| 58 | + case SCL_BUFFER_UNAVAILABLE_TEMPORARY: |
| 59 | + case SCL_RX_BUFFER_ALLOC_FAIL: |
| 60 | + case SCL_BUFFER_ALLOC_FAIL: |
| 61 | + case SCL_MALLOC_FAILURE: |
| 62 | + return NSAPI_ERROR_NO_MEMORY; |
| 63 | + case SCL_ACCESS_POINT_NOT_FOUND: |
| 64 | + case SCL_NETWORK_NOT_FOUND: |
| 65 | + return NSAPI_ERROR_NO_SSID; |
| 66 | + case SCL_NOT_AUTHENTICATED: |
| 67 | + case SCL_INVALID_KEY: |
| 68 | + case SCL_NOT_KEYED: |
| 69 | + return NSAPI_ERROR_AUTH_FAILURE; |
| 70 | + case SCL_PENDING: |
| 71 | + case SCL_JOIN_IN_PROGRESS: |
| 72 | + return NSAPI_ERROR_IN_PROGRESS; |
| 73 | + case SCL_CONNECTION_LOST: |
| 74 | + return NSAPI_ERROR_CONNECTION_LOST; |
| 75 | + case SCL_TIMEOUT: |
| 76 | + case SCL_EAPOL_KEY_PACKET_M1_TIMEOUT: |
| 77 | + case SCL_EAPOL_KEY_PACKET_M3_TIMEOUT: |
| 78 | + case SCL_EAPOL_KEY_PACKET_G1_TIMEOUT: |
| 79 | + return NSAPI_ERROR_CONNECTION_TIMEOUT; |
| 80 | + default: |
| 81 | + return -res; |
| 82 | + } |
| 83 | +} |
| 84 | + |
| 85 | +nsapi_security_t scl_tosecurity(scl_security_t sec) |
| 86 | +{ |
| 87 | + switch (sec) { |
| 88 | + case SCL_SECURITY_OPEN: |
| 89 | + return NSAPI_SECURITY_NONE; |
| 90 | + case SCL_SECURITY_WEP_PSK: |
| 91 | + case SCL_SECURITY_WEP_SHARED: |
| 92 | + return NSAPI_SECURITY_WEP; |
| 93 | + case SCL_SECURITY_WPA_TKIP_PSK: |
| 94 | + case SCL_SECURITY_WPA_TKIP_ENT: |
| 95 | + return NSAPI_SECURITY_WPA; |
| 96 | + case SCL_SECURITY_WPA2_MIXED_PSK: |
| 97 | + return NSAPI_SECURITY_WPA_WPA2; |
| 98 | + case SCL_SECURITY_WPA2_AES_PSK: |
| 99 | + case SCL_SECURITY_WPA2_AES_ENT: |
| 100 | + case SCL_SECURITY_WPA2_FBT_PSK: |
| 101 | + case SCL_SECURITY_WPA2_FBT_ENT: |
| 102 | + return NSAPI_SECURITY_WPA2; |
| 103 | + default: |
| 104 | + return NSAPI_SECURITY_UNKNOWN; |
| 105 | + } |
| 106 | +} |
| 107 | + |
| 108 | +scl_security_t scl_fromsecurity(nsapi_security_t sec) |
| 109 | +{ |
| 110 | + switch (sec) { |
| 111 | + case NSAPI_SECURITY_NONE: |
| 112 | + return SCL_SECURITY_OPEN; |
| 113 | + case NSAPI_SECURITY_WEP: |
| 114 | + return SCL_SECURITY_WEP_PSK; |
| 115 | + case NSAPI_SECURITY_WPA: |
| 116 | + return SCL_SECURITY_WPA_MIXED_PSK; |
| 117 | + case NSAPI_SECURITY_WPA2: |
| 118 | + return SCL_SECURITY_WPA2_AES_PSK; |
| 119 | + case NSAPI_SECURITY_WPA_WPA2: |
| 120 | + return SCL_SECURITY_WPA2_MIXED_PSK; |
| 121 | + default: |
| 122 | + return SCL_SECURITY_UNKNOWN; |
| 123 | + } |
| 124 | +} |
| 125 | + |
| 126 | +SclSTAInterface::SclSTAInterface(SCL_EMAC &emac, OnboardNetworkStack &stack) |
| 127 | + : EMACInterface(emac, stack), |
| 128 | + _ssid("\0"), |
| 129 | + _pass("\0"), |
| 130 | + _security(NSAPI_SECURITY_NONE), |
| 131 | + _scl_emac(emac) |
| 132 | +{ |
| 133 | +} |
| 134 | + |
| 135 | +nsapi_error_t SclSTAInterface::connect(const char *ssid, const char *pass, nsapi_security_t security, uint8_t channel) |
| 136 | +{ |
| 137 | + int err = set_channel(channel); |
| 138 | + if (err) { |
| 139 | + return err; |
| 140 | + } |
| 141 | + |
| 142 | + err = set_credentials(ssid, pass, security); |
| 143 | + if (err) { |
| 144 | + return err; |
| 145 | + } |
| 146 | + |
| 147 | + return connect(); |
| 148 | +} |
| 149 | + |
| 150 | +nsapi_error_t SclSTAInterface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) |
| 151 | +{ |
| 152 | + if ((ssid == NULL) || |
| 153 | + (strlen(ssid) == 0) || |
| 154 | + (pass == NULL && (security != NSAPI_SECURITY_NONE)) || |
| 155 | + (strlen(pass) == 0 && (security != NSAPI_SECURITY_NONE)) || |
| 156 | + (strlen(pass) > 63 && (security == NSAPI_SECURITY_WPA2 || security == NSAPI_SECURITY_WPA || security == NSAPI_SECURITY_WPA_WPA2)) |
| 157 | + ) { |
| 158 | + return NSAPI_ERROR_PARAMETER; |
| 159 | + } |
| 160 | + |
| 161 | + memset(_ssid, 0, sizeof(_ssid)); |
| 162 | + strncpy(_ssid, ssid, sizeof(_ssid)); |
| 163 | + |
| 164 | + memset(_pass, 0, sizeof(_pass)); |
| 165 | + strncpy(_pass, pass, sizeof(_pass)); |
| 166 | + |
| 167 | + _security = security; |
| 168 | + |
| 169 | + return NSAPI_ERROR_OK; |
| 170 | +} |
| 171 | + |
| 172 | +nsapi_error_t SclSTAInterface::connect() |
| 173 | +{ |
| 174 | + |
| 175 | + uint32_t delay_timeout = 0; |
| 176 | + scl_result_t ret_val; |
| 177 | + nsapi_error_t interface_status; |
| 178 | + uint32_t connection_status = 0; |
| 179 | + |
| 180 | + scl_tx_nw_credentials_t.network_ssid = _ssid; |
| 181 | + if (strlen(_ssid) < MAX_SSID_LENGTH) { |
| 182 | + scl_tx_nw_credentials_t.ssid_len = strlen(_ssid); |
| 183 | + } |
| 184 | + scl_tx_nw_credentials_t.network_passphrase = _pass; |
| 185 | + if (strlen(_pass) < MAX_PASSWORD_LENGTH) { |
| 186 | + scl_tx_nw_credentials_t.pass_len = strlen(_pass); |
| 187 | + } |
| 188 | + scl_tx_nw_credentials_t.network_security_type = _security; |
| 189 | + |
| 190 | + ret_val = scl_send_data(SCL_TX_CONNECT, (char *)&scl_tx_nw_credentials_t, TIMER_DEFAULT_VALUE); |
| 191 | + |
| 192 | + if (ret_val == SCL_SUCCESS) { |
| 193 | + SCL_LOG(("wifi provisioning in progress")); |
| 194 | + } |
| 195 | + |
| 196 | + network_parameter.connection_status = NSAPI_STATUS_DISCONNECTED; |
| 197 | + |
| 198 | + |
| 199 | + //Get the network parameter from NP |
| 200 | + while ((network_parameter.connection_status != NSAPI_STATUS_GLOBAL_UP) && delay_timeout < NW_CONNECT_TIMEOUT) { |
| 201 | + ret_val = scl_get_nw_parameters(&network_parameter); |
| 202 | + wait_us(NW_DELAY_TIME_US); |
| 203 | + delay_timeout++; |
| 204 | + } |
| 205 | + |
| 206 | + if (delay_timeout >= NW_CONNECT_TIMEOUT || ret_val != SCL_SUCCESS) { |
| 207 | + return NSAPI_ERROR_NO_CONNECTION; |
| 208 | + } |
| 209 | + |
| 210 | + if (!_scl_emac.powered_up) { |
| 211 | + _scl_emac.power_up(); |
| 212 | + } |
| 213 | + |
| 214 | + if (!_interface) { |
| 215 | + nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface); |
| 216 | + if (err != NSAPI_ERROR_OK) { |
| 217 | + _interface = NULL; |
| 218 | + return err; |
| 219 | + } |
| 220 | + _interface->attach(_connection_status_cb); |
| 221 | + } |
| 222 | + |
| 223 | + if (!scl_wifi_is_ready_to_transceive()) { |
| 224 | + scl_emac_wifi_link_state_changed(true); |
| 225 | + } |
| 226 | + |
| 227 | + interface_status = _interface->bringup(false, |
| 228 | + network_parameter.ip_address, |
| 229 | + network_parameter.netmask, |
| 230 | + network_parameter.gateway, |
| 231 | + DEFAULT_STACK); |
| 232 | + |
| 233 | + scl_send_data(SCL_TX_CONNECTION_STATUS, (char *)&connection_status, TIMER_DEFAULT_VALUE); |
| 234 | + |
| 235 | + return interface_status; |
| 236 | +} |
| 237 | + |
| 238 | +void SclSTAInterface::wifi_on() |
| 239 | +{ |
| 240 | + if (!_scl_emac.powered_up) { |
| 241 | + _scl_emac.power_up(); |
| 242 | + } |
| 243 | +} |
| 244 | + |
| 245 | +nsapi_error_t SclSTAInterface::disconnect() |
| 246 | +{ |
| 247 | + scl_result_t ret_val; |
| 248 | + nsapi_error_t disconnect_status; |
| 249 | + ret_val = scl_send_data(SCL_TX_DISCONNECT, (char *)&disconnect_status, TIMER_DEFAULT_VALUE); |
| 250 | + |
| 251 | + if (ret_val == SCL_ERROR) { |
| 252 | + return NSAPI_ERROR_TIMEOUT; |
| 253 | + } |
| 254 | + |
| 255 | + if (!_interface) { |
| 256 | + return NSAPI_STATUS_DISCONNECTED; |
| 257 | + } |
| 258 | + |
| 259 | + // bring down |
| 260 | + int err = _interface->bringdown(); |
| 261 | + if (err) { |
| 262 | + return err; |
| 263 | + } |
| 264 | + |
| 265 | + scl_emac_wifi_link_state_changed(false); |
| 266 | + |
| 267 | + return NSAPI_ERROR_OK; |
| 268 | +} |
| 269 | + |
| 270 | +int SclSTAInterface::scan(WiFiAccessPoint *res, unsigned count) |
| 271 | +{ |
| 272 | + /* To Do */ |
| 273 | + return NSAPI_ERROR_UNSUPPORTED; |
| 274 | +} |
| 275 | + |
| 276 | +int8_t SclSTAInterface::get_rssi() |
| 277 | +{ |
| 278 | + int32_t rssi; |
| 279 | + scl_result_t res; |
| 280 | + |
| 281 | + if (!_scl_emac.powered_up) { |
| 282 | + _scl_emac.power_up(); |
| 283 | + } |
| 284 | + |
| 285 | + res = (scl_result_t) scl_wifi_get_rssi(&rssi); |
| 286 | + if (res == SCL_ERROR) { |
| 287 | + return SCL_ERROR; |
| 288 | + } |
| 289 | + |
| 290 | + return (int8_t)rssi; |
| 291 | +} |
| 292 | + |
| 293 | +int SclSTAInterface::is_interface_connected(void) |
| 294 | +{ |
| 295 | + if (scl_wifi_is_ready_to_transceive() == SCL_SUCCESS) { |
| 296 | + return SCL_SUCCESS; |
| 297 | + } else { |
| 298 | + return SCL_CONNECTION_LOST; |
| 299 | + } |
| 300 | +} |
| 301 | + |
| 302 | +int SclSTAInterface::get_bssid(uint8_t *bssid) |
| 303 | +{ |
| 304 | + scl_mac_t ap_mac; |
| 305 | + scl_result_t res = SCL_SUCCESS; |
| 306 | + |
| 307 | + if (bssid == NULL) { |
| 308 | + return SCL_BADARG; |
| 309 | + } |
| 310 | + |
| 311 | + memset(&ap_mac, 0, sizeof(ap_mac)); |
| 312 | + if (scl_wifi_is_ready_to_transceive() == SCL_SUCCESS) { |
| 313 | + res = (scl_result_t) scl_wifi_get_bssid(&ap_mac); |
| 314 | + if (res == SCL_SUCCESS) { |
| 315 | + memcpy(bssid, ap_mac.octet, sizeof(ap_mac.octet)); |
| 316 | + } |
| 317 | + } else { |
| 318 | + return SCL_CONNECTION_LOST; |
| 319 | + } |
| 320 | + return res; |
| 321 | +} |
| 322 | + |
| 323 | +int SclSTAInterface::wifi_set_up(void) |
| 324 | +{ |
| 325 | + int res = SCL_SUCCESS; |
| 326 | + res = scl_wifi_set_up(); |
| 327 | + return res; |
| 328 | +} |
0 commit comments