Home | History | Annotate | Download | only in src
      1 /*
      2  * ipc_sta.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_STA.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 <errno.h>
     38 #include <sys/ioctl.h>
     39 #include <unistd.h>
     40 #include <linux/wireless.h>
     41 #include "cu_osapi.h"
     42 #include "oserr.h"
     43 #include "STADExternalIf.h"
     44 #include "ipc_sta.h"
     45 
     46 /* defines */
     47 /***********/
     48 
     49 /* local types */
     50 /***************/
     51 /* Module control block */
     52 typedef struct IpcSta_t
     53 {
     54     struct iwreq    wext_req;
     55     ti_private_cmd_t private_cmd;
     56     S32 STA_socket;
     57 
     58 } IpcSta_t;
     59 
     60 /* local variables */
     61 /*******************/
     62 
     63 /* local fucntions */
     64 /*******************/
     65 
     66 /*
     67  * IpcSta_Sockets_Open - Open a socket.
     68  * Depending on the protocol present, open the right socket. The socket
     69  * will allow us to talk to the driver.
     70  */
     71 static S32 IpcSta_Sockets_Open(VOID)
     72 {
     73     static const S32 families[] = {
     74         AF_INET, AF_IPX, AF_APPLETALK
     75     };
     76     U32    i;
     77     S32    sock;
     78 
     79     /*
     80     * Now pick any (exisiting) useful socket family for generic queries
     81     * Note : don't open all the socket, only returns when one matches,
     82     * all protocols might not be valid.
     83     * Workaround by Jim Kaba <jkaba (at) sarnoff.com>
     84     * Note : in 2001% of the case, we will just open the inet_sock.
     85     * The remaining 2002% case are not fully correct...
     86     */
     87 
     88     /* Try all families we support */
     89     for(i = 0; i < sizeof(families)/sizeof(int); ++i)
     90     {
     91         /* Try to open the socket, if success returns it */
     92         sock = socket(families[i], SOCK_DGRAM, 0);
     93         if(sock >= 0)
     94             return sock;
     95     }
     96 
     97     return -1;
     98 }
     99 
    100 /*
    101  * IpcSta_Sockets_Close - Close the socket used for ioctl.
    102  */
    103 static inline VOID IpcSta_Sockets_Close(S32 skfd)
    104 {
    105     close(skfd);
    106 }
    107 
    108 
    109 /* functions */
    110 /*************/
    111 THandle IpcSta_Create(const PS8 device_name)
    112 {
    113     IpcSta_t* pIpcSta = (IpcSta_t*)os_MemoryCAlloc(sizeof(IpcSta_t), sizeof(U8));
    114     if(pIpcSta == NULL)
    115     {
    116         os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcSta_Create - cant allocate control block\n");
    117         return NULL;
    118     }
    119 
    120     /* open the socket to the driver */
    121     pIpcSta->STA_socket = IpcSta_Sockets_Open();
    122     if(pIpcSta->STA_socket == -1)
    123     {
    124         os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IpcSta_Create - cant open socket for communication with the driver\n");
    125         return NULL;
    126     }
    127 
    128     /* set the driver name */
    129     os_strcpy((PS8)pIpcSta->wext_req.ifr_ifrn.ifrn_name, device_name);
    130 
    131     return pIpcSta;
    132 }
    133 
    134 VOID IpcSta_Destroy(THandle hIpcSta)
    135 {
    136     IpcSta_t* pIpcSta = (IpcSta_t*)hIpcSta;
    137 
    138     /* close the socket to the driver */
    139     IpcSta_Sockets_Close(pIpcSta->STA_socket);
    140 
    141     os_MemoryFree(pIpcSta);
    142 }
    143 
    144 S32 IPC_STA_Private_Send(THandle hIpcSta, U32 ioctl_cmd, PVOID bufIn, U32 sizeIn,
    145                                                 PVOID bufOut, U32 sizeOut)
    146 
    147 {
    148     IpcSta_t* pIpcSta = (IpcSta_t*)hIpcSta;
    149     S32 res;
    150 
    151     pIpcSta ->private_cmd.cmd = ioctl_cmd;
    152     if(bufOut == NULL)
    153         pIpcSta ->private_cmd.flags = PRIVATE_CMD_SET_FLAG;
    154     else
    155         pIpcSta ->private_cmd.flags = PRIVATE_CMD_GET_FLAG;
    156 
    157     pIpcSta ->private_cmd.in_buffer = bufIn;
    158     pIpcSta ->private_cmd.in_buffer_len = sizeIn;
    159     pIpcSta ->private_cmd.out_buffer = bufOut;
    160     pIpcSta ->private_cmd.out_buffer_len = sizeOut;
    161 
    162 
    163     pIpcSta->wext_req.u.data.pointer = &pIpcSta->private_cmd;
    164     pIpcSta->wext_req.u.data.length = sizeof(ti_private_cmd_t);
    165     pIpcSta->wext_req.u.data.flags = 0;
    166 
    167     res = ioctl(pIpcSta->STA_socket, SIOCIWFIRSTPRIV, &pIpcSta->wext_req);
    168     if(res != OK)
    169     {
    170         os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IPC_STA_Private_Send - error sending Wext private IOCTL to STA driver (ioctl_cmd = %x,  res = %d, errno = %d)\n", ioctl_cmd,res,errno);
    171         return EOALERR_IPC_STA_ERROR_SENDING_WEXT;
    172     }
    173 
    174     return OK;
    175 }
    176 
    177 S32 IPC_STA_Wext_Send(THandle hIpcSta, U32 wext_request_id, PVOID p_iwreq_data, U32 len)
    178 {
    179     IpcSta_t* pIpcSta = (IpcSta_t*)hIpcSta;
    180     S32 res;
    181 
    182     os_memcpy(&pIpcSta->wext_req.u.data, p_iwreq_data, len);
    183 
    184     res = ioctl(pIpcSta->STA_socket, wext_request_id, &pIpcSta->wext_req);
    185     if(res != OK)
    186     {
    187         os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - IPC_STA_Wext_Send - error sending Wext IOCTL to STA driver (wext_request_id = 0x%x, res = %d, errno = %d)\n",wext_request_id,res,errno);
    188         return EOALERR_IPC_STA_ERROR_SENDING_WEXT;
    189     }
    190 
    191     os_memcpy(p_iwreq_data, &pIpcSta->wext_req.u.data, len);
    192 
    193     return OK;
    194 }
    195 
    196