Skip to content

Commit 36f2df9

Browse files
DTMESH-646 [DT][OneWifi] DFS event updates (#395)
Reason for change: Update DFS events from driver to OneWifi Test Procedure: Radio State table updated with respective DFS event based on the state changes done on channel Priority: P1 Risks: Medium Signed-off-by: Magesh Renganathan <[email protected]> Co-authored-by: Sathish Kumar Gnanasekaran <[email protected]>
1 parent 3aea19a commit 36f2df9

File tree

2 files changed

+231
-1
lines changed

2 files changed

+231
-1
lines changed

platform/qualcomm/platform_ext.c

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@
3535
#include "server_hal_ipc.h"
3636
#endif
3737

38+
#include <asm/byteorder.h>
39+
#include <linux/netlink.h>
40+
#include <linux/rtnetlink.h>
41+
#include <linux/socket.h>
42+
#include <linux/wireless.h>
43+
#include <pthread.h>
44+
#if defined(__LITTLE_ENDIAN)
45+
#define _BYTE_ORDER _LITTLE_ENDIAN
46+
#elif defined(__BIG_ENDIAN)
47+
#define _BYTE_ORDER _BIG_ENDIAN
48+
#else
49+
#error "Please fix asm/byteorder.h"
50+
#endif
51+
#include <ieee80211_external.h>
52+
3853
#define DEFAULT_CMD_SIZE 256
3954
#define MAX_BUF_SIZE 300
4055
#define MAX_NUM_RADIOS 2
@@ -53,6 +68,13 @@
5368
#define STA_PWD_LEN STATICCPGCFG_LEN
5469
#define QCA_MAX_CMD_SZ 128
5570

71+
static int nl_fd = -1;
72+
static int dfs_nl_listen_start(void);
73+
static void *dfs_event_thread(void *arg);
74+
static void parse_iwcustom_buffer(const void *buf, unsigned int len);
75+
static pthread_t dfs_thread;
76+
static int dfs_thread_running = 0;
77+
5678
extern INT wifi_setMLDaddr(INT apIndex, CHAR *mldMacAddress);
5779

5880
typedef enum radio_band {
@@ -1262,6 +1284,11 @@ int platform_set_radio_pre_init(wifi_radio_index_t index, wifi_radio_operationPa
12621284

12631285
if(!radio->configured)
12641286
{
1287+
if (dfs_nl_listen_start()) {
1288+
wifi_hal_error_print("%s:%d DFS socket establishment failed\n", __func__, __LINE__);
1289+
} else {
1290+
wifi_hal_dbg_print("%s:%d DFS socket initialized\n", __func__, __LINE__);
1291+
}
12651292
wifi_hal_info_print("%s:%d: Radio is getting configured for the first time.\n", __func__, __LINE__);
12661293
return RETURN_OK;
12671294
}
@@ -1315,6 +1342,12 @@ int platform_set_radio_pre_init(wifi_radio_index_t index, wifi_radio_operationPa
13151342
}
13161343
}
13171344
#endif
1345+
if (dfs_nl_listen_start()) {
1346+
wifi_hal_error_print("%s:%d DFS socket establishment failed\n", __func__, __LINE__);
1347+
} else {
1348+
wifi_hal_dbg_print("%s:%d DFS socket initialized\n", __func__, __LINE__);
1349+
}
1350+
13181351
wifi_hal_dbg_print("%s:%d Exit\n",__func__,__LINE__);
13191352
return 0;
13201353
}
@@ -1329,3 +1362,200 @@ INT wifi_sendActionFrame(INT apIndex, mac_address_t MacAddr, UINT frequency, UCH
13291362
{
13301363
return wifi_sendActionFrameExt(apIndex, MacAddr, frequency, 0, frame, len);
13311364
}
1365+
1366+
static int dfs_nl_listen_start(void)
1367+
{
1368+
struct sockaddr_nl addr;
1369+
int fd;
1370+
1371+
if (nl_fd != -1) {
1372+
wifi_hal_dbg_print("%s:%d: DFS socket registered already\n", __func__, __LINE__);
1373+
return 0;
1374+
}
1375+
1376+
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1377+
if (fd < 0) {
1378+
wifi_hal_error_print("%s:%d: failed to create socket: %d (%s)\n", __func__, __LINE__, errno,
1379+
strerror(errno));
1380+
return -1;
1381+
}
1382+
1383+
memset(&addr, 0, sizeof(addr));
1384+
addr.nl_family = AF_NETLINK;
1385+
addr.nl_groups = RTMGRP_LINK;
1386+
1387+
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1388+
wifi_hal_error_print("%s:%d: failed to bind: %d (%s)\n", __func__, __LINE__, errno,
1389+
strerror(errno));
1390+
close(fd);
1391+
return -1;
1392+
}
1393+
1394+
nl_fd = fd;
1395+
1396+
// Start listener thread
1397+
dfs_thread_running = 1;
1398+
if (pthread_create(&dfs_thread, NULL, dfs_event_thread, NULL) != 0) {
1399+
wifi_hal_error_print("%s:%d: Failed to start DFS thread (%s)\n", __func__, __LINE__,
1400+
strerror(errno));
1401+
close(nl_fd);
1402+
nl_fd = -1;
1403+
dfs_thread_running = 0;
1404+
return -1;
1405+
}
1406+
pthread_detach(dfs_thread);
1407+
1408+
wifi_hal_dbg_print("%s:%d: DFS listener initialized\n", __func__, __LINE__);
1409+
return 0;
1410+
}
1411+
1412+
static void *dfs_event_thread(void *arg)
1413+
{
1414+
struct pollfd pfd;
1415+
int len = 0;
1416+
int ret;
1417+
size_t buf_size = 3000;
1418+
1419+
pfd.fd = nl_fd;
1420+
pfd.events = POLLIN;
1421+
1422+
wifi_hal_dbg_print("%s:%d: DFS event thread started\n", __func__, __LINE__);
1423+
1424+
while (dfs_thread_running) {
1425+
ret = poll(&pfd, 1, 1000);
1426+
if (ret < 0) {
1427+
if (errno == EINTR)
1428+
continue;
1429+
wifi_hal_error_print("%s:%d: poll failed, err %d (%s)\n", __func__, __LINE__, errno,
1430+
strerror(errno));
1431+
break;
1432+
}
1433+
if (ret == 0) {
1434+
// no event this cycle just continue
1435+
continue;
1436+
}
1437+
if (pfd.revents & POLLIN) {
1438+
char *event_buf = (char *)malloc(buf_size * sizeof(char));
1439+
if (!event_buf) {
1440+
wifi_hal_error_print("%s:%d: Failed to allocate memory for dfs event\n", __func__,
1441+
__LINE__);
1442+
continue;
1443+
}
1444+
len = recvfrom(nl_fd, event_buf, buf_size, MSG_DONTWAIT, NULL, 0);
1445+
if (len > 0) {
1446+
parse_iwcustom_buffer(event_buf, len);
1447+
} else {
1448+
wifi_hal_error_print("%s:%d: recvfrom returned %d (%s)\n", __func__, __LINE__, len,
1449+
strerror(errno));
1450+
}
1451+
free(event_buf);
1452+
}
1453+
}
1454+
1455+
wifi_hal_dbg_print("%s:%d: DFS event thread exiting\n", __func__, __LINE__);
1456+
return NULL;
1457+
}
1458+
1459+
static void process_event_to_onewifi(const char *ifname,
1460+
wifi_channel_change_event_t radio_channel_param)
1461+
{
1462+
radio_interface_mapping_t radio_map_t[MAX_NUM_RADIOS];
1463+
wifi_device_callbacks_t *callbacks;
1464+
wifi_radio_info_t *radio = NULL;
1465+
int radio_index;
1466+
1467+
get_radio_interface_info_map(radio_map_t);
1468+
callbacks = get_hal_device_callbacks();
1469+
1470+
for (int i = 0; i < MAX_NUM_RADIOS; i++) {
1471+
if (strncmp(ifname, radio_map_t[i].interface_name, sizeof(radio_map_t[i].interface_name)) ==
1472+
0) {
1473+
radio_index = radio_map_t[i].radio_index;
1474+
radio = get_radio_by_rdk_index(radio_index);
1475+
radio_channel_param.radioIndex = radio_index;
1476+
radio_channel_param.channel = radio->oper_param.channel;
1477+
radio_channel_param.channelWidth = radio->oper_param.channelWidth;
1478+
radio_channel_param.op_class = radio->oper_param.operatingClass;
1479+
}
1480+
wifi_hal_dbg_print("%s:%d RadioIndex:%d channel:%d chwid:%d opclass:%d sub-event:%d\n",
1481+
__func__, __LINE__, radio_index, radio_channel_param.channel,
1482+
radio_channel_param.channelWidth, radio_channel_param.op_class,
1483+
radio_channel_param.sub_event);
1484+
}
1485+
radio_channel_param.event = WIFI_EVENT_DFS_RADAR_DETECTED;
1486+
1487+
if ((callbacks != NULL) && (callbacks->channel_change_event_callback) &&
1488+
!(radio_channel_param.sub_event == WIFI_EVENT_RADAR_NOP_FINISHED) &&
1489+
(radio->oper_param.channel)) {
1490+
callbacks->channel_change_event_callback(radio_channel_param);
1491+
}
1492+
}
1493+
1494+
static void parse_iwcustom_buffer(const void *buf, unsigned int len)
1495+
{
1496+
const struct nlmsghdr *hdr;
1497+
const struct rtattr *attr;
1498+
struct ifinfomsg *ifi;
1499+
const struct iw_event *iwe;
1500+
int iwelen;
1501+
int attrlen;
1502+
char ifname[32];
1503+
int ifindex;
1504+
wifi_channel_change_event_t radio_channel_param = { 0 };
1505+
1506+
memset(ifname, 0, sizeof(ifname));
1507+
1508+
for (hdr = buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
1509+
if (hdr->nlmsg_type != RTM_NEWLINK)
1510+
continue;
1511+
1512+
ifi = NLMSG_DATA(hdr);
1513+
attr = IFLA_RTA(ifi);
1514+
attrlen = IFLA_PAYLOAD(hdr);
1515+
1516+
for (attr = NLMSG_DATA(hdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)),
1517+
attrlen = NLMSG_PAYLOAD(hdr, sizeof(struct ifinfomsg));
1518+
RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) {
1519+
if (attr->rta_type != IFLA_WIRELESS)
1520+
continue;
1521+
1522+
ifindex = ifi->ifi_index;
1523+
if (!if_indextoname(ifindex, ifname)) {
1524+
strncpy(ifname, "unknown", sizeof(ifname));
1525+
}
1526+
for (iwe = RTA_DATA(attr), iwelen = RTA_PAYLOAD(attr);
1527+
((iwelen) >= (iwe)->len && (iwelen) > 0);
1528+
iwe = ((iwelen) -= (iwe)->len, (void *)(iwe) + (iwe)->len)) {
1529+
if (iwe->cmd == IWEVCUSTOM) {
1530+
const struct iw_point *iwp;
1531+
const void *data;
1532+
data = ((void *)(iwe) + IW_EV_LCP_LEN);
1533+
1534+
iwp = data - IW_EV_POINT_OFF;
1535+
data += IW_EV_POINT_LEN - IW_EV_POINT_OFF;
1536+
switch (iwp->flags) {
1537+
case IEEE80211_EV_CAC_STARTED:
1538+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_CAC_STARTED;
1539+
process_event_to_onewifi(ifname, radio_channel_param);
1540+
break;
1541+
case IEEE80211_EV_CAC_COMPLETED:
1542+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_CAC_FINISHED;
1543+
process_event_to_onewifi(ifname, radio_channel_param);
1544+
break;
1545+
case IEEE80211_EV_NOL_FINISHED:
1546+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_NOP_FINISHED;
1547+
process_event_to_onewifi(ifname, radio_channel_param);
1548+
break;
1549+
case IEEE80211_EV_RADAR_DETECTED:
1550+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_DETECTED;
1551+
process_event_to_onewifi(ifname, radio_channel_param);
1552+
break;
1553+
default:
1554+
wifi_hal_info_print("Unknown event %s:%d\n", __func__, __LINE__);
1555+
break;
1556+
}
1557+
}
1558+
}
1559+
}
1560+
}
1561+
}

src/wifi_hal_nl80211_utils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ static const char *const eu_op_class_cc[] = {
12051205
"AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
12061206
"DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
12071207
"LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
1208-
"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "GB", NULL
1208+
"RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "GB", "GR", NULL
12091209
};
12101210

12111211
static const char *const jp_op_class_cc[] = {

0 commit comments

Comments
 (0)