| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 | 
							- /*
 
-  * libwebsockets - small server side websockets and web server implementation
 
-  *
 
-  * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
 
-  *
 
-  * Permission is hereby granted, free of charge, to any person obtaining a copy
 
-  * of this software and associated documentation files (the "Software"), to
 
-  * deal in the Software without restriction, including without limitation the
 
-  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 
-  * sell copies of the Software, and to permit persons to whom the Software is
 
-  * furnished to do so, subject to the following conditions:
 
-  *
 
-  * The above copyright notice and this permission notice shall be included in
 
-  * all copies or substantial portions of the Software.
 
-  *
 
-  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
-  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
-  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
-  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
-  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
-  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
-  * IN THE SOFTWARE.
 
-  */
 
- #define LWS_WIFI_MAX_SCAN_TRACK 16
 
- #define LWS_ETH_ALEN 6
 
- typedef uint8_t	lws_wifi_ch_t;
 
- typedef int8_t lws_wifi_rssi_t;
 
- struct lws_netdev_instance;
 
- typedef enum {
 
- 	LWSNDTYP_UNKNOWN,
 
- 	LWSNDTYP_WIFI,
 
- 	LWSNDTYP_ETH,
 
- } lws_netdev_type_t;
 
- /*
 
-  * Base class for netdev configuration
 
-  */
 
- typedef struct lws_netdev_config {
 
- 	void				*plat_config;
 
- } lws_netdev_config_t;
 
- /*
 
-  * Const Logical generic network interface ops
 
-  */
 
- typedef struct lws_netdev_ops {
 
- 	struct lws_netdev_instance * (*create)(struct lws_context *ctx,
 
- 					       const struct lws_netdev_ops *ops,
 
- 					       const char *name, void *platinfo);
 
- 	int (*configure)(struct lws_netdev_instance *nd,
 
- 			 lws_netdev_config_t *config);
 
- 	int (*up)(struct lws_netdev_instance *nd);
 
- 	int (*down)(struct lws_netdev_instance *nd);
 
- 	int (*event)(struct lws_netdev_instance *nd, lws_usec_t timestamp,
 
- 		     void *buf, size_t len);
 
- 	/**< these are SMD events coming from lws event loop thread context */
 
- 	void (*destroy)(struct lws_netdev_instance **pnd);
 
- 	int (*connect)(struct lws_netdev_instance *wnd, const char *ssid,
 
- 			    const char *passphrase, uint8_t *bssid);
 
- 	void (*scan)(struct lws_netdev_instance *nd);
 
- } lws_netdev_ops_t;
 
- /*
 
-  * Network devices on this platform
 
-  *
 
-  * We also hold a list of all known network credentials (when they are needed
 
-  * because there is a network interface without anything to connect to) and
 
-  * the lws_settings instance they are stored in
 
-  */
 
- typedef struct lws_netdevs {
 
- 	lws_dll2_owner_t		owner;
 
- 	/**< list of netdevs / lws_netdev_instance_t -based objects */
 
- 	lws_dll2_owner_t		owner_creds;
 
- 	/**< list of known credentials */
 
- 	struct lwsac			*ac_creds;
 
- 	/**< lwsac holding retreived credentials settings, or NULL */
 
- 	lws_settings_instance_t		*si;
 
- 	lws_sockaddr46			sa46_dns_resolver;
 
- 	uint8_t				refcount_creds;
 
- 	/**< when there are multiple netdevs, must refcount creds in mem */
 
- } lws_netdevs_t;
 
- /*
 
-  * Base class for an allocated instantiated derived object using lws_netdev_ops,
 
-  * ie, a specific ethernet device
 
-  */
 
- typedef struct lws_netdev_instance {
 
- 	const char			*name;
 
- 	const lws_netdev_ops_t		*ops;
 
- 	void				*platinfo;
 
- 	lws_dll2_t			list;
 
- 	uint8_t				mac[LWS_ETH_ALEN];
 
- 	uint8_t				type; /* lws_netdev_type_t */
 
- } lws_netdev_instance_t;
 
- enum {
 
- 	LNDIW_ALG_OPEN,
 
- 	LNDIW_ALG_WPA2,
 
- 	LNDIW_MODE_STA			= (1 << 0),
 
- 	LNDIW_MODE_AP			= (1 << 1),
 
- 	LNDIW_UP			= (1 << 7),
 
- 	LNDIW_ACQ_IPv4			= (1 << 0),
 
- 	LNDIW_ACQ_IPv6			= (1 << 1),
 
- };
 
- /*
 
-  * Group AP / Station State
 
-  */
 
- typedef enum {
 
- 	LWSNDVWIFI_STATE_INITIAL,
 
- 		/*
 
- 		 * We should gratuitously try whatever last worked for us, then
 
- 		 * if that fails, worry about the rest of the logic
 
- 		 */
 
- 	LWSNDVWIFI_STATE_SCAN,
 
- 		/*
 
- 		 * Unconnected, scanning: AP known in one of the config slots ->
 
- 		 * configure it, start timeout + LWSNDVWIFI_STATE_STAT, if no AP
 
- 		 * already up in same group with lower MAC, after a random
 
- 		 * period start up our AP (LWSNDVWIFI_STATE_AP)
 
- 		 */
 
- 	LWSNDVWIFI_STATE_AP,
 
- 		/* Trying to be the group AP... periodically do a scan
 
- 		 * LWSNDVWIFI_STATE_AP_SCAN, faster and then slower
 
-        		 */
 
- 	LWSNDVWIFI_STATE_AP_SCAN,
 
- 		/*
 
- 		 * doing a scan while trying to be the group AP... if we see a
 
- 		 * lower MAC being the AP for the same group AP, abandon being
 
- 		 * an AP and join that AP as a station
 
- 		 */
 
- 	LWSNDVWIFI_STATE_STAT_GRP_AP,
 
- 		/*
 
- 		 * We have decided to join another group member who is being the
 
- 		 * AP, as its MAC is lower than ours.  This is a stable state,
 
- 		 * but we still do periodic scans
 
- 		 * LWSNDVWIFI_STATE_STAT_GRP_AP_SCAN and will always prefer an
 
- 		 * AP configured in a slot.
 
- 		 */
 
- 	LWSNDVWIFI_STATE_STAT_GRP_AP_SCAN,
 
- 		/*
 
- 		 * We have joined a group member who is doing the AP job... we
 
- 		 * want to check every now and then if a configured AP has
 
- 		 * appeared that we should better use instead.  Otherwise stay
 
- 		 * in LWSNDVWIFI_STATE_STAT_GRP_AP
 
- 		 */
 
- 	LWSNDVWIFI_STATE_STAT,
 
- 		/*
 
- 		 * trying to connect to another non-group AP. If we don't get an
 
- 		 * IP within a timeout and retries, mark it as unusable it and go back
 
- 		 */
 
- 	LWSNDVWIFI_STATE_STAT_HAPPY,
 
- } lws_netdev_wifi_state_t;
 
- /*
 
-  * Generic WIFI credentials
 
-  */
 
- typedef struct lws_wifi_creds {
 
- 	lws_dll2_t			list;
 
- 	uint8_t				bssid[LWS_ETH_ALEN];
 
- 	char				passphrase[64];
 
- 	char				ssid[33];
 
- 	uint8_t				alg;
 
- } lws_wifi_creds_t;
 
- /*
 
-  * Generic WIFI Network Device Instance
 
-  */
 
- typedef struct lws_netdev_instance_wifi {
 
- 	lws_netdev_instance_t		inst;
 
- 	lws_dll2_owner_t		scan; /* sorted scan results */
 
- 	lws_sorted_usec_list_t		sul_scan;
 
- 	lws_wifi_creds_t		*ap_cred;
 
- 	const char			*ap_ip;
 
- 	const char			*sta_ads;
 
- 	char				current_attempt_ssid[33];
 
- 	uint8_t				current_attempt_bssid[LWS_ETH_ALEN];
 
- 	uint8_t				flags;
 
- 	uint8_t				state; /* lws_netdev_wifi_state_t */
 
- } lws_netdev_instance_wifi_t;
 
- /*
 
-  * Logical scan results sorted list item
 
-  */
 
- typedef struct lws_wifi_sta {
 
- 	lws_dll2_t			list;
 
- 	uint32_t			last_seen; /* unix time */
 
- 	uint32_t			last_tried; /* unix time */
 
- 	uint8_t				bssid[LWS_ETH_ALEN];
 
- 	char				*ssid; /* points to overallocation */
 
- 	uint8_t				ssid_len;
 
- 	lws_wifi_ch_t			ch;
 
- 	lws_wifi_rssi_t			rssi[8];
 
- 	int16_t				rssi_avg;
 
- 	uint8_t				authmode;
 
- 	uint8_t				rssi_count;
 
- 	uint8_t				rssi_next;
 
- 	/* ssid overallocated afterwards */
 
- } lws_wifi_sta_t;
 
- #define rssi_averaged(_x) (_x->rssi_count ? \
 
- 		((int)_x->rssi_avg / (int)_x->rssi_count) : \
 
- 			-200)
 
- LWS_VISIBLE LWS_EXTERN lws_netdevs_t *
 
- lws_netdevs_from_ctx(struct lws_context *ctx);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_credentials_settings_set(lws_netdevs_t *nds);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_credentials_settings_get(lws_netdevs_t *nds);
 
- LWS_VISIBLE LWS_EXTERN struct lws_netdev_instance *
 
- lws_netdev_wifi_create_plat(struct lws_context *ctx,
 
- 			    const lws_netdev_ops_t *ops, const char *name,
 
- 			    void *platinfo);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_wifi_configure_plat(struct lws_netdev_instance *nd,
 
- 			       lws_netdev_config_t *config);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_wifi_event_plat(struct lws_netdev_instance *nd, lws_usec_t timestamp,
 
- 			   void *buf, size_t len);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_wifi_up_plat(struct lws_netdev_instance *nd);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_wifi_down_plat(struct lws_netdev_instance *nd);
 
- LWS_VISIBLE LWS_EXTERN void
 
- lws_netdev_wifi_destroy_plat(struct lws_netdev_instance **pnd);
 
- LWS_VISIBLE LWS_EXTERN void
 
- lws_netdev_wifi_scan_plat(lws_netdev_instance_t *nd);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_wifi_connect_plat(lws_netdev_instance_t *wnd, const char *ssid,
 
- 			     const char *passphrase, uint8_t *bssid);
 
- LWS_VISIBLE LWS_EXTERN lws_netdev_instance_t *
 
- lws_netdev_find(lws_netdevs_t *netdevs, const char *ifname);
 
- #define lws_netdev_wifi_plat_ops \
 
- 	.create				= lws_netdev_wifi_create_plat, \
 
- 	.configure			= lws_netdev_wifi_configure_plat, \
 
- 	.event				= lws_netdev_wifi_event_plat, \
 
- 	.up				= lws_netdev_wifi_up_plat, \
 
- 	.down				= lws_netdev_wifi_down_plat, \
 
- 	.connect			= lws_netdev_wifi_connect_plat, \
 
- 	.scan				= lws_netdev_wifi_scan_plat, \
 
- 	.destroy			= lws_netdev_wifi_destroy_plat
 
- /*
 
-  * This is for plat / OS level init that is necessary to be able to use
 
-  * networking or wifi at all, without mentioning any specific device
 
-  */
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_plat_init(void);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lws_netdev_plat_wifi_init(void);
 
 
  |