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