Merge "IPACM: Fix AP+STA mode FTP loca-subnet disconnect issue"
diff --git a/ipacm/src/IPACM_Neighbor.cpp b/ipacm/src/IPACM_Neighbor.cpp
index 4e9ae84..d122b92 100644
--- a/ipacm/src/IPACM_Neighbor.cpp
+++ b/ipacm/src/IPACM_Neighbor.cpp
@@ -48,6 +48,7 @@
IPACM_Neighbor::IPACM_Neighbor()
{
num_neighbor_client = 0;
+ IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, this);
IPACM_EvtDispatcher::registr(IPA_NEW_NEIGH_EVENT, this);
IPACM_EvtDispatcher::registr(IPA_DEL_NEIGH_EVENT, this);
return;
@@ -55,7 +56,6 @@
void IPACM_Neighbor::event_callback(ipa_cm_event_id event, void *param)
{
- ipacm_event_data_all *data = (ipacm_event_data_all *)param;
ipacm_event_data_all *data_all = NULL;
int i, ipa_interface_index;
ipacm_cmd_q_data evt_data;
@@ -63,146 +63,40 @@
IPACMDBG("Recieved event %d\n", event);
- ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
-
- if (data->iptype == IPA_IP_v4)
+ switch (event)
{
- if (data->ipv4_addr != 0) /* not 0.0.0.0 */
+ case IPA_WLAN_CLIENT_ADD_EVENT_EX:
{
- IPACMDBG(" Got New_Neighbor event with ipv4 address \n");
- /* check if iface is bridge interface*/
- if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
+ ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param;
+ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
+ uint8_t client_mac_addr[6];
+
+ IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
+ for(i = 0; i < data->num_of_attribs; i++)
{
- /* searh if seen this client or not*/
- for (i = 0; i < num_neighbor_client_temp; i++)
+ if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
{
- if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
- {
- data->if_index = neighbor_client[i].iface_index;
- neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
- /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
- if (event == IPA_NEW_NEIGH_EVENT)
- evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
- else
- evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
-
- data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
- if (data_all == NULL)
- {
- IPACMERR("Unable to allocate memory\n");
- return;
- }
- memcpy(data_all, data, sizeof(ipacm_event_data_all));
- evt_data.evt_data = (void *)data_all;
- IPACM_EvtDispatcher::PostEvt(&evt_data);
-
- /* ask for replaced iface name*/
- ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
- IPACMDBG_H("Posted event %d, with %s for ipv4\n",
- evt_data.event,
- IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
-
- break;
-
- };
+ memcpy(client_mac_addr,
+ data->attribs[i].u.mac_addr,
+ sizeof(client_mac_addr));
+ IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ client_mac_addr[0], client_mac_addr[1], client_mac_addr[2],
+ client_mac_addr[3], client_mac_addr[4], client_mac_addr[5]);
}
- }
- else
- {
- /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
- if (event == IPA_NEW_NEIGH_EVENT)
- evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
else
- evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
-
- data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
- if (data_all == NULL)
{
- IPACMERR("Unable to allocate memory\n");
- return;
- }
- memcpy(data_all, data, sizeof(ipacm_event_data_all));
- evt_data.evt_data = (void *)data_all;
- IPACM_EvtDispatcher::PostEvt(&evt_data);
- IPACMDBG_H("Posted event %d with %s for ipv4\n",
- evt_data.event,
- IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
- }
- }
- }
- else
- { //ipv6 starts
-
- if ((data->ipv6_addr[0]) || (data->ipv6_addr[1]) || (data->ipv6_addr[2]) || (data->ipv6_addr[3]))
- {
- IPACMDBG(" Got New_Neighbor event with ipv6 address \n");
- /* check if iface is bridge interface*/
- if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
- {
- /* searh if seen this client or not*/
- for (i = 0; i < num_neighbor_client_temp; i++)
- {
- if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
- {
- data->if_index = neighbor_client[i].iface_index;
- /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
- if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
- else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
- data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
- if (data_all == NULL)
- {
- IPACMERR("Unable to allocate memory\n");
- return;
- }
- memcpy(data_all, data, sizeof(ipacm_event_data_all));
- evt_data.evt_data = (void *)data_all;
- IPACM_EvtDispatcher::PostEvt(&evt_data);
- /* ask for replaced iface name*/
- ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
- IPACMDBG_H("Posted event %d, with %s for ipv6\n",
- evt_data.event,
- IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
-
- break;
-
- };
+ IPACMDBG_H("The attribute type is not expected!\n");
}
}
- else
- {
- /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
- if (event == IPA_NEW_NEIGH_EVENT)
- evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
- else
- evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
- data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
- if (data_all == NULL)
- {
- IPACMERR("Unable to allocate memory\n");
- return;
- }
- memcpy(data_all, data, sizeof(ipacm_event_data_all));
- evt_data.evt_data = (void *)data_all;
- IPACM_EvtDispatcher::PostEvt(&evt_data);
- IPACMDBG_H("Posted event %d with %s for ipv6\n",
- evt_data.event,
- IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
- }
- }
- else
- {
- IPACMDBG(" Got New_Neighbor event with no ipv6/ipv4 address \n");
- /*no ipv6 in data searh if seen this client or not*/
for (i = 0; i < num_neighbor_client_temp; i++)
{
- /* find the client */
- if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
+ /* find the client */
+ if (memcmp(neighbor_client[i].mac_addr, client_mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
{
/* check if iface is not bridge interface*/
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
{
-
/* use previous ipv4 first */
if(data->if_index != neighbor_client[i].iface_index)
{
@@ -244,43 +138,271 @@
break;
}
}
- /* not find client */
- if (i == num_neighbor_client_temp)
- {
- /* check if iface is not bridge interface*/
- if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
- {
+ }
+ break;
- if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
+ default:
+ {
+ ipacm_event_data_all *data = (ipacm_event_data_all *)param;
+ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
+
+ if (data->iptype == IPA_IP_v4)
+ {
+ if (data->ipv4_addr != 0) /* not 0.0.0.0 */
{
- memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
- data->mac_addr,
- sizeof(data->mac_addr));
- neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
- /* cache the network interface client associated */
- neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
- neighbor_client[num_neighbor_client_temp].v4_addr = 0;
- IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
- neighbor_client[num_neighbor_client_temp].mac_addr[0],
- neighbor_client[num_neighbor_client_temp].mac_addr[1],
- neighbor_client[num_neighbor_client_temp].mac_addr[2],
- neighbor_client[num_neighbor_client_temp].mac_addr[3],
- neighbor_client[num_neighbor_client_temp].mac_addr[4],
- neighbor_client[num_neighbor_client_temp].mac_addr[5],
- num_neighbor_client);
- num_neighbor_client++;
- return;
+ IPACMDBG(" Got New_Neighbor event with ipv4 address \n");
+ /* check if iface is bridge interface*/
+ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
+ {
+ /* searh if seen this client or not*/
+ for (i = 0; i < num_neighbor_client_temp; i++)
+ {
+ if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
+ {
+ data->if_index = neighbor_client[i].iface_index;
+ neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
+ /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
+ if (event == IPA_NEW_NEIGH_EVENT)
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
+ else
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
+
+ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
+ if (data_all == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return;
+ }
+ memcpy(data_all, data, sizeof(ipacm_event_data_all));
+ evt_data.evt_data = (void *)data_all;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+
+ /* ask for replaced iface name*/
+ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
+ IPACMDBG_H("Posted event %d, with %s for ipv4\n",
+ evt_data.event,
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
+ break;
+ };
+ }
+ }
+ else
+ {
+ /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
+ if (event == IPA_NEW_NEIGH_EVENT)
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
+ else
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
+
+ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
+ if (data_all == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return;
+ }
+ memcpy(data_all, data, sizeof(ipacm_event_data_all));
+ evt_data.evt_data = (void *)data_all;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ IPACMDBG_H("Posted event %d with %s for ipv4\n",
+ evt_data.event,
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
+ /* Also save to cache for ipv4 */
+ /*searh if seen this client or not*/
+ for (i = 0; i < num_neighbor_client_temp; i++)
+ {
+ /* find the client */
+ if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
+ {
+ /* update the network interface client associated */
+ neighbor_client[i].iface_index = data->if_index;
+ neighbor_client[i].ipa_if_num = ipa_interface_index;
+ neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
+ IPACMDBG_H("update cache %d-entry, with %s iface, ipv4 address: 0x%x\n",
+ i,
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
+ data->ipv4_addr);
+ break;
+ }
+ }
+ /* not find client */
+ if (i == num_neighbor_client_temp)
+ {
+ if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
+ {
+ memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
+ data->mac_addr,
+ sizeof(data->mac_addr));
+ neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
+ /* cache the network interface client associated */
+ neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
+ neighbor_client[num_neighbor_client_temp].v4_addr = data->ipv4_addr;
+ IPACMDBG_H("Cache wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
+ neighbor_client[num_neighbor_client_temp].mac_addr[0],
+ neighbor_client[num_neighbor_client_temp].mac_addr[1],
+ neighbor_client[num_neighbor_client_temp].mac_addr[2],
+ neighbor_client[num_neighbor_client_temp].mac_addr[3],
+ neighbor_client[num_neighbor_client_temp].mac_addr[4],
+ neighbor_client[num_neighbor_client_temp].mac_addr[5],
+ num_neighbor_client);
+ num_neighbor_client++;
+ return;
+ }
+ else
+ {
+ IPACMERR("error: neighbor client oversize!");
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ { //ipv6 starts
+
+ if ((data->ipv6_addr[0]) || (data->ipv6_addr[1]) || (data->ipv6_addr[2]) || (data->ipv6_addr[3]))
+ {
+ IPACMDBG(" Got New_Neighbor event with ipv6 address \n");
+ /* check if iface is bridge interface*/
+ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
+ {
+ /* searh if seen this client or not*/
+ for (i = 0; i < num_neighbor_client_temp; i++)
+ {
+ if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
+ {
+ data->if_index = neighbor_client[i].iface_index;
+ /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
+ if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
+ else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
+ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
+ if (data_all == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return;
+ }
+ memcpy(data_all, data, sizeof(ipacm_event_data_all));
+ evt_data.evt_data = (void *)data_all;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ /* ask for replaced iface name*/
+ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
+ IPACMDBG_H("Posted event %d, with %s for ipv6\n",
+ evt_data.event,
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
+ break;
+ };
+ }
+ }
+ else
+ {
+ /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
+ if (event == IPA_NEW_NEIGH_EVENT)
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
+ else
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
+ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
+ if (data_all == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return;
+ }
+ memcpy(data_all, data, sizeof(ipacm_event_data_all));
+ evt_data.evt_data = (void *)data_all;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ IPACMDBG_H("Posted event %d with %s for ipv6\n",
+ evt_data.event,
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
+ }
}
else
{
- IPACMERR("error: neighbor client oversize!");
- return;
- }
- }
+ IPACMDBG(" Got New_Neighbor event with no ipv6/ipv4 address \n");
+ /*no ipv6 in data searh if seen this client or not*/
+ for (i = 0; i < num_neighbor_client_temp; i++)
+ {
+ /* find the client */
+ if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
+ {
+ /* check if iface is not bridge interface*/
+ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
+ {
+ /* use previous ipv4 first */
+ if(data->if_index != neighbor_client[i].iface_index)
+ {
+ IPACMERR("update new kernel iface index \n");
+ neighbor_client[i].iface_index = data->if_index;
+ }
- }
+ /* check if client associated with previous network interface */
+ if(ipa_interface_index != neighbor_client[i].ipa_if_num)
+ {
+ IPACMERR("client associate to different AP \n");
+ return;
+ }
+
+ if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
+ {
+ evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
+ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
+ if (data_all == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return;
+ }
+ data_all->iptype = IPA_IP_v4;
+ data_all->if_index = neighbor_client[i].iface_index;
+ data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
+ memcpy(data_all->mac_addr,
+ neighbor_client[i].mac_addr,
+ sizeof(data_all->mac_addr));
+ evt_data.evt_data = (void *)data_all;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ /* ask for replaced iface name*/
+ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
+ IPACMDBG_H("Posted event %d, with %s for ipv4 client re-connect\n",
+ evt_data.event,
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
+ }
+ }
+ break;
+ }
+ }
+ /* not find client */
+ if (i == num_neighbor_client_temp)
+ {
+ /* check if iface is not bridge interface*/
+ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
+ {
+ if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
+ {
+ memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
+ data->mac_addr,
+ sizeof(data->mac_addr));
+ neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
+ /* cache the network interface client associated */
+ neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
+ neighbor_client[num_neighbor_client_temp].v4_addr = 0;
+ IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
+ neighbor_client[num_neighbor_client_temp].mac_addr[0],
+ neighbor_client[num_neighbor_client_temp].mac_addr[1],
+ neighbor_client[num_neighbor_client_temp].mac_addr[2],
+ neighbor_client[num_neighbor_client_temp].mac_addr[3],
+ neighbor_client[num_neighbor_client_temp].mac_addr[4],
+ neighbor_client[num_neighbor_client_temp].mac_addr[5],
+ num_neighbor_client);
+ num_neighbor_client++;
+ return;
+ }
+ else
+ {
+ IPACMERR("error: neighbor client oversize!");
+ return;
+ }
+ }
+ }
+ }
+ } //ipv6 ends
}
- } //ipv6 ends
-
+ break;
+ }
return;
}