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