Home | History | Annotate | Download | only in Linux
      1 /*******************************************************************************
      2 **+--------------------------------------------------------------------------+**
      3 **|                                                                          |**
      4 **| Copyright 1998-2008 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 #include <string.h>
     22 #include <stdlib.h>
     23 #include <stdio.h>
     24 #include <errno.h>
     25 #include <sys/types.h>
     26 #include <sys/socket.h>
     27 #include <sys/un.h>
     28 #include <unistd.h>
     29 #include <linux/stddef.h>
     30 #include <linux/netdevice.h>
     31 #include <linux/rtnetlink.h>
     32 
     33 #include <pthread.h>
     34 
     35 #include "ipc_event.h"
     36 #include "cli_cu_common.h"
     37 #include "tiioctl.h"
     38 #include "TI_IPC_Api.h"
     39 
     40 static int dev_socket = -1;
     41 static int serv_sfd = -1;
     42 
     43 config_registry_t cnfg_registry_table;
     44 
     45 UINT32 prId;
     46 
     47 static tiINT32  ipc_start = 0;
     48 /******************************************************************
     49     _ipc_EventHandler
     50     Driver events handler
     51 */
     52 tiVOID _ipc_EventHandler(UINT8* pEvMessage,  tiUINT32 nEvMessageSize )
     53 {
     54 /*    print_memory_dump((char*)pEvMessage, nEvMessageSize );*/
     55 	if (((IPC_EVENT_PARAMS*) pEvMessage)->pfEventCallback == NULL)
     56 	{
     57         printf("\n---_ipc_EventHandler: ERROR Bad Callback pointer\n");
     58         return;
     59 	}
     60 
     61     if(nEvMessageSize < sizeof(IPC_EVENT_PARAMS))
     62     {
     63         print_err("\n---_ipc_EventHandler: ERROR event size - %x\n ",nEvMessageSize);
     64         return;
     65     }
     66     print_deb("--_ipc_EventHandler: \n");
     67     ((IPC_EVENT_PARAMS*) pEvMessage)->pfEventCallback((IPC_EV_DATA * )pEvMessage);
     68 }
     69 /*********************************************************************
     70     _ipc_cu_handler
     71     CLI configuration events handler
     72 */
     73 tiVOID _ipc_cu_handler(UINT8* pMessage,  tiUINT32 nMessageSize)
     74 {
     75     print_deb("\n---_ipc_cu_handler() data size - %d\n ",nMessageSize);
     76 
     77     print_memory_dump((char*)pMessage, nMessageSize );
     78     IPC_CONFIG_PARAMS *pData_tosend = (IPC_CONFIG_PARAMS *)malloc(sizeof(IPC_CONFIG_PARAMS));
     79 
     80     pData_tosend->F_ConfigNotification = cnfg_registry_table.cfg_cb;
     81 
     82     (*pData_tosend->F_ConfigNotification)(pMessage, nMessageSize );
     83 
     84     free(pData_tosend);
     85 }
     86 /*********************************************************************/
     87 
     88 void check_unbound(void)
     89 {
     90 /*
     91     OS_802_11_MAC_ADDRESS curr_mac = { 0 };
     92     UINT32  size;
     93     if(IPC_DeviceIoControl((TI_HANDLE)ti_drv_name, TIWLN_802_3_CURRENT_ADDRESS, NULL, 0, &curr_mac,
     94                                     sizeof(OS_802_11_MAC_ADDRESS),  (tiUINT32*)nSize ))
     95     {
     96         send unbound
     97 
     98     }
     99  */
    100 }
    101 /**************************************************************/
    102 void *_ipc_EventThread(void *args)
    103 {
    104 	/* set timeout for select*/
    105 	int fd;
    106     char* buf = (char*)malloc(4096); /* the maximum acceptable size*/
    107     fd_set fds_read;
    108 	struct nlmsghdr * nlHdr;
    109 	UINT8 * pData;
    110 	tiUINT32 nDataLen;
    111 
    112 	if (dev_socket > serv_sfd)
    113 		fd = dev_socket+1;
    114 	else
    115         fd = serv_sfd+1;
    116 
    117 	print_deb("---_ipc_EventThread() - thread is running fd = %d\n", fd);
    118 
    119 	while(1)
    120 	{
    121 		/* create fd_set*/
    122 		FD_ZERO(&fds_read);
    123 
    124         if (dev_socket != -1)
    125             FD_SET(dev_socket, &fds_read);
    126 
    127         if (serv_sfd != -1)
    128             FD_SET(serv_sfd, &fds_read);
    129 
    130         /* wait for packet on two sockets*/
    131         int n = select(fd, &fds_read, NULL, NULL,NULL );
    132 
    133         /* if data is available, receive it*/
    134         if( n > 0 )
    135         {
    136 			/* this is event from the driver*/
    137 			if( FD_ISSET(dev_socket, &fds_read) )
    138 			{
    139 			    /* get 'n' bytes from driver socket*/
    140                 n = recvfrom(dev_socket, buf, 4096, 0, NULL,NULL/*(struct sockaddr*)&sanl, &sanllen*/);
    141                 if (n <= 0)
    142                 {
    143                     perror(__FUNCTION__);
    144                     continue;
    145                 }
    146 				nlHdr = (struct nlmsghdr *)buf;
    147 
    148 				/* Check if header is valid */
    149 				if((NLMSG_OK(nlHdr, n) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR)){
    150 					perror("Error in recieved NetLink packet");
    151 					continue;
    152 				}
    153 				pData = (UINT8 *)NLMSG_DATA(nlHdr);
    154 				nDataLen = NLMSG_PAYLOAD(nlHdr,n);
    155 				_ipc_EventHandler (pData, nDataLen );
    156 
    157             }
    158 
    159 			else if( FD_ISSET(serv_sfd, &fds_read) )
    160 			{
    161 
    162                 print_deb(" ---_ipc_EventThread() cu receive socket: %x \n",
    163                                                                     serv_sfd);
    164 
    165                 /*printf(" ---_ipc_EventThread() cu receive enable cnfg_registry_table.enable\n");*/
    166 				/* read, get # bytes read*/
    167 
    168 				    n = recvfrom(serv_sfd, buf, 4096, 0,NULL,NULL);
    169 				    if(n < 0)
    170 				    {
    171 					    print_err("--- _ipc_EventThread() -ERROR receiving config msg \n");
    172                         continue;
    173 				    }
    174 				    else
    175                         _ipc_cu_handler((UINT8*) buf, n);
    176 			}
    177 
    178             else
    179                 print_err(" ---_ipc_EventThread() cu not a socket: %x \n",serv_sfd);
    180         }
    181     }
    182 
    183     print_err("IPC exits \n");
    184 
    185     return 0;
    186 }
    187 
    188 
    189 /******************************************************************************/
    190 tiINT32 rtnl_open(void)
    191 {
    192 
    193     int fd;
    194     struct sockaddr_nl      local;
    195     prId = getpid();
    196 
    197     /*printf("PROCCESS: %d\n", prId);*/
    198 
    199     fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
    200     if (fd < 0) {
    201          perror(__FUNCTION__);
    202          return -1;
    203      }
    204 
    205      memset(&local, 0, sizeof(local));
    206      local.nl_family = AF_NETLINK;
    207      /*    local.nl_groups = RTMGRP_LINK;*/
    208      local.nl_pid = prId;
    209 
    210      if (bind(fd, (struct sockaddr*)&local, sizeof(local)) < 0) {
    211          perror(__FUNCTION__);
    212          return -1;
    213      }
    214      /*printf("User: socket - %d\n",fd);*/
    215      return fd;
    216 
    217 
    218 }
    219 /*****************************************************************************/
    220 tiINT32 cnfg_open(void)
    221 {
    222 	/*int rc;*/
    223 	struct sockaddr_un serv_addr;/* clnt_addr;*/
    224 
    225 	int serv_addr_len;/* clnt_addr_len, max_clnt_len, n;*/
    226 
    227     unlink("/var/run/echo_server");
    228 	/* Create socket */
    229 	if(( serv_sfd = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)
    230 	{
    231 		print_err("--Server: error creating socket\n");
    232 		return -1;
    233 	}
    234     print_deb("---cnfg_open(): socket - %d\n", serv_sfd);
    235 	/*bzero(serv_addr,sizeof(serv_addr));*/
    236 	/* Store the client s name in the socket address. */
    237 	serv_addr.sun_family = AF_LOCAL;
    238 	strcpy (serv_addr.sun_path, "/var/run/echo_server");
    239 
    240 	serv_addr_len = sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path);
    241 
    242 	if(bind(serv_sfd, (struct sockaddr*)&serv_addr, serv_addr_len) <0 )
    243 	{
    244 		print_err("--Server: error binding to server socket - err %d(%s)\n", errno, strerror(errno));
    245 		return -1;
    246 	}
    247 	return 0;
    248 }
    249 /*****************************************************************************/
    250 tiINT32 ipc_interfaces_init(tiVOID)
    251 {
    252 	int                 rc;
    253     pthread_t           ev_thread_id;
    254 
    255 
    256 	/* Open netlink channel */
    257     if((dev_socket = rtnl_open()) < 0)
    258     {
    259       printf("\nCan't initialize rtnetlink socket\n");
    260       return -1;
    261     }
    262     print_deb("---ipc_interfaces_init - rtnetlink socket  is created \n");
    263     rc = pthread_create(&ev_thread_id, NULL, _ipc_EventThread, (void*)NULL);
    264 
    265     print_deb("---ipc_CreateInterface() - thread is created \n");
    266 	if (rc)
    267 		printf("---ipc_CreateInterface() - ERROR code from pthread_create() is %d\n", rc);
    268 	return 0;
    269 }
    270 /******************************************************************************/
    271 tiINT32 IPC_RegisterEvent(TI_HANDLE hDevice, IPC_EVENT_PARAMS* 	pEvParams)
    272 {
    273 
    274     /*set ioctl event enable*/
    275     IPC_EVENT_PARAMS* pReg = (IPC_EVENT_PARAMS*)pEvParams;
    276     IPC_EVENT_PARAMS ouput;
    277     tiINT32 res;
    278     tiUINT32 bytesReturned;
    279 
    280     if(pReg->uEventType == IPC_EVENT_UNBOUND)/*insert UNBOUND*/
    281     {
    282 		return 0;
    283     }
    284 
    285 
    286     pEvParams->uDeliveryType = DELIVERY_PUSH;
    287     pEvParams->uProcessID = prId;
    288     print_deb("---IPC_RegisterEvent() event - %#x\n",  pReg->uEventType);
    289     res = IPC_DeviceIoControl(hDevice, TIWLN_802_11_ENABLE_EVENT, (tiVOID*)pEvParams, sizeof(IPC_EVENT_PARAMS), /*NULL,0*/&ouput, sizeof(IPC_EVENT_PARAMS), &bytesReturned );
    290     pReg->uEventID = ouput.uEventID;
    291     return res;
    292 
    293 }
    294 /******************************************************************************/
    295 tiINT32 IPC_UnRegisterEvent(TI_HANDLE hDevice, IPC_EVENT_PARAMS* pEvParams)
    296 {
    297     UINT32 id = (UINT32)pEvParams->uEventID;
    298     tiUINT32 bytesReturned;
    299 
    300     /*set ioctl event disable*/
    301     return IPC_DeviceIoControl(hDevice, TIWLN_802_11_DISABLE_EVENT, (tiVOID*)&id, sizeof(UINT32), NULL, 0, &bytesReturned );
    302 }
    303 /******************************************************************************/
    304 tiINT32 IPC_RegisterConfig(tiVOID* pEvParams, tiUINT32 EvParamsSize)
    305 {
    306     /*set ioctl event enable*/
    307 
    308     IPC_CONFIG_PARAMS	*pData      = (IPC_CONFIG_PARAMS*)pEvParams;
    309 
    310     cnfg_registry_table.len = EvParamsSize;
    311     cnfg_registry_table.cfg_cb = pData->F_ConfigNotification;
    312     cnfg_registry_table.enable = 1;
    313     print_deb("---IPC_RegisterConfig() l - %x \n", cnfg_registry_table.len);
    314     return 0;
    315 
    316 }
    317 
    318 /*****************************************************************************/
    319 TI_HANDLE IPC_Init(void)
    320 {
    321     int rc = 0;
    322     if(ipc_start)
    323         return (TI_HANDLE)rc;
    324     else
    325     {
    326         rc = ipc_interfaces_init();
    327         ipc_start++;
    328     }
    329     return (TI_HANDLE)rc;
    330 
    331 }
    332 /*****************************************************************************/
    333 tiINT32 IPC_DeInit (void)
    334 {
    335    /* close(dev_socket );*/
    336    /* close(serv_sfd );*/
    337     return 0;
    338 }
    339