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
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+
5577extern INT wifi_setMLDaddr (INT apIndex , CHAR * mldMacAddress );
5678
5779typedef 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+ }
0 commit comments