OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / system / wlan / ti / wilink_6_1 / CUDK / os / linux / src / ipc_event.c
diff --git a/system/wlan/ti/wilink_6_1/CUDK/os/linux/src/ipc_event.c b/system/wlan/ti/wilink_6_1/CUDK/os/linux/src/ipc_event.c
new file mode 100644 (file)
index 0000000..b7e7d74
--- /dev/null
@@ -0,0 +1,666 @@
+/*
+ * ipc_event.c
+ *
+ * Copyright 2001-2009 Texas Instruments, Inc. - http://www.ti.com/
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and  
+ * limitations under the License.
+ */
+
+/****************************************************************************
+*
+*   MODULE:  IPC_Event.c
+*   
+*   PURPOSE: 
+* 
+*   DESCRIPTION:  
+*   ============
+*      
+*
+****************************************************************************/
+
+/* includes */
+/************/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <linux/rtnetlink.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <linux/wireless.h>
+#include "cu_osapi.h"
+#include "oserr.h"
+
+#include "TWDriver.h"
+#include "STADExternalIf.h"
+
+#include "ParsEvent.h"
+#include "ipc_event.h"
+
+/* defines */
+/***********/
+#define PIPE_READ 0
+#define PIPE_WRITE 1
+#define IPC_EVENT_KEY ((key_t)123456789)
+
+/* IPC evemt messages to child */
+#define IPC_EVENT_MSG_KILL                  "IPC_EVENT_MSG_KILL"
+#define IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL    "IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL"
+#define IPC_EVENT_MSG_MAX_LEN   50
+
+/* local types */
+/***************/
+typedef struct IpcEvent_Shared_Memory_t
+{
+    int pipe_fields[2];
+    U32 event_mask;
+    union 
+    {
+        S32 debug_level;
+    } content;
+} IpcEvent_Shared_Memory_t;
+
+/* Module control block */
+typedef struct IpcEvent_t
+{
+    IpcEvent_Shared_Memory_t* p_shared_memory;
+    S32 child_process_id;
+    S32 pipe_to_child;
+} IpcEvent_t;
+
+typedef struct IpcEvent_Child_t
+{
+    S32 STA_socket;
+    IpcEvent_Shared_Memory_t* p_shared_memory;
+    S32 pipe_from_parent;    
+} IpcEvent_Child_t;
+
+/* local variables */
+/*******************/
+VOID g_tester_send_event(U8 event_index);
+/* local fucntions */
+/*******************/
+static VOID IpcEvent_SendMessageToChild(IpcEvent_t* pIpcEvent, PS8 msg)
+{
+    write(pIpcEvent->pipe_to_child, msg, os_strlen(msg));    
+}
+
+static S32 IpcEvent_Sockets_Open(VOID)
+{
+    S32 skfd;
+    struct sockaddr_nl  local;
+
+    skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+    if (skfd < 0) 
+    {
+        return -1;
+    }
+
+    os_memset(&local, 0, sizeof(local));
+    local.nl_family = AF_NETLINK;
+    local.nl_groups = RTMGRP_LINK;
+    if (bind(skfd, (struct sockaddr *) &local, sizeof(local)) < 0) 
+    {
+        close(skfd);
+        return -2;
+    }
+    
+    return skfd;
+}
+
+static inline VOID IpcEvent_Sockets_Close(S32 skfd)
+{
+    close(skfd);
+}
+
+void ProcessLoggerMessage(PU8 data, U16 len);
+
+static VOID IpcEvent_PrintEvent(IpcEvent_Child_t* pIpcEventChild, U32 EventId, TI_UINT8* pData, S32 DataLen)
+{
+   
+    if(pIpcEventChild->p_shared_memory->event_mask & (1<<EventId))
+    {
+        switch(EventId)
+        {
+            case IPC_EVENT_DISASSOCIATED:
+            {
+                OS_802_11_DISASSOCIATE_REASON_T    *pDisAssoc;
+
+                if (NULL == pData)
+                {
+                    return;
+                }
+                else
+                {
+                    pDisAssoc = (OS_802_11_DISASSOCIATE_REASON_T*)pData;
+                }
+
+                switch(pDisAssoc->eDisAssocType)
+                {
+                    case OS_DISASSOC_STATUS_UNSPECIFIED:
+                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated with unspecified reason (User/SG/Recovery)\n");
+                        break;
+                    case OS_DISASSOC_STATUS_AUTH_REJECT:
+                        if (pDisAssoc->uStatusCode == STATUS_PACKET_REJ_TIMEOUT)
+                        {
+                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to no Auth response \n");
+                        } 
+                        else
+                        {
+                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to Auth response packet with reason = %d\n", pDisAssoc->uStatusCode);
+                        }
+                        break;
+                    case OS_DISASSOC_STATUS_ASSOC_REJECT:
+                        if (pDisAssoc->uStatusCode == STATUS_PACKET_REJ_TIMEOUT)
+                        {
+                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to no Assoc response \n");
+                        } 
+                        else
+                        {
+                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to Assoc response packet with reason = %d\n", pDisAssoc->uStatusCode);
+                        }
+                        break;
+                    case OS_DISASSOC_STATUS_SECURITY_FAILURE:
+                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to RSN failure\n");
+                        break;
+                    case OS_DISASSOC_STATUS_AP_DEAUTHENTICATE:
+                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to AP deAuthenticate packet with reason = %d\n", pDisAssoc->uStatusCode);
+                        break;
+                    case OS_DISASSOC_STATUS_AP_DISASSOCIATE:
+                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to AP disAssoc packet with reason = %d\n", pDisAssoc->uStatusCode);
+                        break;
+                    case OS_DISASSOC_STATUS_ROAMING_TRIGGER:
+                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to roaming trigger = %d\n", pDisAssoc->uStatusCode);
+                        break;
+                    default:
+                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated with unknown reason = %d\n", pDisAssoc->eDisAssocType);
+                        break; 
+                }
+                
+                break; /* the end of the IPC_EVENT_DISASSOCIATED case */
+            }
+            case IPC_EVENT_ASSOCIATED:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_ASSOCIATED\n");
+                break;
+            case IPC_EVENT_MEDIA_SPECIFIC:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_MEDIA_SPECIFIC\n");
+                break;
+            case IPC_EVENT_SCAN_COMPLETE:
+                               os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_SCAN_COMPLETE\n");
+                break;
+            /* custom events */
+            case IPC_EVENT_SCAN_STOPPED:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_SCAN_STOPPED\n");
+                break;
+            case IPC_EVENT_LINK_SPEED:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_LINK_SPEED\n");
+                break;
+            case IPC_EVENT_AUTH_SUCC:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_AUTH_SUCC\n");
+                break;
+            case IPC_EVENT_CCKM_START:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_CCKM_START\n");
+                break;
+            case IPC_EVENT_EAPOL:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_EAPOL\n");
+                break;
+            case IPC_EVENT_RE_AUTH_STARTED:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RE_AUTH_STARTED\n");
+                break;
+            case IPC_EVENT_RE_AUTH_COMPLETED:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RE_AUTH_COMPLETED\n");
+                break;
+            case IPC_EVENT_RE_AUTH_TERMINATED:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RE_AUTH_TERMINATED\n");
+                break;
+            case IPC_EVENT_BOUND:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_BOUND\n");
+                break;
+            case IPC_EVENT_UNBOUND:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_UNBOUND\n");
+                break;
+            case IPC_EVENT_PREAUTH_EAPOL:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_PREAUTH_EAPOL\n");
+                break;
+            case IPC_EVENT_LOW_RSSI:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_LOW_RSSI\n");
+                break;
+            case IPC_EVENT_TSPEC_STATUS:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TSPEC_STATUS\n");
+                break;
+            case IPC_EVENT_TSPEC_RATE_STATUS:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TSPEC_RATE_STATUS\n");
+                break;
+            case IPC_EVENT_MEDIUM_TIME_CROSS:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_MEDIUM_TIME_CROSS\n");
+                break;
+            case IPC_EVENT_ROAMING_COMPLETE:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_ROAMING_COMPLETE\n");
+                break;
+            case IPC_EVENT_EAP_AUTH_FAILURE:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_EAP_AUTH_FAILURE\n");
+                break;
+            case IPC_EVENT_WPA2_PREAUTHENTICATION:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_WPA2_PREAUTHENTICATION\n");
+                break;
+            case IPC_EVENT_TRAFFIC_INTENSITY_THRESHOLD_CROSSED:
+            {
+                U32 *crossInfo = (U32 *)pData;
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TRAFFIC_INTENSITY_THRESHOLD_CROSSED\n");
+                os_error_printf(CU_MSG_ERROR, (PS8)"Threshold(High=0,  Low=1)   crossed= %d\n", crossInfo[0]);
+                os_error_printf(CU_MSG_ERROR, (PS8)"Direction(Above=0, Below=1) crossed= %d\n", crossInfo[1]);
+                break;
+            }
+            case IPC_EVENT_SCAN_FAILED:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_SCAN_FAILED\n");
+                break;
+            case IPC_EVENT_WPS_SESSION_OVERLAP:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_WPS_SESSION_OVERLAP\n");
+                break;
+            case IPC_EVENT_RSSI_SNR_TRIGGER_0:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RSSI_SNR_TRIGGER_0, Data = %d\n", (S8)(*pData));
+                break;
+            case IPC_EVENT_RSSI_SNR_TRIGGER_1:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RSSI_SNR_TRIGGER_1, Data = %d\n", (S8)(*pData));
+                break;
+            case IPC_EVENT_RSSI_SNR_TRIGGER:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RSSI_SNR_TRIGGER, Data = %d\n", (S8)(*pData));
+                break;
+            case IPC_EVENT_TIMEOUT:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TIMEOUT\n");
+                break;
+            case IPC_EVENT_GWSI:
+                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_GWSI\n");
+                break;
+            case IPC_EVENT_LOGGER:
+#ifdef ETH_SUPPORT
+                ProcessLoggerMessage(pData, (U16)DataLen);
+#endif   
+                break;
+            default :
+                os_error_printf(CU_MSG_ERROR, (PS8)"**** Unknow EventId %d ****\n", EventId); 
+        }
+    }   
+}
+
+static VOID IpcEvent_wext_event_wireless(IpcEvent_Child_t* pIpcEventChild, PS8 data, S32 len)
+{
+    struct iw_event     iwe;      
+    struct stream_descr stream;                 
+    S32                 ret;  
+    IPC_EV_DATA*        pEvent;    
+       U32                                     EventId = 0;
+
+    /* init the event stream */
+    os_memset((char *)&stream, '\0', sizeof(struct stream_descr));
+    stream.current = (char *)data;
+    stream.end = (char *)(data + len);
+
+    do  
+    {     
+        /* Extract an event and print it */   
+        ret = ParsEvent_GetEvent(&stream, &iwe);     
+
+        if(ret <= 0)   
+            break;
+
+        switch (iwe.cmd) 
+        {
+            case SIOCGIWAP:
+                if((iwe.u.ap_addr.sa_data[0] == 0) && 
+                    (iwe.u.ap_addr.sa_data[1] == 0) &&
+                    (iwe.u.ap_addr.sa_data[2] == 0) &&
+                    (iwe.u.ap_addr.sa_data[3] == 0) &&
+                    (iwe.u.ap_addr.sa_data[4] == 0) &&
+                    (iwe.u.ap_addr.sa_data[5] == 0))
+                {
+                                       EventId=IPC_EVENT_DISASSOCIATED;
+                     IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);
+                } 
+                else 
+                {
+                                       EventId=IPC_EVENT_ASSOCIATED;
+                     IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);                
+                }
+                break;
+            case IWEVMICHAELMICFAILURE:
+                               EventId=IPC_EVENT_MEDIA_SPECIFIC;
+                IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);
+                break;
+            case IWEVCUSTOM:
+                               pEvent =  (IPC_EV_DATA*)iwe.u.data.pointer;
+                if (pEvent)
+                {
+                    EventId = (U32)pEvent->EvParams.uEventType;
+                    IpcEvent_PrintEvent (pIpcEventChild, EventId, pEvent->uBuffer, pEvent->uBufferSize);
+                }
+                               break;
+            case SIOCGIWSCAN:
+                               EventId=IPC_EVENT_SCAN_COMPLETE;
+                IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);             
+                break;
+            case IWEVASSOCREQIE:
+                /* NOP */
+                break;
+            case IWEVASSOCRESPIE:
+                /* NOP */
+                break;
+            case IWEVPMKIDCAND:
+                               EventId=IPC_EVENT_MEDIA_SPECIFIC;
+                IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);    
+                break;
+        }
+
+               g_tester_send_event((U8) EventId);
+
+    }      
+    while(1);
+}
+
+static VOID IpcEvent_wext_event_rtm_newlink(IpcEvent_Child_t* pIpcEventChild, struct nlmsghdr *h, 
+                                            S32 len)
+{
+    struct ifinfomsg *ifi;
+    S32 attrlen, nlmsg_len, rta_len;
+    struct rtattr * attr;
+
+    if (len < sizeof(*ifi))
+        return;
+
+    ifi = NLMSG_DATA(h);
+
+    /*
+    if ((if_nametoindex("wlan") != ifi->ifi_index) && (if_nametoindex("wifi") != ifi->ifi_index))
+    {
+        os_error_printf(CU_MSG_ERROR, "ERROR - IpcEvent_wext_event_rtm_newlink - Ignore event for foreign ifindex %d",
+               ifi->ifi_index);
+        return;
+    }
+    */
+
+    nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
+
+    attrlen = h->nlmsg_len - nlmsg_len;
+    if (attrlen < 0)
+        return;
+
+    attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+
+    rta_len = RTA_ALIGN(sizeof(struct rtattr));
+    while (RTA_OK(attr, attrlen)) {
+        if (attr->rta_type == IFLA_WIRELESS) 
+        {
+            IpcEvent_wext_event_wireless(pIpcEventChild, ((PS8) attr) + rta_len,
+                attr->rta_len - rta_len);
+        } 
+        else if (attr->rta_type == IFLA_IFNAME) 
+        {
+            os_error_printf(CU_MSG_WARNING, (PS8)"WARNING - IpcEvent_wext_event_rtm_newlink - unsupported rta_type = IFLA_IFNAME\n");
+            
+        }
+        attr = RTA_NEXT(attr, attrlen);
+    }
+}
+
+static VOID IpcEvent_Handle_STA_Event(IpcEvent_Child_t* pIpcEventChild)
+{       
+    S8 buf[512];
+    S32 left;
+    struct sockaddr_nl from;
+    socklen_t fromlen;
+    struct nlmsghdr *h;
+
+    fromlen = sizeof(from);
+    left = recvfrom(pIpcEventChild->STA_socket, buf, sizeof(buf), MSG_DONTWAIT,
+            (struct sockaddr *) &from, &fromlen);
+    if (left < 0) 
+    {
+        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_STA_Event - cant recv from socket %X .\n", 
+                                               pIpcEventChild->STA_socket);
+        return;
+    }
+
+    h = (struct nlmsghdr *) buf;
+
+    while (left >= sizeof(*h)) 
+    {
+        S32 len, plen;
+
+        len = h->nlmsg_len;
+        plen = len - sizeof(*h);
+        if (len > left || plen < 0) {
+            os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_STA_Event - Malformed netlink message: len=%d left=%d plen=%d",
+                   len, left, plen);
+            break;
+        }
+
+        switch (h->nlmsg_type) 
+        {
+        case RTM_NEWLINK:
+            IpcEvent_wext_event_rtm_newlink(pIpcEventChild, h, plen);
+            break;      
+        }
+
+        len = NLMSG_ALIGN(len);
+        left -= len;
+        h = (struct nlmsghdr *) ((char *) h + len);
+    }
+
+    if (left > 0) 
+    {
+        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_STA_Event - %d extra bytes in the end of netlink ",
+               left);
+        IpcEvent_Handle_STA_Event(pIpcEventChild);
+    }
+    
+}
+
+static S32 IpcEvent_Handle_Parent_Event(IpcEvent_Child_t* pIpcEventChild)
+{
+    S8 msg[IPC_EVENT_MSG_MAX_LEN];
+
+    S32 msgLen = read(pIpcEventChild->pipe_from_parent,msg, IPC_EVENT_MSG_MAX_LEN);
+    msg[msgLen] = 0;
+
+    if(!os_strcmp(msg, (PS8)IPC_EVENT_MSG_KILL))
+    {
+        return TRUE;
+    }
+    if(!os_strcmp(msg, (PS8)IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL))
+    {
+/*        g_debug_level= pIpcEventChild->p_shared_memory->content.debug_level;*/
+        return FALSE;
+    }else
+        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_Parent_Event - unknown msgLen=%d msg=|%s| \n",msgLen,msg);  
+
+       return FALSE;
+
+}
+
+static VOID IpcEvent_Child_Destroy(IpcEvent_Child_t* pIpcEventChild)
+{
+    if(pIpcEventChild->STA_socket)
+    {
+        IpcEvent_Sockets_Close(pIpcEventChild->STA_socket);
+    }
+    
+}
+    
+static VOID IpcEvent_Child(IpcEvent_Child_t* pIpcEventChild)
+{
+    /* open the socket from the driver */
+    pIpcEventChild->STA_socket = IpcEvent_Sockets_Open();
+    if(pIpcEventChild->STA_socket < 0)
+    {
+        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant open socket for communication with the driver (%d)\n",pIpcEventChild->STA_socket);
+        return;
+    }
+    
+    while(1)    
+    {      
+        fd_set      read_set;       /* File descriptors for select */           
+        S32         ret;      
+        
+        FD_ZERO(&read_set);
+        FD_SET(pIpcEventChild->STA_socket, &read_set);
+        FD_SET(pIpcEventChild->pipe_from_parent, &read_set);
+
+#ifndef ANDROID
+        ret = select(max(pIpcEventChild->pipe_from_parent,pIpcEventChild->STA_socket) + 1, 
+                    &read_set, NULL, NULL, NULL);
+#else
+        ret = select(pIpcEventChild->STA_socket + 1, 
+                    &read_set, NULL, NULL, NULL);
+#endif
+
+        if(ret < 0) 
+        {             
+            os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Child - Unhandled signal - exiting...\n");    
+            break;
+        }      
+        if(ret == 0)    {     continue; }      /* Check for interface discovery events. */      
+        if(FD_ISSET(pIpcEventChild->STA_socket, &read_set))
+            IpcEvent_Handle_STA_Event(pIpcEventChild);    
+
+#ifndef ANDROID 
+        if(FD_ISSET(pIpcEventChild->pipe_from_parent, &read_set))   
+        {
+            S32 exit = IpcEvent_Handle_Parent_Event(pIpcEventChild);
+             if(exit)
+                break;
+        }
+#endif
+
+    }  
+
+    IpcEvent_Child_Destroy(pIpcEventChild);
+}
+
+/* functions */
+/*************/
+THandle IpcEvent_Create(VOID)
+{   
+    IpcEvent_t* pIpcEvent = (IpcEvent_t*)os_MemoryCAlloc(sizeof(IpcEvent_t), sizeof(U8));
+    if(pIpcEvent == NULL)
+    {
+        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant allocate control block\n");
+        return NULL;
+    }
+     
+    /* create a shared memory space */
+    pIpcEvent->p_shared_memory = mmap(0, sizeof(IpcEvent_Shared_Memory_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
+    if ( pIpcEvent->p_shared_memory == ((PVOID)-1)) 
+    {
+        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant allocate shared memory\n");
+        IpcEvent_Destroy(pIpcEvent);
+        return NULL;
+    }
+
+    /* create a pipe */
+    pipe(pIpcEvent->p_shared_memory->pipe_fields);
+
+    /* set the event mask to all disabled */
+    pIpcEvent->p_shared_memory->event_mask = 0;
+
+    /* Create a child process */
+    pIpcEvent->child_process_id = fork();
+
+    if (0 == pIpcEvent->child_process_id)
+    {
+        /******************/
+        /* Child process */
+        /****************/      
+        IpcEvent_Child_t* pIpcEventChild = (IpcEvent_Child_t*)os_MemoryCAlloc(sizeof(IpcEvent_Child_t), sizeof(U8));        
+        if(pIpcEventChild == NULL)
+        {
+            os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant allocate child control block\n");
+            _exit(1);
+        }
+
+        pIpcEventChild->p_shared_memory = pIpcEvent->p_shared_memory;
+
+        pIpcEventChild->pipe_from_parent = pIpcEventChild->p_shared_memory->pipe_fields[PIPE_READ];
+        close(pIpcEventChild->p_shared_memory->pipe_fields[PIPE_WRITE]);
+
+        IpcEvent_Child(pIpcEventChild);
+
+        os_MemoryFree(pIpcEventChild);
+
+        _exit(0);
+    }
+    pIpcEvent->pipe_to_child = pIpcEvent->p_shared_memory->pipe_fields[PIPE_WRITE];
+    close(pIpcEvent->p_shared_memory->pipe_fields[PIPE_READ]);
+    
+    return pIpcEvent;
+}
+
+VOID IpcEvent_Destroy(THandle hIpcEvent)
+{
+    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
+
+    if((pIpcEvent->p_shared_memory != ((PVOID)-1)) && (pIpcEvent->p_shared_memory))
+    {       
+        munmap(pIpcEvent->p_shared_memory, sizeof(IpcEvent_Shared_Memory_t));
+    }
+
+    /* kill child process */
+    kill(pIpcEvent->child_process_id, SIGKILL);
+    
+     os_MemoryFree(pIpcEvent);
+
+}
+
+S32 IpcEvent_EnableEvent(THandle hIpcEvent, U32 event)
+{
+    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
+    
+    if(pIpcEvent->p_shared_memory->event_mask & (1 << event))
+    {
+        return EOALERR_IPC_EVENT_ERROR_EVENT_ALREADY_ENABLED;
+    }
+    else
+    {
+        pIpcEvent->p_shared_memory->event_mask |= (1 << event);
+    }
+
+    return OK;
+        
+}
+
+S32 IpcEvent_DisableEvent(THandle hIpcEvent, U32 event)
+{
+    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
+    
+    if(!(pIpcEvent->p_shared_memory->event_mask & (1 << event)))
+    {
+        return EOALERR_IPC_EVENT_ERROR_EVENT_ALREADY_DISABLED;
+    }
+    else
+    {
+        pIpcEvent->p_shared_memory->event_mask &= ~(1 << event);
+    }
+
+    return OK;
+}
+
+S32 IpcEvent_UpdateDebugLevel(THandle hIpcEvent, S32 debug_level)
+{
+    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
+
+    pIpcEvent->p_shared_memory->content.debug_level = debug_level;
+    IpcEvent_SendMessageToChild(pIpcEvent, (PS8)IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL);
+
+    return OK;
+}
+