Skip to content

Commit a06391c

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 7cbf2c7 commit a06391c

File tree

1 file changed

+226
-0
lines changed

1 file changed

+226
-0
lines changed

platform/qualcomm/platform_ext.c

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

0 commit comments

Comments
 (0)