mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-29 17:42:41 +00:00 
			
		
		
		
	 8b5e2058f3
			
		
	
	8b5e2058f3
	
	
	
		
			
			- Add support for multi-bss channel switch inside ubus switch_chan method - Fix hostapd crash occuring while sending channel switch event to cloud. - Fix memory leak. Signed-off-by: Yashvardhan <yashvardhan@netexperience.com>
		
			
				
	
	
		
			179 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/src/ap/dfs.c
 | |
| +++ b/src/ap/dfs.c
 | |
| @@ -18,7 +18,7 @@
 | |
|  #include "drivers/driver.h"
 | |
|  #include "dfs.h"
 | |
|  #include "crypto/crypto.h"
 | |
| -
 | |
| +#include "ubus.h"
 | |
|  
 | |
|  static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
 | |
|  {
 | |
| @@ -1151,6 +1151,11 @@ static int hostapd_dfs_start_channel_swi
 | |
|  			break;
 | |
|  	}
 | |
|  
 | |
| +	if (!err) {
 | |
| +		wpa_printf(MSG_DEBUG, "Reporting DFS event to ubus");
 | |
| +		hostapd_ubus_handle_channel_switch_event(iface, HOSTAPD_UBUS_DFS_SWITCH,  channel->freq);
 | |
| +	}
 | |
| +
 | |
|  	if (err) {
 | |
|  		wpa_printf(MSG_WARNING, "DFS failed to schedule CSA (%d) - trying fallback",
 | |
|  			   err);
 | |
| --- a/src/ap/ubus.c
 | |
| +++ b/src/ap/ubus.c
 | |
| @@ -29,6 +29,8 @@ static int ctx_ref;
 | |
|  static char** bss_lst = NULL;
 | |
|  static size_t bss_nr = 0;
 | |
|  
 | |
| +static LIST_HEAD(chan_events);
 | |
| +
 | |
|  static inline struct hapd_interfaces *get_hapd_interfaces_from_object(struct ubus_object *obj)
 | |
|  {
 | |
|  	return container_of(obj, struct hapd_interfaces, ubus);
 | |
| @@ -714,6 +716,44 @@ static int hostapd_sessions(struct ubus_
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| +static int hostapd_get_chan_switch_events(struct ubus_context *ctx,
 | |
| +			struct ubus_object *obj,
 | |
| +		        struct ubus_request_data *req,
 | |
| +			const char *method,
 | |
| +                        struct blob_attr *msg)
 | |
| +{
 | |
| +	void *a = NULL;
 | |
| +	void *t = NULL;
 | |
| +	struct hostapd_chan_event_list *entry, *tmp;
 | |
| +
 | |
| +	blob_buf_init(&b_ev, 0);
 | |
| +	a = blobmsg_open_table(&b_ev, "chan_switch_event");
 | |
| +	list_for_each_entry(entry, &chan_events, list)
 | |
| +	{
 | |
| +		t = blobmsg_open_table(&b_ev, "event");
 | |
| +		blobmsg_add_u32(&b_ev, "radio_name", entry->records.band);
 | |
| +		blobmsg_add_u32(&b_ev, "reason", entry->records.reason);
 | |
| +		blobmsg_add_u64(&b_ev, "timestamp", entry->records.ts);
 | |
| +		blobmsg_add_u32(&b_ev, "frequency", entry->records.freq);
 | |
| +		blobmsg_close_table(&b_ev, t);
 | |
| +	}
 | |
| +
 | |
| +	blobmsg_close_table(&b_ev, a);
 | |
| +	ubus_send_reply(ctx, req, b_ev.head);
 | |
| +
 | |
| +	/*delete list*/
 | |
| +
 | |
| +	if (!list_empty(&chan_events)) {
 | |
| +	list_for_each_entry_safe(entry, tmp, &chan_events, list)
 | |
| +		{
 | |
| +			list_del(&entry->list);
 | |
| +			free(entry);
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
|  static int
 | |
|  hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
 | |
|  		    struct ubus_request_data *req, const char *method,
 | |
| @@ -749,6 +789,9 @@ hostapd_switch_chan(struct ubus_context
 | |
|  
 | |
|  	if (hostapd_switch_channel(hapd, &css) != 0)
 | |
|  		return UBUS_STATUS_NOT_SUPPORTED;
 | |
| +
 | |
| +	hostapd_ubus_handle_channel_switch_event(hapd->iface,HOSTAPD_UBUS_HIGH_INTERFERENCE,  css.freq_params.freq);
 | |
| +
 | |
|  	return UBUS_STATUS_OK;
 | |
|  #undef SET_CSA_SETTING
 | |
|  }
 | |
| @@ -1444,6 +1487,7 @@ static const struct ubus_method daemon_m
 | |
|  	UBUS_METHOD("config_add", hostapd_config_add, config_add_policy),
 | |
|  	UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy),
 | |
|  	UBUS_METHOD_NOARG("get_bss_list", hostapd_get_bss_list),
 | |
| +	UBUS_METHOD_NOARG("get_chan_switch_events", hostapd_get_chan_switch_events)
 | |
|  };
 | |
|  
 | |
|  static struct ubus_object_type daemon_object_type =
 | |
| @@ -1507,6 +1551,28 @@ ubus_event_cb(struct ubus_notify_request
 | |
|  	ureq->resp = ret;
 | |
|  }
 | |
|  
 | |
| +
 | |
| +void hostapd_ubus_handle_channel_switch_event(struct hostapd_iface *iface, int reason,
 | |
| +			       int freq)
 | |
| +{
 | |
| +	struct hostapd_chan_event_list *rec = NULL;
 | |
| +	struct timespec ts;
 | |
| +	uint64_t timestamp = 0;
 | |
| +
 | |
| +	clock_gettime(CLOCK_REALTIME, &ts);
 | |
| +	timestamp = get_time_in_ms(&ts);
 | |
| +
 | |
| +	rec = os_zalloc(sizeof(struct hostapd_chan_event_list));
 | |
| +
 | |
| +	rec->records.reason = reason;
 | |
| +	rec->records.band = iface->freq;
 | |
| +	rec->records.ts = timestamp;
 | |
| +	rec->records.freq = freq;
 | |
| +
 | |
| +	list_add_tail(&rec->list, &chan_events);
 | |
| +
 | |
| +}
 | |
| +
 | |
|  int hostapd_ubus_handle_rt_event(struct hostapd_data *hapd,
 | |
|  				 struct hostapd_ubus_request *req)
 | |
|  {
 | |
| --- a/src/ap/ubus.h
 | |
| +++ b/src/ap/ubus.h
 | |
| @@ -17,9 +17,15 @@ enum hostapd_ubus_event_type {
 | |
|  	HOSTAPD_UBUS_DEAUTH_REQ,
 | |
|  	HOSTAPD_UBUS_FDATA_REQ,
 | |
|  	HOSTAPD_UBUS_IP_REQ,
 | |
| +	HOSTAPD_UBUS_CHAN_SWITCH,
 | |
|  	HOSTAPD_UBUS_TYPE_MAX
 | |
|  };
 | |
|  
 | |
| +enum hostapd_ubus_chan_event_reason {
 | |
| +	HOSTAPD_UBUS_DFS_SWITCH,
 | |
| +	HOSTAPD_UBUS_HIGH_INTERFERENCE
 | |
| +};
 | |
| +
 | |
|  struct hostapd_ubus_request {
 | |
|  	enum hostapd_ubus_event_type type;
 | |
|  	const struct ieee80211_mgmt *mgmt_frame;
 | |
| @@ -40,6 +46,7 @@ struct rrm_measurement_beacon_report;
 | |
|  
 | |
|  #include <libubox/avl.h>
 | |
|  #include <libubus.h>
 | |
| +#include <libubox/list.h>
 | |
|  
 | |
|  struct hostapd_ubus_bss {
 | |
|  	struct ubus_object obj;
 | |
| @@ -121,11 +128,24 @@ struct hostapd_event_avl_rec {
 | |
|  	struct avl_node avl;
 | |
|  };
 | |
|  
 | |
| +struct channel_switch_event {
 | |
| +	int band; /* Radio name*/
 | |
| +	uint8_t reason;
 | |
| +	uint64_t ts;
 | |
| +	uint32_t freq;
 | |
| +};
 | |
| +
 | |
| +struct hostapd_chan_event_list {
 | |
| +	struct channel_switch_event records;
 | |
| +	struct list_head list;
 | |
| +};
 | |
| +
 | |
|  void hostapd_ubus_add_iface(struct hostapd_iface *iface);
 | |
|  void hostapd_ubus_free_iface(struct hostapd_iface *iface);
 | |
|  void hostapd_ubus_add_bss(struct hostapd_data *hapd);
 | |
|  void hostapd_ubus_free_bss(struct hostapd_data *hapd);
 | |
| -
 | |
| +void hostapd_ubus_handle_channel_switch_event(struct hostapd_iface *iface, int reason,
 | |
| +			       int channel);
 | |
|  int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req);
 | |
|  int hostapd_ubus_handle_rt_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req);
 | |
|  void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac);
 |