/*
* EvHandler.c
*
* Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
* 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 Texas Instruments 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE 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.
*/
#define __FILE_ID__ FILE_ID_50
#include "IPCKernelApi.h"
#include "EvHandler.h"
#include "osApi.h"
#include "osDebug.h"
#ifndef _WINDOWS
#include "windows_types.h"
#else
#include <windows.h>
#endif /*_WINDOWS*/
#ifdef EV_HANDLER_DEBUG
TI_HANDLE ghEvHandler; /* for debug, remove later*/
#endif
/* ************************** Upper Interface **********************************/
TI_HANDLE EvHandler_Create (TI_HANDLE hOs)
{
TEvHandlerObj *pEvHandler;
PRINT(DBG_INIT_LOUD, (" EvHandlerInit\n"));
pEvHandler = os_memoryAlloc(hOs,sizeof(TEvHandlerObj));
if(NULL == pEvHandler)
{
PRINT(DBG_INIT_LOUD, ("EvHandler_Create() - Allocation failed! Returning NULL.\n"));
return NULL;
}
os_memoryZero(hOs,pEvHandler,sizeof(TEvHandlerObj));
#ifdef EV_HANDLER_DEBUG
ghEvHandler= pEvHandler;
PRINTF(DBG_INIT_VERY_LOUD, ("EvHandlerInit: ghEvHandler set to %08X\n", ghEvHandler));
#endif
pEvHandler->hOs = hOs;
pEvHandler->LastUMEventType = 0xFFFFFFFF;
return (TI_HANDLE) pEvHandler;
}
TI_UINT32 EvHandlerUnload (TI_HANDLE hEvHandler)
{
TEvHandlerObj *pEvHandler;
PRINT(DBG_INIT_LOUD, (" ev_handler_unLoad\n"));
pEvHandler = (TEvHandlerObj *)hEvHandler;
os_memoryFree(pEvHandler->hOs,pEvHandler,sizeof(TEvHandlerObj));
return TI_OK;
}
TI_UINT32 EvHandlerRegisterEvent(TI_HANDLE hEvHandler, TI_UINT8* pData, TI_UINT32 Length)
{
TEvHandlerObj *pEvHandler;
IPC_EVENT_PARAMS *pEvParams;
TI_UINT32 ModuleIndex;
if( (hEvHandler==NULL) || (pData == NULL)){
PRINT(DBG_INIT_ERROR, "EvHandler:EvHandlerRegisterEvent Bad Handle passed \n");
return TI_NOK;
}
#ifdef EV_HANDLER_DEBUG
if (ghEvHandler != hEvHandler)
{
return TI_NOK;
}
#endif
pEvHandler = (TEvHandlerObj *)hEvHandler;
pEvParams = (IPC_EVENT_PARAMS *)pData;
PRINTF(DBG_INIT_LOUD, (" EvHandlerRegisterEvent EventType = %d \n",pEvParams->uEventType));
/* used to be: if ( sizeof(IPC_EVENT_PARAMS) != Length)
relaxed size checking (okay if output buffer is larger) */
if (sizeof(IPC_EVENT_PARAMS) > Length)
{
PRINTF(DBG_INIT_ERROR, (" EvHandlerRegisterEvent Error sizeof(IPC_EVENT_PARAMS) != Length,"
"%d != %d \n",sizeof(IPC_EVENT_PARAMS), (int)Length));
return (TI_UINT32)STATUS_INVALID_PARAMETER;
}
if (pEvParams->uEventType >= IPC_EVENT_MAX){
PRINTF(DBG_INIT_ERROR, (" EvHandlerRegisterEvent Error - Invalid Event Type = %d \n",
pEvParams->uEventType));
return (TI_UINT32)STATUS_INVALID_PARAMETER;
}
ModuleIndex = 0;
while ((ModuleIndex < MAX_REGISTERED_MODULES) &&
(pEvHandler->RegistrationArray[pEvParams->uEventType][ModuleIndex].uEventID != NULL))
{
ModuleIndex++;
}
if (ModuleIndex == MAX_REGISTERED_MODULES)
{
PRINTF(DBG_INIT_WARNING, (" EvHandlerRegisterEvent %d "
"Registration queue full or event already registered!\n",
pEvParams->uEventType));
return (TI_UINT32)STATUS_INVALID_PARAMETER;
}
os_memoryCopy(pEvHandler->hOs,(TI_UINT8*)&pEvHandler->RegistrationArray[pEvParams->uEventType][ModuleIndex],
(TI_UINT8*)pEvParams,Length);
pEvParams->uEventID = (TI_HANDLE)&pEvHandler->RegistrationArray[pEvParams->uEventType][ModuleIndex];
pEvHandler->RegistrationArray[pEvParams->uEventType][ModuleIndex].uEventID = pEvParams->uEventID;
PRINT(DBG_INIT_LOUD, " EvHandlerRegisterEvent Out \n");
return STATUS_SUCCESS;
}
TI_UINT32 EvHandlerUnRegisterEvent(TI_HANDLE hEvHandler, TI_HANDLE uEventID)
{
TEvHandlerObj *pEvHandler;
IPC_EVENT_PARAMS *pEvParams;
TI_UINT32 ModuleIndex;
#ifdef EV_HANDLER_DEBUG
if (ghEvHandler != hEvHandler )
{
return TI_NOK;
}
#endif
if (uEventID == NULL)
{
return TI_NOK;
}
pEvHandler = (TEvHandlerObj *)hEvHandler;
pEvParams = (IPC_EVENT_PARAMS *)uEventID;
PRINTF(DBG_INIT_LOUD, (" EvHandlerUnRegisterEvent EventType = %d \n",pEvParams->uEventType));
if( pEvParams->uEventType >= IPC_EVENT_MAX){
PRINTF(DBG_INIT_ERROR, (" EvHandlerRegisterEvent Error Event Type = %d \n",
pEvParams->uEventType));
return (TI_UINT32)STATUS_INVALID_PARAMETER;
}
ModuleIndex = 0;
while ((ModuleIndex < MAX_REGISTERED_MODULES) &&
(pEvHandler->RegistrationArray[pEvParams->uEventType][ModuleIndex].uEventID != pEvParams->uEventID))
{
ModuleIndex++;
}
if (ModuleIndex == MAX_REGISTERED_MODULES)
{
PRINTF(DBG_INIT_ERROR, (" EvHandlerUnRegisterEvent %d "
"Registration queue doesn't hold this event!\n",
pEvParams->uEventType ));
return (TI_UINT32)STATUS_INVALID_PARAMETER;
}
pEvHandler->RegistrationArray[pEvParams->uEventType][ModuleIndex].uEventID = NULL;
return STATUS_SUCCESS;
}
/* ************************** Upper Interface End*********************************/
/* ************************** Bottom Interface **********************************/
TI_UINT32 EvHandlerSendEvent(TI_HANDLE hEvHandler, TI_UINT32 EvType, TI_UINT8* pData, TI_UINT32 Length)
{
TEvHandlerObj *pEvHandler;
IPC_EV_DATA* pNewEvent;
TI_UINT32 TailIndex=0;
TI_UINT32 ModuleIndex=0;
PRINTF(DBG_INIT_LOUD, (" EvHandlerSendEvent %d \n", EvType));
if(hEvHandler == NULL){
PRINT(DBG_INIT_ERROR, "EvHandlerSendEvent Bad Handle passed \n");
return TI_NOK;
}
#ifdef EV_HANDLER_DEBUG
if (ghEvHandler != hEvHandler)
{
return TI_NOK;
}
#endif
pEvHandler = (TEvHandlerObj *)hEvHandler;
TailIndex = pEvHandler->SendEventArray.TailIndex;
while ((ModuleIndex < MAX_REGISTERED_MODULES) && (EvType <= IPC_EVENT_MAX))
{
if (pEvHandler->RegistrationArray[EvType][ModuleIndex].uEventID != NULL )
{
if(pEvHandler->SendEventArray.Counter == MAX_SEND_EVENTS)
{
PRINT(DBG_INIT_ERROR, " EvHandlerSendEvent Array Full u Fool! \n");
return TI_NOK;
}
pNewEvent = &pEvHandler->SendEventArray.Array[TailIndex];
/* copy the event parameters and data to the events queue*/
os_memoryCopy(pEvHandler->hOs,(TI_UINT8*)&pNewEvent->EvParams,
(TI_UINT8*)&pEvHandler->RegistrationArray[EvType][ModuleIndex],
sizeof(IPC_EVENT_PARAMS));
os_memoryZero(pEvHandler->hOs,(TI_UINT8*)pNewEvent->uBuffer, sizeof(pNewEvent->uBuffer));
os_memoryCopy(pEvHandler->hOs,
(TI_UINT8*)pNewEvent->uBuffer,
(TI_UINT8*)pData,
Length);
pNewEvent->uBufferSize = Length;
if(pNewEvent->EvParams.uDeliveryType == DELIVERY_PUSH)
{
PRINTF(DBG_INIT_LOUD, (" EvHandlerSendEvent %d to OS \n", EvType));
PRINTF(DBG_INIT_LOUD, ("EvHandlerSendEvent Matching OS Registered event found at EvType = %d,"
"ModuleIndex = %d \n", EvType, ModuleIndex));
IPC_EventSend (pEvHandler->hOs,(TI_UINT8*)pNewEvent,sizeof(IPC_EV_DATA));
}
else {
pEvHandler->LastUMEventType = EvType;
pEvHandler->SendEventArray.TailIndex = (TailIndex+1) % MAX_SEND_EVENTS;
pEvHandler->SendEventArray.Counter++;
TailIndex = pEvHandler->SendEventArray.TailIndex;
PRINTF(DBG_INIT_LOUD, (" EvHandlerSendEvent %d to User Mode \n", EvType));
PRINTF(DBG_INIT_LOUD, ("EvHandlerSendEvent Matching User Mode Registered event found at EvType = %d,"
"ModuleIndex = %d \n", EvType, ModuleIndex));
if (pEvHandler->SendEventArray.Counter == 1)
{
IPC_EventSend (pEvHandler->hOs,NULL,0);
}
}
} /* end if*/
ModuleIndex++;
} /* end of while*/
return TI_OK;
}
/* ************************** Bottom Interface End **********************************/