Added scan and connect commands.
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
9add7e515b
commit
60a5a9fb07
12
README.md
12
README.md
|
@ -71,15 +71,9 @@ typedef enum {
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
Who owns the buffers? How many buffers should we allocate?
|
* Only a subset of commands are implemented.
|
||||||
|
* Jumbo frames (larger than 1518 bytes) are not supported, since no `realloc` available.
|
||||||
* Minimize the memory block operations (malloc and free)
|
* Just hope ESP won't send some frame larger than that.
|
||||||
* Control plane and data plane can be async
|
|
||||||
* Control API can be blocking until responded
|
|
||||||
* At least 2 full-sized buffers are required (for full duplex operations)
|
|
||||||
* To re-use the bus while a request is underway, control plane and data plane RX buffers should be copied
|
|
||||||
* Bus TX operation should be blocking, however the previous RX data (if any) can be received.
|
|
||||||
* The response for the request being transmitted will never arrive within the same transaction
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
Not decided yet, please be patient. At least not before the project is usable.
|
Not decided yet, please be patient. At least not before the project is usable.
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "nh_shared_if.h"
|
#include "nh_shared_if.h"
|
||||||
|
|
||||||
|
#define NH_CTRL_API_MAC_LENGTH 17
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NH_CTRL_WIFI_MODE_NONE,
|
NH_CTRL_WIFI_MODE_NONE,
|
||||||
NH_CTRL_WIFI_MODE_STA,
|
NH_CTRL_WIFI_MODE_STA,
|
||||||
|
@ -11,26 +13,45 @@ typedef enum {
|
||||||
} nh_ctrl_wifi_mode_t;
|
} nh_ctrl_wifi_mode_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NH_CTRL_WIFI_ENC_MODE_OPEN,
|
NH_CTRL_API_ENC_MODE_OPEN,
|
||||||
NH_CTRL_WIFI_ENC_MODE_WEP,
|
NH_CTRL_API_ENC_MODE_WEP,
|
||||||
NH_CTRL_WIFI_ENC_MODE_WPA_PSK,
|
NH_CTRL_API_ENC_MODE_WPA_PSK,
|
||||||
NH_CTRL_WIFI_ENC_MODE_WPA2_PSK,
|
NH_CTRL_API_ENC_MODE_WPA2_PSK,
|
||||||
NH_CTRL_WIFI_ENC_MODE_WPA_WPA2_PSK,
|
NH_CTRL_API_ENC_MODE_WPA_WPA2_PSK,
|
||||||
NH_CTRL_WIFI_ENC_MODE_WPA2_ENT,
|
NH_CTRL_API_ENC_MODE_WPA2_ENT,
|
||||||
NH_CTRL_WIFI_ENC_MODE_WPA3_PSK,
|
NH_CTRL_API_ENC_MODE_WPA3_PSK,
|
||||||
NH_CTRL_WIFI_ENC_MODE_WPA2_WPA3_PSK,
|
NH_CTRL_API_ENC_MODE_WPA2_WPA3_PSK,
|
||||||
} nh_ctrl_api_wifi_encryption_mode_t;
|
} nh_ctrl_ap_enc_mode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NH_CTRL_CONNECT_SUCCESS = 0x00U,
|
||||||
|
NH_CTRL_CONNECT_NO_AP_FOUND = 0x02U,
|
||||||
|
NH_CTRL_CONNECT_INVALID_PASSWORD = 0x03U,
|
||||||
|
NH_CTRL_CONNECT_FAILURE = 0xFFU,
|
||||||
|
} nh_ctrl_conn_status_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *ssid;
|
char *ssid;
|
||||||
char *bssid;
|
char *bssid;
|
||||||
int rssi;
|
int rssi;
|
||||||
int channel;
|
uint32_t channel;
|
||||||
nh_ctrl_api_wifi_encryption_mode_t encryption_mode;
|
nh_ctrl_ap_enc_mode_t encryption_mode;
|
||||||
} nh_ctrl_api_wifi_scan_item_t;
|
} nh_ctrl_ap_scan_item_t;
|
||||||
|
|
||||||
typedef void (*nh_ctrl_api_ap_scan_list_cb_t)(void *handle, nh_ctrl_api_wifi_scan_item_t);
|
typedef struct {
|
||||||
|
char *ssid;
|
||||||
|
char *bssid;
|
||||||
|
char *password;
|
||||||
|
bool wpa3_supported;
|
||||||
|
int32_t listen_interval;
|
||||||
|
} nh_ctrl_ap_conn_params_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
nh_ctrl_conn_status_t status;
|
||||||
|
char *mac_addr;
|
||||||
|
} nh_ctrl_ap_conn_result_t;
|
||||||
|
|
||||||
|
typedef void (*nh_ctrl_api_ap_scan_list_cb_t)(void *handle, nh_ctrl_ap_scan_item_t *item);
|
||||||
typedef void (*nh_ctrl_api_event_cb_init_t)(void *handle);
|
typedef void (*nh_ctrl_api_event_cb_init_t)(void *handle);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -53,5 +74,7 @@ typedef struct {
|
||||||
nh_ret_t nh_ctrl_api_init(nh_ctrl_api_t *api);
|
nh_ret_t nh_ctrl_api_init(nh_ctrl_api_t *api);
|
||||||
void nh_ctrl_api_task(nh_ctrl_api_t *api);
|
void nh_ctrl_api_task(nh_ctrl_api_t *api);
|
||||||
nh_ret_t nh_ctrl_api_get_mac_address(nh_ctrl_api_t *api, uint8_t *mac_addr, nh_ctrl_wifi_mode_t mode);
|
nh_ret_t nh_ctrl_api_get_mac_address(nh_ctrl_api_t *api, uint8_t *mac_addr, nh_ctrl_wifi_mode_t mode);
|
||||||
|
nh_ret_t nh_ctrl_api_get_ap_scan_list(nh_ctrl_api_t *api, nh_ctrl_api_ap_scan_list_cb_t cb);
|
||||||
|
nh_ret_t nh_ctrl_api_connect_ap(nh_ctrl_api_t *api, nh_ctrl_ap_conn_params_t *params, nh_ctrl_ap_conn_result_t *result);
|
||||||
|
|
||||||
#endif // NH_CTRL_API_H
|
#endif // NH_CTRL_API_H
|
||||||
|
|
|
@ -86,6 +86,9 @@ nh_ret_t nh_ctrl_api_get_mac_address(nh_ctrl_api_t *api, uint8_t *mac_addr, nh_c
|
||||||
ret = nh_ctrl_api_general_response(api, &rx_msg, &c_alloc);
|
ret = nh_ctrl_api_general_response(api, &rx_msg, &c_alloc);
|
||||||
if (ret != NH_RET_SUCCESS || rx_msg->msg_id != CTRL_MSG_ID__Resp_GetMACAddress) goto free_msg_exit;
|
if (ret != NH_RET_SUCCESS || rx_msg->msg_id != CTRL_MSG_ID__Resp_GetMACAddress) goto free_msg_exit;
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (rx_msg->resp_get_mac_address->mac.len != NH_CTRL_API_MAC_LENGTH) goto free_msg_exit;
|
||||||
|
|
||||||
memcpy(mac_addr, rx_msg->resp_get_mac_address->mac.data, rx_msg->resp_get_mac_address->mac.len);
|
memcpy(mac_addr, rx_msg->resp_get_mac_address->mac.data, rx_msg->resp_get_mac_address->mac.len);
|
||||||
mac_addr[rx_msg->resp_get_mac_address->mac.len] = '\0';
|
mac_addr[rx_msg->resp_get_mac_address->mac.len] = '\0';
|
||||||
|
|
||||||
|
@ -127,11 +130,38 @@ nh_ret_t nh_ctrl_api_get_ap_scan_list(nh_ctrl_api_t *api, nh_ctrl_api_ap_scan_li
|
||||||
ret = nh_ctrl_api_general_response(api, &rx_msg, &c_alloc);
|
ret = nh_ctrl_api_general_response(api, &rx_msg, &c_alloc);
|
||||||
if (ret != NH_RET_SUCCESS || rx_msg->msg_id != CTRL_MSG_ID__Resp_GetAPScanList) goto free_msg_exit;
|
if (ret != NH_RET_SUCCESS || rx_msg->msg_id != CTRL_MSG_ID__Resp_GetAPScanList) goto free_msg_exit;
|
||||||
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rx_msg->resp_scan_ap_list->count; i++) {
|
for (uint32_t i = 0; i < rx_msg->resp_scan_ap_list->count; i++) {
|
||||||
nh_ctrl_api_wifi_scan_item_t item = {
|
nh_ctrl_ap_scan_item_t item = {
|
||||||
.ssid = rx_msg->resp_scan_ap_list->entries[i]->ssid.data,
|
.rssi = rx_msg->resp_scan_ap_list->entries[i]->rssi,
|
||||||
|
.channel = rx_msg->resp_scan_ap_list->entries[i]->chnl,
|
||||||
|
.encryption_mode = (nh_ctrl_ap_enc_mode_t)rx_msg->resp_scan_ap_list->entries[i]->sec_prot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32_t ssid_len = rx_msg->resp_scan_ap_list->entries[i]->ssid.len;
|
||||||
|
uint32_t bssid_len = rx_msg->resp_scan_ap_list->entries[i]->bssid.len;
|
||||||
|
|
||||||
|
ret = NH_CTRL_API_ALLOC(api, (uint8_t **)&item.ssid, ssid_len + 1);
|
||||||
|
if (ret != NH_RET_SUCCESS) goto free_msg_exit;
|
||||||
|
|
||||||
|
ret = NH_CTRL_API_ALLOC(api, (uint8_t **)&item.bssid, bssid_len + 1);
|
||||||
|
if (ret != NH_RET_SUCCESS) {
|
||||||
|
NH_CTRL_API_FREE(api, (uint8_t *)item.ssid);
|
||||||
|
|
||||||
|
goto free_msg_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(item.ssid, rx_msg->resp_scan_ap_list->entries[i]->ssid.data, ssid_len);
|
||||||
|
memcpy(item.bssid, rx_msg->resp_scan_ap_list->entries[i]->bssid.data, bssid_len);
|
||||||
|
|
||||||
|
item.ssid[ssid_len] = '\0';
|
||||||
|
item.bssid[bssid_len] = '\0';
|
||||||
|
|
||||||
|
if (cb) {
|
||||||
|
cb(api->user_data, &item);
|
||||||
|
}
|
||||||
|
|
||||||
|
NH_CTRL_API_FREE(api, (uint8_t *)item.ssid);
|
||||||
|
NH_CTRL_API_FREE(api, (uint8_t *)item.bssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_msg_exit:
|
free_msg_exit:
|
||||||
|
@ -146,6 +176,59 @@ give_sem_exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nh_ret_t nh_ctrl_api_connect_ap(nh_ctrl_api_t *api, nh_ctrl_ap_conn_params_t *params,
|
||||||
|
nh_ctrl_ap_conn_result_t *result) {
|
||||||
|
nh_ret_t ret = NH_RET_SUCCESS;
|
||||||
|
|
||||||
|
NH_CTRL_API_CREATE_ALLOCATOR(c_alloc);
|
||||||
|
ret = NH_CTRL_API_TAKE_SEM(api, NH_COMMAND_TIMEOUT_MSEC);
|
||||||
|
if (ret != NH_RET_SUCCESS) return ret;
|
||||||
|
|
||||||
|
CtrlMsg tx_msg;
|
||||||
|
ctrl_msg__init(&tx_msg);
|
||||||
|
|
||||||
|
tx_msg.msg_id = CTRL_MSG_ID__Req_ConnectAP;
|
||||||
|
tx_msg.payload_case = CTRL_MSG__PAYLOAD_REQ_CONNECT_AP;
|
||||||
|
|
||||||
|
ret = NH_CTRL_API_ALLOC(api, (uint8_t **)&tx_msg.req_connect_ap, sizeof(CtrlMsgReqConnectAP));
|
||||||
|
if (ret != NH_RET_SUCCESS) goto give_sem_exit;
|
||||||
|
|
||||||
|
ctrl_msg__req__connect_ap__init(tx_msg.req_connect_ap);
|
||||||
|
|
||||||
|
tx_msg.req_connect_ap->ssid = params->ssid;
|
||||||
|
tx_msg.req_connect_ap->bssid = params->bssid;
|
||||||
|
tx_msg.req_connect_ap->pwd = params->password;
|
||||||
|
tx_msg.req_connect_ap->is_wpa3_supported = params->wpa3_supported;
|
||||||
|
tx_msg.req_connect_ap->listen_interval = params->listen_interval;
|
||||||
|
|
||||||
|
ret = nh_ctrl_api_general_request(api, &tx_msg);
|
||||||
|
if (ret != NH_RET_SUCCESS) goto free_payload_exit;
|
||||||
|
|
||||||
|
CtrlMsg *rx_msg;
|
||||||
|
|
||||||
|
ret = nh_ctrl_api_general_response(api, &rx_msg, &c_alloc);
|
||||||
|
if (ret != NH_RET_SUCCESS || rx_msg->msg_id != CTRL_MSG_ID__Resp_ConnectAP) goto free_msg_exit;
|
||||||
|
|
||||||
|
uint32_t mac_len = rx_msg->resp_connect_ap->mac.len;
|
||||||
|
if (mac_len != NH_CTRL_API_MAC_LENGTH) goto free_msg_exit;
|
||||||
|
|
||||||
|
memcpy(result->mac_addr, rx_msg->resp_connect_ap->mac.data, mac_len);
|
||||||
|
result->mac_addr[mac_len] = '\0';
|
||||||
|
|
||||||
|
result->status = (nh_ctrl_conn_status_t)rx_msg->resp_connect_ap->resp;
|
||||||
|
|
||||||
|
free_msg_exit:
|
||||||
|
ctrl_msg__free_unpacked(rx_msg, &c_alloc);
|
||||||
|
|
||||||
|
free_payload_exit:
|
||||||
|
NH_CTRL_API_FREE(api, (uint8_t *)tx_msg.req_connect_ap);
|
||||||
|
|
||||||
|
give_sem_exit:
|
||||||
|
NH_CTRL_API_GIVE_SEM(api);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void nh_ctrl_api_task(nh_ctrl_api_t *api) {
|
void nh_ctrl_api_task(nh_ctrl_api_t *api) {
|
||||||
nh_ret_t ret = NH_RET_SUCCESS;
|
nh_ret_t ret = NH_RET_SUCCESS;
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ typedef struct __attribute__((packed)) {
|
||||||
}; /* Offset: 0x0B */
|
}; /* Offset: 0x0B */
|
||||||
} nh_xfer_pkt_hdr_t; /* Size: 0x0C (12 bytes) */
|
} nh_xfer_pkt_hdr_t; /* Size: 0x0C (12 bytes) */
|
||||||
|
|
||||||
|
static void nh_shared_if_dispatch_sta(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len);
|
||||||
|
static void nh_shared_if_dispatch_ap(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len);
|
||||||
static void nh_shared_if_dispatch_if_serial(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len);
|
static void nh_shared_if_dispatch_if_serial(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len);
|
||||||
static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload);
|
static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload);
|
||||||
|
|
||||||
|
@ -243,20 +245,26 @@ void nh_shared_if_task(nh_shared_if_t *shared_if) {
|
||||||
item.buf_len = LE16_TO_H(hdr->len);
|
item.buf_len = LE16_TO_H(hdr->len);
|
||||||
item.buf = &shared_if->p_buf_frame_rx[LE16_TO_H(hdr->offset)]; /* DO NOT FREE THIS!! */
|
item.buf = &shared_if->p_buf_frame_rx[LE16_TO_H(hdr->offset)]; /* DO NOT FREE THIS!! */
|
||||||
|
|
||||||
if (item.type == NH_SHARED_IF_TYPE_SERIAL) {
|
|
||||||
if (!item.buf_len) {
|
if (!item.buf_len) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.type == NH_SHARED_IF_TYPE_SERIAL) {
|
||||||
nh_shared_if_dispatch_if_serial(shared_if, item.buf, item.buf_len);
|
nh_shared_if_dispatch_if_serial(shared_if, item.buf, item.buf_len);
|
||||||
} else if (item.type == NH_SHARED_IF_TYPE_PRIV) {
|
} else if (item.type == NH_SHARED_IF_TYPE_PRIV) {
|
||||||
if (!item.buf_len) {
|
nh_shared_if_dispatch_if_priv(shared_if, hdr->priv_pkt_type, item.buf);
|
||||||
return;
|
} else if (item.type == NH_SHARED_IF_TYPE_STA) {
|
||||||
|
nh_shared_if_dispatch_sta(shared_if, item.buf, item.buf_len);
|
||||||
|
} else if(item.type == NH_SHARED_IF_TYPE_AP) {
|
||||||
|
nh_shared_if_dispatch_ap(shared_if, item.buf, item.buf_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nh_shared_if_dispatch_if_priv(shared_if, hdr->priv_pkt_type, item.buf);
|
static void nh_shared_if_dispatch_sta(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len) {
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nh_shared_if_dispatch_ap(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload) {
|
static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload) {
|
||||||
|
|
Loading…
Reference in New Issue