1 /*
2  * Copyright (c) 2024, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef USBH_BL616_H
7 #define USBH_BL616_H
8 
9 #define USBWIFI_DATA_TYPE_CMD 0xA55A
10 #define USBWIFI_DATA_TYPE_PKT 0x6996
11 
12 #define USB_DATA_FLAG_AP_PKT (1u << 0)
13 
14 typedef enum {
15     BFLB_CMD_REBOOT = 0,
16     BFLB_CMD_RESET,
17     BFLB_CMD_HELLO,
18     BFLB_CMD_PING,
19 
20     BFLB_CMD_GET_MAC_ADDR,
21 
22     // Scan
23     BFLB_CMD_SCAN,
24     BFLB_CMD_SCAN_RESULTS,
25 
26     // STA
27     BFLB_CMD_STA_CONNECT,
28     BFLB_CMD_STA_DISCONNECT,
29     BFLB_CMD_STA_CONNECTED_IND,
30     BFLB_CMD_STA_DISCONNECTED_IND,
31     BFLB_CMD_STA_IP_UPDATE_IND,
32     BFLB_CMD_STA_SET_AUTO_RECONNECT,
33     BFLB_CMD_STA_GET_LINK_STATUS,
34 
35     // AP
36     BFLB_CMD_AP_START,
37     BFLB_CMD_AP_STOP,
38     BFLB_CMD_AP_STARTED_IND,
39     BFLB_CMD_AP_STOPPED_IND,
40     BFLB_CMD_AP_GET_STA_LIST,
41 
42     // Monitor
43     BFLB_CMD_MONITOR_START,
44     BFLB_CMD_MONITOR_STOP,
45     BFLB_CMD_MONITOR_SET_CHANNEL,
46     BFLB_CMD_MONITOR_GET_CHANNEL,
47 
48     BFLB_CMD_SET_LPM_MODE,
49 
50     // OTA
51     BFLB_CMD_GET_DEV_VERSION,
52     BFLB_CMD_OTA,
53 
54     BFLB_CMD_EXT,
55 
56     BFLB_CMD_USER_EXT,
57     BFLB_CMD_UNLOAD_DRV,
58 
59     BFLB_CMD_MAX,
60 } bflb_cmd_t;
61 
62 typedef enum {
63     STATUS_OK,
64     STATUS_NOMEM = 128,
65     STATUS_INVALID_INPUT,
66     STATUS_INVALID_MODE,
67     STATUS_ERR_UNSPECIFIED,
68     STATUS_NOT_IMPLEMENTED,
69 } cmd_status_t;
70 
71 typedef enum {
72     RNM_WIFI_AUTH_UNKNOWN = 0,
73     RNM_WIFI_AUTH_OPEN,
74     RNM_WIFI_AUTH_WEP,
75     RNM_WIFI_AUTH_WPA_PSK,
76     RNM_WIFI_AUTH_WPA2_PSK,
77     RNM_WIFI_AUTH_WPA_WPA2_PSK,
78     RNM_WIFI_AUTH_WPA_ENTERPRISE,
79     RNM_WIFI_AUTH_WPA3_SAE,
80     RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE,
81     RNM_WIFI_AUTH_MAX,
82 } rnm_wifi_auth_mode_t;
83 
84 typedef enum {
85     RNM_WIFI_CIPHER_UNKNOWN = 0,
86     RNM_WIFI_CIPHER_NONE,
87     RNM_WIFI_CIPHER_WEP,
88     RNM_WIFI_CIPHER_AES,
89     RNM_WIFI_CIPHER_TKIP,
90     RNM_WIFI_CIPHER_TKIP_AES,
91     RNM_WIFI_CIPHER_MAX,
92 } rnm_wifi_cipher_t;
93 
94 /* common header */
95 typedef struct {
96     uint16_t cmd;
97     // flag ACK is used by server to indicate a response to client
98 #define RNM_MSG_FLAG_ACK         (1 << 0)
99     // flag TRANSPARENT is never transfered to peer but used locally
100 #define RNM_MSG_FLAG_TRANSPARENT (1 << 1)
101     // flag ASYNC is used by server to notify client events such as STA_CONNECTED
102 #define RNM_MSG_FLAG_ASYNC       (1 << 2)
103     uint16_t flags;
104     uint16_t status;
105     uint16_t msg_id;
106     uint16_t session_id;
107     uint16_t msg_id_replying;
108 } rnm_base_msg_t;
109 
110 typedef struct {
111     rnm_base_msg_t hdr;
112 } rnm_ack_msg_t;
113 
114 typedef struct {
115     rnm_base_msg_t hdr;
116     uint8_t sta_mac[6];
117     uint8_t ap_mac[6];
118 } rnm_mac_addr_ind_msg_t;
119 
120 typedef struct {
121     rnm_base_msg_t hdr;
122     uint16_t ssid_len;
123     uint8_t ssid[32];
124     uint8_t password[64];
125 } rnm_sta_connect_msg_t;
126 
127 typedef struct {
128     rnm_base_msg_t hdr;
129     uint8_t ip4_addr[4];
130     uint8_t ip4_mask[4];
131     uint8_t ip4_gw[4];
132     uint8_t ip4_dns1[4];
133     uint8_t ip4_dns2[4];
134     uint8_t gw_mac[6];
135 } rnm_sta_ip_update_ind_msg_t;
136 
137 struct bf1b_wifi_scan_record {
138     uint8_t bssid[6];
139     // TODO use compressed SSID encoding to save room
140     uint8_t ssid[32 + 1];
141     uint16_t channel;
142     int8_t rssi;
143     uint8_t auth_mode;
144     uint8_t cipher;
145 } __PACKED;
146 
147 typedef struct {
148     rnm_base_msg_t hdr;
149     uint16_t num;
150     struct bf1b_wifi_scan_record records[];
151 } rnm_scan_ind_msg_t;
152 
153 typedef enum {
154     BL_MODE_NONE,
155     BL_MODE_STA,      // card is STA
156     BL_MODE_AP,       // card is AP
157     BL_MODE_STA_AP,   // card is STA&AP
158     BL_MODE_SNIFFER,  // card is sniffer
159     BL_MODE_MAX,
160 } bl_wifi_mode_t;
161 
162 typedef struct {
163     uint16_t type;
164     uint16_t length;
165     uint16_t flags;
166     uint16_t payload_offset;
167     uint32_t rsvd[8];
168     uint8_t payload[];
169 } __attribute__((aligned(4))) usb_data_t;
170 
171 struct usbh_bl616 {
172     struct usbh_hubport *hport;
173     struct usb_endpoint_descriptor *bulkin;  /* Bulk IN endpoint */
174     struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */
175 
176     struct usbh_urb bulkout_urb;
177     struct usbh_urb bulkin_urb;
178 
179     uint8_t intf;
180 
181     uint8_t sta_mac[6];
182     uint8_t ap_mac[6];
183     uint8_t mode;
184     bool connect_status;
185 
186     void *user_data;
187 };
188 
189 #ifdef __cplusplus
190 extern "C" {
191 #endif
192 
193 int usbh_bl616_wifi_sta_connect(const char *ssid,
194                                 const int ssid_len,
195                                 const char *password,
196                                 const int pwd_len);
197 
198 int usbh_bl616_wifi_sta_disconnect(void);
199 int usbh_bl616_wifi_scan(void);
200 
201 void usbh_bl616_sta_connect_callback(void);
202 void usbh_bl616_sta_disconnect_callback(void);
203 void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4]);
204 
205 uint8_t *usbh_bl616_get_eth_txbuf(void);
206 int usbh_bl616_eth_output(uint32_t buflen);
207 void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen);
208 void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
209 
210 void usbh_bl616_run(struct usbh_bl616 *bl616_class);
211 void usbh_bl616_stop(struct usbh_bl616 *bl616_class);
212 
213 int wifi_sta_connect(int argc, char **argv);
214 int wifi_scan(int argc, char **argv);
215 
216 #ifdef __cplusplus
217 }
218 #endif
219 
220 #endif /* USBH_BL616_H */
221