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
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,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