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 <stdio.h> 22 #include <string.h> 23 #include <errno.h> 24 25 #include <sys/ioctl.h> 26 #include <sys/socket.h> 27 #include <linux/if.h> 28 #include <linux/wireless.h> 29 #include <stdlib.h> 30 31 #include <unistd.h> 32 33 #include "tiioctl.h" 34 35 #include "osDot11.h" 36 #include "linux_ioctl_common.h" 37 #include "cli_cu_common.h" 38 39 #include "TI_IPC_Api.h" 40 41 42 static int g_socket = 0; /* socket descriptor */ 43 44 static int iw_sockets_open(void) 45 { 46 /* int netlink_sock = -1; */ /* Kernel user interface device */ 47 int ipx_sock = -1; /* IPX socket */ 48 int ax25_sock = -1; /* AX.25 socket */ 49 int inet_sock = -1; /* INET socket */ 50 int ddp_sock = -1; /* Appletalk DDP socket */ 51 52 /* 53 * Now pick any (exisiting) useful socket family for generic queries 54 * Note : don't open all the socket, only returns when one matches, 55 * all ocols might not be valid. 56 * Workaround by Jim Kaba <jkaba (at) sarnoff.com> 57 * Note : in 99% of the case, we will just open the inet_sock. 58 * The remaining 1% case are not fully correct... 59 */ 60 /*netlink_sock=socket(PF_NETLINK, SOCK_DGRAM, 0); 61 if(netlink_sock!=-1) 62 return netlink_sock;*/ 63 inet_sock=socket(AF_INET, SOCK_DGRAM, 0); 64 if(inet_sock!=-1) 65 return inet_sock; 66 ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0); 67 if(ipx_sock!=-1) 68 return ipx_sock; 69 ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0); 70 if(ax25_sock!=-1) 71 return ax25_sock; 72 ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0); 73 /* 74 * If this is -1 we have no known network layers and its time to jump. 75 */ 76 return ddp_sock; 77 } 78 79 80 TI_HANDLE IPC_DeviceOpen (tiVOID* pAdapterName) 81 { 82 g_socket = iw_sockets_open(); 83 if( g_socket == -1 ) 84 { 85 perror("socket"); 86 return 0; 87 } 88 /* create interfaces for events receiving */ 89 /* 90 if (_ipc_CreateInterface(pAdapterName)) 91 { 92 print_err("**IPC error**\n"); 93 return NULL; 94 } 95 */ 96 return (pAdapterName && *((char *) pAdapterName)) ? (TI_HANDLE) pAdapterName : NULL; 97 } 98 99 tiINT32 IPC_DeviceClose(TI_HANDLE hDevice) 100 { 101 if( g_socket ) 102 close( g_socket ); 103 return 0; 104 } 105 106 tiINT32 IPC_DeviceIoControl(TI_HANDLE hDevice, tiUINT32 ioctl_cmd, tiVOID* bufIn, tiUINT32 sizeIn, 107 tiVOID* bufOut, tiUINT32 sizeOut, tiUINT32* sizeRet ) 108 109 { 110 int res, max_size, cmd; 111 struct ifreq req; 112 tiioctl_req_t *ti_req = (tiioctl_req_t *) &req.ifr_ifru; 113 tiVOID* buf, *setget_buf = NULL; 114 tiUINT32 size; 115 int cmd_type = ((bufOut) ? IOCTL_GET : 0) | ((bufIn) ? IOCTL_SET : 0); 116 if( !g_socket ) 117 { 118 print_err("**Socket error**\n"); 119 return -EINVAL; 120 } 121 122 if( (cmd_type & IOCTL_SETGET) == IOCTL_SETGET ) 123 { 124 size = max( max(sizeIn, sizeOut ), 8 ); /* always pass as pointer to buffer*/ 125 if( size >= 0xFFFF ) 126 { 127 print_err("Max. size for SET_GET ioctl - %u bytes (sizeIn=%u, sizeOut=%u)\n", 128 0xFFFF, sizeIn, sizeOut ); 129 return -ENOMEM; 130 } 131 buf = setget_buf = malloc(size); 132 if( !setget_buf ){ 133 print_err("IPC_DeviceIoControl: setget_buf is NULL\n"); 134 return -ENOMEM; 135 } 136 memmove(setget_buf, bufIn, sizeIn ); 137 138 cmd = SIOCDEVPRIVATE; 139 } 140 else 141 { 142 if( cmd_type & IOCTL_GET ) 143 { 144 buf = bufOut; 145 size = sizeOut; 146 cmd = SIOCDEVPRIVATE+1; /* for GET private ioctls */ 147 } 148 else 149 { 150 buf = bufIn; 151 size= sizeIn; 152 cmd = SIOCDEVPRIVATE; /* for SET private ioctls */ 153 } 154 } 155 #if DEBUG 156 memset(&req, 0xfe, sizeof(req) ); 157 #endif 158 print_deb("===IPC_DeviceIoControl('%s', cmd=%u (%s%s), data=%p (%#x), size=%u, sizeRet = %p(%x))\n", 159 (char *) hDevice, ioctl_cmd, 160 (cmd_type & IOCTL_SET) ? "SET" : "", (cmd_type & IOCTL_GET) ? "GET" : "", 161 buf, (buf) ? * (tiINT32 *)buf : 0, size, sizeRet, sizeRet ? *sizeRet : -1); 162 163 max_size = ((char *) &req + sizeof(req)) - (char *) &ti_req->user_data_pointer; 164 165 ti_req->length = size; 166 ti_req->cmd = ioctl_cmd; 167 ti_req->cmd_type = cmd_type; 168 169 if( size > max_size ) 170 { 171 ti_req->user_data_pointer = (tiUINT32) buf; 172 } 173 else 174 { 175 if( cmd_type & IOCTL_SET ) /* SET ioctl */ 176 { 177 /*print_deb("util_get_ioctl(): offset=%d, data='%s', size=%d\n", offset, (char *)data, size);*/ 178 memmove( ((tiCHAR *) &ti_req->user_data_pointer), buf, size ); 179 } 180 else 181 ti_req->user_data_pointer = 0; 182 } 183 184 strncpy(req.ifr_ifrn.ifrn_name, (char *) hDevice, IFNAMSIZ); 185 186 print_deb("===== send_ioctl: socket=%d, cmd=%d, &req=%p\n", g_socket, cmd, &req ); 187 print_deb("===== send_ioctl: req={name='%s', sub_cmd=%ld, size=%ld (max=%d), data=%p\n", 188 req.ifr_ifrn.ifrn_name, ti_req->cmd, ti_req->length, max_size, (void *) ti_req->user_data_pointer ); 189 190 /* print_memory_dump( (char *) &req, sizeof(req));*/ 191 res = ioctl(g_socket, cmd, &req); 192 #ifdef GWSI_DRIVER 193 /* Yuck - set the result to 0 in case ioctl return error */ 194 if (res == -1) res = 0; 195 #endif 196 if( res ) 197 { /* for DEBUG version ONLY*/ 198 print_deb( "** IPC_DeviceIoControl() return %d\n", res /*(char *) hDevice*/ ); 199 /* return res;*/ 200 } 201 else 202 { 203 if( cmd_type & IOCTL_GET ) 204 { 205 size = ti_req->length; 206 207 if( (cmd_type & IOCTL_SETGET) == IOCTL_SETGET ) 208 { 209 memmove(bufOut,setget_buf,size); 210 free( setget_buf ); 211 } 212 else 213 { 214 if( size <= max_size ) 215 memmove( buf, (char *) &ti_req->user_data_pointer, size ); 216 print_memory_dump((char *) buf, min(32, size) ); 217 print_deb( "IPC_DeviceIoControl(): Size=%u, max_size=%d, *data=%x\n", size, max_size, * (tiUINT32*) buf ); 218 } 219 } 220 221 if( sizeRet ) 222 *sizeRet = size; /* ti_req->length */ 223 224 print_deb("===== send_ioctl: res=%d, sizeRet=%p (%x)\n", res, sizeRet, sizeRet ? *sizeRet : -1); 225 } 226 227 return res; 228 } 229 230 231 /* --------------------------------------------------------- */ 232 233 234 235 /* tiINT32 TI_hwReset (TI_HANDLE hAdapter)*/ 236 /* {*/ 237 /* tiUINT32 data = 1;*/ 238 /* return IPC_DeviceIoControl( hAdapter, TIWLN_HW_RESET_HW, IOCTRL_SET, &data, sizeof(data) );*/ 239 /* return tiwlan_get_ioctl(hAdapter, -1, TIWLN_HW_RESET_HW, &data, sizeof(data) ); */ 240 /* }*/ 241 242 /* tiINT32 TI_NumberOfAntennas (TI_HANDLE hAdapter, tiUINT32* puNumberOfAntennas )*/ 243 /* {*/ 244 /* return IPC_DeviceIoControl( hAdapter, TIWLN_802_11_NUMBER_OF_ANTENNAS, IOCTRL_GET, puNumberOfAntennas, sizeof(tiUINT32) );*/ 245 /* }*/ 246 247 248 /* int tiwlan_set_mixed_mode( U32 drv_handler, U32 data )*/ 249 /* {*/ 250 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_MIXED_MODE_SET, &data, sizeof(data) );*/ 251 /* }*/ 252 /* */ 253 /* int tiwlan_get_mixed_mode( U32 drv_handler, U32 *p_data )*/ 254 /* {*/ 255 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_MIXED_MODE_GET, p_data, sizeof(*p_data) );*/ 256 /* }*/ 257 /* */ 258 /* int tiwlan_set_privacy_mode( U32 drv_handler, U32 data )*/ 259 /* {*/ 260 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_PRIVACY_MODE_SET, &data, sizeof(data) );*/ 261 /* }*/ 262 /* */ 263 /* int tiwlan_get_privacy_mode( U32 drv_handler, U32 *p_data )*/ 264 /* {*/ 265 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_PRIVACY_MODE_GET, p_data, sizeof(*p_data) );*/ 266 /* }*/ 267 /* */ 268 /* int tiwlan_set_exc_security_type( U32 drv_handler, U32 data )*/ 269 /* {*/ 270 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_EXC_SECURITY_TYPE_SET, &data, sizeof(data) );*/ 271 /* }*/ 272 /* */ 273 /* int tiwlan_get_exc_security_type( U32 drv_handler, U32 *p_data )*/ 274 /* {*/ 275 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_EXC_SECURITY_TYPE_GET, p_data, sizeof(*p_data) );*/ 276 /* }*/ 277 /* int tiwlan_set_tx_power_val( U32 drv_handler, U32 data )*/ 278 /* {*/ 279 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_TX_POWER_VALUE_SET, &data, sizeof(data) );*/ 280 /* }*/ 281 /* */ 282 /* int tiwlan_get_tx_power_val( U32 drv_handler, U32 *p_data )*/ 283 /* {*/ 284 /* print_deb("===GET_TX_POWER_VAL: %d\n", TIWLN_TX_POWER_VALUE_GET );*/ 285 /* return tiwlan_get_ioctl( g_id_adapter, -1, TIWLN_TX_POWER_VALUE_GET, p_data, sizeof(*p_data) );*/ 286 /* }*/ 287 /* */ 288 289 /* int tiwlan_get_current_mac( TI_HANDLE drv_handler, OS_802_11_MAC_ADDRESS *data)*/ 290 /* {*/ 291 /* return IPC_DeviceIoControl(drv_handler, TIWLN_802_3_CURRENT_ADDRESS, NULL, 0, data, sizeof(*data), NULL);*/ 292 /* }*/ 293 294 /* int tiwlan_get_current_channel(TI_HANDLE drv_handler, tiUINT32 *data)*/ 295 /* {*/ 296 /* return IPC_DeviceIoControl( drv_handler, TIWLN_802_11_CHANNEL_GET, NULL, 0, data, sizeof(data), NULL );*/ 297 /* }*/ 298 299 /* int tiwlan_get_desired_ssid(TI_HANDLE drv_handler, char *data)*/ 300 /* {*/ 301 /* OS_802_11_SSID ssid = { 0 };*/ 302 /* int res = IPC_DeviceIoControl( drv_handler, TIWLN_802_11_DESIRED_SSID_GET, NULL, 0, &ssid, sizeof(OS_802_11_SSID), NULL );*/ 303 /* if( !res )*/ 304 /* {*/ 305 /* memmove(data, ssid.Ssid, ssid.SsidLength );*/ 306 /* data[ssid.SsidLength] = 0;*/ 307 /* }*/ 308 /* return res;*/ 309 /* }*/ 310 311 312 void print_memory_dump(char *addr, int size ) 313 { 314 int i; 315 char buf[4096]; 316 317 if( size * 4 > sizeof(buf) ) 318 { 319 print_err("print_memory_dump(): buffer too small\n"); 320 return; 321 } 322 323 buf[0] = 0; 324 for(i=0; i<size; i++ ) 325 { 326 if( !(i % 16) ) 327 sprintf(&buf[strlen(buf)], "%sTI_CU:%p: ", (i) ? "\n" : "", addr+i ); 328 sprintf(&buf[strlen(buf)], "%02x ", (unsigned char) addr[i] ); 329 } 330 print_deb("%s\n", buf); 331 } 332 333