aboutsummaryrefslogtreecommitdiff
path: root/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp
diff options
context:
space:
mode:
authorLouis Popi <theh2o64@gmail.com>2016-05-06 10:13:04 +0200
committerdavidevinavil <davidevinavil@gmail.com>2017-01-21 18:19:27 +0100
commit11e7b3c6aa71b15800f7cf989ac71bbd85a68e51 (patch)
tree67eadbdd23c445f3650bd45773800ae5c917e9d8 /data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp
parent5b17622206a2697dfe6e6a31a21e427fc85ab8ee (diff)
z2_plus: Import data-ipa-cfg-mgr from CAF
Change-Id: I6f134eb024b8b5be7ae119005cbc471d583ee8a6
Diffstat (limited to 'data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp')
-rw-r--r--data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp979
1 files changed, 979 insertions, 0 deletions
diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp
new file mode 100644
index 0000000..fa8756e
--- /dev/null
+++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp
@@ -0,0 +1,979 @@
+/*
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*!
+ @file
+ IPACM_Main.cpp
+
+ @brief
+ This file implements the IPAM functionality.
+
+ @Author
+ Skylar Chang
+
+*/
+/******************************************************************************
+
+ IPCM_MAIN.C
+
+******************************************************************************/
+
+#include <sys/socket.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/ioctl.h>
+#include <linux/if.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <fcntl.h>
+#include <sys/inotify.h>
+#include <stdlib.h>
+#include <signal.h>
+#include "linux/ipa_qmi_service_v01.h"
+
+#define __stringify_1(x...) #x
+#define __stringify(x...) __stringify_1(x)
+
+#include "IPACM_CmdQueue.h"
+#include "IPACM_EvtDispatcher.h"
+#include "IPACM_Defs.h"
+#include "IPACM_Neighbor.h"
+#include "IPACM_IfaceManager.h"
+#include "IPACM_Log.h"
+
+#include "IPACM_ConntrackListener.h"
+#include "IPACM_ConntrackClient.h"
+#include "IPACM_Netlink.h"
+
+/* not defined(FEATURE_IPA_ANDROID)*/
+#ifndef FEATURE_IPA_ANDROID
+#include "IPACM_LanToLan.h"
+#endif
+
+
+const char *ipacm_event_name[] = {
+ __stringify(IPA_CFG_CHANGE_EVENT), /* 1 NULL */
+ __stringify(IPA_LINK_UP_EVENT), /* 2 ipacm_event_data_fid */
+ __stringify(IPA_LINK_DOWN_EVENT), /* 3 ipacm_event_data_fid */
+ __stringify(IPA_ADDR_ADD_EVENT), /* 4 ipacm_event_data_addr */
+ __stringify(IPA_ADDR_DEL_EVENT), /* 5 no use */
+ __stringify(IPA_ROUTE_ADD_EVENT), /* 6 ipacm_event_data_addr */
+ __stringify(IPA_ROUTE_DEL_EVENT), /* 7 ipacm_event_data_addr */
+ __stringify(IPA_FIREWALL_CHANGE_EVENT), /* 8 NULL */
+ __stringify(IPA_WLAN_AP_LINK_UP_EVENT), /* 9 ipacm_event_data_mac */
+ __stringify(IPA_WLAN_STA_LINK_UP_EVENT), /* 10 ipacm_event_data_mac */
+ __stringify(IPA_WLAN_CLIENT_ADD_EVENT), /* 11 ipacm_event_data_mac */
+ __stringify(IPA_WLAN_CLIENT_DEL_EVENT), /* 12 ipacm_event_data_mac */
+ __stringify(IPA_WLAN_CLIENT_POWER_SAVE_EVENT), /* 13 ipacm_event_data_mac */
+ __stringify(IPA_WLAN_CLIENT_RECOVER_EVENT), /* 14 ipacm_event_data_mac */
+ __stringify(IPA_NEW_NEIGH_EVENT), /* 15 ipacm_event_data_all */
+ __stringify(IPA_DEL_NEIGH_EVENT), /* 16 ipacm_event_data_all */
+ __stringify(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT), /* 17 ipacm_event_data_all */
+ __stringify(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT), /* 18 ipacm_event_data_all */
+ __stringify(IPA_SW_ROUTING_ENABLE), /* 19 NULL */
+ __stringify(IPA_SW_ROUTING_DISABLE), /* 20 NULL */
+ __stringify(IPA_PROCESS_CT_MESSAGE), /* 21 ipacm_ct_evt_data */
+ __stringify(IPA_HANDLE_WAN_UP), /* 22 ipacm_event_iface_up */
+ __stringify(IPA_HANDLE_WAN_DOWN), /* 23 ipacm_event_iface_up */
+ __stringify(IPA_HANDLE_WLAN_UP), /* 24 ipacm_event_iface_up */
+ __stringify(IPA_HANDLE_LAN_UP), /* 25 ipacm_event_iface_up */
+ __stringify(IPA_WLAN_CLIENT_ADD_EVENT_EX), /* 26 ipacm_event_data_wlan_ex */
+ __stringify(IPA_HANDLE_WAN_UP_V6), /* 27 NULL */
+ __stringify(IPA_HANDLE_WAN_DOWN_V6), /* 28 NULL */
+ __stringify(IPA_LAN_CLIENT_ACTIVE), /* 29 ipacm_event_lan_client*/
+ __stringify(IPA_LAN_CLIENT_INACTIVE), /* 30 ipacm_event_lan_client*/
+ __stringify(IPA_LAN_CLIENT_DISCONNECT), /* 31 ipacm_event_lan_client*/
+ __stringify(IPA_LAN_CLIENT_POWER_SAVE), /* 32 ipacm_event_lan_client*/
+ __stringify(IPA_LAN_CLIENT_POWER_RECOVER), /* 33 ipacm_event_lan_client*/
+ __stringify(IPA_LAN_TO_LAN_NEW_CONNECTION), /* 34 ipacm_event_connection */
+ __stringify(IPA_LAN_TO_LAN_DEL_CONNECTION), /* 35 ipacm_event_connection */
+ __stringify(IPA_LAN_DELETE_SELF), /* 36 ipacm_event_data_fid */
+ __stringify(IPA_WLAN_LINK_DOWN_EVENT), /* 37 ipacm_event_data_mac */
+ __stringify(IPA_USB_LINK_UP_EVENT), /* 38 ipacm_event_data_fid */
+ __stringify(IPA_PROCESS_CT_MESSAGE_V6), /* 39 ipacm_ct_evt_data */
+ __stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT), /* 40 ipacm_event_data_fid */
+ __stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT), /* 41 ipacm_event_data_fid */
+ __stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT), /* 42 ipacm_event_data_fid */
+ __stringify(IPA_WAN_XLAT_CONNECT_EVENT), /* 43 ipacm_event_data_fid */
+};
+
+#define IPA_DRIVER "/dev/ipa"
+
+#define IPACM_FIREWALL_FILE_NAME "mobileap_firewall.xml"
+#define IPACM_CFG_FILE_NAME "IPACM_cfg.xml"
+#ifdef FEATURE_IPA_ANDROID
+#define IPACM_PID_FILE "/data/misc/ipa/ipacm.pid"
+#define IPACM_DIR_NAME "/data"
+#else/* defined(FEATURE_IPA_ANDROID) */
+#define IPACM_PID_FILE "/etc/ipacm.pid"
+#define IPACM_DIR_NAME "/etc"
+#endif /* defined(NOT FEATURE_IPA_ANDROID)*/
+#define IPACM_NAME "ipacm"
+
+#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
+#define INOTIFY_BUF_LEN (INOTIFY_EVENT_SIZE + 2*sizeof(IPACM_FIREWALL_FILE_NAME))
+
+#define IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS 3
+#define IPA_DRIVER_WLAN_EVENT_SIZE (sizeof(struct ipa_wlan_msg_ex)+ IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS*sizeof(ipa_wlan_hdr_attrib_val))
+#define IPA_DRIVER_PIPE_STATS_EVENT_SIZE (sizeof(struct ipa_get_data_stats_resp_msg_v01))
+#define IPA_DRIVER_WLAN_META_MSG (sizeof(struct ipa_msg_meta))
+#define IPA_DRIVER_WLAN_BUF_LEN (IPA_DRIVER_PIPE_STATS_EVENT_SIZE + IPA_DRIVER_WLAN_META_MSG)
+
+uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
+bool ipacm_logging = true;
+
+void ipa_is_ipacm_running(void);
+int ipa_get_if_index(char *if_name, int *if_index);
+
+/* start netlink socket monitor*/
+void* netlink_start(void *param)
+{
+ ipa_nl_sk_fd_set_info_t sk_fdset;
+ int ret_val = 0;
+ memset(&sk_fdset, 0, sizeof(ipa_nl_sk_fd_set_info_t));
+ IPACMDBG_H("netlink starter memset sk_fdset succeeds\n");
+ ret_val = ipa_nl_listener_init(NETLINK_ROUTE, (RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK |
+ RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH |
+ RTNLGRP_IPV6_PREFIX),
+ &sk_fdset, ipa_nl_recv_msg);
+
+ if (ret_val != IPACM_SUCCESS)
+ {
+ IPACMERR("Failed to initialize IPA netlink event listener\n");
+ return NULL;
+ }
+
+ return NULL;
+}
+
+/* start firewall-rule monitor*/
+void* firewall_monitor(void *param)
+{
+ int length;
+ int wd;
+ char buffer[INOTIFY_BUF_LEN];
+ int inotify_fd;
+ ipacm_cmd_q_data evt_data;
+ uint32_t mask = IN_MODIFY | IN_MOVE;
+
+ inotify_fd = inotify_init();
+ if (inotify_fd < 0)
+ {
+ PERROR("inotify_init");
+ }
+
+ IPACMDBG_H("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_DIR_NAME, mask);
+
+ wd = inotify_add_watch(inotify_fd,
+ IPACM_DIR_NAME,
+ mask);
+
+ while (1)
+ {
+ length = read(inotify_fd, buffer, INOTIFY_BUF_LEN);
+ if (length < 0)
+ {
+ IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask);
+ continue;
+ }
+
+ struct inotify_event* event;
+ event = (struct inotify_event*)malloc(length);
+ if(event == NULL)
+ {
+ IPACMERR("Failed to allocate memory.\n");
+ return NULL;
+ }
+ memset(event, 0, length);
+ memcpy(event, buffer, length);
+
+ if (event->len > 0)
+ {
+ if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE))
+ {
+ if (event->mask & IN_ISDIR)
+ {
+ IPACMDBG_H("The directory %s was 0x%x\n", event->name, event->mask);
+ }
+ else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change
+ {
+ IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
+ IPACMDBG_H("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME);
+
+ evt_data.event = IPA_FIREWALL_CHANGE_EVENT;
+ evt_data.evt_data = NULL;
+
+ /* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ }
+ else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change
+ {
+ IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
+ IPACMDBG_H("The interested file %s .\n", IPACM_CFG_FILE_NAME);
+
+ evt_data.event = IPA_CFG_CHANGE_EVENT;
+ evt_data.evt_data = NULL;
+
+ /* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ }
+ }
+ IPACMDBG_H("Received monitoring event %s.\n", event->name);
+ }
+ free(event);
+ }
+
+ (void)inotify_rm_watch(inotify_fd, wd);
+ (void)close(inotify_fd);
+ return NULL;
+}
+
+
+/* start IPACM wan-driver notifier */
+void* ipa_driver_msg_notifier(void *param)
+{
+ int length, fd, cnt;
+ char buffer[IPA_DRIVER_WLAN_BUF_LEN];
+ struct ipa_msg_meta event_hdr;
+ struct ipa_ecm_msg event_ecm;
+ struct ipa_wan_msg event_wan;
+ struct ipa_wlan_msg_ex event_ex_o;
+ struct ipa_wlan_msg *event_wlan=NULL;
+ struct ipa_wlan_msg_ex *event_ex= NULL;
+ struct ipa_get_data_stats_resp_msg_v01 event_data_stats;
+ struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats;
+
+ ipacm_cmd_q_data evt_data;
+ ipacm_event_data_mac *data = NULL;
+ ipacm_event_data_fid *data_fid = NULL;
+ ipacm_event_data_iptype *data_iptype = NULL;
+ ipacm_event_data_wlan_ex *data_ex;
+ ipa_get_data_stats_resp_msg_v01 *data_tethering_stats = NULL;
+ ipa_get_apn_data_stats_resp_msg_v01 *data_network_stats = NULL;
+
+ ipacm_cmd_q_data new_neigh_evt;
+ ipacm_event_data_all* new_neigh_data;
+
+ fd = open(IPA_DRIVER, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DRIVER);
+ return NULL;
+ }
+
+ while (1)
+ {
+ IPACMDBG_H("Waiting for nofications from IPA driver \n");
+ memset(buffer, 0, sizeof(buffer));
+ memset(&evt_data, 0, sizeof(evt_data));
+ memset(&new_neigh_evt, 0, sizeof(ipacm_cmd_q_data));
+ new_neigh_data = NULL;
+ data = NULL;
+ data_fid = NULL;
+ data_tethering_stats = NULL;
+ data_network_stats = NULL;
+
+ length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN);
+ if (length < 0)
+ {
+ PERROR("didn't read IPA_driver correctly");
+ continue;
+ }
+
+ memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Message type: %d\n", event_hdr.msg_type);
+ IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len);
+
+ /* Insert WLAN_DRIVER_EVENT to command queue */
+ switch (event_hdr.msg_type)
+ {
+
+ case SW_ROUTING_ENABLE:
+ IPACMDBG_H("Received SW_ROUTING_ENABLE\n");
+ evt_data.event = IPA_SW_ROUTING_ENABLE;
+ IPACMDBG_H("Not supported anymore\n");
+ continue;
+
+ case SW_ROUTING_DISABLE:
+ IPACMDBG_H("Received SW_ROUTING_DISABLE\n");
+ evt_data.event = IPA_SW_ROUTING_DISABLE;
+ IPACMDBG_H("Not supported anymore\n");
+ continue;
+
+ case WLAN_AP_CONNECT:
+ event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name);
+ IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data_fid\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
+ evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
+ evt_data.evt_data = data_fid;
+ break;
+
+ case WLAN_AP_DISCONNECT:
+ event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name);
+ IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data_fid\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
+ evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
+ evt_data.evt_data = data_fid;
+ break;
+ case WLAN_STA_CONNECT:
+ event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name);
+ IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
+ if(data == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data_fid\n");
+ return NULL;
+ }
+ memcpy(data->mac_addr,
+ event_wlan->mac_addr,
+ sizeof(event_wlan->mac_addr));
+ ipa_get_if_index(event_wlan->name, &(data->if_index));
+ evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
+ evt_data.evt_data = data;
+ break;
+
+ case WLAN_STA_DISCONNECT:
+ event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name);
+ IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data_fid\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
+ evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
+ evt_data.evt_data = data_fid;
+ break;
+
+ case WLAN_CLIENT_CONNECT:
+ event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n");
+ IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
+ if (data == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data\n");
+ return NULL;
+ }
+ memcpy(data->mac_addr,
+ event_wlan->mac_addr,
+ sizeof(event_wlan->mac_addr));
+ ipa_get_if_index(event_wlan->name, &(data->if_index));
+ evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT;
+ evt_data.evt_data = data;
+ break;
+
+ case WLAN_CLIENT_CONNECT_EX:
+ IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n");
+
+ memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex));
+ if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS)
+ {
+ IPACMERR("buffer size overflow\n");
+ return NULL;
+ }
+ length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val);
+ IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length);
+ event_ex = (ipa_wlan_msg_ex *)malloc(length);
+ if(event_ex == NULL )
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return NULL;
+ }
+ memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
+ data_ex = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipacm_event_data_wlan_ex) + event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
+ if (data_ex == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data\n");
+ return NULL;
+ }
+ data_ex->num_of_attribs = event_ex->num_of_attribs;
+
+ memcpy(data_ex->attribs,
+ event_ex->attribs,
+ event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
+
+ ipa_get_if_index(event_ex->name, &(data_ex->if_index));
+ evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX;
+ evt_data.evt_data = data_ex;
+
+ /* Construct new_neighbor msg with netdev device internally */
+ new_neigh_data = (ipacm_event_data_all*)malloc(sizeof(ipacm_event_data_all));
+ if(new_neigh_data == NULL)
+ {
+ IPACMERR("Failed to allocate memory.\n");
+ return NULL;
+ }
+ memset(new_neigh_data, 0, sizeof(ipacm_event_data_all));
+ new_neigh_data->iptype = IPA_IP_v6;
+ for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++)
+ {
+ if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
+ {
+ memcpy(new_neigh_data->mac_addr, event_ex->attribs[cnt].u.mac_addr, sizeof(new_neigh_data->mac_addr));
+ IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2],
+ event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]);
+ }
+ else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
+ {
+ IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id);
+ }
+ else
+ {
+ IPACMDBG_H("Wlan message has unexpected type!\n");
+ }
+ }
+ new_neigh_data->if_index = data_ex->if_index;
+ new_neigh_evt.evt_data = (void*)new_neigh_data;
+ new_neigh_evt.event = IPA_NEW_NEIGH_EVENT;
+ free(event_ex);
+ break;
+
+ case WLAN_CLIENT_DISCONNECT:
+ IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n");
+ event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
+ if (data == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data\n");
+ return NULL;
+ }
+ memcpy(data->mac_addr,
+ event_wlan->mac_addr,
+ sizeof(event_wlan->mac_addr));
+ ipa_get_if_index(event_wlan->name, &(data->if_index));
+ evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT;
+ evt_data.evt_data = data;
+ break;
+
+ case WLAN_CLIENT_POWER_SAVE_MODE:
+ IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n");
+ event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
+ if (data == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data\n");
+ return NULL;
+ }
+ memcpy(data->mac_addr,
+ event_wlan->mac_addr,
+ sizeof(event_wlan->mac_addr));
+ ipa_get_if_index(event_wlan->name, &(data->if_index));
+ evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT;
+ evt_data.evt_data = data;
+ break;
+
+ case WLAN_CLIENT_NORMAL_MODE:
+ IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n");
+ event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
+ event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
+ data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
+ if (data == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_wlan data\n");
+ return NULL;
+ }
+ memcpy(data->mac_addr,
+ event_wlan->mac_addr,
+ sizeof(event_wlan->mac_addr));
+ ipa_get_if_index(event_wlan->name, &(data->if_index));
+ evt_data.evt_data = data;
+ evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT;
+ break;
+
+ case ECM_CONNECT:
+ memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
+ IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_ecm data_fid\n");
+ return NULL;
+ }
+ data_fid->if_index = event_ecm.ifindex;
+ evt_data.event = IPA_USB_LINK_UP_EVENT;
+ evt_data.evt_data = data_fid;
+ break;
+
+ case ECM_DISCONNECT:
+ memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
+ IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name);
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_ecm data_fid\n");
+ return NULL;
+ }
+ data_fid->if_index = event_ecm.ifindex;
+ evt_data.event = IPA_LINK_DOWN_EVENT;
+ evt_data.evt_data = data_fid;
+ break;
+ /* Add for 8994 Android case */
+ case WAN_UPSTREAM_ROUTE_ADD:
+ memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
+ IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
+ data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
+ if(data_iptype == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
+ ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
+ data_iptype->iptype = event_wan.ip;
+ IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
+ data_iptype->if_index_tether, data_iptype->iptype);
+ evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
+ evt_data.evt_data = data_iptype;
+ break;
+ case WAN_UPSTREAM_ROUTE_DEL:
+ memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
+ IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
+ data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
+ if(data_iptype == NULL)
+ {
+ IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
+ ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
+ data_iptype->iptype = event_wan.ip;
+ IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
+ evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
+ evt_data.evt_data = data_iptype;
+ break;
+ /* End of adding for 8994 Android case */
+
+ /* Add for embms case */
+ case WAN_EMBMS_CONNECT:
+ memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
+ IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data_fid\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
+ evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
+ evt_data.evt_data = data_fid;
+ break;
+
+ case WLAN_SWITCH_TO_SCC:
+ IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
+ case WLAN_WDI_ENABLE:
+ IPACMDBG_H("Received WLAN_WDI_ENABLE\n");
+ if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
+ {
+ IPACM_Iface::ipacmcfg->isMCC_Mode = false;
+ evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
+ break;
+ }
+ continue;
+ case WLAN_SWITCH_TO_MCC:
+ IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
+ case WLAN_WDI_DISABLE:
+ IPACMDBG_H("Received WLAN_WDI_DISABLE\n");
+ if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
+ {
+ IPACM_Iface::ipacmcfg->isMCC_Mode = true;
+ evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
+ break;
+ }
+ continue;
+
+ case WAN_XLAT_CONNECT:
+ memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
+ sizeof(struct ipa_wan_msg));
+ IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
+ event_wan.upstream_ifname);
+
+ /* post IPA_LINK_UP_EVENT event
+ * may be WAN interface is not up
+ */
+ data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for xlat event\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
+ evt_data.event = IPA_LINK_UP_EVENT;
+ evt_data.evt_data = data_fid;
+ IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+
+ /* post IPA_WAN_XLAT_CONNECT_EVENT event */
+ memset(&evt_data, 0, sizeof(evt_data));
+ data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for xlat event\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
+ evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
+ evt_data.evt_data = data_fid;
+ IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
+ break;
+
+ case IPA_TETHERING_STATS_UPDATE_STATS:
+ memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01));
+ data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01));
+ if(data_tethering_stats == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data_tethering_stats\n");
+ return NULL;
+ }
+ memcpy(data_tethering_stats,
+ &event_data_stats,
+ sizeof(struct ipa_get_data_stats_resp_msg_v01));
+ IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type);
+ IPACMDBG("Received %d UL, %d DL pipe stats\n",data_tethering_stats->ul_src_pipe_stats_list_len, data_tethering_stats->dl_dst_pipe_stats_list_len);
+ evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT;
+ evt_data.evt_data = data_tethering_stats;
+ break;
+
+ case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS:
+ memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
+ data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01));
+ if(data_network_stats == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data_network_stats\n");
+ return NULL;
+ }
+ memcpy(data_network_stats,
+ &event_network_stats,
+ sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
+ IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len);
+ evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT;
+ evt_data.evt_data = data_network_stats;
+ break;
+
+ default:
+ IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
+ continue;
+
+ }
+ /* finish command queue */
+ IPACMDBG_H("Posting event:%d\n", evt_data.event);
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ /* push new_neighbor with netdev device internally */
+ if(new_neigh_data != NULL)
+ {
+ IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
+ IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
+ }
+ }
+
+ (void)close(fd);
+ return NULL;
+}
+
+void IPACM_Sig_Handler(int sig)
+{
+ int cnt;
+ ipacm_cmd_q_data evt_data;
+
+ printf("Received Signal: %d\n", sig);
+ memset(&evt_data, 0, sizeof(evt_data));
+
+ switch(sig)
+ {
+ case SIGUSR1:
+ IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
+ evt_data.event = IPA_SW_ROUTING_ENABLE;
+ IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
+ break;
+
+ case SIGUSR2:
+ IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
+ evt_data.event = IPA_SW_ROUTING_DISABLE;
+ IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
+ break;
+ }
+ /* finish command queue */
+ IPACMDBG_H("Posting event:%d\n", evt_data.event);
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ return;
+}
+
+void RegisterForSignals(void)
+{
+
+ signal(SIGUSR1, IPACM_Sig_Handler);
+ signal(SIGUSR2, IPACM_Sig_Handler);
+}
+
+
+int main(int argc, char **argv)
+{
+ int ret;
+ pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
+ pthread_t cmd_queue_thread = 0;
+
+ /* check if ipacm is already running or not */
+ ipa_is_ipacm_running();
+
+ IPACMDBG_H("In main()\n");
+ IPACM_Neighbor *neigh = new IPACM_Neighbor();
+ IPACM_IfaceManager *ifacemgr = new IPACM_IfaceManager();
+#ifndef FEATURE_ETH_BRIDGE_LE
+#ifndef FEATURE_IPA_ANDROID
+ IPACM_LanToLan* lan2lan = new IPACM_LanToLan();
+#endif /* defined(FEATURE_IPA_ANDROID)*/
+#endif
+ IPACM_ConntrackClient *cc = IPACM_ConntrackClient::GetInstance();
+ CtList = new IPACM_ConntrackListener();
+
+ IPACMDBG_H("Staring IPA main\n");
+ IPACMDBG_H("ipa_cmdq_successful\n");
+
+
+ RegisterForSignals();
+
+ if (IPACM_SUCCESS == cmd_queue_thread)
+ {
+ ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
+ if (IPACM_SUCCESS != ret)
+ {
+ IPACMERR("unable to command queue thread\n");
+ return ret;
+ }
+ IPACMDBG_H("created command queue thread\n");
+ if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
+ {
+ IPACMERR("unable to set thread name\n");
+ }
+ }
+
+ if (IPACM_SUCCESS == netlink_thread)
+ {
+ ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
+ if (IPACM_SUCCESS != ret)
+ {
+ IPACMERR("unable to create netlink thread\n");
+ return ret;
+ }
+ IPACMDBG_H("created netlink thread\n");
+ if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
+ {
+ IPACMERR("unable to set thread name\n");
+ }
+ }
+
+ /* Enable Firewall support only on MDM targets */
+#ifndef FEATURE_IPA_ANDROID
+ if (IPACM_SUCCESS == monitor_thread)
+ {
+ ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
+ if (IPACM_SUCCESS != ret)
+ {
+ IPACMERR("unable to create monitor thread\n");
+ return ret;
+ }
+ IPACMDBG_H("created firewall monitor thread\n");
+ if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
+ {
+ IPACMERR("unable to set thread name\n");
+ }
+ }
+#endif
+
+ if (IPACM_SUCCESS == ipa_driver_thread)
+ {
+ ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
+ if (IPACM_SUCCESS != ret)
+ {
+ IPACMERR("unable to create ipa_driver_wlan thread\n");
+ return ret;
+ }
+ IPACMDBG_H("created ipa_driver_wlan thread\n");
+ if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
+ {
+ IPACMERR("unable to set thread name\n");
+ }
+ }
+
+ pthread_join(cmd_queue_thread, NULL);
+ pthread_join(netlink_thread, NULL);
+ pthread_join(monitor_thread, NULL);
+ pthread_join(ipa_driver_thread, NULL);
+ return IPACM_SUCCESS;
+}
+
+/*===========================================================================
+ FUNCTION ipa_is_ipacm_running
+===========================================================================*/
+/*!
+@brief
+ Determine whether there's already an IPACM process running, if so, terminate
+ the current one
+
+@return
+ None
+
+@note
+
+- Dependencies
+ - None
+
+- Side Effects
+ - None
+*/
+/*=========================================================================*/
+
+void ipa_is_ipacm_running(void) {
+
+ int fd;
+ struct flock lock;
+ int retval;
+
+ fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
+ if ( fd <= 0 )
+ {
+ IPACMERR("Failed to open %s, error is %d - %s\n",
+ IPACM_PID_FILE, errno, strerror(errno));
+ exit(0);
+ }
+
+ /*
+ * Getting an exclusive Write lock on the file, if it fails,
+ * it means that another instance of IPACM is running and it
+ * got the lock before us.
+ */
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ retval = fcntl(fd, F_SETLK, &lock);
+
+ if (retval != 0)
+ {
+ retval = fcntl(fd, F_GETLK, &lock);
+ if (retval == 0)
+ {
+ IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
+ IPACM_PID_FILE, getpid(), lock.l_pid);
+ close(fd);
+ exit(0);
+ }
+ }
+ else
+ {
+ IPACMERR("PID %d is IPACM main process\n", getpid());
+ }
+
+ return;
+}
+
+/*===========================================================================
+ FUNCTION ipa_get_if_index
+===========================================================================*/
+/*!
+@brief
+ get ipa interface index by given the interface name
+
+@return
+ IPACM_SUCCESS or IPA_FALUIRE
+
+@note
+
+- Dependencies
+ - None
+
+- Side Effects
+ - None
+*/
+/*=========================================================================*/
+int ipa_get_if_index
+(
+ char *if_name,
+ int *if_index
+ )
+{
+ int fd;
+ struct ifreq ifr;
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ PERROR("get interface index socket create failed");
+ return IPACM_FAILURE;
+ }
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+
+ (void)strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
+
+ if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
+ {
+ IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
+ *if_index = -1;
+ close(fd);
+ return IPACM_FAILURE;
+ }
+
+ *if_index = ifr.ifr_ifindex;
+ close(fd);
+ return IPACM_SUCCESS;
+}