• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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