Skip to content

Commit eec67c7

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 044b39b commit eec67c7

File tree

2 files changed

+236
-8
lines changed

2 files changed

+236
-8
lines changed

platform/qualcomm/platform_ext.c

Lines changed: 229 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
@@ -52,6 +67,13 @@
5267
#define STATICCPGCFG_1 "/tmp/.staticCpgCfg_1"
5368
#define STA_PWD_LEN STATICCPGCFG_LEN
5469

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

5779
typedef enum radio_band {
@@ -1201,6 +1223,11 @@ int platform_set_radio_pre_init(wifi_radio_index_t index, wifi_radio_operationPa
12011223

12021224
if(!radio->configured)
12031225
{
1226+
if (dfs_nl_listen_start()) {
1227+
wifi_hal_error_print("%s:%d DFS socket establishment failed\n", __func__, __LINE__);
1228+
} else {
1229+
wifi_hal_dbg_print("%s:%d DFS socket initialized\n", __func__, __LINE__);
1230+
}
12041231
wifi_hal_info_print("%s:%d: Radio is getting configured for the first time.\n", __func__, __LINE__);
12051232
return RETURN_OK;
12061233
}
@@ -1253,6 +1280,11 @@ int platform_set_radio_pre_init(wifi_radio_index_t index, wifi_radio_operationPa
12531280
return 0;
12541281
}
12551282
}
1283+
if (dfs_nl_listen_start()) {
1284+
wifi_hal_error_print("%s:%d DFS socket establishment failed\n", __func__, __LINE__);
1285+
} else {
1286+
wifi_hal_dbg_print("%s:%d DFS socket initialized\n", __func__, __LINE__);
1287+
}
12561288
wifi_hal_dbg_print("%s:%d Exit\n",__func__,__LINE__);
12571289
return 0;
12581290
}
@@ -1267,3 +1299,200 @@ INT wifi_sendActionFrame(INT apIndex, mac_address_t MacAddr, UINT frequency, UCH
12671299
{
12681300
return wifi_sendActionFrameExt(apIndex, MacAddr, frequency, 0, frame, len);
12691301
}
1302+
1303+
static int dfs_nl_listen_start(void)
1304+
{
1305+
struct sockaddr_nl addr;
1306+
int fd;
1307+
1308+
if (nl_fd != -1) {
1309+
wifi_hal_dbg_print("%s:%d: DFS socket registered already\n", __func__, __LINE__);
1310+
return 0;
1311+
}
1312+
1313+
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1314+
if (fd < 0) {
1315+
wifi_hal_error_print("%s:%d: failed to create socket: %d (%s)\n", __func__, __LINE__, errno,
1316+
strerror(errno));
1317+
return -1;
1318+
}
1319+
1320+
memset(&addr, 0, sizeof(addr));
1321+
addr.nl_family = AF_NETLINK;
1322+
addr.nl_groups = RTMGRP_LINK;
1323+
1324+
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1325+
wifi_hal_error_print("%s:%d: failed to bind: %d (%s)\n", __func__, __LINE__, errno,
1326+
strerror(errno));
1327+
close(fd);
1328+
return -1;
1329+
}
1330+
1331+
nl_fd = fd;
1332+
1333+
// Start listener thread
1334+
dfs_thread_running = 1;
1335+
if (pthread_create(&dfs_thread, NULL, dfs_event_thread, NULL) != 0) {
1336+
wifi_hal_error_print("%s:%d: Failed to start DFS thread (%s)\n", __func__, __LINE__,
1337+
strerror(errno));
1338+
close(nl_fd);
1339+
nl_fd = -1;
1340+
dfs_thread_running = 0;
1341+
return -1;
1342+
}
1343+
pthread_detach(dfs_thread);
1344+
1345+
wifi_hal_dbg_print("%s:%d: DFS listener initialized\n", __func__, __LINE__);
1346+
return 0;
1347+
}
1348+
1349+
static void *dfs_event_thread(void *arg)
1350+
{
1351+
struct pollfd pfd;
1352+
int len = 0;
1353+
int ret;
1354+
size_t buf_size = 3000;
1355+
1356+
pfd.fd = nl_fd;
1357+
pfd.events = POLLIN;
1358+
1359+
wifi_hal_dbg_print("%s:%d: DFS event thread started\n", __func__, __LINE__);
1360+
1361+
while (dfs_thread_running) {
1362+
ret = poll(&pfd, 1, 1000);
1363+
if (ret < 0) {
1364+
if (errno == EINTR)
1365+
continue;
1366+
wifi_hal_error_print("%s:%d: poll failed, err %d (%s)\n", __func__, __LINE__, errno,
1367+
strerror(errno));
1368+
break;
1369+
}
1370+
if (ret == 0) {
1371+
// no event this cycle just continue
1372+
continue;
1373+
}
1374+
if (pfd.revents & POLLIN) {
1375+
char *event_buf = (char *)malloc(buf_size * sizeof(char));
1376+
if (!event_buf) {
1377+
wifi_hal_error_print("%s:%d: Failed to allocate memory for dfs event\n", __func__,
1378+
__LINE__);
1379+
continue;
1380+
}
1381+
len = recvfrom(nl_fd, event_buf, buf_size, MSG_DONTWAIT, NULL, 0);
1382+
if (len > 0) {
1383+
parse_iwcustom_buffer(event_buf, len);
1384+
} else {
1385+
wifi_hal_error_print("%s:%d: recvfrom returned %d (%s)\n", __func__, __LINE__, len,
1386+
strerror(errno));
1387+
}
1388+
free(event_buf);
1389+
}
1390+
}
1391+
1392+
wifi_hal_dbg_print("%s:%d: DFS event thread exiting\n", __func__, __LINE__);
1393+
return NULL;
1394+
}
1395+
1396+
static void process_event_to_onewifi(const char *ifname,
1397+
wifi_channel_change_event_t radio_channel_param)
1398+
{
1399+
radio_interface_mapping_t radio_map_t[MAX_NUM_RADIOS];
1400+
wifi_device_callbacks_t *callbacks;
1401+
wifi_radio_info_t *radio = NULL;
1402+
int radio_index;
1403+
1404+
get_radio_interface_info_map(radio_map_t);
1405+
callbacks = get_hal_device_callbacks();
1406+
1407+
for (int i = 0; i < MAX_NUM_RADIOS; i++) {
1408+
if (strncmp(ifname, radio_map_t[i].interface_name, sizeof(radio_map_t[i].interface_name)) ==
1409+
0) {
1410+
radio_index = radio_map_t[i].radio_index;
1411+
radio = get_radio_by_rdk_index(radio_index);
1412+
radio_channel_param.radioIndex = radio_index;
1413+
radio_channel_param.channel = radio->oper_param.channel;
1414+
radio_channel_param.channelWidth = radio->oper_param.channelWidth;
1415+
radio_channel_param.op_class = radio->oper_param.operatingClass;
1416+
}
1417+
wifi_hal_dbg_print("%s:%d RadioIndex:%d channel:%d chwid:%d opclass:%d sub-event:%d\n",
1418+
__func__, __LINE__, radio_index, radio_channel_param.channel,
1419+
radio_channel_param.channelWidth, radio_channel_param.op_class,
1420+
radio_channel_param.sub_event);
1421+
}
1422+
radio_channel_param.event = WIFI_EVENT_DFS_RADAR_DETECTED;
1423+
1424+
if ((callbacks != NULL) && (callbacks->channel_change_event_callback) &&
1425+
!(radio_channel_param.sub_event == WIFI_EVENT_RADAR_NOP_FINISHED) &&
1426+
(radio->oper_param.channel)) {
1427+
callbacks->channel_change_event_callback(radio_channel_param);
1428+
}
1429+
}
1430+
1431+
static void parse_iwcustom_buffer(const void *buf, unsigned int len)
1432+
{
1433+
const struct nlmsghdr *hdr;
1434+
const struct rtattr *attr;
1435+
struct ifinfomsg *ifi;
1436+
const struct iw_event *iwe;
1437+
int iwelen;
1438+
int attrlen;
1439+
char ifname[32];
1440+
int ifindex;
1441+
wifi_channel_change_event_t radio_channel_param = { 0 };
1442+
1443+
memset(ifname, 0, sizeof(ifname));
1444+
1445+
for (hdr = buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
1446+
if (hdr->nlmsg_type != RTM_NEWLINK)
1447+
continue;
1448+
1449+
ifi = NLMSG_DATA(hdr);
1450+
attr = IFLA_RTA(ifi);
1451+
attrlen = IFLA_PAYLOAD(hdr);
1452+
1453+
for (attr = NLMSG_DATA(hdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)),
1454+
attrlen = NLMSG_PAYLOAD(hdr, sizeof(struct ifinfomsg));
1455+
RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) {
1456+
if (attr->rta_type != IFLA_WIRELESS)
1457+
continue;
1458+
1459+
ifindex = ifi->ifi_index;
1460+
if (!if_indextoname(ifindex, ifname)) {
1461+
strncpy(ifname, "unknown", sizeof(ifname));
1462+
}
1463+
for (iwe = RTA_DATA(attr), iwelen = RTA_PAYLOAD(attr);
1464+
((iwelen) >= (iwe)->len && (iwelen) > 0);
1465+
iwe = ((iwelen) -= (iwe)->len, (void *)(iwe) + (iwe)->len)) {
1466+
if (iwe->cmd == IWEVCUSTOM) {
1467+
const struct iw_point *iwp;
1468+
const void *data;
1469+
data = ((void *)(iwe) + IW_EV_LCP_LEN);
1470+
1471+
iwp = data - IW_EV_POINT_OFF;
1472+
data += IW_EV_POINT_LEN - IW_EV_POINT_OFF;
1473+
switch (iwp->flags) {
1474+
case IEEE80211_EV_CAC_STARTED:
1475+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_CAC_STARTED;
1476+
process_event_to_onewifi(ifname, radio_channel_param);
1477+
break;
1478+
case IEEE80211_EV_CAC_COMPLETED:
1479+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_CAC_FINISHED;
1480+
process_event_to_onewifi(ifname, radio_channel_param);
1481+
break;
1482+
case IEEE80211_EV_NOL_FINISHED:
1483+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_NOP_FINISHED;
1484+
process_event_to_onewifi(ifname, radio_channel_param);
1485+
break;
1486+
case IEEE80211_EV_RADAR_DETECTED:
1487+
radio_channel_param.sub_event = WIFI_EVENT_RADAR_DETECTED;
1488+
process_event_to_onewifi(ifname, radio_channel_param);
1489+
break;
1490+
default:
1491+
wifi_hal_info_print("Unknown event %s:%d\n", __func__, __LINE__);
1492+
break;
1493+
}
1494+
}
1495+
}
1496+
}
1497+
}
1498+
}

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)