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