• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
IpcSta_Sockets_Open(VOID)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@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  */
IpcSta_Sockets_Close(S32 skfd)103 static inline VOID IpcSta_Sockets_Close(S32 skfd)
104 {
105     close(skfd);
106 }
107 
108 
109 /* functions */
110 /*************/
IpcSta_Create(const PS8 device_name)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 
IpcSta_Destroy(THandle hIpcSta)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 
IPC_STA_Private_Send(THandle hIpcSta,U32 ioctl_cmd,PVOID bufIn,U32 sizeIn,PVOID bufOut,U32 sizeOut)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 
IPC_STA_Wext_Send(THandle hIpcSta,U32 wext_request_id,PVOID p_iwreq_data,U32 len)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