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_Config.cpp
32 
33 		@brief
34 		This file implements the IPACM Configuration from XML file
35 
36 		@Author
37 		Skylar Chang
38 
39 */
40 #include <IPACM_Config.h>
41 #include <IPACM_Log.h>
42 #include <IPACM_Iface.h>
43 #include <sys/ioctl.h>
44 #include <fcntl.h>
45 
46 IPACM_Config *IPACM_Config::pInstance = NULL;
47 const char *IPACM_Config::DEVICE_NAME = "/dev/ipa";
48 const char *IPACM_Config::DEVICE_NAME_ODU = "/dev/odu_ipa_bridge";
49 
50 #define __stringify(x...) #x
51 
52 const char *ipacm_event_name[] = {
53 	__stringify(IPA_CFG_CHANGE_EVENT),                     /* NULL */
54 	__stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT),          /* ipacm_event_data_fid */
55 	__stringify(IPA_FIREWALL_CHANGE_EVENT),                /* NULL */
56 	__stringify(IPA_LINK_UP_EVENT),                        /* ipacm_event_data_fid */
57 	__stringify(IPA_LINK_DOWN_EVENT),                      /* ipacm_event_data_fid */
58 	__stringify(IPA_USB_LINK_UP_EVENT),                    /* ipacm_event_data_fid */
59 	__stringify(IPA_BRIDGE_LINK_UP_EVENT),                 /* ipacm_event_data_all */
60 	__stringify(IPA_WAN_EMBMS_LINK_UP_EVENT),              /* ipacm_event_data_mac */
61 	__stringify(IPA_ADDR_ADD_EVENT),                       /* ipacm_event_data_addr */
62 	__stringify(IPA_ADDR_DEL_EVENT),                       /* no use */
63 	__stringify(IPA_ROUTE_ADD_EVENT),                      /* ipacm_event_data_addr */
64 	__stringify(IPA_ROUTE_DEL_EVENT),                      /* ipacm_event_data_addr */
65 	__stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT),         /* ipacm_event_data_fid */
66 	__stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT),         /* ipacm_event_data_fid */
67 	__stringify(IPA_WLAN_AP_LINK_UP_EVENT),                /* ipacm_event_data_mac */
68 	__stringify(IPA_WLAN_STA_LINK_UP_EVENT),               /* ipacm_event_data_mac */
69 	__stringify(IPA_WLAN_LINK_DOWN_EVENT),                 /* ipacm_event_data_mac */
70 	__stringify(IPA_WLAN_CLIENT_ADD_EVENT),                /* ipacm_event_data_mac */
71 	__stringify(IPA_WLAN_CLIENT_ADD_EVENT_EX),             /* ipacm_event_data_wlan_ex */
72 	__stringify(IPA_WLAN_CLIENT_DEL_EVENT),                /* ipacm_event_data_mac */
73 	__stringify(IPA_WLAN_CLIENT_POWER_SAVE_EVENT),         /* ipacm_event_data_mac */
74 	__stringify(IPA_WLAN_CLIENT_RECOVER_EVENT),            /* ipacm_event_data_mac */
75 	__stringify(IPA_NEW_NEIGH_EVENT),                      /* ipacm_event_data_all */
76 	__stringify(IPA_DEL_NEIGH_EVENT),                      /* ipacm_event_data_all */
77 	__stringify(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT),       /* ipacm_event_data_all */
78 	__stringify(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT),       /* ipacm_event_data_all */
79 	__stringify(IPA_SW_ROUTING_ENABLE),                    /* NULL */
80 	__stringify(IPA_SW_ROUTING_DISABLE),                   /* NULL */
81 	__stringify(IPA_PROCESS_CT_MESSAGE),                   /* ipacm_ct_evt_data */
82 	__stringify(IPA_PROCESS_CT_MESSAGE_V6),                /* ipacm_ct_evt_data */
83 	__stringify(IPA_LAN_TO_LAN_NEW_CONNECTION),            /* ipacm_event_connection */
84 	__stringify(IPA_LAN_TO_LAN_DEL_CONNECTION),            /* ipacm_event_connection */
85 	__stringify(IPA_WLAN_SWITCH_TO_SCC),                   /* No Data */
86 	__stringify(IPA_WLAN_SWITCH_TO_MCC),                   /* No Data */
87 	__stringify(IPA_CRADLE_WAN_MODE_SWITCH),               /* ipacm_event_cradle_wan_mode */
88 	__stringify(IPA_WAN_XLAT_CONNECT_EVENT),               /* ipacm_event_data_fid */
89 	__stringify(IPA_TETHERING_STATS_UPDATE_EVENT),         /* ipacm_event_data_fid */
90 	__stringify(IPA_NETWORK_STATS_UPDATE_EVENT),           /* ipacm_event_data_fid */
91 	__stringify(IPA_DOWNSTREAM_ADD),                       /* ipacm_event_ipahal_stream */
92 	__stringify(IPA_DOWNSTREAM_DEL),                       /* ipacm_event_ipahal_stream */
93 	__stringify(IPA_EXTERNAL_EVENT_MAX),
94 	__stringify(IPA_HANDLE_WAN_UP),                        /* ipacm_event_iface_up  */
95 	__stringify(IPA_HANDLE_WAN_DOWN),                      /* ipacm_event_iface_up  */
96 	__stringify(IPA_HANDLE_WAN_UP_V6),                     /* NULL */
97 	__stringify(IPA_HANDLE_WAN_DOWN_V6),                   /* NULL */
98 	__stringify(IPA_HANDLE_WAN_UP_TETHER),                 /* ipacm_event_iface_up_tehter */
99 	__stringify(IPA_HANDLE_WAN_DOWN_TETHER),               /* ipacm_event_iface_up_tehter */
100 	__stringify(IPA_HANDLE_WAN_UP_V6_TETHER),              /* ipacm_event_iface_up_tehter */
101 	__stringify(IPA_HANDLE_WAN_DOWN_V6_TETHER),            /* ipacm_event_iface_up_tehter */
102 	__stringify(IPA_HANDLE_WLAN_UP),                       /* ipacm_event_iface_up */
103 	__stringify(IPA_HANDLE_LAN_UP),                        /* ipacm_event_iface_up */
104 	__stringify(IPA_ETH_BRIDGE_IFACE_UP),                  /* ipacm_event_eth_bridge*/
105 	__stringify(IPA_ETH_BRIDGE_IFACE_DOWN),                /* ipacm_event_eth_bridge*/
106 	__stringify(IPA_ETH_BRIDGE_CLIENT_ADD),                /* ipacm_event_eth_bridge*/
107 	__stringify(IPA_ETH_BRIDGE_CLIENT_DEL),                /* ipacm_event_eth_bridge*/
108 	__stringify(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH),       /* ipacm_event_eth_bridge*/
109 	__stringify(IPA_LAN_DELETE_SELF),                      /* ipacm_event_data_fid */
110 	__stringify(IPACM_EVENT_MAX),
111 };
112 
IPACM_Config()113 IPACM_Config::IPACM_Config()
114 {
115 	iface_table = NULL;
116 	alg_table = NULL;
117 	pNatIfaces = NULL;
118 	memset(&ipa_client_rm_map_tbl, 0, sizeof(ipa_client_rm_map_tbl));
119 	memset(&ipa_rm_tbl, 0, sizeof(ipa_rm_tbl));
120 	ipa_rm_a2_check=0;
121 	ipacm_odu_enable = false;
122 	ipacm_odu_router_mode = false;
123 	ipa_num_wlan_guest_ap = 0;
124 
125 	ipa_num_ipa_interfaces = 0;
126 	ipa_num_private_subnet = 0;
127 	ipa_num_alg_ports = 0;
128 	ipa_nat_max_entries = 0;
129 	ipa_nat_iface_entries = 0;
130 	ipa_sw_rt_enable = false;
131 	ipa_bridge_enable = false;
132 	isMCC_Mode = false;
133 	ipa_max_valid_rm_entry = 0;
134 
135 	memset(&rt_tbl_default_v4, 0, sizeof(rt_tbl_default_v4));
136 	memset(&rt_tbl_lan_v4, 0, sizeof(rt_tbl_lan_v4));
137 	memset(&rt_tbl_wan_v4, 0, sizeof(rt_tbl_wan_v4));
138 	memset(&rt_tbl_v6, 0, sizeof(rt_tbl_v6));
139 	memset(&rt_tbl_wan_v6, 0, sizeof(rt_tbl_wan_v6));
140 	memset(&rt_tbl_wan_dl, 0, sizeof(rt_tbl_wan_dl));
141 	memset(&rt_tbl_odu_v4, 0, sizeof(rt_tbl_odu_v4));
142 	memset(&rt_tbl_odu_v6, 0, sizeof(rt_tbl_odu_v6));
143 
144 	memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
145 	memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
146 
147 	qmap_id = ~0;
148 
149 	memset(flt_rule_count_v4, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int));
150 	memset(flt_rule_count_v6, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int));
151 	memset(bridge_mac, 0, IPA_MAC_ADDR_SIZE*sizeof(uint8_t));
152 
153 	IPACMDBG_H(" create IPACM_Config constructor\n");
154 	return;
155 }
156 
Init(void)157 int IPACM_Config::Init(void)
158 {
159 	/* Read IPACM Config file */
160 	char	IPACM_config_file[IPA_MAX_FILE_LEN];
161 	IPACM_conf_t	*cfg;
162 	cfg = (IPACM_conf_t *)malloc(sizeof(IPACM_conf_t));
163 	if(cfg == NULL)
164 	{
165 		IPACMERR("Unable to allocate cfg memory.\n");
166 		return IPACM_FAILURE;
167 	}
168 	uint32_t subnet_addr;
169 	uint32_t subnet_mask;
170 	int i, ret = IPACM_SUCCESS;
171 	struct in_addr in_addr_print;
172 
173 	m_fd = open(DEVICE_NAME, O_RDWR);
174 	if (0 > m_fd)
175 	{
176 		IPACMERR("Failed opening %s.\n", DEVICE_NAME);
177 	}
178 #ifdef FEATURE_IPACM_HAL
179 	strncpy(IPACM_config_file, "/vendor/etc/IPACM_cfg.xml", sizeof(IPACM_config_file));
180 #else
181 	strncpy(IPACM_config_file, "/etc/IPACM_cfg.xml", sizeof(IPACM_config_file));
182 #endif
183 
184 	IPACMDBG_H("\n IPACM XML file is %s \n", IPACM_config_file);
185 	if (IPACM_SUCCESS == ipacm_read_cfg_xml(IPACM_config_file, cfg))
186 	{
187 		IPACMDBG_H("\n IPACM XML read OK \n");
188 	}
189 	else
190 	{
191 		IPACMERR("\n IPACM XML read failed \n");
192 		ret = IPACM_FAILURE;
193 		goto fail;
194 	}
195 
196 	/* Construct IPACM Iface table */
197 	ipa_num_ipa_interfaces = cfg->iface_config.num_iface_entries;
198 	if (iface_table != NULL)
199 	{
200 		free(iface_table);
201 		iface_table = NULL;
202 		IPACMDBG_H("RESET IPACM_Config::iface_table\n");
203 	}
204 	iface_table = (ipa_ifi_dev_name_t *)calloc(ipa_num_ipa_interfaces,
205 					sizeof(ipa_ifi_dev_name_t));
206 	if(iface_table == NULL)
207 	{
208 		IPACMERR("Unable to allocate iface_table memory.\n");
209 		ret = IPACM_FAILURE;
210 		goto fail;
211 	}
212 
213 	for (i = 0; i < cfg->iface_config.num_iface_entries; i++)
214 	{
215 		strncpy(iface_table[i].iface_name, cfg->iface_config.iface_entries[i].iface_name, sizeof(iface_table[i].iface_name));
216 		iface_table[i].if_cat = cfg->iface_config.iface_entries[i].if_cat;
217 		iface_table[i].if_mode = cfg->iface_config.iface_entries[i].if_mode;
218 		iface_table[i].wlan_mode = cfg->iface_config.iface_entries[i].wlan_mode;
219 		IPACMDBG_H("IPACM_Config::iface_table[%d] = %s, cat=%d, mode=%d wlan-mode=%d \n", i, iface_table[i].iface_name,
220 				iface_table[i].if_cat, iface_table[i].if_mode, iface_table[i].wlan_mode);
221 		/* copy bridge interface name to ipacmcfg */
222 		if( iface_table[i].if_cat == VIRTUAL_IF)
223 		{
224 			strlcpy(ipa_virtual_iface_name, iface_table[i].iface_name, sizeof(ipa_virtual_iface_name));
225 			IPACMDBG_H("ipa_virtual_iface_name(%s) \n", ipa_virtual_iface_name);
226 		}
227 	}
228 
229 	/* Construct IPACM Private_Subnet table */
230 	memset(&private_subnet_table, 0, sizeof(private_subnet_table));
231 	ipa_num_private_subnet = cfg->private_subnet_config.num_subnet_entries;
232 
233 	for (i = 0; i < cfg->private_subnet_config.num_subnet_entries; i++)
234 	{
235 		memcpy(&private_subnet_table[i].subnet_addr,
236 					 &cfg->private_subnet_config.private_subnet_entries[i].subnet_addr,
237 					 sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_addr));
238 
239 		memcpy(&private_subnet_table[i].subnet_mask,
240 					 &cfg->private_subnet_config.private_subnet_entries[i].subnet_mask,
241 					 sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_mask));
242 
243 		subnet_addr = htonl(private_subnet_table[i].subnet_addr);
244 		memcpy(&in_addr_print,&subnet_addr,sizeof(in_addr_print));
245 		IPACMDBG_H("%dst::private_subnet_table= %s \n ", i,
246 						 inet_ntoa(in_addr_print));
247 
248 		subnet_mask =  htonl(private_subnet_table[i].subnet_mask);
249 		memcpy(&in_addr_print,&subnet_mask,sizeof(in_addr_print));
250 		IPACMDBG_H("%dst::private_subnet_table= %s \n ", i,
251 						 inet_ntoa(in_addr_print));
252 	}
253 
254 	/* Construct IPACM ALG table */
255 	ipa_num_alg_ports = cfg->alg_config.num_alg_entries;
256 	if (alg_table != NULL)
257 	{
258 		free(alg_table);
259 		alg_table = NULL;
260 		IPACMDBG_H("RESET IPACM_Config::alg_table \n");
261 	}
262 	alg_table = (ipacm_alg *)calloc(ipa_num_alg_ports,
263 				sizeof(ipacm_alg));
264 	if(alg_table == NULL)
265 	{
266 		IPACMERR("Unable to allocate alg_table memory.\n");
267 		ret = IPACM_FAILURE;
268 		free(iface_table);
269 		goto fail;;
270 	}
271 	for (i = 0; i < cfg->alg_config.num_alg_entries; i++)
272 	{
273 		alg_table[i].protocol = cfg->alg_config.alg_entries[i].protocol;
274 		alg_table[i].port = cfg->alg_config.alg_entries[i].port;
275 		IPACMDBG_H("IPACM_Config::ipacm_alg[%d] = %d, port=%d\n", i, alg_table[i].protocol, alg_table[i].port);
276 	}
277 
278 	ipa_nat_max_entries = cfg->nat_max_entries;
279 	IPACMDBG_H("Nat Maximum Entries %d\n", ipa_nat_max_entries);
280 
281 	/* Find ODU is either router mode or bridge mode*/
282 	ipacm_odu_enable = cfg->odu_enable;
283 	ipacm_odu_router_mode = cfg->router_mode_enable;
284 	ipacm_odu_embms_enable = cfg->odu_embms_enable;
285 	IPACMDBG_H("ipacm_odu_enable %d\n", ipacm_odu_enable);
286 	IPACMDBG_H("ipacm_odu_mode %d\n", ipacm_odu_router_mode);
287 	IPACMDBG_H("ipacm_odu_embms_enable %d\n", ipacm_odu_embms_enable);
288 
289 	ipacm_ip_passthrough_mode = cfg->ip_passthrough_mode;
290 	IPACMDBG_H("ipacm_ip_passthrough_mode %d. \n", ipacm_ip_passthrough_mode);
291 
292 	ipa_num_wlan_guest_ap = cfg->num_wlan_guest_ap;
293 	IPACMDBG_H("ipa_num_wlan_guest_ap %d\n",ipa_num_wlan_guest_ap);
294 
295 	/* Allocate more non-nat entries if the monitored iface dun have Tx/Rx properties */
296 	if (pNatIfaces != NULL)
297 	{
298 		free(pNatIfaces);
299 		pNatIfaces = NULL;
300 		IPACMDBG_H("RESET IPACM_Config::pNatIfaces \n");
301 	}
302 	ipa_nat_iface_entries = 0;
303 	pNatIfaces = (NatIfaces *)calloc(ipa_num_ipa_interfaces, sizeof(NatIfaces));
304 	if (pNatIfaces == NULL)
305 	{
306 		IPACMERR("unable to allocate nat ifaces\n");
307 		ret = IPACM_FAILURE;
308 		free(iface_table);
309 		free(alg_table);
310 		goto fail;
311 	}
312 
313 	/* Construct the routing table ictol name in iface static member*/
314 	rt_tbl_default_v4.ip = IPA_IP_v4;
315 	strncpy(rt_tbl_default_v4.name, V4_DEFAULT_ROUTE_TABLE_NAME, sizeof(rt_tbl_default_v4.name));
316 
317 	rt_tbl_lan_v4.ip = IPA_IP_v4;
318 	strncpy(rt_tbl_lan_v4.name, V4_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan_v4.name));
319 
320 	rt_tbl_wan_v4.ip = IPA_IP_v4;
321 	strncpy(rt_tbl_wan_v4.name, V4_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v4.name));
322 
323 	rt_tbl_v6.ip = IPA_IP_v6;
324 	strncpy(rt_tbl_v6.name, V6_COMMON_ROUTE_TABLE_NAME, sizeof(rt_tbl_v6.name));
325 
326 	rt_tbl_wan_v6.ip = IPA_IP_v6;
327 	strncpy(rt_tbl_wan_v6.name, V6_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v6.name));
328 
329 	rt_tbl_odu_v4.ip = IPA_IP_v4;
330 	strncpy(rt_tbl_odu_v4.name, V4_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v4.name));
331 
332 	rt_tbl_odu_v6.ip = IPA_IP_v6;
333 	strncpy(rt_tbl_odu_v6.name, V6_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v6.name));
334 
335 	rt_tbl_wan_dl.ip = IPA_IP_MAX;
336 	strncpy(rt_tbl_wan_dl.name, WAN_DL_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_dl.name));
337 
338 	/* Construct IPACM ipa_client map to rm_resource table */
339 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_PROD]= IPA_RM_RESOURCE_WLAN_PROD;
340 	ipa_client_rm_map_tbl[IPA_CLIENT_USB_PROD]= IPA_RM_RESOURCE_USB_PROD;
341 	ipa_client_rm_map_tbl[IPA_CLIENT_A5_WLAN_AMPDU_PROD]= IPA_RM_RESOURCE_HSIC_PROD;
342 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_PROD]= IPA_RM_RESOURCE_Q6_PROD;
343 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_PROD]= IPA_RM_RESOURCE_Q6_PROD;
344 	ipa_client_rm_map_tbl[IPA_CLIENT_APPS_LAN_WAN_PROD]= IPA_RM_RESOURCE_Q6_PROD;
345 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
346 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN2_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
347 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN3_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
348 	ipa_client_rm_map_tbl[IPA_CLIENT_WLAN4_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
349 	ipa_client_rm_map_tbl[IPA_CLIENT_USB_CONS]= IPA_RM_RESOURCE_USB_CONS;
350 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_CONS]= IPA_RM_RESOURCE_Q6_CONS;
351 	ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_CONS]= IPA_RM_RESOURCE_Q6_CONS;
352 	ipa_client_rm_map_tbl[IPA_CLIENT_APPS_WAN_CONS]= IPA_RM_RESOURCE_Q6_CONS;
353 	ipa_client_rm_map_tbl[IPA_CLIENT_ODU_PROD]= IPA_RM_RESOURCE_ODU_ADAPT_PROD;
354 	ipa_client_rm_map_tbl[IPA_CLIENT_ODU_EMB_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS;
355 	ipa_client_rm_map_tbl[IPA_CLIENT_ODU_TETH_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS;
356 
357 	/* Create the entries which IPACM wants to add dependencies on */
358 	ipa_rm_tbl[0].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
359 	ipa_rm_tbl[0].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
360 	ipa_rm_tbl[0].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
361 	ipa_rm_tbl[0].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
362 
363 	ipa_rm_tbl[1].producer_rm1 = IPA_RM_RESOURCE_USB_PROD;
364 	ipa_rm_tbl[1].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
365 	ipa_rm_tbl[1].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
366 	ipa_rm_tbl[1].consumer_rm2 = IPA_RM_RESOURCE_USB_CONS;
367 
368 	ipa_rm_tbl[2].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
369 	ipa_rm_tbl[2].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS;
370 	ipa_rm_tbl[2].producer_rm2 = IPA_RM_RESOURCE_USB_PROD;
371 	ipa_rm_tbl[2].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
372 
373 	ipa_rm_tbl[3].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
374 	ipa_rm_tbl[3].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
375 	ipa_rm_tbl[3].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
376 	ipa_rm_tbl[3].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
377 
378 	ipa_rm_tbl[4].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
379 	ipa_rm_tbl[4].consumer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
380 	ipa_rm_tbl[4].producer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
381 	ipa_rm_tbl[4].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
382 
383 	ipa_rm_tbl[5].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
384 	ipa_rm_tbl[5].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS;
385 	ipa_rm_tbl[5].producer_rm2 = IPA_RM_RESOURCE_USB_PROD;
386 	ipa_rm_tbl[5].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
387 	ipa_max_valid_rm_entry = 6; /* max is IPA_MAX_RM_ENTRY (6)*/
388 
389 	IPACMDBG_H(" depend MAP-0 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_Q6_CONS);
390 	IPACMDBG_H(" depend MAP-1 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_USB_PROD, IPA_RM_RESOURCE_Q6_CONS);
391 	IPACMDBG_H(" depend MAP-2 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_USB_CONS);
392 	IPACMDBG_H(" depend MAP-3 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_Q6_CONS);
393 	IPACMDBG_H(" depend MAP-4 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_ODU_ADAPT_CONS);
394 	IPACMDBG_H(" depend MAP-5 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_USB_CONS);
395 
396 fail:
397 	if (cfg != NULL)
398 	{
399 		free(cfg);
400 		cfg = NULL;
401 	}
402 
403 	return ret;
404 }
405 
GetInstance()406 IPACM_Config* IPACM_Config::GetInstance()
407 {
408 	int res = IPACM_SUCCESS;
409 
410 	if (pInstance == NULL)
411 	{
412 		pInstance = new IPACM_Config();
413 
414 		res = pInstance->Init();
415 		if (res != IPACM_SUCCESS)
416 		{
417 			delete pInstance;
418 			IPACMERR("unable to initialize config instance\n");
419 			return NULL;
420 		}
421 	}
422 
423 	return pInstance;
424 }
425 
GetAlgPorts(int nPorts,ipacm_alg * pAlgPorts)426 int IPACM_Config::GetAlgPorts(int nPorts, ipacm_alg *pAlgPorts)
427 {
428 	if (nPorts <= 0 || pAlgPorts == NULL)
429 	{
430 		IPACMERR("Invalid input\n");
431 		return -1;
432 	}
433 
434 	for (int cnt = 0; cnt < nPorts; cnt++)
435 	{
436 		pAlgPorts[cnt].protocol = alg_table[cnt].protocol;
437 		pAlgPorts[cnt].port = alg_table[cnt].port;
438 	}
439 
440 	return 0;
441 }
442 
GetNatIfaces(int nIfaces,NatIfaces * pIfaces)443 int IPACM_Config::GetNatIfaces(int nIfaces, NatIfaces *pIfaces)
444 {
445 	if (nIfaces <= 0 || pIfaces == NULL)
446 	{
447 		IPACMERR("Invalid input\n");
448 		return -1;
449 	}
450 
451 	for (int cnt=0; cnt<nIfaces; cnt++)
452 	{
453 		memcpy(pIfaces[cnt].iface_name,
454 					 pNatIfaces[cnt].iface_name,
455 					 sizeof(pIfaces[cnt].iface_name));
456 	}
457 
458 	return 0;
459 }
460 
461 
AddNatIfaces(char * dev_name)462 int IPACM_Config::AddNatIfaces(char *dev_name)
463 {
464 	int i;
465 	/* Check if this iface already in NAT-iface*/
466 	for(i = 0; i < ipa_nat_iface_entries; i++)
467 	{
468 		if(strncmp(dev_name,
469 							 pNatIfaces[i].iface_name,
470 							 sizeof(pNatIfaces[i].iface_name)) == 0)
471 		{
472 			IPACMDBG("Interface (%s) is add to nat iface already\n", dev_name);
473 				return 0;
474 		}
475 	}
476 
477 	IPACMDBG_H("Add iface %s to NAT-ifaces, origin it has %d nat ifaces\n",
478 					          dev_name, ipa_nat_iface_entries);
479 	ipa_nat_iface_entries++;
480 
481 	if (ipa_nat_iface_entries < ipa_num_ipa_interfaces)
482 	{
483 		strlcpy(pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
484 					 dev_name, IPA_IFACE_NAME_LEN);
485 
486 		IPACMDBG_H("Add Nat IfaceName: %s ,update nat-ifaces number: %d\n",
487 						 pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
488 						 ipa_nat_iface_entries);
489 	}
490 
491 	return 0;
492 }
493 
DelNatIfaces(char * dev_name)494 int IPACM_Config::DelNatIfaces(char *dev_name)
495 {
496 	int i = 0;
497 	IPACMDBG_H("Del iface %s from NAT-ifaces, origin it has %d nat ifaces\n",
498 					 dev_name, ipa_nat_iface_entries);
499 
500 	for (i = 0; i < ipa_nat_iface_entries; i++)
501 	{
502 		if (strcmp(dev_name, pNatIfaces[i].iface_name) == 0)
503 		{
504 			IPACMDBG_H("Found Nat IfaceName: %s with nat-ifaces number: %d\n",
505 							 pNatIfaces[i].iface_name, ipa_nat_iface_entries);
506 
507 			/* Reset the matched entry */
508 			memset(pNatIfaces[i].iface_name, 0, IPA_IFACE_NAME_LEN);
509 
510 			for (; i < ipa_nat_iface_entries - 1; i++)
511 			{
512 				memcpy(pNatIfaces[i].iface_name,
513 							 pNatIfaces[i + 1].iface_name, IPA_IFACE_NAME_LEN);
514 
515 				/* Reset the copied entry */
516 				memset(pNatIfaces[i + 1].iface_name, 0, IPA_IFACE_NAME_LEN);
517 			}
518 			ipa_nat_iface_entries--;
519 			IPACMDBG_H("Update nat-ifaces number: %d\n", ipa_nat_iface_entries);
520 			return 0;
521 		}
522 	}
523 
524 	IPACMDBG_H("Can't find Nat IfaceName: %s with total nat-ifaces number: %d\n",
525 					    dev_name, ipa_nat_iface_entries);
526 	return 0;
527 }
528 
CheckNatIfaces(const char * dev_name)529 int IPACM_Config::CheckNatIfaces(const char *dev_name)
530 {
531 	int i = 0;
532 	IPACMDBG_H("Check iface %s from NAT-ifaces, currently it has %d nat ifaces\n",
533 					 dev_name, ipa_nat_iface_entries);
534 
535 	for (i = 0; i < ipa_nat_iface_entries; i++)
536 	{
537 		if (strcmp(dev_name, pNatIfaces[i].iface_name) == 0)
538 		{
539 			IPACMDBG_H("Find Nat IfaceName: %s ,previous nat-ifaces number: %d\n",
540 							 pNatIfaces[i].iface_name, ipa_nat_iface_entries);
541 			return 0;
542 		}
543 	}
544 	IPACMDBG_H("Can't find Nat IfaceName: %s with total nat-ifaces number: %d\n",
545 					    dev_name, ipa_nat_iface_entries);
546 	return -1;
547 }
548 
549 /* for IPACM resource manager dependency usage
550    add either Tx or Rx ipa_rm_resource_name and
551    also indicate that endpoint property if valid */
AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa)552 void IPACM_Config::AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa)
553 {
554 	int retval = 0;
555 	struct ipa_ioc_rm_dependency dep;
556 
557 	IPACMDBG_H(" Got rm add-depend index : %d \n", rm1);
558 	/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
559 	if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
560 	{
561 		ipa_rm_a2_check+=1;
562 		IPACMDBG_H("got %d times default RT routing from A2 \n", ipa_rm_a2_check);
563 	}
564 
565 	for(int i=0;i<ipa_max_valid_rm_entry;i++)
566 	{
567 		if(rm1 == ipa_rm_tbl[i].producer_rm1)
568 		{
569 			ipa_rm_tbl[i].producer1_up = true;
570 			/* entry1's producer actually dun have registered Rx-property */
571 			ipa_rm_tbl[i].rx_bypass_ipa = rx_bypass_ipa;
572 			IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 with non_rx_prop: %d \n", i,ipa_rm_tbl[i].rx_bypass_ipa);
573 
574 			if(ipa_rm_tbl[i].consumer1_up == true && ipa_rm_tbl[i].rm_set == false)
575 			{
576 				IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency  \n", i);
577 				/* add bi-directional dependency*/
578 				if(ipa_rm_tbl[i].rx_bypass_ipa)
579 				{
580 					IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
581 				}
582 				else
583 				{
584 					memset(&dep, 0, sizeof(dep));
585 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
586 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
587 					retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
588 					IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
589 					if (retval)
590 					{
591 						IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
592 					}
593 				}
594 				memset(&dep, 0, sizeof(dep));
595 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
596 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
597 				retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
598 				IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
599 				if (retval)
600 				{
601 					IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d)  \n", i,retval);
602 				}
603 				ipa_rm_tbl[i].rm_set = true;
604 			}
605 			else
606 			{
607 				IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set);
608 			}
609 		}
610 
611 		if(rm1 == ipa_rm_tbl[i].consumer_rm1)
612 		{
613 			ipa_rm_tbl[i].consumer1_up = true;
614 			IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 \n", i);
615 
616 			if(ipa_rm_tbl[i].producer1_up == true && ipa_rm_tbl[i].rm_set == false)
617 			{
618 				IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency  \n", i);
619 				/* add bi-directional dependency*/
620 				if(ipa_rm_tbl[i].rx_bypass_ipa)
621 				{
622 					IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
623 				}
624 				else
625 				{
626 					memset(&dep, 0, sizeof(dep));
627 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
628 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
629 					retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
630 					IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
631 					if (retval)
632 					{
633 						IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d)  \n", i,retval);
634 					}
635 				}
636 
637 				memset(&dep, 0, sizeof(dep));
638 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
639 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
640 				retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
641 				IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
642 				if (retval)
643 				{
644 					IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d)  \n", i,retval);
645 				}
646 				ipa_rm_tbl[i].rm_set = true;
647 			}
648 			else
649 			{
650 				IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set);
651 			}
652 	   }
653    }
654    return ;
655 }
656 
657 /* for IPACM resource manager dependency usage
658    delete either Tx or Rx ipa_rm_resource_name */
659 
DelRmDepend(ipa_rm_resource_name rm1)660 void IPACM_Config::DelRmDepend(ipa_rm_resource_name rm1)
661 {
662 	int retval = 0;
663 	struct ipa_ioc_rm_dependency dep;
664 
665 	IPACMDBG_H(" Got rm del-depend index : %d \n", rm1);
666 	/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
667 	if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
668 	{
669 		ipa_rm_a2_check-=1;
670 		IPACMDBG_H("Left %d times default RT routing from A2 \n", ipa_rm_a2_check);
671 	}
672 
673 	for(int i=0;i<ipa_max_valid_rm_entry;i++)
674 	{
675 
676 		if(rm1 == ipa_rm_tbl[i].producer_rm1)
677 		{
678 			if(ipa_rm_tbl[i].rm_set == true)
679 			{
680 				IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 and dependency is up \n", i);
681 				ipa_rm_tbl[i].rm_set = false;
682 
683 				/* delete bi-directional dependency*/
684 				if(ipa_rm_tbl[i].rx_bypass_ipa)
685 				{
686 					IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
687 				}
688 				else
689 				{
690 					memset(&dep, 0, sizeof(dep));
691 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
692 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
693 					retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
694 					IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
695 					if (retval)
696 					{
697 						IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
698 					}
699 				}
700 				memset(&dep, 0, sizeof(dep));
701 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
702 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
703 				retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
704 				IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
705 				if (retval)
706 				{
707 					IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
708 				}
709 			}
710 			ipa_rm_tbl[i].producer1_up = false;
711 			ipa_rm_tbl[i].rx_bypass_ipa = false;
712 		}
713 		if(rm1 == ipa_rm_tbl[i].consumer_rm1)
714 		{
715 			/* ipa_rm_a2_check: IPA_RM_RESOURCE_!6_CONS*/
716 			if(ipa_rm_tbl[i].consumer_rm1 == IPA_RM_RESOURCE_Q6_CONS && ipa_rm_a2_check == 1)
717 			{
718 				IPACMDBG_H(" still have %d default RT routing from A2 \n", ipa_rm_a2_check);
719 				continue;
720 			}
721 
722 			if(ipa_rm_tbl[i].rm_set == true)
723 			{
724 				IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 and dependency is up \n", i);
725 				ipa_rm_tbl[i].rm_set = false;
726 				/* delete bi-directional dependency*/
727 				if(ipa_rm_tbl[i].rx_bypass_ipa)
728 				{
729 					IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
730 				}
731 				else
732 				{
733 					memset(&dep, 0, sizeof(dep));
734 					dep.resource_name = ipa_rm_tbl[i].producer_rm1;
735 					dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
736 					retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
737 					IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
738 					if (retval)
739 					{
740 						IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
741 					}
742 				}
743 
744 				memset(&dep, 0, sizeof(dep));
745 				dep.resource_name = ipa_rm_tbl[i].producer_rm2;
746 				dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
747 				retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
748 				IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
749 				if (retval)
750 				{
751 					IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
752 				}
753 			}
754 			ipa_rm_tbl[i].consumer1_up = false;
755 		}
756 	}
757 	return ;
758 }
759 
SetExtProp(ipa_ioc_query_intf_ext_props * prop)760 int IPACM_Config::SetExtProp(ipa_ioc_query_intf_ext_props *prop)
761 {
762 	int i, num;
763 
764 	if(prop == NULL || prop->num_ext_props <= 0)
765 	{
766 		IPACMERR("There is no extended property!\n");
767 		return IPACM_FAILURE;
768 	}
769 
770 	num = prop->num_ext_props;
771 	for(i=0; i<num; i++)
772 	{
773 		if(prop->ext[i].ip == IPA_IP_v4)
774 		{
775 			if(ext_prop_v4.num_ext_props >= MAX_NUM_EXT_PROPS)
776 			{
777 				IPACMERR("IPv4 extended property table is full!\n");
778 				continue;
779 			}
780 			memcpy(&ext_prop_v4.prop[ext_prop_v4.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop));
781 			ext_prop_v4.num_ext_props++;
782 		}
783 		else if(prop->ext[i].ip == IPA_IP_v6)
784 		{
785 			if(ext_prop_v6.num_ext_props >= MAX_NUM_EXT_PROPS)
786 			{
787 				IPACMERR("IPv6 extended property table is full!\n");
788 				continue;
789 			}
790 			memcpy(&ext_prop_v6.prop[ext_prop_v6.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop));
791 			ext_prop_v6.num_ext_props++;
792 		}
793 		else
794 		{
795 			IPACMERR("The IP type is not expected!\n");
796 			return IPACM_FAILURE;
797 		}
798 	}
799 
800 	IPACMDBG_H("Set extended property succeeded.\n");
801 
802 	return IPACM_SUCCESS;
803 }
804 
GetExtProp(ipa_ip_type ip_type)805 ipacm_ext_prop* IPACM_Config::GetExtProp(ipa_ip_type ip_type)
806 {
807 	if(ip_type == IPA_IP_v4)
808 		return &ext_prop_v4;
809 	else if(ip_type == IPA_IP_v6)
810 		return &ext_prop_v6;
811 	else
812 	{
813 		IPACMERR("Failed to get extended property: the IP version is neither IPv4 nor IPv6!\n");
814 		return NULL;
815 	}
816 }
817 
DelExtProp(ipa_ip_type ip_type)818 int IPACM_Config::DelExtProp(ipa_ip_type ip_type)
819 {
820 	if(ip_type != IPA_IP_v6)
821 	{
822 		memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
823 	}
824 
825 	if(ip_type != IPA_IP_v4)
826 	{
827 		memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
828 	}
829 
830 	return IPACM_SUCCESS;
831 }
832 
getEventName(ipa_cm_event_id event_id)833 const char* IPACM_Config::getEventName(ipa_cm_event_id event_id)
834 {
835 	if(event_id >= sizeof(ipacm_event_name)/sizeof(ipacm_event_name[0]))
836 	{
837 		IPACMERR("Event name array is not consistent with event array!\n");
838 		return NULL;
839 	}
840 
841 	return ipacm_event_name[event_id];
842 }
843