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 <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