Skip to content

Commit 0929e3c

Browse files
DTMESH-646 [DT][OneWifi] DFS event updates
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]>
1 parent 6db0429 commit 0929e3c

File tree

2 files changed

+237
-8
lines changed

2 files changed

+237
-8
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: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,14 +1266,13 @@ wifi_country_radio_op_class_t cn_op_class = {
12661266
/* We need to update correct country global oprating class information */
12671267
wifi_country_radio_op_class_t other_op_class = {
12681268
wifi_countrycode_IN,
1269-
{
1270-
{ 81, 0, 13, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0} },
1271-
{ 82, 0, 1, {14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
1272-
{ 115, 0, 4, {36, 40, 44, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
1273-
{ 121, 0, 12, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 0, 0, 0, 0} },
1274-
{ 124, 0, 4, {149, 153, 157, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
1275-
{ 125, 0, 6, {149, 153, 157, 161, 165, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }
1276-
}
1269+
{ { 81, 0, 13, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0 } },
1270+
{ 82, 0, 1, { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
1271+
{ 115, 0, 4, { 36, 40, 44, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
1272+
{ 118, 0, 4, { 52, 56, 60, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
1273+
{ 121, 0, 12, { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 0, 0, 0, 0 } },
1274+
{ 124, 0, 4, { 149, 153, 157, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
1275+
{ 125, 0, 6, { 149, 153, 157, 161, 165, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }
12771276
};
12781277

12791278
unsigned int get_sizeof_interfaces_index_map(void) {

0 commit comments

Comments
 (0)