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