From: Anders J. <and...@us...> - 2003-11-06 19:12:54
|
The following files were modified in linux/drivers/char/bluetooth: Name Old version New version Tag Comment ---- ----------- ----------- --- ------- bluetooth.c 1.242 1.243=20=20=20=20=20=20=20=20=20=20=20=20=20 hci.c 1.211 1.212=20=20=20=20=20=20=20=20=20=20=20=20=20 The accompanying log: Added IOCTL:s to write/read pincode type.=20 The diff of the modified file(s): --- bluetooth.c 2003/11/05 19:03:12 1.242 +++ bluetooth.c 2003/11/06 19:12:52 1.243 @@ -1634,6 +1634,33 @@ hci_inq_exit0: return name_request_response[0]; } =20 + case HCIREADPINTYPE: + { + tmp =3D hci_read_pin_type(); + if(tmp < 0) + { + tmp =3D -MSGCODE(MSG_LAYER_HCI, -tmp); + } +=09=09 + put_user(tmp, (s32*) arg); + break; + } + + case HCIWRITEPINTYPE: + { + u8 type; + GET_USER(tmp, (s32*)arg); + type =3D (u8)(tmp & 0xff); + BT_DRIVER("BTWRITEPINTYPE: %d\n", type); + tmp =3D hci_write_pin_type(type); + if(tmp < 0) + { + tmp =3D -MSGCODE(MSG_LAYER_HCI, -tmp); + } + put_user(tmp, (s32*)arg); + break; + }=20=20=20 + default: return -ENOIOCTLCMD; } --- hci.c 2003/11/05 15:21:58 1.211 +++ hci.c 2003/11/06 19:12:52 1.212 @@ -1583,6 +1583,29 @@ process_return_param(u8 *buf) D_CMD(__FUNCTION__ ": WRITE_NUM_BROADCAST_RETRANSMISSIONS \n "); break; =20 + case READ_PIN_TYPE: + D_CMD(__FUNCTION__ ": READ_PIN_TYPE\n"); + if (r_val[0]) { + D_ERR(__FUNCTION__ ": READ_PIN_TYPE: %s\n",=20 + get_err_msg(r_val[0])); + result_param =3D -r_val[0]; + } else { + result_param =3D r_val[1]; + D_CMD(__FUNCTION__ ": READ_PIN_TYPE: %s\n", r_val[1] ? "Fixed" : "Vari= able"); + } + break; + + case WRITE_PIN_TYPE: + D_CMD(__FUNCTION__ ": WRITE_PIN_TYPE\n"); + if (r_val[0]) { + D_ERR(__FUNCTION__ ": WRITE_PIN_TYPE: %s\n",=20 + get_err_msg(r_val[0])); + result_param =3D -r_val[0]; + } else { + D_CMD(__FUNCTION__ ": WRITE_PIN_TYPE Success\n"); + result_param =3D 0; + } + break; =20 default: D_CMD(__FUNCTION__ ": HCI_HC, ocf %d not recognised!\n", ocf); @@ -3538,6 +3561,31 @@ s32 hci_read_rssi(u32 hdl) tmp =3D send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN); =20 return (tmp<0)|(result_param=3D=3D256) ? 2<<8 : result_param|(1<<8); +} + +s32 hci_read_pin_type(void) +{ + s32 tmp; + c_pkt.type =3D CMD_PKT; + c_pkt.opcode =3D hci_put_opcode(READ_PIN_TYPE, HCI_HC); + c_pkt.len =3D 0; + if((tmp =3D send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HD= R_LEN, DEFAULT_TIMEOUT)) < 0) { + return tmp; + } + return result_param; +} + +s32 hci_write_pin_type(u8 type) +{ + s32 tmp; + c_pkt.type =3D CMD_PKT; + c_pkt.opcode =3D hci_put_opcode(WRITE_PIN_TYPE, HCI_HC); + c_pkt.data[0] =3D type; + c_pkt.len =3D 1;=09 + if((tmp =3D send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HD= R_LEN, DEFAULT_TIMEOUT)) < 0) { + return tmp; + } + return result_param; } =20 /* Sends a connect request to the BT unit with the address bd_addr */ |
From: Anders J. <and...@us...> - 2004-01-09 15:27:20
|
The following files were modified in linux/drivers/char/bluetooth: Name Old version New version Tag Comment ---- ----------- ----------- --- ------- bluetooth.c 1.246 1.247=20=20=20=20=20=20=20=20=20=20=20=20=20 sdp.c 1.91 1.92=20=20=20=20=20=20=20=20=20=20=20=20=20=20 The accompanying log: * Cleanup of old sdp-stuff, bt-lines are now only usable for RFCOMM. * Added IOCTL to send SDP-queries from userspace. The diff of the modified file(s): --- bluetooth.c 2003/11/18 18:03:32 1.246 +++ bluetooth.c 2004/01/09 15:27:18 1.247 @@ -213,7 +213,6 @@ static s32 bt_disconnect(u32 con_id); static const u8* psmname(u16 psm); #endif static void wq_timeout(unsigned long ptr); -static s32 bt_execute_sdp_request(bt_sdp_request *sdpRequest); =20 #ifdef __USE_OLD_SYMTAB__ /* @@ -574,28 +573,49 @@ __bt_ioctl(struct tty_struct *tty, struc switch (cmd) { case BT_SDP_REQUEST: { - bt_sdp_request sdpRequest; + bt_sdp_request *sdpRequest; int returnValue =3D -1; + u16 len; =20 /* Copy arguments to kernel space */ =20 BT_DRIVER(__FUNCTION__ ": Copying arguments from user to kernel space\n"= ); - copy_from_user(&sdpRequest, (s32*)arg, size); =20 - /* Now execute the request */ + /* First two bytes specifies size of data */ + copy_from_user(&len, (s32*)arg, 2); =20 - BT_DRIVER(__FUNCTION__ ": Executing bt_execute_sdp_request\n"); + if(!(sdpRequest =3D (bt_sdp_request *)kmalloc(sizeof(bt_sdp_request) += =20 + len, GFP_KERNEL))) { + D_ERR("%s: Failed to allocate memory\n", __FUNCTION__); + return -ENOMEM; + } =20 - if ((returnValue =3D bt_execute_sdp_request(&sdpRequest)) >=3D 0) { + copy_from_user(sdpRequest, (s32*)arg, sizeof(bt_sdp_request) + len); =20 - /* Copy the data back to user space and return */ + /* Allocate memory for the data * =20 - BT_DRIVER(__FUNCTION__ ": Copying data back to user space\n"); - copy_to_user((s32*)arg, &sdpRequest, size); - } + /* Now execute the request */ + + BT_DRIVER("%s: Executing bt_execute_sdp_request\n", __FUNCTION__); =20 + if ((returnValue =3D sdp_query(sdpRequest)) >=3D 0) { + /* Copy the data back to user space and return */ + copy_to_user((s32*)arg, sdpRequest,=20 + MIN(sdpRequest->allocated, sdpRequest->len) + sizeof(bt_sdp_reque= st)); + } + kfree(sdpRequest); return returnValue; } + case SDPCONNECT: + { + u8 *bd_addr; + /* argument is an object with all info to start a remote + connection */ + copy_from_user(&btcon, (s32*)arg, size); + BT_DRIVER(__FUNCTION__ ": SDP_CONNECT\n"); + return sdp_connect(btcon.bd, &btcon.pincode); + } +=09 =20 #ifdef CONFIG_BLUETOOTH_USE_SECURITY_MANAGER case BT_GETCACHEDLINKKEY: @@ -2289,52 +2309,6 @@ hci_receive_data_task(void) } #endif /* CONFIG_BLUETOOTH_USE_INBUFFER */ =20 - -/* - * Searches data buffer for number of completed packets (NCP) - * If only NCP data was found tell serial driver not to - * schedule a flip of DMA inbuffer. - */ -int bt_catch_ncp(u8* data, u32 count) -{ - int index =3D 0; - - /* fixme -- do this for BCSP as well */ -#ifdef CONFIG_BLUETOOTH_SUPPORT_BCSP - if (bt_use_bcsp(-1)) - return 0; -#endif - - /* || uart hdr | event code | par_len | nbr_handles | [data...] || */ - - while (index+2 < count && - data[index] =3D=3D EVENT_PKT && - data[index+1] =3D=3D NBR_OF_COMPLETED_PACKETS) { - /* we found a NCP */ - index +=3D (3 + data[index + 2]); /* event hdr + par len */ - } - - if (index =3D=3D count) { - /* Contains _only_ NCP data, parse it ! */ - - /* The easy way would be to call bt_receive_data(data, count), - but since it calls hci_receive_data() which is a state - machine, we might mess up its state... */ - index =3D 0; - while (index+2 < count) { - update_ncp(data[index+3], data+index+4); - index +=3D (3 + data[index + 2]); - } - - return 1; - } - - /* Contains more than NCP data, tell serial - driver to queue it up as usual */ - return 0; -} - - static void bt_receive_data(u8* data, u32 count) { @@ -2400,67 +2374,6 @@ bt_connect(bt_connection *btcon) } break; =20 - case SDP_LAYER: - { - int sdp_connection_id =3D -1; - int return_value; - - /* Initiate the connection */ - - BT_DRIVER(__FUNCTION__ ": Connecting SDP on line %d\n", line); - BT_DATADUMP("Remote BD: ", bd_addr, 6); - if ((sdp_connection_id =3D sdp_connect_req(bd_addr, line, &btcon->pincod= e)) >=3D 0) { - - /* - * If here, we have successfully created an SDP - * connection entry and are starting the sequence of - * opening an l2cap connection. Allow the bottom - * half to process the request and get back to us. - */ - - /* I seem to be having a lot of trouble with the L2CAP - traffic just not appearing on this side of the link - while I'm waiting for the SDP conneciton to finish - up. So let's start a timer to wake us up if things - don't appear to be working out. - --gmcnutt - */ - start_wq_timer(&bt_ctrl.bt_timer[line], BT_CON_TIMEOUT, - &bt_ctrl.connect_wq[line]); - - /* The timeout routine doesn't have a hendle to our - session status, so set things up to reflect a - timeout error by default. If we really do get a - connection then this value _should_ be changed by - the time we wake up to reflect a good connection. - --gmcnutt - */ - bt_ctrl.session[line].connect_status =3D -ETIMEDOUT; - - BT_DRIVER(__FUNCTION__ ": Sleep on line %d\n", line); - interruptible_sleep_on(&bt_ctrl.connect_wq[line]); - release_wq_timer(&bt_ctrl.bt_timer[line]); - - /* - * If the connect_status is >=3D 0, then the lower - * stack did not have a problem handling the request. - * Therefore return the sdp_connection_id - */ - - BT_DRIVER(__FUNCTION__ ": Wake up - line %d\n", line); - if (bt_ctrl.session[line].connect_status >=3D 0) { - return_value =3D sdp_connection_id; - } else { - return_value =3D bt_ctrl.session[line].connect_status; - } - } else { - return_value =3D sdp_connection_id; - } - - return return_value; - } - break; - case L2CAP_TEST_LAYER: case L2CAP_TEST2_LAYER: case L2CAP_TEST3_LAYER: @@ -2484,52 +2397,6 @@ bt_connect(bt_connection *btcon) return -1; } =20 -static s32 bt_execute_sdp_request(bt_sdp_request *sdpRequest) -{ - int line =3D GET_LINE(sdpRequest->conID); - int sdpIndex =3D GET_SDPINDEX(sdpRequest->conID); - - if (SESSIONSTATE(line) !=3D BT_ACTIVE) { - - /* SDP connection not active! Don't issue the request */ - - BT_DRIVER(__FUNCTION__ ": Line %d does not have an active connection!\n"= , line); - return -ENOTCONN; - } - - BT_DRIVER(__FUNCTION__ ": Line %d SDP index %d\n", - line, sdpIndex); - - if (sdpStartRequest(sdpIndex, - sdpRequest->sdpCommand, - sdpRequest->pduPayload, - sdpRequest->pduLength) < 0) - return -1; /* fixme -- EPERM probably not appropriate */ - - /* Sleep on this line while the response is going through */ - - printk(__FUNCTION__ ": Sleep on line %d\n", line); - interruptible_sleep_on(&bt_ctrl.connect_wq[line]); - - /* If we're back, there may be data to send back. - Copy into sdpRequest and return */ - - if (bt_ctrl.session[line].sdpRequestResponseData) { - - BT_DRIVER(__FUNCTION__ ": sdpRequestResponseData 0x%x - copying\n", - (int)bt_ctrl.session[line].sdpRequestResponseData); - - memcpy(sdpRequest->requestResponse, - bt_ctrl.session[line].sdpRequestResponseData, - bt_ctrl.session[line].sdpRequestResponseDataLength); - sdpRequest->responseLength =3D - bt_ctrl.session[line].sdpRequestResponseDataLength; - - } - - return 0; -} - void bt_connect_ind(u32 con_id) { @@ -2573,54 +2440,12 @@ bt_connect_cfm(u32 con_id, s32 status) wake_up_interruptible(&bt_ctrl.any_wq); break; =20 - case SDP_LAYER: - /* Record the connection status for bt_connect() to proces= s. */ - bt_ctrl.session[line].connect_status =3D status; - BT_DRIVER(__FUNCTION__ ": Line %d [%s]\n", line, psmname(psm)); - BT_DRIVER(__FUNCTION__ ": Wake up line %d\n", line); - release_wq_timer(&bt_ctrl.bt_timer[line]); - wake_up_interruptible(&bt_ctrl.connect_wq[line]); - wake_up_interruptible(&bt_ctrl.any_wq); - break; - - case TCS_LAYER: - BT_DRIVER(__FUNCTION__ ": [%s]\n", psmname(psm)); - break; - default: D_ERR(__FUNCTION__ ": Unknown layer %d\n", psm); break; } } =20 -void -bt_send_sdp_data_received(u8 line, u8 *data, int len) -{ - /* Check the line for validity */ - if (line > BT_NBR_DATAPORTS) { - D_ERR(__FUNCTION__ ": Invalid line (%d)\n", line); - return; - } - - /* When data received for this line, we simply attach the - data (& length) and wake up */ - - BT_DRIVER(__FUNCTION__ ": data 0x%x len %d\n", (int)data, len); - /* If previous data, deallocate it */ - - if (bt_ctrl.session[line].sdpRequestResponseData) { - D_WARN(__FUNCTION__ ": sdpRequestResponseData set - deallocate\n"); - kfree(bt_ctrl.session[line].sdpRequestResponseData); - bt_ctrl.session[line].sdpRequestResponseData =3D NULL; - bt_ctrl.session[line].sdpRequestResponseDataLength =3D 0; - } - - bt_ctrl.session[line].sdpRequestResponseData =3D data; - bt_ctrl.session[line].sdpRequestResponseDataLength =3D len; - wake_up_interruptible(&bt_ctrl.connect_wq[line]); - return; -} - static s32 bt_disconnect(u32 con_id) { @@ -3389,36 +3214,6 @@ bt_register_rfcomm(struct rfcomm_con *rf } =20 s32 -bt_register_sdp(u8 line, u8 sdpID) -{ - s32 found =3D 0; - - if (!bt_stack_initiated) { - D_WARN(__FUNCTION__ ": Bluetooth stack not initialised\n"); - return -1; - } - - /* Better not have any sdp data pending for this connection */ - - if (bt_ctrl.session[line].sdpRequestResponseData) { - D_WARN(__FUNCTION__ ": Pending SDP data for this new connection on line = %d\n", line); - } - - if (SESSIONSTATE(line) =3D=3D BT_INACTIVE) { - /* now register ! */ - DSYS(__FUNCTION__ ": Line %d\n", line); - SESSIONSTATE(line) =3D BT_ACTIVE; - bt_ctrl.session[line].sdpID =3D sdpID; - found =3D 1; - } - - if (!found) - D_WARN(__FUNCTION__ ": Could not find any available lines\n"); - - return found; -} - -s32 bt_unregister_rfcomm(s32 line) { BT_DRIVER(__FUNCTION__ ": Line %d\n", line); @@ -3444,34 +3239,6 @@ bt_unregister_rfcomm(s32 line) #ifdef __KERNEL__ bt_hangupline(line); #endif - return 0; -} - -s32 bt_unregister_sdp(s32 line) -{ - BT_DRIVER(__FUNCTION__ ": Line %d\n", line); - - if (!bt_stack_initiated) { - D_WARN(__FUNCTION__ ": Bluetooth stack not initialised\n"); - return -1; - } - - /* Part of unregistering SDP is to deallocate any sdp request - response data AND clear length and pointer */ - - if (bt_ctrl.session[line].sdpRequestResponseData) { - DSYS(__FUNCTION__ ": Free request data 0x%x\n", - (unsigned int)bt_ctrl.session[line].sdpRequestResponseData); - kfree(bt_ctrl.session[line].sdpRequestResponseData); - bt_ctrl.session[line].sdpRequestResponseData =3D NULL; - bt_ctrl.session[line].sdpRequestResponseDataLength =3D 0; - } - - if (SESSIONSTATE(line) =3D=3D BT_ACTIVE) { - SESSIONSTATE(line) =3D BT_INACTIVE; - bt_ctrl.session[line].sdpID =3D -1; - } - return 0; } =20 --- sdp.c 2003/11/05 15:21:59 1.91 +++ sdp.c 2004/01/09 15:27:18 1.92 @@ -109,10 +109,6 @@ #define USE_NEW_PROC #endif =20 -#ifndef __KERNEL__ -#define SDP_SRV_SOCK "/tmp/sdp_sock" -#endif - #define GET_TYPE(ch) (((ch) >> 3) & 0x1f) #define GET_SIZE(ch) ((ch) & 0x7) #define SET_DE_HDR(type,size) ((((type) << 3) & 0xf8) + ((size) & 0x7)) @@ -166,11 +162,6 @@ static s32 sdp_database_write(struct ino static s32 sdp_proc_dir_entry_read(char *buf, char **start, off_t offset, s32 len, s32 unused); #endif - -#else /* USERMODE STACK */ -static s32 open_socket(char *name); -static s32 sdp_doquery(s32 fd, u8 *request, s32 len); -static s32 send_error_rsp(sdp_con *sdp, u16 trans_id, u16 err_code); #endif =20 /****************** GLOBAL VARIABLE DECLARATION SECTION ******************= ***/ @@ -311,41 +302,7 @@ static bt_tx_buf *db_write_tx_buf; static s32 db_write_recv; #endif =20 -#ifndef __KERNEL__ -static s32 sdp_sock; -#endif - /****************** FUNCTION DEFINITION SECTION **************************= ***/ - -#ifndef __KERNEL__ -int -open_socket(char *name) -{ - struct sockaddr_un server_address; - s32 client_sockfd; - s32 server_len; - - printf("Opening socket %s\n", name); - - client_sockfd =3D socket(AF_UNIX, SOCK_STREAM, 0); - - /* 'destination' socket */ - server_address.sun_family =3D AF_UNIX; - strcpy(server_address.sun_path, name); - server_len =3D sizeof(server_address); -=20=20 - if (connect(client_sockfd,=20 - (struct sockaddr *)&server_address, server_len) < 0) { - perror("connect client socket"); - D_ERR("Couldn't open socket, sdp will not be used\n"); - return -1; - } - - printf("Socket connected to %s\n", server_address.sun_path); - return client_sockfd; -} -#endif /* !__KERNEL__ */ - void=20 sdp_init(s32 srv) { @@ -376,15 +333,18 @@ sdp_init(s32 srv) sdp_con_list[i].l2cap =3D NULL; sdp_con_list[i].state =3D SDP_DISCONNECTED; sdp_con_list[i].initiator =3D 0; - sdp_con_list[i].line =3D 0; +#if LINUX_VERSION_CODE >=3D KERNEL_VERSION(2,4,0) + init_waitqueue_head(&sdp_con_list[i].waitqueue); +#else + sdp_con_list[i].waitqueue =3D NULL; +#endif + sdp_con_list[i].status =3D 0; + sdp_con_list[i].request =3D NULL; } =20 if (srv) { DSYS("Init SDP as server\n"); role =3D 1; -#ifndef __KERNEL__ - sdp_sock =3D open_socket(SDP_SRV_SOCK); -#endif } else { DSYS("Init SDP as client\n"); role =3D 0; @@ -467,9 +427,10 @@ sdp_remove_proc_file(void) #endif /* __KERNEL__ */ =20 s32=20 -sdp_connect_req(u8* bd_addr, u8 line, bt_pincode *pincode) +sdp_connect_req(u8* bd_addr, bt_pincode *pincode) { sdp_con *sdp; + s32 retval; =20=20=20 sdp =3D get_free_sdp_con(); if (!sdp) { @@ -479,20 +440,51 @@ sdp_connect_req(u8* bd_addr, u8 line, bt } sdp->state =3D SDP_CONNECTING; sdp->initiator =3D TRUE; - sdp->line =3D line; =20=09 - if (l2ca_connect_req(bd_addr, SDP_LAYER, pincode)) { + if ((retval =3D l2ca_connect_req(bd_addr, SDP_LAYER, pincode)) < 0) { D_ERR(__FUNCTION__ " ERROR l2ca_connect_req failed\n"); - return -1; + return retval; } return sdp->id; } =20 +/* Wrapper for sdp_connect_req to wait here until the connection is comple= te */ +s32 +sdp_connect(u8* bd_addr, bt_pincode *pincode) +{ + s32 retval; + s32 i; + sdp_con *con; +=09 + i =3D sdp_connect_req(bd_addr, pincode); +=09 + if (i < 0) { + return i; + } + + con =3D &sdp_con_list[i]; + + /* Wait for connection complete */ + if(con->state =3D=3D SDP_CONNECTING) + { + start_wq_timer(&sdp_con_list[i].timer, 10 * HZ, &sdp_con_list[i].waitque= ue); + interruptible_sleep_on(&con->waitqueue); + release_wq_timer(&con->timer); + } + + /* Check status and return correct value */ + if(sdp_con_list[i].status) + { + return -sdp_con_list[i].status; + } else { + return i; + } +}=09 + /* only client receives connect pnd */ void sdp_connect_pnd(l2cap_con *l2cap, s32 status) { printk("sdp_connect_pnd : reason %d\n", status);=09 - //PRINTPSM(l2cap); } =20 void=20 @@ -525,16 +517,6 @@ sdp_connect_cfm(l2cap_con *l2cap, s32 st s32 i =3D 0; s32 stop =3D 0; =20=20=20 - if (status) { - DSYS(__FUNCTION__ " Connection failed\n"); - //bt_connect_cfm(CREATE_SDP_ID(sdp->line, 0), -1); - return; - } - - if(l2cap->current_state !=3D OPEN) { - DSYS(__FUNCTION__ ": Configuration not done yet\n"); - } - /* Find the connecting sdp_con */ while ((i < MAX_NBR_SDP) && (!stop)) { if ((sdp_con_list[i].state =3D=3D SDP_CONNECTING) &&=20 @@ -545,11 +527,25 @@ sdp_connect_cfm(l2cap_con *l2cap, s32 st i++; } =20=20=20 - if (sdp !=3D NULL) { - /*-----------------------------------------------------------*/ - /* Set the connection in bt. */ - /*-----------------------------------------------------------*/ - bt_register_sdp(sdp->line, sdp->id); + if(!sdp) { + D_ERR(__FUNCTION__ " couldn't find the correct sdp_connection\n"); + return; + } +=09 + + sdp->status =3D status; + if (status) { + DSYS(__FUNCTION__ " Connection failed\n"); + sdp->status =3D status; + wake_up_interruptible(&sdp->waitqueue); + release_wq_timer(&sdp->timer); + return; + } + + if(l2cap->current_state !=3D OPEN) { + DSYS(__FUNCTION__ ": Configuration not done yet\n"); + } +=20=20 =20 if (!l2ca_local_conf_done(l2cap) && !l2cap->conf_req_sent) { /* still haven't sent config request yet */ @@ -559,11 +555,8 @@ sdp_connect_cfm(l2cap_con *l2cap, s32 st /* store connection */ sdp->l2cap =3D l2cap; l2cap->upper_con =3D (void*) sdp; - } else=20 - DSYS(__FUNCTION__ " already sent back a pos response\n"); } else { - D_ERR(__FUNCTION__ " couldn't find the correct sdp_connection\n"); - bt_connect_cfm(CREATE_SDP_ID(sdp->line, 0), -1); + DSYS(__FUNCTION__ " already sent back a pos response\n"); } } =20 @@ -589,94 +582,57 @@ sdp_config_ind(l2cap_con* l2cap) D_REC("already ready with config req\n"); } =20 -#ifdef __KERNEL__ -/*------------------------------------------------------------------------= ---*/ -/* sdpStartRequest() - This function is used to initiate a SDP request. = */ -/*------------------------------------------------------------------------= ---*/ -int sdpStartRequest(u8 sdpIndex, u8 sdpCommand, u8 *pduData, u16 pduLength) +/* Sends a request over the connection associated to the */ +s32=20 +sdp_query(bt_sdp_request *request) { - s32 returnValue =3D -1; - - /*-------------------------------------------------------------------*/ - /* Check the connection state. State must be SDP_CONNECTED. */ - /*-------------------------------------------------------------------*/ - if (sdp_con_list[sdpIndex].state =3D=3D SDP_CONNECTED) { - /*-----------------------------------------------------------*/ - /* Initiate a query here. Send a SDP_SERVICESEARCH_REQ. */ - /*-----------------------------------------------------------*/ - sdp_tx_buf *sdp_buf; - bt_tx_buf *tx_buf; - u32 sdp_frame_len; - u16 trans_id; + sdp_con *con =3D NULL; + BD_ADDR bd; + int i; + l2cap_con *l2cap; =20=20=20=20 - /*-----------------------------------------------------------*/ - /* What are we sending in the PDU? */ - /* */ - /* A BB CC D E F GG */ - /* A =3D SDP_SERVICESEARCH_REQ */ - /* BB =3D Transaction ID */ - /* CC =3D PDU Length (not including header). */ - /* D =3D Data Element Sequence Header (0x35) */ - /* E =3D Number of bytes (which in this case is 3) */ - /* F =3D UUID16_HDR (1 bytes) (0x19). */ - /* GG =3D PublicBrowseGroup (0x1002). */ - /* Total number of bytes 10. */ - /*-----------------------------------------------------------*/ + /* BD stored as little endian, convert */ + for(i =3D 0 ; i < 6 ; i++) { + bd[i] =3D request->bd[5 - i]; + } =20 - /*-----------------------------------------------------------*/ - /* Generate random tranaction ID. */ - /*-----------------------------------------------------------*/ - get_random_bytes(&trans_id, 2 /* bytes */); + /* Find correct connection in list */ + for (i =3D 0; i < MAX_NBR_SDP; i++) { + if((sdp_con_list[i].state =3D=3D SDP_CONNECTED) && sdp_con_list[i].l2cap= ) { + l2cap =3D sdp_con_list[i].l2cap; + if(memcmp(l2cap->remote_bd, bd, 6) =3D=3D 0) { + break; + } + } + } =20=20=20=20 - /*-----------------------------------------------------------*/ - /* Allocate the buffer. */ - /*-----------------------------------------------------------*/ - sdp_frame_len =3D SDP_HDR_SIZE + pduLength; - tx_buf =3D subscribe_bt_buf(sizeof(sdp_tx_buf) + sdp_frame_len); + if(i =3D=3D MAX_NBR_SDP) { + return -1; + } =20 - if (!tx_buf) { - D_ERR(__FUNCTION__ " failed to get tx buffer\n"); - } else { - /*---------------------------------------------------*/ - /* Set the current length of the transmission buffer */ - /*---------------------------------------------------*/ - tx_buf->cur_len =3D sdp_frame_len; + con =3D &sdp_con_list[i]; + con->request =3D request; + con->request_status =3D SDP_REQUEST_SENT; =20 - /*---------------------------------------------------*/ - /* Poke the SDP header. */ - /* Notice that the "poking" is in little endian */ - /*---------------------------------------------------*/ - sdp_buf =3D (sdp_tx_buf*) (tx_buf->data); - sdp_buf->frame[0] =3D sdpCommand; - sdp_buf->frame[1] =3D (trans_id >> 8) & 0xff; - sdp_buf->frame[2] =3D trans_id & 0xff; - sdp_buf->frame[3] =3D (pduLength >> 8) & 0xff; - sdp_buf->frame[4] =3D pduLength & 0xff; + if(sdp_send_data(con, request->data, request->len) < 0) { + con->request =3D NULL; + con->request_status =3D SDP_REQUEST_IDLE; + return -1; + } =20 - /*---------------------------------------------------*/ - /* Copy the pduData. */ - /*---------------------------------------------------*/ - memcpy(&sdp_buf->frame[5], pduData, pduLength); + /* Wait for the response */ + start_wq_timer(&con->timer, 10 * HZ, &con->waitqueue); + interruptible_sleep_on(&con->waitqueue); + release_wq_timer(&con->timer); =20 - /*---------------------------------------------------*/ - /* Send the l2cap data transfer. */ - /*---------------------------------------------------*/ - l2cap_send_data(tx_buf, sdp_con_list[sdpIndex].l2cap); - DSYS(__FUNCTION__ " Client finished sending data.\n"); - returnValue =3D 0;=20 + if(con->request_status !=3D SDP_REQUEST_RESPONSE) { + return -1; } - } else { - /*-----------------------------------------------------------*/ - /* No active SDP connection here!. This is an error. */ - /*-----------------------------------------------------------*/ - D_ERR(__FUNCTION__ " No active connection on SDP ID =3D %d\n", sdpIndex); + con->request_status =3D SDP_REQUEST_IDLE; + con->request =3D NULL; + return 0; } =20 - return returnValue; -} /* End of sdpStartRequest() */ - -#endif /* __KERNEL__ */ - void=20 sdp_config_cfm(l2cap_con *l2cap, s32 status) { @@ -705,14 +661,12 @@ sdp_config_cfm(l2cap_con *l2cap, s32 sta /* initator, this is a SDP client connection request. If not, then */ /* we're the server and must process requests. */ /*-------------------------------------------------------------------*/ + if (sdp->initiator) { - /*-----------------------------------------------------------*/ - /* We are the initator. Therefore a SDP client on on this */ - /* machine initiated the connection. Inform the "ioctl" or */ - /* bluetooth layer. */ - /*-----------------------------------------------------------*/ - bt_connect_cfm(CREATE_SDP_ID(sdp->line, 0), - ((sdp_con *)l2cap->upper_con)->id); + DSYS(__FUNCTION__ ", we initiated the connection\n"); + /* Wakeup anyone waiting */ + wake_up_interruptible(&sdp->waitqueue); + release_wq_timer(&sdp->timer); } else { DSYS(__FUNCTION__ ", we are the server\n"); } @@ -739,15 +693,10 @@ sdp_disconnect_req(u32 sdp_id) D_ERR(__FUNCTION__ ", An error with error code %d occured during discon= netion of sdp channel %d\n", err, sdp_id); sdp_con_list[sdp_id].state =3D SDP_DISCONNECTED; sdp_con_list[sdp_id].l2cap =3D NULL;=20=20 + sdp_con_list[sdp_id].request =3D NULL; }=20 -#if 0 - /* sdp_disconnect_cfm wakes up this queue, but by the time we - get here it already did, so we sleep forever! - */ - else { - interruptible_sleep_on(&sdp_disc_wq); - } -#endif + } else { + D_ERR("%s: Didn't find connection\n", __FUNCTION__); } } =20 @@ -760,6 +709,10 @@ sdp_disconnect_ind(l2cap_con *l2cap)=20 if ((sdp =3D (sdp_con*) l2cap->upper_con)) { sdp->state =3D SDP_DISCONNECTED; sdp->l2cap =3D NULL; + sdp->status =3D 0; + sdp->request =3D NULL; + wake_up_interruptible(&sdp->waitqueue); + release_wq_timer(&sdp->timer); } =20 l2ca_disconnect_rsp(l2cap); @@ -769,17 +722,14 @@ void=20 sdp_disconnect_cfm(l2cap_con *l2cap) { sdp_con *sdp; - u8 line; =20 D_MISC(__FUNCTION__ ", remote cid : %d\n", l2cap->remote_cid); =20 sdp =3D (sdp_con*) l2cap->upper_con; - line =3D sdp->line; sdp->state =3D SDP_DISCONNECTED; sdp->l2cap =3D NULL;=20=20 - - bt_unregister_sdp(line); - wake_up_interruptible(&sdp_disc_wq); + sdp->status =3D 0; + sdp->request =3D NULL; } =20 void=20 @@ -787,6 +737,7 @@ sdp_receive_data(l2cap_con *l2cap, u8* d { sdp_con *sdp; data_struct *db_hdl; + bt_sdp_request *request; =20 D_REC(__FUNCTION__ "\n"); =20 @@ -798,28 +749,25 @@ sdp_receive_data(l2cap_con *l2cap, u8* d PRINTPKT(__FUNCTION__, data, len);=20=20 sdp =3D (sdp_con*) l2cap->upper_con; =20 -#ifndef __KERNEL__ - if (sdp_sock < 0) { - send_error_rsp(sdp, le16_to_cpu(get_unaligned((u16 *)&data[1])), 6); - } -#endif - /*--------------------------------------------------------*/ /* If __KERNEL__ mode, we must bounce the received data */ /* up if this stack initiated the request. */ /*--------------------------------------------------------*/ -#if __KERNEL__ if (sdp->initiator) { u8 *dataPointer =3D NULL; - - /*------------------------------------------------------*/ - /* Grab a copy of the data to send up. */ - /*------------------------------------------------------*/ - dataPointer =3D (u8 *) kmalloc(len, GFP_ATOMIC); - memcpy(dataPointer, data, len); - bt_send_sdp_data_received(sdp->line, dataPointer, len); + if(!(request =3D sdp->request)) { + return; + } + sdp->request_status =3D SDP_REQUEST_RESPONSE; + if(len > (request->allocated)) { + D_ERR("%s: Received more data than allocated\n", __FUNCTION__); + } + memcpy(request->data, data, MIN(request->allocated, len)); + request->len =3D len; + /* Wakeup anyone waiting */ + wake_up_interruptible(&sdp->waitqueue); + release_wq_timer(&sdp->timer); } else -#endif { db_hdl =3D (data_struct*)database_query.query; =20 @@ -829,54 +777,11 @@ sdp_receive_data(l2cap_con *l2cap, u8* d memcpy(db_hdl->data, data, len); =20 database_query.count =3D sizeof(data_struct) + len; - -#ifdef __KERNEL__ D_PROC("wake_up process %i (%s) awakening\n", current->pid, current->com= m); wake_up_interruptible(&database_wq); D_PROC("wake_up process %i (%s) woke up\n", current->pid, current->comm); -#else - sdp_doquery(sdp_sock, database_query.query, database_query.count); -#endif - } -} - -#ifndef __KERNEL__=20 -s32 -send_error_rsp(sdp_con *sdp, u16 trans_id, u16 err_code) -{ - sdp_tx_buf *sdp_buf; - bt_tx_buf *tx_buf; - u32 sdp_frame_len; - u32 pdu_len; - - /* Since we do not send any error information the pdu length is just - the size of the error code length, which is two bytes */ - pdu_len =3D 2; - sdp_frame_len =3D SDP_HDR_SIZE + pdu_len; - - tx_buf =3D subscribe_bt_buf(sizeof(sdp_tx_buf) + sdp_frame_len); - - if (!tx_buf) { - D_ERR(__FUNCTION__ " failed to get tx buffer\n"); - return -1; } - - tx_buf->cur_len =3D sdp_frame_len; -=09 - sdp_buf =3D (sdp_tx_buf*) (tx_buf->data); - - sdp_buf->frame[0] =3D SDP_ERROR_RSP; - sdp_buf->frame[1] =3D (trans_id >> 8) & 0xff; - sdp_buf->frame[2] =3D trans_id & 0xff; - sdp_buf->frame[3] =3D (pdu_len >> 8) & 0xff; - sdp_buf->frame[4] =3D pdu_len & 0xff; - - sdp_buf->frame[5] =3D (err_code >> 8) & 0xff; - sdp_buf->frame[6] =3D err_code & 0xff; -=09 - return l2cap_send_data(tx_buf, sdp->l2cap); } -#endif =20 #ifdef __KERNEL__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) @@ -986,35 +891,6 @@ s32 sdp_database_write(struct inode *ino db_write_recv =3D 0; =20 return read1 + read2; -} -#else /* __KERNEL__ */ - -s32 sdp_doquery(s32 fd, u8 *request, s32 len) -{ - s32 n; - u8 tmpbuf[512]; - data_struct *db_hdl; - s32 recv; - - D_XMIT("sdp_doquery : sending request %d bytes\n", len); - write(fd, request, len); -=09 - if ((n =3D read(fd, tmpbuf, 512)) < 0) - return n; - - D_REC(__FUNCTION__ ", Received %d bytes\n", n); -=09 - db_hdl =3D (data_struct*) tmpbuf; -=09 - /* what if not all is written once */ - - for (recv =3D n; recv < sizeof *db_hdl + db_hdl->len; recv +=3D n) - if ((n =3D read(fd, tmpbuf + recv, 512 - recv)) < 0) - return n; - - sdp_send_data(&sdp_con_list[db_hdl->sdp_con_id], db_hdl->data, db_hdl->le= n);=20 -=09 - return recv; } #endif =20 |