• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: APF hmac function.
15  * Create: 2022-10-14
16  */
17 
18 /*****************************************************************************
19   1 头文件包含
20 *****************************************************************************/
21 #include "hmac_apf.h"
22 #include "msg_apf_rom.h"
23 #include "frw_util_notifier.h"
24 #include "hmac_feature_interface.h"
25 #ifdef _PRE_PLAT_FEATURE_CUSTOMIZE
26 #include "soc_customize_wifi.h"
27 #endif
28 
29 #ifdef __cplusplus
30 #if __cplusplus
31 extern "C" {
32 #endif
33 #endif
34 
35 #undef  THIS_FILE_ID
36 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_APF_C
37 
38 #undef THIS_MOD_ID
39 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
40 
41 /*****************************************************************************
42   2 全局变量定义
43 *****************************************************************************/
44 /* APF规则信息全局结构体 */
45 mac_apf_stru g_hmac_st_apf = {0};
46 osal_u8      g_hmac_st_apf_ip[0x4] = {0};
47 
48 /*****************************************************************************
49   3 函数实现
50 *****************************************************************************/
51 
52 /*****************************************************************************
53  功能描述  : 更新APF过滤规则中自己的IP地址
54 *****************************************************************************/
hmac_apf_update_st_apf(osal_void)55 OSAL_STATIC osal_void hmac_apf_update_st_apf(osal_void)
56 {
57     frw_msg msg2device = {0};
58     osal_s32 ret;
59     osal_u32 j;
60     osal_u32 i;
61 
62     if (g_hmac_st_apf.program_len < APF_PROGRAM_IPV4_BROADCAST_END) {
63         return;
64     }
65     /* 从第76 - 79字符是IPV4地址 */
66     for (j = APF_PROGRAM_IPV4_BEGIN, i = 0; j <= APF_PROGRAM_IPV4_END; j++, i++) {
67         g_hmac_st_apf.program[j] = ((osal_u8 *)(g_hmac_st_apf_ip))[i];
68     }
69 
70     /* 替换网段广播地址,从第143 - 145字符是IPV4段广播地址 */
71     for (j = APF_PROGRAM_IPV4_BROADCAST_BEGIN, i = 0; j <= APF_PROGRAM_IPV4_BROADCAST_END; j++, i++) {
72         g_hmac_st_apf.program[j] = ((osal_u8 *)(g_hmac_st_apf_ip))[i];
73     }
74 
75     if (g_hmac_st_apf.is_enabled == OAL_TRUE) {
76         // 下发事件更新apf规则
77         frw_msg_init((osal_u8 *)&g_hmac_st_apf, sizeof(mac_apf_stru), OSAL_NULL, 0, &msg2device);
78         ret = send_cfg_to_device(0, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
79         if (ret != OAL_SUCC) {
80             oam_error_log1(0, OAM_SF_APF, "{hmac_apf_update_st_apf:: send apf on to device fail [%d]!}", ret);
81         }
82     }
83 }
84 
hmac_apf_set_ip_addr_etc(osal_void * notify_data)85 OSAL_STATIC osal_bool hmac_apf_set_ip_addr_etc(osal_void *notify_data)
86 {
87     if (notify_data == OAL_PTR_NULL) {
88         oam_error_log0(0, OAM_SF_PWR, "{hmac_apf_set_ip_addr_etc::The ip_addr is NULL. }");
89         return OSAL_FALSE;
90     }
91     (osal_void)memcpy_s(g_hmac_st_apf_ip, sizeof(g_hmac_st_apf_ip), notify_data, sizeof(g_hmac_st_apf_ip));
92     hmac_apf_update_st_apf();
93     return OSAL_TRUE;
94 }
95 
96 /*****************************************************************************
97  功能描述  : APF功能开关
98 *****************************************************************************/
hmac_apf_filter_switch(osal_void * notify_data)99 OSAL_STATIC osal_bool hmac_apf_filter_switch(osal_void *notify_data)
100 {
101     frw_msg                     msg2device = {0};
102     oal_bool_enum_uint8         device_apf_msg;
103     osal_s32                    ret;
104     oal_bool_enum_uint8 apf_switch = *(oal_bool_enum_uint8 *)notify_data;
105     osal_u32 pps_rate = 0;
106     osal_void *fhook = hmac_get_feature_fhook(HMAC_FHOOK_AUTO_FREQ_PPS);
107 
108     if (apf_switch >= OAL_BUTT) {
109         return OSAL_FALSE;
110     }
111 
112     if (fhook != OSAL_NULL) {
113         ((hmac_get_pps_handle_pps_rate_cb)fhook)(&pps_rate);
114     }
115 
116     /* 如果apf已处状态和设置状态一致 则直接返回 */
117     if (g_hmac_st_apf.is_enabled == apf_switch) {
118         return OSAL_TRUE;
119     }
120 
121     /* 开关状态置为关 */
122     if (apf_switch == OAL_FALSE) {
123         oam_warning_log0(0, OAM_SF_APF, "hmac_apf_filter_switch::disable");
124         device_apf_msg = OAL_FALSE;
125         g_hmac_st_apf.is_enabled = OAL_FALSE;
126 
127         // 下发事件将device的apf功能给关了
128         frw_msg_init((osal_u8 *)&device_apf_msg, sizeof(oal_bool_enum_uint8), OSAL_NULL, 0, &msg2device);
129         /* snyc ps config to device */
130         ret = send_cfg_to_device(0, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
131         if (ret != OAL_SUCC) {
132             oam_error_log1(0, OAM_SF_APF, "{hmac_apf_filter_switch:: send apf off to device fail [%d]!}", ret);
133             return OSAL_FALSE;
134         }
135         return OSAL_TRUE;
136     }
137 
138     if ((g_hmac_st_apf.program_len != 0) && (pps_rate <= PPS_VALUE_1)) {
139         g_hmac_st_apf.is_enabled = OAL_TRUE;
140 
141         oam_warning_log3(0, OAM_SF_APF, "hmac_apf_filter_switch:enable[%hhu] program len[%hu], over[%u]",
142             g_hmac_st_apf.is_enabled, g_hmac_st_apf.program_len, PPS_VALUE_1);
143 
144         // 下发事件开apf功能
145         frw_msg_init((osal_u8 *)&g_hmac_st_apf, sizeof(mac_apf_stru), OSAL_NULL, 0, &msg2device);
146         ret = send_cfg_to_device(0, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
147         if (ret != OAL_SUCC) {
148             oam_error_log1(0, OAM_SF_APF, "{hmac_apf_filter_switch:: send apf on to device fail [%d]!}", ret);
149             return OSAL_FALSE;
150         }
151     } else {
152         oam_warning_log0(0, OAM_SF_APF, "hmac_apf_filter_switch::can't enable apf.");
153     }
154     return OSAL_TRUE;
155 }
156 
157 /*****************************************************************************
158  功能描述  : 强制停止APF
159 *****************************************************************************/
hmac_config_force_stop_filter(hmac_vap_stru * hmac_vap,frw_msg * msg)160 OSAL_STATIC osal_s32 hmac_config_force_stop_filter(hmac_vap_stru *hmac_vap, frw_msg *msg)
161 {
162     oal_bool_enum_uint8 uc_switch = OAL_FALSE;
163     hmac_device_stru *hmac_device;
164     osal_u8 force_stop_filter;
165 
166     if (hmac_vap == OAL_PTR_NULL || msg == OAL_PTR_NULL) {
167         oam_warning_log0(0, OAM_SF_APF, "hmac_config_force_stop_filter:: NULL ptr error.");
168         return OAL_ERR_CODE_PTR_NULL;
169     }
170 
171     if (hwifi_get_apf_enable() == OSAL_FALSE) {
172         oam_warning_log0(0, OAM_SF_APF, "{hmac_config_force_stop_filter: apf isn't supported.}");
173         return OAL_SUCC;
174     }
175 
176     hmac_device = hmac_res_get_mac_dev_etc(hmac_vap->device_id);
177     if (hmac_device == OAL_PTR_NULL) {
178         oam_warning_log0(0, OAM_SF_APF, "hmac_config_force_stop_filter::hmac_device NULL error");
179         return OAL_ERR_CODE_PTR_NULL;
180     }
181 
182     force_stop_filter = (*((osal_s32 *)msg->data) == OSAL_SWITCH_ON);
183     /* 在暗屏情况下, force_stop_filter不使能时,开启apf过滤; 使能时,强制关闭apf */
184     if ((hmac_device->in_suspend == OSAL_TRUE) && (force_stop_filter == OAL_FALSE)) {
185         // 打开apf
186         uc_switch = OAL_TRUE;
187     }
188     hmac_apf_filter_switch(&uc_switch);
189     return OAL_SUCC;
190 }
191 
192 /*****************************************************************************
193  功能描述  : 配置APF过滤条件
194 *****************************************************************************/
hmac_apf_filter_install(const mac_apf_filter_cmd_stru * apf_filter_cmd)195 OSAL_STATIC osal_void hmac_apf_filter_install(const mac_apf_filter_cmd_stru *apf_filter_cmd)
196 {
197     osal_u8 *program = apf_filter_cmd->program;
198     osal_u16 program_len = apf_filter_cmd->program_len;
199 
200     if (program_len > APF_PROGRAM_MAX_LEN) {
201         oam_error_log2(0, OAM_SF_APF, "{hmac_apf_filter_install::program_len [%hu] > APF_PROGRAM_MAX_LEN[%d]!.}",
202             program_len, APF_PROGRAM_MAX_LEN);
203         return;
204     }
205 
206     if (memcpy_s(g_hmac_st_apf.program, APF_PROGRAM_MAX_LEN, program, program_len) != EOK) {
207         oam_error_log0(0, OAM_SF_APF, "hmac_apf_filter_install::memcpy fail.");
208         return;
209     }
210     g_hmac_st_apf.program_len = program_len;
211     hmac_apf_update_st_apf();
212     g_hmac_st_apf.install_timestamp = (osal_u32)(osal_get_time_stamp_ms() >> BIT_OFFSET_10); /* 秒级时间戳 */
213 
214     oam_warning_log1(0, OAM_SF_APF, "{hmac_apf_filter_install::set_apf_filter succ, program_len[%hu].}",
215         g_hmac_st_apf.program_len);
216     return;
217 }
218 
219 /*****************************************************************************
220  功能描述  : 删除APF过滤条件
221 *****************************************************************************/
hmac_apf_filter_del_user(osal_void * notify_data)222 OSAL_STATIC osal_bool hmac_apf_filter_del_user(osal_void *notify_data)
223 {
224     frw_msg                     msg2device = {0};
225     oal_bool_enum_uint8         device_apf_msg;
226     osal_s32                    ret;
227     hmac_vap_stru *hmac_vap = OSAL_NULL;
228     hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
229 
230     hmac_vap = mac_res_get_hmac_vap(hmac_user->vap_id);
231     if (hmac_vap == OSAL_NULL) {
232         oam_warning_log1(0, 0, "{hmac_apf_filter_del_user:vap[%d] is null.}", hmac_user->vap_id);
233         return OSAL_FALSE;
234     }
235 
236     if (!is_legacy_sta(hmac_vap)) {
237         return OSAL_TRUE;
238     }
239 
240     /* 如果apf正打开,则发事件关闭 */
241     if (g_hmac_st_apf.is_enabled == OSAL_TRUE) {
242         device_apf_msg = OSAL_FALSE;
243         frw_msg_init((osal_u8 *)&device_apf_msg, sizeof(oal_bool_enum_uint8), OSAL_NULL, 0, &msg2device);
244         /* snyc ps config to device */
245         ret = send_cfg_to_device(hmac_vap->vap_id, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
246         if (ret != OAL_SUCC) {
247             oam_error_log1(0, OAM_SF_APF, "{hmac_apf_filter_uninstall:: send apf off to device fail [%d]!}", ret);
248         }
249     }
250     oam_warning_log1(0, OAM_SF_APF, "dmac_apf_filter_uninstall::program_len[%hu].", g_hmac_st_apf.program_len);
251     g_hmac_st_apf.is_enabled = OAL_FALSE;
252     g_hmac_st_apf.program_len = 0;
253     return OSAL_TRUE;
254 }
255 
256 /*****************************************************************************
257  功能描述:
258  1.当apf_filter_cmd->cmd_type == APF_SET_FILTER_CMD时,
259    下发APF过滤规则到dmac
260  2.当apf_filter_cmd->cmd_type != APF_SET_FILTER_CMD时,
261    上报HMAC侧当前APF过滤规则
262 *****************************************************************************/
hmac_config_apf_filter_cmd(hmac_vap_stru * hmac_vap,frw_msg * msg)263 OSAL_STATIC osal_s32 hmac_config_apf_filter_cmd(hmac_vap_stru *hmac_vap, frw_msg *msg)
264 {
265     mac_apf_filter_cmd_stru *apf_filter_cmd = OSAL_NULL;
266     frw_msg msg2device;
267     osal_s32 ret;
268     osal_u32 i;
269 
270     if (hmac_vap == OSAL_NULL || msg == OSAL_NULL || msg->data == OSAL_NULL) {
271         oam_error_log0(0, OAM_SF_APF, "{hmac_config_apf_filter_cmd::mac_vap or param or msg->data is null.}");
272         return OAL_ERR_CODE_PTR_NULL;
273     }
274 
275     apf_filter_cmd = (mac_apf_filter_cmd_stru *)msg->data;
276     if (apf_filter_cmd->cmd_type == APF_SET_FILTER_CMD) {
277         hmac_apf_filter_install(apf_filter_cmd);
278         /* 规则发生变动需要看目前是否开启apf,如果开启则需要重新下发规则给device */
279         if (g_hmac_st_apf.is_enabled == OAL_TRUE) {
280             frw_msg_init((osal_u8 *)&g_hmac_st_apf, sizeof(mac_apf_stru), OSAL_NULL, 0, &msg2device);
281             ret = send_cfg_to_device(hmac_vap->vap_id, WLAN_MSG_H2D_C_CFG_APF_EXEC, &msg2device, OSAL_TRUE);
282             if (ret != OAL_SUCC) {
283                 oam_error_log1(0, OAM_SF_APF, "{hmac_config_apf_filter_cmd:: send apf on to device fail [%d]!}", ret);
284                 return ret;
285             }
286         }
287     } else if (apf_filter_cmd->cmd_type == APF_GET_FILTER_CMD) {
288         for (i = 0; i < g_hmac_st_apf.program_len; ++i) {
289             wifi_printf("%02x", g_hmac_st_apf.program[i]);
290         }
291     }
292 
293     return OAL_SUCC;
294 }
295 
hmac_apf_init(osal_void)296 osal_u32 hmac_apf_init(osal_void)
297 {
298     /* 注册监听 */
299     frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_apf_filter_del_user);
300     frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_INETADDR_NOTIFIER_UP, hmac_apf_set_ip_addr_etc);
301     frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_SUSPEND_CHANGE, hmac_apf_filter_switch);
302     /* 注册消息 */
303     frw_msg_hook_register(WLAN_MSG_W2H_CFG_SET_FILTER_LIST, hmac_config_apf_filter_cmd);
304     frw_msg_hook_register(WLAN_MSG_W2H_CFG_FORCE_STOP_FILTER, hmac_config_force_stop_filter);
305     return OAL_SUCC;
306 }
307 
hmac_apf_deinit(osal_void)308 osal_void hmac_apf_deinit(osal_void)
309 {
310     /* 去注册监听 */
311     frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_apf_filter_del_user);
312     frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_INETADDR_NOTIFIER_UP, hmac_apf_set_ip_addr_etc);
313     frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_SUSPEND_CHANGE, hmac_apf_filter_switch);
314     /* 去注册消息 */
315     frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_SET_FILTER_LIST);
316     frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_FORCE_STOP_FILTER);
317     return;
318 }
319 
320 #ifdef __cplusplus
321 #if __cplusplus
322 }
323 #endif
324 #endif
325