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