1 /*
2 Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*!
30 @file
31 IPACM_IfaceManager.cpp
32
33 @brief
34 This file implements the IPAM iface_manager functionality.
35
36 @Author
37 Skylar Chang
38
39 */
40 #include <string.h>
41 #include <sys/ioctl.h>
42
43 #include <IPACM_IfaceManager.h>
44 #include <IPACM_EvtDispatcher.h>
45 #include <IPACM_Defs.h>
46 #include <IPACM_Wlan.h>
47 #include <IPACM_Lan.h>
48 #include <IPACM_Wan.h>
49 #include <IPACM_Iface.h>
50 #include <IPACM_Log.h>
51
52 iface_instances *IPACM_IfaceManager::head = NULL;
53
IPACM_IfaceManager()54 IPACM_IfaceManager::IPACM_IfaceManager()
55 {
56 IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, this); // register for IPA_CFG_CHANGE event
57 IPACM_EvtDispatcher::registr(IPA_LINK_UP_EVENT, this);
58 IPACM_EvtDispatcher::registr(IPA_WLAN_AP_LINK_UP_EVENT, this); // register for wlan AP-iface
59 IPACM_EvtDispatcher::registr(IPA_WLAN_STA_LINK_UP_EVENT, this); // register for wlan STA-iface
60 #ifndef FEATURE_IPA_ANDROID
61 /* only MDM targets support device on bridge mode */
62 IPACM_EvtDispatcher::registr(IPA_BRIDGE_LINK_UP_EVENT, this); // register for IPA_BRIDGE_LINK_UP_EVENT event
63 #endif /* not defined(FEATURE_IPA_ANDROID)*/
64 IPACM_EvtDispatcher::registr(IPA_USB_LINK_UP_EVENT, this); // register for USB-iface
65 IPACM_EvtDispatcher::registr(IPA_WAN_EMBMS_LINK_UP_EVENT, this); // register for wan eMBMS-iface
66 return;
67 }
68
event_callback(ipa_cm_event_id event,void * param)69 void IPACM_IfaceManager::event_callback(ipa_cm_event_id event, void *param)
70 {
71 int ipa_interface_index;
72 ipacm_event_data_fid *evt_data = (ipacm_event_data_fid *)param;
73 ipacm_event_data_mac *StaData = (ipacm_event_data_mac *)param;
74 ipacm_event_data_all *data_all = (ipacm_event_data_all *)param;
75 ipacm_ifacemgr_data ifmgr_data;
76
77 memset(&ifmgr_data,0,sizeof(ifmgr_data));
78
79 switch(event)
80 {
81 case IPA_CFG_CHANGE_EVENT:
82 IPACMDBG_H(" RESET IPACM_cfg \n");
83 IPACM_Iface::ipacmcfg->Init();
84 break;
85 case IPA_BRIDGE_LINK_UP_EVENT:
86 IPACMDBG_H(" Save the bridge0 mac info in IPACM_cfg \n");
87 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
88 /* check for failure return */
89 if (IPACM_FAILURE == ipa_interface_index) {
90 IPACMERR("IPA_BRIDGE_LINK_UP_EVENT: not supported iface id: %d\n", data_all->if_index);
91 break;
92 }
93 /* check if iface is bridge interface*/
94 if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
95 {
96 IPACM_Iface::ipacmcfg->ipa_bridge_enable = true;
97 memcpy(IPACM_Iface::ipacmcfg->bridge_mac,
98 data_all->mac_addr,
99 sizeof(IPACM_Iface::ipacmcfg->bridge_mac));
100 IPACMDBG_H("cached bridge0 MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
101 IPACM_Iface::ipacmcfg->bridge_mac[0], IPACM_Iface::ipacmcfg->bridge_mac[1], IPACM_Iface::ipacmcfg->bridge_mac[2],
102 IPACM_Iface::ipacmcfg->bridge_mac[3], IPACM_Iface::ipacmcfg->bridge_mac[4], IPACM_Iface::ipacmcfg->bridge_mac[5]);
103 }
104 break;
105 case IPA_LINK_UP_EVENT:
106 IPACMDBG_H("Recieved IPA_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
107 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
108 /* check for failure return */
109 if (IPACM_FAILURE == ipa_interface_index) {
110 IPACMERR("IPA_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
111 break;
112 }
113 /* LTE-backhaul */
114 if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == EMBMS_IF)
115 {
116 IPACMDBG("WAN-EMBMS (%s) link already up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
117 }
118 else if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
119 {
120 IPACMDBG_H("WAN-LTE (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
121 ifmgr_data.if_index = evt_data->if_index;
122 ifmgr_data.if_type = Q6_WAN;
123 create_iface_instance(&ifmgr_data);
124 }
125 break;
126
127 case IPA_USB_LINK_UP_EVENT:
128 IPACMDBG_H("Recieved IPA_USB_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
129 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
130 /* check for failure return */
131 if (IPACM_FAILURE == ipa_interface_index) {
132 IPACMERR("IPA_USB_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
133 break;
134 }
135 /* check if it's WAN_IF */
136 if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
137 {
138 /* usb-backhaul using sta_mode ECM_WAN*/
139 IPACMDBG_H("WAN-usb (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, evt_data->if_index);
140 ifmgr_data.if_index = evt_data->if_index;
141 ifmgr_data.if_type = ECM_WAN;
142 create_iface_instance(&ifmgr_data);
143 }
144 else
145 {
146 ifmgr_data.if_index = evt_data->if_index;
147 ifmgr_data.if_type = Q6_WAN;
148 create_iface_instance(&ifmgr_data);
149 }
150 break;
151
152 case IPA_WLAN_AP_LINK_UP_EVENT:
153 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
154 /* check for failure return */
155 if (IPACM_FAILURE == ipa_interface_index) {
156 IPACMERR("IPA_WLAN_AP_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
157 break;
158 }
159 /* change iface category from unknown to WLAN_IF */
160 if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
161 {
162 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WLAN_IF;
163 IPACMDBG_H("WLAN AP (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
164 ifmgr_data.if_index = evt_data->if_index;
165 ifmgr_data.if_type = Q6_WAN;
166 create_iface_instance(&ifmgr_data);
167 }
168 else
169 {
170 IPACMDBG_H("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
171 }
172 break;
173
174 case IPA_WLAN_STA_LINK_UP_EVENT:
175 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(StaData->if_index);
176 /* check for failure return */
177 if (IPACM_FAILURE == ipa_interface_index) {
178 IPACMERR("IPA_WLAN_STA_LINK_UP_EVENT: not supported iface id: %d\n", StaData->if_index);
179 break;
180 }
181 /* change iface category from unknown to WAN_IF */
182 if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
183 {
184 /* wlan-backhaul using sta_mode WLAN_WAN */
185 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WAN_IF;
186 IPACMDBG_H("WLAN STA (%s) link up, iface: %d: \n",
187 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, StaData->if_index);
188
189 ifmgr_data.if_index = StaData->if_index;
190 ifmgr_data.if_type = WLAN_WAN;
191 memcpy(ifmgr_data.mac_addr, StaData->mac_addr, sizeof(ifmgr_data.mac_addr));
192 create_iface_instance(&ifmgr_data);
193 }
194 else
195 {
196 IPACMDBG_H("iface %s already up and act as %d mode: \n",
197 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
198 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
199 }
200 break;
201
202 /* Add new instance open for eMBMS iface and wan iface */
203 case IPA_WAN_EMBMS_LINK_UP_EVENT:
204 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
205 /* check for failure return */
206 if (IPACM_FAILURE == ipa_interface_index) {
207 IPACMERR("IPA_WAN_EMBMS_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
208 break;
209 }
210 /* change iface category from unknown to EMBMS_IF */
211 if ((IPACM_Iface::ipacmcfg->ipacm_odu_enable == true) && (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true))
212 {
213 IPACMDBG(" ODU-mode enable or not (%d) \n",IPACM_Iface::ipacmcfg->ipacm_odu_enable);
214 if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
215 {
216 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat=EMBMS_IF;
217 IPACMDBG("WAN eMBMS (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
218 ifmgr_data.if_index = StaData->if_index;
219 ifmgr_data.if_type = Q6_WAN;
220 create_iface_instance(&ifmgr_data);
221 }
222 else
223 {
224 IPACMDBG("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
225 }
226 }
227 break;
228
229 default:
230 break;
231 }
232 return;
233 }
234
create_iface_instance(ipacm_ifacemgr_data * param)235 int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
236 {
237 int if_index = param->if_index;
238 ipacm_wan_iface_type is_sta_mode = param->if_type;
239
240 int ipa_interface_index;
241 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(if_index);
242
243 if(ipa_interface_index == INVALID_IFACE)
244 {
245 IPACMDBG_H("Unhandled interface received, fid: %d\n",if_index);
246 return IPACM_SUCCESS;
247 }
248
249 /* check if duplicate instance*/
250 if(SearchInstance(ipa_interface_index) == IPA_INSTANCE_NOT_FOUND)
251 {
252 /* IPA_INSTANCE_NOT_FOUND */
253 switch(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat)
254 {
255
256 case LAN_IF:
257 {
258 IPACMDBG_H("Creating Lan interface\n");
259 IPACM_Lan *lan = new IPACM_Lan(ipa_interface_index);
260 if (lan->rx_prop == NULL && lan->tx_prop == NULL)
261 {
262 /* close the netdev instance if IPA not support*/
263 lan->delete_iface();
264 return IPACM_FAILURE;
265 }
266 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, lan);
267 //IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, lan);
268 //IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, lan);
269 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, lan);
270 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, lan);
271 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, lan);
272 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, lan);
273 #ifdef FEATURE_IPA_ANDROID
274 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, lan);
275 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, lan);
276 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, lan);
277 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, lan);
278 #ifdef FEATURE_IPACM_HAL
279 IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_ADD, lan);
280 IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_DEL, lan);
281 #endif
282 #else
283 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, lan);
284 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, lan);
285 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, lan);
286 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan);
287 #endif
288 IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); // register for IPA_CFG_CHANGE event
289 IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, lan); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
290 #ifdef FEATURE_IPA_ANDROID
291 IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, lan);
292 #endif
293 IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, lan);
294 #ifdef IPA_MTU_EVENT_MAX
295 IPACM_EvtDispatcher::registr(IPA_MTU_UPDATE, lan);
296 #endif
297 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan);
298 /* IPA_LAN_DELETE_SELF should be always last */
299 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan);
300 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", lan->dev_name, lan->ipa_if_num);
301 registr(ipa_interface_index, lan);
302 /* solve the new_addr comes earlier issue */
303 IPACM_Iface::iface_addr_query(if_index);
304 }
305 break;
306
307 case ETH_IF:
308 {
309 IPACMDBG_H("Creating ETH interface in router mode\n");
310 IPACM_Lan *ETH = new IPACM_Lan(ipa_interface_index);
311 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, ETH);
312 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, ETH);
313 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, ETH);
314 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, ETH);
315 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, ETH);
316 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, ETH);
317 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, ETH);
318 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, ETH);
319 IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, ETH);
320 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, ETH);
321 /* IPA_LAN_DELETE_SELF should be always last */
322 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, ETH);
323 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", ETH->dev_name, ETH->ipa_if_num);
324 registr(ipa_interface_index, ETH);
325 /* solve the new_addr comes earlier issue */
326 IPACM_Iface::iface_addr_query(if_index);
327 }
328 break;
329
330 case ODU_IF:
331 {
332 if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
333 {
334 IPACMDBG_H("Creating ODU interface in router mode\n");
335 IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
336 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
337 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
338 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, odu);
339 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
340 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
341 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, odu);
342 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, odu);
343 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, odu);
344 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, odu);
345 IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, odu);
346 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
347 /* IPA_LAN_DELETE_SELF should be always last */
348 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
349 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
350 registr(ipa_interface_index, odu);
351 /* solve the new_addr comes earlier issue */
352 IPACM_Iface::iface_addr_query(if_index);
353 }
354 else
355 {
356 IPACMDBG_H("Creating ODU interface in bridge mode\n");
357 IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
358 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
359 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
360 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
361 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
362 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
363 /* IPA_LAN_DELETE_SELF should be always last */
364 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
365 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
366 registr(ipa_interface_index, odu);
367 /* solve the new_addr comes earlier issue */
368 IPACM_Iface::iface_addr_query(if_index);
369 }
370 }
371 break;
372
373 case WLAN_IF:
374 {
375 IPACMDBG_H("Creating WLan interface\n");
376 IPACM_Wlan *wl = new IPACM_Wlan(ipa_interface_index);
377 if (wl->rx_prop == NULL && wl->tx_prop == NULL)
378 {
379 /* reset the AP-iface category to unknown */
380 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = UNKNOWN_IF;
381 /* close the netdev instance if IPA not support*/
382 wl->delete_iface();
383 return IPACM_FAILURE;
384 }
385 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, wl);
386 IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, wl);
387 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT, wl);
388 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, wl);
389 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_DEL_EVENT, wl);
390 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_POWER_SAVE_EVENT, wl);
391 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_RECOVER_EVENT, wl);
392 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, wl);
393 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, wl);
394 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, wl);
395 #ifdef FEATURE_IPA_ANDROID
396 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, wl);
397 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, wl);
398 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, wl);
399 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, wl);
400 #ifdef FEATURE_IPACM_HAL
401 IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_ADD, wl);
402 IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_DEL, wl);
403 IPACM_EvtDispatcher::registr(IPA_SSR_NOTICE, wl);
404 #endif
405 #else
406 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl);
407 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, wl);
408 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl);
409 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
410 #endif
411 IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
412 if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
413 IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, wl);
414 IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, wl);
415 IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
416 #ifndef FEATURE_IPA_ANDROID
417 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, wl);
418 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, wl);
419 #else
420 IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, wl);
421 #endif
422 #ifdef FEATURE_IPACM_HAL
423 IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, wl);
424 #endif
425 IPACM_EvtDispatcher::registr(IPA_WIGIG_CLIENT_ADD_EVENT, wl);
426 #ifdef IPA_MTU_EVENT_MAX
427 IPACM_EvtDispatcher::registr(IPA_MTU_UPDATE, wl);
428 #endif
429 /* IPA_LAN_DELETE_SELF should be always last */
430 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
431 IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num);
432 registr(ipa_interface_index, wl);
433 /* solve the new_addr comes earlier issue */
434 IPACM_Iface::iface_addr_query(if_index);
435 }
436 break;
437
438 case WAN_IF:
439 {
440 if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == false) || (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true))
441 {
442 IPACMDBG_H("Creating Wan interface\n");
443 IPACM_Wan *w;
444 if(is_sta_mode == WLAN_WAN)
445 {
446 w = new IPACM_Wan(ipa_interface_index, is_sta_mode, param->mac_addr);
447 if (w->rx_prop == NULL && w->tx_prop == NULL)
448 {
449 /* reset the AP-iface category to unknown */
450 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = UNKNOWN_IF;
451 /* close the netdev instance if IPA not support*/
452 w->delete_iface();
453 return IPACM_FAILURE;
454 }
455 }
456 else
457 {
458 w = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
459 if (w->rx_prop == NULL && w->tx_prop == NULL)
460 {
461 /* close the netdev instance if IPA not support*/
462 w->delete_iface();
463 return IPACM_FAILURE;
464 }
465 }
466 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
467 #ifdef FEATURE_IPA_ANDROID
468 IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, w);
469 IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w);
470 if(is_sta_mode == Q6_WAN)
471 {
472 IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w);
473 #ifdef IPA_MTU_EVENT_MAX
474 IPACM_EvtDispatcher::registr(IPA_MTU_SET, w);
475 #endif
476 };
477 #else/* defined(FEATURE_IPA_ANDROID) */
478 IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w);
479 IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, w);
480 #endif /* not defined(FEATURE_IPA_ANDROID)*/
481 IPACM_EvtDispatcher::registr(IPA_FIREWALL_CHANGE_EVENT, w);
482 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, w);
483 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, w);
484 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, w);
485 IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, w); // register for IPA_CFG_CHANGE event
486 IPACM_EvtDispatcher::registr(IPA_WAN_XLAT_CONNECT_EVENT, w);
487 if(is_sta_mode == WLAN_WAN)
488 {
489 IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode
490 #ifndef FEATURE_IPA_ANDROID
491 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, w);
492 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, w);
493 #ifdef FEATURE_IPACM_HAL
494 IPACM_EvtDispatcher::registr(IPA_SSR_NOTICE, w);
495 IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, w);
496 #endif
497 #endif
498 }
499 else
500 {
501 IPACM_EvtDispatcher::registr(IPA_COALESCE_NOTICE, w);
502 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, w);
503 }
504
505 IPACMDBG_H("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", w->dev_name, w->ipa_if_num);
506 registr(ipa_interface_index, w);
507 /* solve the new_addr comes earlier issue */
508 IPACM_Iface::iface_addr_query(if_index);
509 }
510 }
511 break;
512
513 /* WAN-eMBMS instance */
514 case EMBMS_IF:
515 {
516 IPACMDBG("Creating Wan-eMBSM interface\n");
517 IPACM_Wan *embms = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
518 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, embms);
519 IPACMDBG("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", embms->dev_name, embms->ipa_if_num);
520 registr(ipa_interface_index, embms);
521 }
522 break;
523
524 default:
525 IPACMDBG_H("Unhandled interface category received iface name: %s, category: %d\n",
526 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
527 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
528 return IPACM_SUCCESS;
529 }
530 }
531 return IPACM_SUCCESS;
532 }
533
534
registr(int ipa_if_index,IPACM_Listener * obj)535 int IPACM_IfaceManager::registr(int ipa_if_index, IPACM_Listener *obj)
536 {
537 iface_instances *tmp = head,*nw;
538
539 nw = (iface_instances *)malloc(sizeof(iface_instances));
540 if(nw != NULL)
541 {
542 nw->ipa_if_index = ipa_if_index;
543 nw->obj = obj;
544 nw->next = NULL;
545 }
546 else
547 {
548 return IPACM_FAILURE;
549 }
550
551 if(head == NULL)
552 {
553 head = nw;
554 }
555 else
556 {
557 while(tmp->next)
558 {
559 tmp = tmp->next;
560 }
561 tmp->next = nw;
562 }
563 return IPACM_SUCCESS;
564 }
565
deregistr(IPACM_Listener * param)566 int IPACM_IfaceManager::deregistr(IPACM_Listener *param)
567 {
568 iface_instances *tmp = head,*tmp1,*prev = head;
569
570 while(tmp != NULL)
571 {
572 if(tmp->obj == param)
573 {
574 tmp1 = tmp;
575 if(tmp == head)
576 {
577 head = head->next;
578 }
579 else if(tmp->next == NULL)
580 {
581 prev->next = NULL;
582 }
583 else
584 {
585 prev->next = tmp->next;
586 }
587
588 tmp = tmp->next;
589 free(tmp1);
590 }
591 else
592 {
593 prev = tmp;
594 tmp = tmp->next;
595 }
596 }
597 return IPACM_SUCCESS;
598 }
599
600
SearchInstance(int ipa_if_index)601 int IPACM_IfaceManager::SearchInstance(int ipa_if_index)
602 {
603
604 iface_instances *tmp = head;
605
606 while(tmp != NULL)
607 {
608 if(ipa_if_index == tmp->ipa_if_index)
609 {
610 IPACMDBG_H("Find existed iface-instance name: %s\n",
611 IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name);
612 return IPA_INSTANCE_FOUND;
613 }
614 tmp = tmp->next;
615 }
616
617 IPACMDBG_H("No existed iface-instance name: %s,\n",
618 IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name);
619
620 return IPA_INSTANCE_NOT_FOUND;
621 }
622