1 /*
2 Copyright (c) 2013-2018, 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 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan);
295 /* IPA_LAN_DELETE_SELF should be always last */
296 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan);
297 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", lan->dev_name, lan->ipa_if_num);
298 registr(ipa_interface_index, lan);
299 /* solve the new_addr comes earlier issue */
300 IPACM_Iface::iface_addr_query(if_index);
301 }
302 break;
303
304 case ETH_IF:
305 {
306 IPACMDBG_H("Creating ETH interface in router mode\n");
307 IPACM_Lan *ETH = new IPACM_Lan(ipa_interface_index);
308 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, ETH);
309 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, ETH);
310 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, ETH);
311 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, ETH);
312 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, ETH);
313 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, ETH);
314 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, ETH);
315 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, ETH);
316 IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, ETH);
317 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, ETH);
318 /* IPA_LAN_DELETE_SELF should be always last */
319 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, ETH);
320 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", ETH->dev_name, ETH->ipa_if_num);
321 registr(ipa_interface_index, ETH);
322 /* solve the new_addr comes earlier issue */
323 IPACM_Iface::iface_addr_query(if_index);
324 }
325 break;
326
327 case ODU_IF:
328 {
329 if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
330 {
331 IPACMDBG_H("Creating ODU interface in router mode\n");
332 IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
333 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
334 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
335 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, odu);
336 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
337 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
338 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, odu);
339 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, odu);
340 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, odu);
341 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, odu);
342 IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, odu);
343 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
344 /* IPA_LAN_DELETE_SELF should be always last */
345 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
346 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
347 registr(ipa_interface_index, odu);
348 /* solve the new_addr comes earlier issue */
349 IPACM_Iface::iface_addr_query(if_index);
350 }
351 else
352 {
353 IPACMDBG_H("Creating ODU interface in bridge mode\n");
354 IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
355 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
356 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
357 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
358 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
359 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
360 /* IPA_LAN_DELETE_SELF should be always last */
361 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
362 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
363 registr(ipa_interface_index, odu);
364 /* solve the new_addr comes earlier issue */
365 IPACM_Iface::iface_addr_query(if_index);
366 }
367 }
368 break;
369
370 case WLAN_IF:
371 {
372 IPACMDBG_H("Creating WLan interface\n");
373 IPACM_Wlan *wl = new IPACM_Wlan(ipa_interface_index);
374 if (wl->rx_prop == NULL && wl->tx_prop == NULL)
375 {
376 /* reset the AP-iface category to unknown */
377 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = UNKNOWN_IF;
378 /* close the netdev instance if IPA not support*/
379 wl->delete_iface();
380 return IPACM_FAILURE;
381 }
382 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, wl);
383 IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, wl);
384 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT, wl);
385 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, wl);
386 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_DEL_EVENT, wl);
387 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_POWER_SAVE_EVENT, wl);
388 IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_RECOVER_EVENT, wl);
389 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, wl);
390 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, wl);
391 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, wl);
392 #ifdef FEATURE_IPA_ANDROID
393 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, wl);
394 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, wl);
395 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, wl);
396 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, wl);
397 #ifdef FEATURE_IPACM_HAL
398 IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_ADD, wl);
399 IPACM_EvtDispatcher::registr(IPA_DOWNSTREAM_DEL, wl);
400 IPACM_EvtDispatcher::registr(IPA_SSR_NOTICE, wl);
401 #endif
402 #else
403 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl);
404 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, wl);
405 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl);
406 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
407 #endif
408 IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
409 #ifdef FEATURE_ETH_BRIDGE_LE
410 IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, wl);
411 #endif
412 IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, wl);
413 IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
414 #ifndef FEATURE_IPA_ANDROID
415 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, wl);
416 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, wl);
417 #else
418 IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, wl);
419 #endif
420 #ifdef FEATURE_IPACM_HAL
421 IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, wl);
422 #endif
423 /* IPA_LAN_DELETE_SELF should be always last */
424 IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
425 IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num);
426 registr(ipa_interface_index, wl);
427 /* solve the new_addr comes earlier issue */
428 IPACM_Iface::iface_addr_query(if_index);
429 }
430 break;
431
432 case WAN_IF:
433 {
434 if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == false) || (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true))
435 {
436 IPACMDBG_H("Creating Wan interface\n");
437 IPACM_Wan *w;
438 if(is_sta_mode == WLAN_WAN)
439 {
440 w = new IPACM_Wan(ipa_interface_index, is_sta_mode, param->mac_addr);
441 if (w->rx_prop == NULL && w->tx_prop == NULL)
442 {
443 /* reset the AP-iface category to unknown */
444 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = UNKNOWN_IF;
445 /* close the netdev instance if IPA not support*/
446 w->delete_iface();
447 return IPACM_FAILURE;
448 }
449 }
450 else
451 {
452 w = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
453 }
454 IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
455 #ifdef FEATURE_IPA_ANDROID
456 IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, w);
457 IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w);
458 if(is_sta_mode == Q6_WAN)
459 {
460 IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w);
461 };
462 #else/* defined(FEATURE_IPA_ANDROID) */
463 IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w);
464 IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, w);
465 #endif /* not defined(FEATURE_IPA_ANDROID)*/
466 IPACM_EvtDispatcher::registr(IPA_FIREWALL_CHANGE_EVENT, w);
467 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, w);
468 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, w);
469 IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, w);
470 IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, w); // register for IPA_CFG_CHANGE event
471 IPACM_EvtDispatcher::registr(IPA_WAN_XLAT_CONNECT_EVENT, w);
472 if(is_sta_mode == WLAN_WAN)
473 {
474 IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode
475 #ifndef FEATURE_IPA_ANDROID
476 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, w);
477 IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, w);
478 #ifdef FEATURE_IPACM_HAL
479 IPACM_EvtDispatcher::registr(IPA_SSR_NOTICE, w);
480 IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, w);
481 #endif
482 #endif
483 }
484 else
485 {
486 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, w);
487 }
488
489 IPACMDBG_H("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", w->dev_name, w->ipa_if_num);
490 registr(ipa_interface_index, w);
491 /* solve the new_addr comes earlier issue */
492 IPACM_Iface::iface_addr_query(if_index);
493 }
494 }
495 break;
496
497 /* WAN-eMBMS instance */
498 case EMBMS_IF:
499 {
500 IPACMDBG("Creating Wan-eMBSM interface\n");
501 IPACM_Wan *embms = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
502 IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, embms);
503 IPACMDBG("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", embms->dev_name, embms->ipa_if_num);
504 registr(ipa_interface_index, embms);
505 }
506 break;
507
508 default:
509 IPACMDBG_H("Unhandled interface category received iface name: %s, category: %d\n",
510 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
511 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
512 return IPACM_SUCCESS;
513 }
514 }
515 return IPACM_SUCCESS;
516 }
517
518
registr(int ipa_if_index,IPACM_Listener * obj)519 int IPACM_IfaceManager::registr(int ipa_if_index, IPACM_Listener *obj)
520 {
521 iface_instances *tmp = head,*nw;
522
523 nw = (iface_instances *)malloc(sizeof(iface_instances));
524 if(nw != NULL)
525 {
526 nw->ipa_if_index = ipa_if_index;
527 nw->obj = obj;
528 nw->next = NULL;
529 }
530 else
531 {
532 return IPACM_FAILURE;
533 }
534
535 if(head == NULL)
536 {
537 head = nw;
538 }
539 else
540 {
541 while(tmp->next)
542 {
543 tmp = tmp->next;
544 }
545 tmp->next = nw;
546 }
547 return IPACM_SUCCESS;
548 }
549
deregistr(IPACM_Listener * param)550 int IPACM_IfaceManager::deregistr(IPACM_Listener *param)
551 {
552 iface_instances *tmp = head,*tmp1,*prev = head;
553
554 while(tmp != NULL)
555 {
556 if(tmp->obj == param)
557 {
558 tmp1 = tmp;
559 if(tmp == head)
560 {
561 head = head->next;
562 }
563 else if(tmp->next == NULL)
564 {
565 prev->next = NULL;
566 }
567 else
568 {
569 prev->next = tmp->next;
570 }
571
572 tmp = tmp->next;
573 free(tmp1);
574 }
575 else
576 {
577 prev = tmp;
578 tmp = tmp->next;
579 }
580 }
581 return IPACM_SUCCESS;
582 }
583
584
SearchInstance(int ipa_if_index)585 int IPACM_IfaceManager::SearchInstance(int ipa_if_index)
586 {
587
588 iface_instances *tmp = head;
589
590 while(tmp != NULL)
591 {
592 if(ipa_if_index == tmp->ipa_if_index)
593 {
594 IPACMDBG_H("Find existed iface-instance name: %s\n",
595 IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name);
596 return IPA_INSTANCE_FOUND;
597 }
598 tmp = tmp->next;
599 }
600
601 IPACMDBG_H("No existed iface-instance name: %s,\n",
602 IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name);
603
604 return IPA_INSTANCE_NOT_FOUND;
605 }
606