1/*
2 * ipc_event.c
3 *
4 * Copyright 2001-2009 Texas Instruments, Inc. - http://www.ti.com/
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/****************************************************************************
20*
21*   MODULE:  IPC_Event.c
22*
23*   PURPOSE:
24*
25*   DESCRIPTION:
26*   ============
27*
28*
29****************************************************************************/
30
31/* includes */
32/************/
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <net/if.h>
36#include <linux/rtnetlink.h>
37#include <signal.h>
38#include <sys/mman.h>
39#include <unistd.h>
40#include <linux/wireless.h>
41#include "cu_osapi.h"
42#include "oserr.h"
43
44#include "TWDriver.h"
45#include "STADExternalIf.h"
46
47#include "ParsEvent.h"
48#include "ipc_event.h"
49
50/* defines */
51/***********/
52#define PIPE_READ 0
53#define PIPE_WRITE 1
54#define IPC_EVENT_KEY ((key_t)123456789)
55
56/* IPC evemt messages to child */
57#define IPC_EVENT_MSG_KILL                  "IPC_EVENT_MSG_KILL"
58#define IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL    "IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL"
59#define IPC_EVENT_MSG_MAX_LEN   50
60
61/* local types */
62/***************/
63typedef struct IpcEvent_Shared_Memory_t
64{
65    int pipe_fields[2];
66    u64 event_mask;
67    union
68    {
69        S32 debug_level;
70    } content;
71} IpcEvent_Shared_Memory_t;
72
73/* Module control block */
74typedef struct IpcEvent_t
75{
76    IpcEvent_Shared_Memory_t* p_shared_memory;
77    S32 child_process_id;
78    S32 pipe_to_child;
79} IpcEvent_t;
80
81typedef struct IpcEvent_Child_t
82{
83    S32 STA_socket;
84    IpcEvent_Shared_Memory_t* p_shared_memory;
85    S32 pipe_from_parent;
86} IpcEvent_Child_t;
87
88/* local variables */
89/*******************/
90VOID g_tester_send_event(U8 event_index);
91/* local fucntions */
92/*******************/
93static VOID IpcEvent_SendMessageToChild(IpcEvent_t* pIpcEvent, PS8 msg)
94{
95    write(pIpcEvent->pipe_to_child, msg, os_strlen(msg));
96}
97
98static S32 IpcEvent_Sockets_Open(VOID)
99{
100    S32 skfd;
101    struct sockaddr_nl  local;
102
103    skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
104    if (skfd < 0)
105    {
106        return -1;
107    }
108
109    os_memset(&local, 0, sizeof(local));
110    local.nl_family = AF_NETLINK;
111    local.nl_groups = RTMGRP_LINK;
112    if (bind(skfd, (struct sockaddr *) &local, sizeof(local)) < 0)
113    {
114        close(skfd);
115        return -2;
116    }
117
118    return skfd;
119}
120
121static inline VOID IpcEvent_Sockets_Close(S32 skfd)
122{
123    close(skfd);
124}
125
126void ProcessLoggerMessage(PU8 data, U16 len);
127
128static VOID IpcEvent_PrintEvent(IpcEvent_Child_t* pIpcEventChild, U32 EventId, TI_UINT8* pData, S32 DataLen)
129{
130
131    if(pIpcEventChild->p_shared_memory->event_mask & ((u64)1<<EventId))
132    {
133        switch(EventId)
134        {
135            case IPC_EVENT_DISASSOCIATED:
136            {
137                OS_802_11_DISASSOCIATE_REASON_T    *pDisAssoc;
138
139                if (NULL == pData)
140                {
141                    return;
142                }
143                else
144                {
145                    pDisAssoc = (OS_802_11_DISASSOCIATE_REASON_T*)pData;
146                }
147
148                switch(pDisAssoc->eDisAssocType)
149                {
150                    case OS_DISASSOC_STATUS_UNSPECIFIED:
151                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated with unspecified reason (User/SG/Recovery)\n");
152                        break;
153                    case OS_DISASSOC_STATUS_AUTH_REJECT:
154                        if (pDisAssoc->uStatusCode == STATUS_PACKET_REJ_TIMEOUT)
155                        {
156                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to no Auth response \n");
157                        }
158                        else
159                        {
160                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to Auth response packet with reason = %d\n", pDisAssoc->uStatusCode);
161                        }
162                        break;
163                    case OS_DISASSOC_STATUS_ASSOC_REJECT:
164                        if (pDisAssoc->uStatusCode == STATUS_PACKET_REJ_TIMEOUT)
165                        {
166                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to no Assoc response \n");
167                        }
168                        else
169                        {
170                            os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to Assoc response packet with reason = %d\n", pDisAssoc->uStatusCode);
171                        }
172                        break;
173                    case OS_DISASSOC_STATUS_SECURITY_FAILURE:
174                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to RSN failure\n");
175                        break;
176                    case OS_DISASSOC_STATUS_AP_DEAUTHENTICATE:
177                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to AP deAuthenticate packet with reason = %d\n", pDisAssoc->uStatusCode);
178                        break;
179                    case OS_DISASSOC_STATUS_AP_DISASSOCIATE:
180                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to AP disAssoc packet with reason = %d\n", pDisAssoc->uStatusCode);
181                        break;
182                    case OS_DISASSOC_STATUS_ROAMING_TRIGGER:
183                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated due to roaming trigger = %d\n", pDisAssoc->uStatusCode);
184                        break;
185                    default:
186                        os_error_printf(CU_MSG_ERROR, "CLI Event - Disassociated with unknown reason = %d\n", pDisAssoc->eDisAssocType);
187                        break;
188                }
189
190                break; /* the end of the IPC_EVENT_DISASSOCIATED case */
191            }
192            case IPC_EVENT_ASSOCIATED:
193                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_ASSOCIATED\n");
194                break;
195            case IPC_EVENT_MEDIA_SPECIFIC:
196                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_MEDIA_SPECIFIC\n");
197                break;
198            case IPC_EVENT_SCAN_COMPLETE:
199				os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_SCAN_COMPLETE\n");
200                break;
201            /* custom events */
202            case IPC_EVENT_SCAN_STOPPED:
203                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_SCAN_STOPPED\n");
204                break;
205            case IPC_EVENT_LINK_SPEED:
206                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_LINK_SPEED\n");
207                break;
208            case IPC_EVENT_AUTH_SUCC:
209                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_AUTH_SUCC\n");
210                break;
211            case IPC_EVENT_CCKM_START:
212                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_CCKM_START\n");
213                break;
214            case IPC_EVENT_EAPOL:
215                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_EAPOL\n");
216                break;
217            case IPC_EVENT_RE_AUTH_STARTED:
218                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RE_AUTH_STARTED\n");
219                break;
220            case IPC_EVENT_RE_AUTH_COMPLETED:
221                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RE_AUTH_COMPLETED\n");
222                break;
223            case IPC_EVENT_RE_AUTH_TERMINATED:
224                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RE_AUTH_TERMINATED\n");
225                break;
226            case IPC_EVENT_BOUND:
227                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_BOUND\n");
228                break;
229            case IPC_EVENT_UNBOUND:
230                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_UNBOUND\n");
231                break;
232            case IPC_EVENT_PREAUTH_EAPOL:
233                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_PREAUTH_EAPOL\n");
234                break;
235            case IPC_EVENT_LOW_RSSI:
236                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_LOW_RSSI\n");
237                break;
238            case IPC_EVENT_TSPEC_STATUS:
239                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TSPEC_STATUS\n");
240
241                OS_802_11_QOS_TSPEC_PARAMS* tspec = (OS_802_11_QOS_TSPEC_PARAMS*)pData;
242                os_error_printf(CU_MSG_ERROR, "CLI Event - IPC_EVENT_TSPEC_STATUS -- (ReasonCode = %d) \n",tspec->uReasonCode);
243                os_error_printf(CU_MSG_ERROR, "Tspec Parameters (as received through event handler):\n");
244                os_error_printf(CU_MSG_ERROR, "-----------------------------------------------------\n");
245                os_error_printf(CU_MSG_ERROR, "userPriority = %d\n",tspec->uUserPriority);
246                os_error_printf(CU_MSG_ERROR, "uNominalMSDUsize = %d\n",tspec->uNominalMSDUsize);
247                os_error_printf(CU_MSG_ERROR, "uMeanDataRate = %d\n",tspec->uMeanDataRate);
248                os_error_printf(CU_MSG_ERROR, "uMinimumPHYRate = %d\n",tspec->uMinimumPHYRate);
249                os_error_printf(CU_MSG_ERROR, "uSurplusBandwidthAllowance = %d\n",tspec->uSurplusBandwidthAllowance);
250                os_error_printf(CU_MSG_ERROR, "uAPSDFlag = %d\n",tspec->uAPSDFlag);
251                os_error_printf(CU_MSG_ERROR, "MinimumServiceInterval = %d\n",tspec->uMinimumServiceInterval);
252                os_error_printf(CU_MSG_ERROR, "MaximumServiceInterval = %d\n",tspec->uMaximumServiceInterval);
253                os_error_printf(CU_MSG_ERROR, "uMediumTime = %d\n\n",tspec->uMediumTime);
254
255                break;
256            case IPC_EVENT_TSPEC_RATE_STATUS:
257                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TSPEC_RATE_STATUS\n");
258                break;
259            case IPC_EVENT_MEDIUM_TIME_CROSS:
260                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_MEDIUM_TIME_CROSS\n");
261                break;
262            case IPC_EVENT_ROAMING_COMPLETE:
263                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_ROAMING_COMPLETE\n");
264                break;
265            case IPC_EVENT_EAP_AUTH_FAILURE:
266                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_EAP_AUTH_FAILURE\n");
267                break;
268            case IPC_EVENT_WPA2_PREAUTHENTICATION:
269                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_WPA2_PREAUTHENTICATION\n");
270                break;
271            case IPC_EVENT_TRAFFIC_INTENSITY_THRESHOLD_CROSSED:
272            {
273                U32 *crossInfo = (U32 *)pData;
274                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TRAFFIC_INTENSITY_THRESHOLD_CROSSED\n");
275                os_error_printf(CU_MSG_ERROR, (PS8)"Threshold(High=0,  Low=1)   crossed= %d\n", crossInfo[0]);
276                os_error_printf(CU_MSG_ERROR, (PS8)"Direction(Above=0, Below=1) crossed= %d\n", crossInfo[1]);
277                break;
278            }
279            case IPC_EVENT_SCAN_FAILED:
280                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_SCAN_FAILED\n");
281                break;
282            case IPC_EVENT_WPS_SESSION_OVERLAP:
283                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_WPS_SESSION_OVERLAP\n");
284                break;
285            case IPC_EVENT_RSSI_SNR_TRIGGER:
286                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_RSSI_SNR_TRIGGER (index = %d), Data = %d\n", (S8)(*(pData + 2) - 1),(S8)(*pData));
287                break;
288            case IPC_EVENT_TIMEOUT:
289                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_TIMEOUT\n");
290                break;
291            case IPC_EVENT_GWSI:
292                os_error_printf(CU_MSG_ERROR, (PS8)"IpcEvent_PrintEvent - received IPC_EVENT_GWSI\n");
293                break;
294            case IPC_EVENT_LOGGER:
295#ifdef ETH_SUPPORT
296                ProcessLoggerMessage(pData, (U16)DataLen);
297#endif
298                break;
299            default :
300                os_error_printf(CU_MSG_ERROR, (PS8)"**** Unknow EventId %d ****\n", EventId);
301        }
302    }
303}
304
305static VOID IpcEvent_wext_event_wireless(IpcEvent_Child_t* pIpcEventChild, PS8 data, S32 len)
306{
307    struct iw_event     iwe;
308    struct stream_descr stream;
309    S32                 ret;
310    IPC_EV_DATA*        pEvent;
311	U32					EventId = 0;
312
313    /* init the event stream */
314    os_memset((char *)&stream, '\0', sizeof(struct stream_descr));
315    stream.current = (char *)data;
316    stream.end = (char *)(data + len);
317
318    do
319    {
320        /* Extract an event and print it */
321        ret = ParsEvent_GetEvent(&stream, &iwe);
322
323        if(ret <= 0)
324            break;
325
326        switch (iwe.cmd)
327        {
328            case SIOCGIWAP:
329                if((iwe.u.ap_addr.sa_data[0] == 0) &&
330                    (iwe.u.ap_addr.sa_data[1] == 0) &&
331                    (iwe.u.ap_addr.sa_data[2] == 0) &&
332                    (iwe.u.ap_addr.sa_data[3] == 0) &&
333                    (iwe.u.ap_addr.sa_data[4] == 0) &&
334                    (iwe.u.ap_addr.sa_data[5] == 0))
335                {
336					EventId=IPC_EVENT_DISASSOCIATED;
337                     IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);
338                }
339                else
340                {
341#ifdef XCC_MODULE_INCLUDED
342                    /* Send a signal to the udhcpc application to trigger the renew request */
343                    system("killall -SIGUSR1 udhcpc");
344#endif
345					EventId=IPC_EVENT_ASSOCIATED;
346                     IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);
347                }
348                break;
349            case IWEVMICHAELMICFAILURE:
350				EventId=IPC_EVENT_MEDIA_SPECIFIC;
351                IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);
352                break;
353            case IWEVCUSTOM:
354				pEvent =  (IPC_EV_DATA*)iwe.u.data.pointer;
355                if (pEvent)
356                {
357                    EventId = (U32)pEvent->EvParams.uEventType;
358                    IpcEvent_PrintEvent (pIpcEventChild, EventId, pEvent->uBuffer, pEvent->uBufferSize);
359                }
360				break;
361            case SIOCGIWSCAN:
362				EventId=IPC_EVENT_SCAN_COMPLETE;
363                IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);
364                break;
365            case IWEVASSOCREQIE:
366                /* NOP */
367                break;
368            case IWEVASSOCRESPIE:
369                /* NOP */
370                break;
371            case IWEVPMKIDCAND:
372				EventId=IPC_EVENT_MEDIA_SPECIFIC;
373                IpcEvent_PrintEvent(pIpcEventChild, EventId, NULL,0);
374                break;
375        }
376
377		g_tester_send_event((U8) EventId);
378
379    }
380    while(1);
381}
382
383static VOID IpcEvent_wext_event_rtm_newlink(IpcEvent_Child_t* pIpcEventChild, struct nlmsghdr *h,
384                                            S32 len)
385{
386    struct ifinfomsg *ifi;
387    S32 attrlen, nlmsg_len, rta_len;
388    struct rtattr * attr;
389
390    if (len < sizeof(*ifi))
391        return;
392
393    ifi = NLMSG_DATA(h);
394
395    /*
396    if ((if_nametoindex("wlan") != ifi->ifi_index) && (if_nametoindex("wifi") != ifi->ifi_index))
397    {
398        os_error_printf(CU_MSG_ERROR, "ERROR - IpcEvent_wext_event_rtm_newlink - Ignore event for foreign ifindex %d",
399               ifi->ifi_index);
400        return;
401    }
402    */
403
404    nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
405
406    attrlen = h->nlmsg_len - nlmsg_len;
407    if (attrlen < 0)
408        return;
409
410    attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
411
412    rta_len = RTA_ALIGN(sizeof(struct rtattr));
413    while (RTA_OK(attr, attrlen)) {
414        if (attr->rta_type == IFLA_WIRELESS)
415        {
416            IpcEvent_wext_event_wireless(pIpcEventChild, ((PS8) attr) + rta_len,
417                attr->rta_len - rta_len);
418        }
419        else if (attr->rta_type == IFLA_IFNAME)
420        {
421            os_error_printf(CU_MSG_WARNING, (PS8)"WARNING - IpcEvent_wext_event_rtm_newlink - unsupported rta_type = IFLA_IFNAME\n");
422
423        }
424        attr = RTA_NEXT(attr, attrlen);
425    }
426}
427
428static VOID IpcEvent_Handle_STA_Event(IpcEvent_Child_t* pIpcEventChild)
429{
430    S8 buf[512];
431    S32 left;
432    struct sockaddr_nl from;
433    socklen_t fromlen;
434    struct nlmsghdr *h;
435
436    fromlen = sizeof(from);
437    left = recvfrom(pIpcEventChild->STA_socket, buf, sizeof(buf), MSG_DONTWAIT,
438            (struct sockaddr *) &from, &fromlen);
439    if (left < 0)
440    {
441        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_STA_Event - cant recv from socket %X .\n",
442						pIpcEventChild->STA_socket);
443        return;
444    }
445
446    h = (struct nlmsghdr *) buf;
447
448    while (left >= sizeof(*h))
449    {
450        S32 len, plen;
451
452        len = h->nlmsg_len;
453        plen = len - sizeof(*h);
454        if (len > left || plen < 0) {
455            os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_STA_Event - Malformed netlink message: len=%d left=%d plen=%d",
456                   len, left, plen);
457            break;
458        }
459
460        switch (h->nlmsg_type)
461        {
462        case RTM_NEWLINK:
463            IpcEvent_wext_event_rtm_newlink(pIpcEventChild, h, plen);
464            break;
465        }
466
467        len = NLMSG_ALIGN(len);
468        left -= len;
469        h = (struct nlmsghdr *) ((char *) h + len);
470    }
471
472    if (left > 0)
473    {
474        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_STA_Event - %d extra bytes in the end of netlink ",
475               left);
476        IpcEvent_Handle_STA_Event(pIpcEventChild);
477    }
478
479}
480
481static S32 IpcEvent_Handle_Parent_Event(IpcEvent_Child_t* pIpcEventChild)
482{
483    S8 msg[IPC_EVENT_MSG_MAX_LEN];
484
485    S32 msgLen = read(pIpcEventChild->pipe_from_parent,msg, IPC_EVENT_MSG_MAX_LEN);
486    msg[msgLen] = 0;
487
488    if(!os_strcmp(msg, (PS8)IPC_EVENT_MSG_KILL))
489    {
490        return TRUE;
491    }
492    if(!os_strcmp(msg, (PS8)IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL))
493    {
494/*        g_debug_level= pIpcEventChild->p_shared_memory->content.debug_level;*/
495        return FALSE;
496    }else
497        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Handle_Parent_Event - unknown msgLen=%d msg=|%s| \n",msgLen,msg);
498
499	return FALSE;
500
501}
502
503static VOID IpcEvent_Child_Destroy(IpcEvent_Child_t* pIpcEventChild)
504{
505    if(pIpcEventChild->STA_socket)
506    {
507        IpcEvent_Sockets_Close(pIpcEventChild->STA_socket);
508    }
509
510}
511
512static VOID IpcEvent_Child(IpcEvent_Child_t* pIpcEventChild)
513{
514    /* open the socket from the driver */
515    pIpcEventChild->STA_socket = IpcEvent_Sockets_Open();
516    if(pIpcEventChild->STA_socket < 0)
517    {
518        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant open socket for communication with the driver (%d)\n",pIpcEventChild->STA_socket);
519        return;
520    }
521
522    while(1)
523    {
524        fd_set      read_set;       /* File descriptors for select */
525        S32         ret;
526
527        FD_ZERO(&read_set);
528        FD_SET(pIpcEventChild->STA_socket, &read_set);
529        FD_SET(pIpcEventChild->pipe_from_parent, &read_set);
530
531#ifndef ANDROID
532        ret = select(max(pIpcEventChild->pipe_from_parent,pIpcEventChild->STA_socket) + 1,
533                    &read_set, NULL, NULL, NULL);
534#else
535        ret = select(pIpcEventChild->STA_socket + 1,
536                    &read_set, NULL, NULL, NULL);
537#endif
538
539        if(ret < 0)
540        {
541            os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Child - Unhandled signal - exiting...\n");
542            break;
543        }
544        if(ret == 0)    {     continue; }      /* Check for interface discovery events. */
545        if(FD_ISSET(pIpcEventChild->STA_socket, &read_set))
546            IpcEvent_Handle_STA_Event(pIpcEventChild);
547
548#ifndef ANDROID
549        if(FD_ISSET(pIpcEventChild->pipe_from_parent, &read_set))
550        {
551            S32 exit = IpcEvent_Handle_Parent_Event(pIpcEventChild);
552             if(exit)
553                break;
554        }
555#endif
556
557    }
558
559    IpcEvent_Child_Destroy(pIpcEventChild);
560}
561
562/* functions */
563/*************/
564THandle IpcEvent_Create(VOID)
565{
566    IpcEvent_t* pIpcEvent = (IpcEvent_t*)os_MemoryCAlloc(sizeof(IpcEvent_t), sizeof(U8));
567    if(pIpcEvent == NULL)
568    {
569        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant allocate control block\n");
570        return NULL;
571    }
572
573    /* create a shared memory space */
574    pIpcEvent->p_shared_memory = mmap(0, sizeof(IpcEvent_Shared_Memory_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
575    if ( pIpcEvent->p_shared_memory == ((PVOID)-1))
576    {
577        os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant allocate shared memory\n");
578        IpcEvent_Destroy(pIpcEvent);
579        return NULL;
580    }
581
582    /* create a pipe */
583    pipe(pIpcEvent->p_shared_memory->pipe_fields);
584
585    /* set the event mask to all disabled */
586    pIpcEvent->p_shared_memory->event_mask = 0;
587
588    /* Create a child process */
589    pIpcEvent->child_process_id = fork();
590
591    if (0 == pIpcEvent->child_process_id)
592    {
593        /******************/
594        /* Child process */
595        /****************/
596        IpcEvent_Child_t* pIpcEventChild = (IpcEvent_Child_t*)os_MemoryCAlloc(sizeof(IpcEvent_Child_t), sizeof(U8));
597        if(pIpcEventChild == NULL)
598        {
599            os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcEvent_Create - cant allocate child control block\n");
600            _exit(1);
601        }
602
603        pIpcEventChild->p_shared_memory = pIpcEvent->p_shared_memory;
604
605        pIpcEventChild->pipe_from_parent = pIpcEventChild->p_shared_memory->pipe_fields[PIPE_READ];
606        close(pIpcEventChild->p_shared_memory->pipe_fields[PIPE_WRITE]);
607
608        IpcEvent_Child(pIpcEventChild);
609
610        os_MemoryFree(pIpcEventChild);
611
612        _exit(0);
613    }
614
615    pIpcEvent->pipe_to_child = pIpcEvent->p_shared_memory->pipe_fields[PIPE_WRITE];
616    close(pIpcEvent->p_shared_memory->pipe_fields[PIPE_READ]);
617
618    return pIpcEvent;
619}
620
621VOID IpcEvent_Destroy(THandle hIpcEvent)
622{
623    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
624
625    if((pIpcEvent->p_shared_memory != ((PVOID)-1)) && (pIpcEvent->p_shared_memory))
626    {
627        munmap(pIpcEvent->p_shared_memory, sizeof(IpcEvent_Shared_Memory_t));
628    }
629
630    /* kill child process */
631    kill(pIpcEvent->child_process_id, SIGKILL);
632
633     os_MemoryFree(pIpcEvent);
634
635}
636
637S32 IpcEvent_EnableEvent(THandle hIpcEvent, U32 event)
638{
639    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
640
641    if(pIpcEvent->p_shared_memory->event_mask & ((u64)1 << event))
642    {
643        return EOALERR_IPC_EVENT_ERROR_EVENT_ALREADY_ENABLED;
644    }
645    else
646    {
647       pIpcEvent->p_shared_memory->event_mask |= ((u64)1 << event);
648    }
649
650    return OK;
651
652}
653
654S32 IpcEvent_DisableEvent(THandle hIpcEvent, U32 event)
655{
656    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
657
658    if(!(pIpcEvent->p_shared_memory->event_mask & (1 << event)))
659    {
660        return EOALERR_IPC_EVENT_ERROR_EVENT_ALREADY_DISABLED;
661    }
662    else
663    {
664        pIpcEvent->p_shared_memory->event_mask &= ~(1 << event);
665    }
666
667    return OK;
668}
669
670S32 IpcEvent_UpdateDebugLevel(THandle hIpcEvent, S32 debug_level)
671{
672    IpcEvent_t* pIpcEvent = (IpcEvent_t*)hIpcEvent;
673
674    pIpcEvent->p_shared_memory->content.debug_level = debug_level;
675    IpcEvent_SendMessageToChild(pIpcEvent, (PS8)IPC_EVENT_MSG_UPDATE_DEBUG_LEVEL);
676
677    return OK;
678}
679
680