📄 bluetooth.c
字号:
} else if (_IOC_DIR(cmd) & _IOC_WRITE) { err = verify_area(VERIFY_READ, (void*)arg, size); if (err) { BT_DRIVER("verify_area(VERIFY_READ) error:%d\n", err); return err; } } switch (cmd) { case BT_SDP_REQUEST: { bt_sdp_request sdpRequest; int returnValue = -1; /* Copy arguments to kernel space */ BT_DRIVER(__FUNCTION__ ": Copying arguments from user to kernel space\n"); copy_from_user(&sdpRequest, (s32*)arg, size); /* Now execute the request */ BT_DRIVER(__FUNCTION__ ": Executing bt_execute_sdp_request\n"); if ((returnValue = bt_execute_sdp_request(&sdpRequest)) >= 0) { /* Copy the data back to user space and return */ BT_DRIVER(__FUNCTION__ ": Copying data back to user space\n"); copy_to_user((s32*)arg, &sdpRequest, size); } return returnValue; }#ifdef CONFIG_BLUETOOTH_USE_SECURITY_MANAGER case BT_GETCACHEDLINKKEY: { unsigned char link_key_info[6 + 16]; /* Now execute the request */ BT_DRIVER(__FUNCTION__ ": Executing sec_man_get_cached_link_key\n"); sec_man_get_cached_link_key(link_key_info); BT_DRIVER(__FUNCTION__ ": Copying data back to user space\n"); copy_to_user((s32*)arg, link_key_info, 6 + 16); return 0; }#endif case BTCONNECT: /* argument is an object with all info to start a remote connection */ copy_from_user(&btcon, (s32*)arg, size); BT_DRIVER(__FUNCTION__ ": BTCONNECT\n"); return bt_connect(btcon.bd, btcon.id); case BTDISCONNECT: { s32 con_id; BT_DRIVER(__FUNCTION__ ": BTDISCONNECT\n"); copy_from_user(&con_id, (s32*)arg, size); return bt_disconnect(con_id); } case BTWAITFORCONNECTION: { s32 line; copy_from_user(&line, (s32*)arg, size); /* check if we already have a connection otherwise wait... */ if ((SESSIONSTATE(line) == BT_LOWERCONNECTED)|| (SESSIONSTATE(line) == BT_ACTIVE)) { BT_DRIVER("Already got connection on line %d\n", line); return 0; } BT_DRIVER("Waiting on line %d\n", line); interruptible_sleep_on(&bt_ctrl.connect_wq[line]); BT_DRIVER("Got connection on line %d\n", line); break; } case BTWAITNEWCONNECTIONS: /* wait for any new connections coming in */ BT_DRIVER("Waiting for new connections\n"); interruptible_sleep_on(&bt_ctrl.any_wq); break; case BTISLOWERCONNECTED: { s32 line; copy_from_user(&line, (s32*)arg, size); return SESSIONSTATE(line) == BT_LOWERCONNECTED; } case BTINITSTACK: return bt_init_stack(); case BTSHUTDOWN: bt_shutdown(); break; case BTREADREMOTEBDADDR: { BD_ADDR rev_bd; s32 line; u16 i; BT_DRIVER(__FUNCTION__ ": BTREADREMOTEBDADDR\n"); copy_from_user(&line, (s32*)arg, size); get_remote_bd(line, bd_addr); /* return as big endian */ for (i = 0; i < 6; i++) { rev_bd[5-i] = bd_addr[i]; } copy_to_user((s32*)arg, rev_bd, 6); break; } case BTRESETPHYSICALHW: bt_reset_phys_hw(); break; case BTISINITIATED: put_user(bt_stack_initiated, (s32*)arg); break; case BTHWVENDOR: copy_to_user((u8*)arg, bt_hw_vendor(), strlen(bt_hw_vendor())+1); break; case BTFIRMWAREINFO: BT_DRIVER(__FUNCTION__ ": BTFIRMWAREINFO\n"); copy_to_user((u8*)arg, bt_hw_firmware(), strlen(bt_hw_firmware())+1); break; case BTSENDTESTDATA: copy_from_user(&tmp, (s32*)arg, 4); copy_from_user(&utmp, (s32*)arg + 1, 4); rfcomm_send_testdata(tmp, utmp); break; case HCITESTCONNECTREQ: { u8 bd[6]; copy_from_user(bd, (s32*)arg, 6); return hci_test_connect_req(bd); } /* First byte is length */ case BTTESTCOMMAND: { u8 cmd[261]; copy_from_user(cmd, (u8*)arg, 260); test_process_cmd(cmd+1, cmd[0]); return 0; } /* Ioctls executing HCI commands */ /* Link Control Command */ case HCIINQUIRY: { inquiry_results *inq_res; s32 in_param[2]; u8 lap[3]; int ret; BT_DRIVER(__FUNCTION__ ": HCINQUIRY\n"); copy_from_user(in_param, (s32*)arg, 8); if ((inq_res = (inquiry_results*) kmalloc(sizeof(inquiry_results) + 6 * in_param[0], GFP_ATOMIC)) < 0) { ret = -ENOMEM; goto hci_inq_exit0; } if ((ret = hci_inquiry(lap, in_param[1], in_param[0], inq_res)) < 0) goto hci_inq_exit1; copy_to_user((s32*)arg, inq_res, size + 6 * inq_res->nbr_of_units); hci_inq_exit1: kfree(inq_res); hci_inq_exit0: return ret; } case HCILINKKEYREPLY: { u8 param[size]; s32 result; BT_DRIVER(__FUNCTION__ ": HCILINKKEYREPLY\n"); copy_from_user(param, (s32*)arg, size); /* First part of param contains BD address, last part link key, see Bluetooth specification for more info*/ result = hci_link_key_request_reply(param, param + 6); put_user(result, (s32*)arg); break; } case HCILINKKEYNEGATIVEREPLY: { u8 bd_addr[size]; s32 result; BT_DRIVER(__FUNCTION__ ": HCILINKKEYNEGATIVEREPLY\n"); copy_from_user(bd_addr, (s32*)arg, size); result = hci_link_key_request_negative_reply(bd_addr); put_user(result, (s32*)arg); break; } case HCIPINCODEREPLY: { u8 param[size]; s32 result; BT_DRIVER(__FUNCTION__ ": HCIPINCODEREPLY\n"); copy_from_user(param, (s32*)arg, size); /* First part of param contains BD address, second part of the pin code, and the last part och the pin code length */ result = hci_pin_code_request_reply(param, param + 6, *(param + 22)); put_user(result, (s32*)arg); break; } case HCIPINCODENEGATIVEREPLY: { u8 bd_addr[size]; s32 result; BT_DRIVER(__FUNCTION__ ": HCIPINCODENEGATIVEREPLY\n"); copy_from_user(bd_addr, (s32*)arg, size); result = hci_pin_code_request_negative_reply(bd_addr); put_user(result, (s32*)arg); break; } case HCIAUTHENTICATION_REQUESTED: { u8 bd_addr[size]; BT_DRIVER(__FUNCTION__ ": HCIAUTHENTICATION_REQUESTED\n"); copy_from_user(bd_addr, (s32*)arg, size); hci_authentication_requested_bd(bd_addr); break; } case HCISETCONNECTION_ENCRYPTION: { u8 param[7]; BT_DRIVER(__FUNCTION__ ": HCISETCONNECTION_ENCRYPTION\n"); copy_from_user(param, (s32*)arg, size); hci_set_connection_encryption_bd(param + 1, *param); break; } /* Link Policy Commands */ case HCISWITCHROLE: { u8 param[size]; copy_from_user(param, (s32*)arg, size); hci_switch_role(¶m[0], param[6]); break; } /* Host Controller & Baseband Commands */ case HCIRESET: hci_reset(); break; case HCIFLUSH: break; case HCICREATE_NEW_UNIT_KEY: { s32 result; BT_DRIVER(__FUNCTION__ ": HCICREATE_NEW_UNIT_KEY\n"); result = hci_create_new_unit_link_key(); put_user(result, (s32*)arg); break; } case HCIREADSTOREDLINKKEY: { s32 result; u8 param[size]; BT_DRIVER(__FUNCTION__ ": HCIREADSTOREDLINKKEY\n"); copy_from_user(param, (s32*)arg, size); result = hci_read_stored_link_key(param + 1, *param); put_user(result, (s32*)arg); break; } case HCIWRITESTOREDLINKKEY: { s32 result; u8 param[size]; BT_DRIVER(__FUNCTION__ ": HCIWRITESTOREDLINKKEY\n"); copy_from_user(param, (s32*)arg, size); result = hci_write_stored_link_key(param, param + 6); put_user(result, (s32*)arg); break; } case HCIDELETESTOREDLINKKEY: { s32 result; u8 param[size]; BT_DRIVER(__FUNCTION__ ": HCIDELETESTOREDLINKKEY\n"); copy_from_user(param, (s32*)arg, size); result = hci_delete_stored_link_key(param + 1, *param); put_user(result, (s32*)arg); break; } case HCISETLOCALNAME: { /* FIXME: If we send the length of the string too, we don't have to copy all the 248 byte... */ u8 local_name[248]; BT_DRIVER(__FUNCTION__ ": HCISETLOCALNAME\n"); copy_from_user(local_name, (s32*)arg, 248); hci_change_local_name(local_name); break; } case HCIREADSCANENABLE: BT_DRIVER("Reading scan enable\n"); tmp = hci_read_scan_enable(); put_user(tmp, (s32*)arg); break; case HCIWRITESCANENABLE: GET_USER(tmp, (s32*)arg); BT_DRIVER("Setting write scan enable: [0x%x]\n", tmp); hci_write_scan_enable(tmp); break; case HCIWRITEPAGESCANACTIVITY: { u32 par[2]; copy_from_user(&par, (s32*)arg, size); BT_DRIVER("Setting write page scan activity: [0x%x,0x%x]\n", par[0], par[1]); hci_write_pagescan_activity(par[0], par[1]); break; } case HCIWRITECLASSOFDEVICE: { u8 class_of_device[3]; BT_DRIVER(__FUNCTION__ ": HCIWRITECLASSOFDEVICE\n"); copy_from_user(class_of_device, (s32*)arg, size); hci_write_class_of_device(class_of_device); break; } case HCIREAD_AUTHENTICATION_ENABLE: { s32 result = hci_read_authentication_enable(); BT_DRIVER(__FUNCTION__ ": HCIREAD_AUTHENTICATION_ENABLE\n"); put_user(result, (s32*)arg); break; } case HCIWRITE_AUTHENTICATION_ENABLE: { u8 enable; s32 result = 0; BT_DRIVER(__FUNCTION__ ": HCIWRITE_AUTHENTICATION_ENABLE\n"); GET_USER(tmp, (s32*)arg); enable = (u8)(tmp & 0xff); hci_write_authentication_enable(enable); put_user(result, (s32*)arg); break; } case HCIREAD_ENCRYPTION_MODE: { s32 result = hci_read_encryption_mode(); BT_DRIVER(__FUNCTION__ ": HCIREAD_ENCRYPTION_MODE\n"); put_user(result, (s32*)arg); break; } case HCIWRITE_ENCRYPTION_MODE: { u8 enable; s32 result = 0; BT_DRIVER(__FUNCTION__ ": HCIWRITE_ENCRYPTION_MODE\n"); GET_USER(tmp, (s32*)arg); enable = (u8)(tmp & 0xff); hci_write_encryption_mode(enable); put_user(result, (s32*)arg); break; } case HCISET_EVENT_FILTER: { u8 param[size]; BT_DRIVER(__FUNCTION__ ": HCISET_EVENT_FILTER\n"); copy_from_user(param, (s32*)arg, size); hci_set_event_filter(param); break; } /* Informational Parameters */ case HCIREADLOCALBDADDR: { BD_ADDR rev_bd; u16 i; BT_DRIVER(__FUNCTION__ ": HCIREADLOCALBDADDR\n"); hci_read_local_bd(bd_addr); /* return as big endian */ for (i = 0; i < 6; i++) { rev_bd[5-i] = bd_addr[i]; } copy_to_user((s32*)arg, rev_bd, 6); break; } case HCIREADCOUNTRYCODE: BT_DRIVER(__FUNCTION__ ": HCIREADCOUNTRYCODE\n"); tmp = hci_read_country_code(); put_user(tmp, (s32*) arg); break; /* Status Parameters */ /* Testing Commands */ case HCIENABLEDUT: hci_enable_dut(); break; /* ioctls vendor specific HCI commands */ case HCISETBAUDRATE: { s32 tmp; /* Set baudrate in hardware */ GET_USER(tmp, (s32*)arg); BT_DRIVER(__FUNCTION__ ": Setting baudrate in host controller to %d\n", tmp); tmp = hci_set_baudrate(tmp); return tmp; } case HCIWRITEBDADDR: copy_from_user(&bd_addr, (s32*)arg, size); BT_DRIVER(__FUNCTION__ ": Setting BD_ADDR to\n"); print_data("bd:",(u8*)bd_addr,6); hci_set_bd_addr(bd_addr); break; /* | len (1) | hci header (4) | data (max 256)| */ case HCISENDRAWDATA: { u8 len; u8 data[261]; /* first byte contains length of whole hci message */ copy_from_user(&len, (u8*)arg, 1); BT_DRIVER("Copying %d bytes to raw interface\n", len); copy_from_user(data, (u8*)arg + 1, len); BT_DRIVER("Sending %d bytes\n", len); BT_DATADUMP("RAW: ", data, len); hci_send_raw_data(data, len); break; } case BTPING: { ping_struct ping; copy_from_user(&ping, (u8*)arg, 8); print_data("ping bd: ", ping.bd, 6);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -