📄 dbus.c
字号:
/* Check for valid parameters */ if (length >= min_period || min_period >= max_period || length < 0x01 || length > 0x30 || lap < 0x9e8b00 || lap > 0x9e8b3f) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); goto failed; } inq_param.num_rsp = num_rsp; inq_param.length = length; inq_param.max_period = htobs(max_period); inq_param.min_period = htobs(min_period); inq_param.lap[0] = lap & 0xff; inq_param.lap[1] = (lap >> 8) & 0xff; inq_param.lap[2] = (lap >> 16) & 0xff; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_PERIODIC_INQUIRY; rq.cparam = &inq_param; rq.clen = PERIODIC_INQUIRY_CP_SIZE; rq.rparam = &status; rq.rlen = sizeof(status); if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending periodic inquiry command failed: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (status) { syslog(LOG_ERR, "Periodic inquiry failed with status 0x%02x", status); reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (dd >= 0) close(dd); return reply;}static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data){ DBusMessage *reply = NULL; struct hci_request rq; struct hci_dbus_data *dbus_data = data; uint8_t status; int dd = -1; dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_EXIT_PERIODIC_INQUIRY; rq.rparam = &status; rq.rlen = sizeof(status); if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending exit periodic inquiry command failed: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (status) { syslog(LOG_ERR, "Exit periodic inquiry failed with status 0x%02x", status); reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (dd >= 0) close(dd); return reply;}static DBusMessage* handle_inq_req(DBusMessage *msg, void *data){ DBusMessage *reply = NULL; inquiry_cp cp; evt_cmd_status rp; struct hci_request rq; struct hci_dbus_data *dbus_data = data; int dd = -1; uint8_t length = 8, num_rsp = 0; uint32_t lap = 0x9e8b33; if (dbus_message_has_signature(msg, HCI_INQ_EXT_SIGNATURE)) { dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &length, DBUS_TYPE_UINT32, &lap, DBUS_TYPE_INVALID); if (length < 0x01 || length > 0x30 || lap < 0x9e8b00 || lap > 0x9e8b3f) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); goto failed; } } dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "Unable to open device %d: %s (%d)", dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } memset(&cp, 0, sizeof(cp)); cp.lap[0] = lap & 0xff; cp.lap[1] = (lap >> 8) & 0xff; cp.lap[2] = (lap >> 16) & 0xff; cp.length = length; cp.num_rsp = num_rsp; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_INQUIRY; rq.cparam = &cp; rq.clen = INQUIRY_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_CMD_STATUS_SIZE; rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to start inquiry: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (dd >= 0) hci_close_dev(dd); return reply;}static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data){ DBusMessage *reply = NULL; struct hci_request rq; struct hci_dbus_data *dbus_data = data; uint8_t status; int dd = -1; dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "Unable to open device %d: %s (%d)", dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_INQUIRY_CANCEL; rq.rparam = &status; rq.rlen = sizeof(status); if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending cancel inquiry failed: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (status) { syslog(LOG_ERR, "Cancel inquiry failed with status 0x%02x", status); reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (dd >= 0) hci_close_dev(dd); return reply;}static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data){ DBusMessage *reply = NULL; char *str_bdaddr = NULL; struct hci_dbus_data *dbus_data = data; bdaddr_t bdaddr; uint8_t role; int dev_id = -1, dd = -1; dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str_bdaddr, DBUS_TYPE_BYTE, &role, DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { syslog(LOG_ERR, "Bluetooth device failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } if (dbus_data->dev_id != dev_id) { syslog(LOG_ERR, "Connection not found"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; } dd = hci_open_dev(dev_id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) { syslog(LOG_ERR, "Switch role request failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } reply = dbus_message_new_method_return(msg);failed: return reply;}static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data){ DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; int dd = -1; const char *str_bdaddr; bdaddr_t bdaddr; struct hci_request rq; remote_name_req_cp cp; evt_cmd_status rp; dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str_bdaddr, DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "Unable to open device %d: %s (%d)", dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } memset(&cp, 0, sizeof(cp)); cp.bdaddr = bdaddr; cp.pscan_rep_mode = 0x01; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_REMOTE_NAME_REQ; rq.cparam = &cp; rq.clen = REMOTE_NAME_REQ_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_CMD_STATUS_SIZE; rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to send remote name request: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (dd >= 0) hci_close_dev(dd); return reply;}static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data){ struct hci_conn_list_req *cl = NULL; struct hci_conn_info *ci = NULL; DBusMessage *reply = NULL; DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter struct_iter; char addr[18]; const char array_sig[] = HCI_CONN_INFO_STRUCT_SIGNATURE; const char *paddr = addr; struct hci_dbus_data *dbus_data = data; int sk = -1; int i; sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } cl = malloc(MAX_CONN_NUMBER * sizeof(*ci) + sizeof(*cl)); if (!cl) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); goto failed; } cl->dev_id = dbus_data->dev_id; cl->conn_num = MAX_CONN_NUMBER; ci = cl->conn_info; if (ioctl(sk, HCIGETCONNLIST, (void *) cl) < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } reply = dbus_message_new_method_return(msg); if (reply == NULL) { syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); goto failed; } dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); for (i = 0; i < cl->conn_num; i++, ci++) { ba2str(&ci->bdaddr, addr); dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 ,&(ci->handle)); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING ,&paddr); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE ,&(ci->type)); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE ,&(ci->out)); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 ,&(ci->state)); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32 ,&(ci->link_mode)); dbus_message_iter_close_container(&array_iter, &struct_iter); } dbus_message_iter_close_container(&iter, &array_iter);failed: if (sk >= 0) close(sk); if (cl) free(cl); return reply;}static DBusMessage* handle_auth_req(DBusMessage *msg, void *data){ struct hci_request rq; auth_requested_cp cp; evt_cmd_status rp; DBusMessage *reply = NULL; char *str_bdaddr = NULL; struct hci_dbus_data *dbus_data = data; struct hci_conn_info_req *cr = NULL; bdaddr_t bdaddr; int dev_id = -1; int dd = -1; dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str_bdaddr, DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; } if (dbus_data->dev_id != dev_id) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; } dd = hci_open_dev(dev_id); if (dd < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); goto failed; } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } memset(&cp, 0, sizeof(cp)); cp.handle = cr->conn_info->handle; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_AUTH_REQUESTED; rq.cparam = &cp; rq.clen = AUTH_REQUESTED_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_CMD_STATUS_SIZE; rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to send authentication request: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (dd >= 0) close(dd); if (cr) free(cr); return reply;}/***************************************************************** * * Section reserved to local device configuration D-Bus Services * *****************************************************************/static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data){ DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; struct hci_dev_info di; struct hci_dev_req dr; int sk = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -