Home | History | Annotate | Download | only in src
      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_EvtDispatcher.cpp
     32 
     33 	@brief
     34 	This file implements the IPAM event dispatcher functionality
     35 
     36 	@Author
     37 
     38 */
     39 #include <string.h>
     40 #include <pthread.h>
     41 #include <IPACM_EvtDispatcher.h>
     42 #include <IPACM_Neighbor.h>
     43 #include "IPACM_CmdQueue.h"
     44 #include "IPACM_Defs.h"
     45 
     46 
     47 extern pthread_mutex_t mutex;
     48 extern pthread_cond_t  cond_var;
     49 
     50 cmd_evts *IPACM_EvtDispatcher::head = NULL;
     51 extern uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
     52 
     53 int IPACM_EvtDispatcher::PostEvt
     54 (
     55 	 ipacm_cmd_q_data *data
     56 )
     57 {
     58 	Message *item = NULL;
     59 	MessageQueue *MsgQueue = NULL;
     60 
     61 	if(data->event < IPA_EXTERNAL_EVENT_MAX)
     62 	{
     63 		IPACMDBG("Insert event into external queue.\n");
     64 		MsgQueue = MessageQueue::getInstanceExternal();
     65 	}
     66 	else
     67 	{
     68 		IPACMDBG("Insert event into internal queue.\n");
     69 		MsgQueue = MessageQueue::getInstanceInternal();
     70 	}
     71 	if(MsgQueue == NULL)
     72 	{
     73 		IPACMERR("unable to retrieve MsgQueue instance\n");
     74 		return IPACM_FAILURE;
     75 	}
     76 
     77 	item = new Message();
     78 	if(item == NULL)
     79 	{
     80 		IPACMERR("unable to create new message item\n");
     81 		return IPACM_FAILURE;
     82 	}
     83 
     84 	item->evt.callback_ptr = IPACM_EvtDispatcher::ProcessEvt;
     85 	memcpy(&item->evt.data, data, sizeof(ipacm_cmd_q_data));
     86 
     87 	if(pthread_mutex_lock(&mutex) != 0)
     88 	{
     89 		IPACMERR("unable to lock the mutex\n");
     90 		return IPACM_FAILURE;
     91 	}
     92 
     93 	IPACMDBG("Enqueing item\n");
     94 	MsgQueue->enqueue(item);
     95 	IPACMDBG("Enqueued item %p\n", item);
     96 
     97 	if(pthread_cond_signal(&cond_var) != 0)
     98 	{
     99 		IPACMDBG("unable to lock the mutex\n");
    100 		/* Release the mutex before you return failure */
    101 		if(pthread_mutex_unlock(&mutex) != 0)
    102 		{
    103 			IPACMERR("unable to unlock the mutex\n");
    104 			return IPACM_FAILURE;
    105 		}
    106 		return IPACM_FAILURE;
    107 	}
    108 
    109 	if(pthread_mutex_unlock(&mutex) != 0)
    110 	{
    111 		IPACMERR("unable to unlock the mutex\n");
    112 		return IPACM_FAILURE;
    113 	}
    114 
    115 	return IPACM_SUCCESS;
    116 }
    117 
    118 void IPACM_EvtDispatcher::ProcessEvt(ipacm_cmd_q_data *data)
    119 {
    120 
    121 	cmd_evts *tmp = head, tmp1;
    122 
    123 	if(head == NULL)
    124 	{
    125 		IPACMDBG("Queue is empty\n");
    126 	}
    127 
    128 	while(tmp != NULL)
    129 	{
    130 	        memcpy(&tmp1, tmp, sizeof(tmp1));
    131 		if(data->event == tmp1.event)
    132 		{
    133 			ipacm_event_stats[data->event]++;
    134 			tmp1.obj->event_callback(data->event, data->evt_data);
    135 			IPACMDBG(" Find matched registered events\n");
    136 		}
    137 	        tmp = tmp1.next;
    138 	}
    139 
    140 	IPACMDBG(" Finished process events\n");
    141 
    142 	if(data->evt_data != NULL)
    143 	{
    144 		IPACMDBG("free the event:%d data: %p\n", data->event, data->evt_data);
    145 		free(data->evt_data);
    146 	}
    147 	return;
    148 }
    149 
    150 int IPACM_EvtDispatcher::registr(ipa_cm_event_id event, IPACM_Listener *obj)
    151 {
    152 	cmd_evts *tmp = head,*nw;
    153 
    154 	nw = (cmd_evts *)malloc(sizeof(cmd_evts));
    155 	if(nw != NULL)
    156 	{
    157 		nw->event = event;
    158 		nw->obj = obj;
    159 		nw->next = NULL;
    160 	}
    161 	else
    162 	{
    163 		return IPACM_FAILURE;
    164 	}
    165 
    166 	if(head == NULL)
    167 	{
    168 		head = nw;
    169 	}
    170 	else
    171 	{
    172 		while(tmp->next)
    173 		{
    174 			tmp = tmp->next;
    175 		}
    176 		tmp->next = nw;
    177 	}
    178 	return IPACM_SUCCESS;
    179 }
    180 
    181 
    182 int IPACM_EvtDispatcher::deregistr(IPACM_Listener *param)
    183 {
    184 	cmd_evts *tmp = head,*tmp1,*prev = head;
    185 
    186 	while(tmp != NULL)
    187 	{
    188 		if(tmp->obj == param)
    189 		{
    190 			tmp1 = tmp;
    191 			if(tmp == head)
    192 			{
    193 				head = head->next;
    194 			}
    195 			else if(tmp->next == NULL)
    196 			{
    197 				prev->next = NULL;
    198 			}
    199 			else
    200 			{
    201 				prev->next = tmp->next;
    202 			}
    203 
    204 			tmp = tmp->next;
    205 			free(tmp1);
    206 		}
    207 		else
    208 		{
    209 			prev = tmp;
    210 			tmp = tmp->next;
    211 		}
    212 	}
    213 	return IPACM_SUCCESS;
    214 }
    215