📄 dbus.c
字号:
static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data){ DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; int sk = -1; /* Create and bind HCI socket */ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (ioctl(sk, HCIDEVDOWN, dbus_data->dev_id) < 0) { syslog(LOG_ERR, "Can't down device hci%d: %s (%d)", dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (sk >= 0) close(sk); return reply;}static DBusMessage* handle_device_set_property_req(DBusMessage *msg, void *data){ const struct service_data *handlers = set_property_services; DBusMessageIter iter; DBusMessage *reply = NULL; const char *signature; char *str_name; uint32_t error = BLUEZ_EDBUS_WRONG_PARAM; signature = dbus_message_get_signature(msg); dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &str_name); for (; handlers->name != NULL; handlers++) { if (strcasecmp(handlers->name, str_name)) continue; if (strcmp(handlers->signature, signature) == 0) { reply = handlers->handler_func(msg, data); error = 0; break; } else { error = BLUEZ_EDBUS_WRONG_SIGNATURE; break; } } if (error) reply = bluez_new_failure_msg(msg, error); return reply;}static DBusMessage* handle_device_get_property_req(DBusMessage *msg, void *data){ const struct service_data *handlers = get_property_services; DBusMessageIter iter; DBusMessage *reply = NULL; char *str_name; uint32_t error = BLUEZ_EDBUS_WRONG_PARAM; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &str_name); for (; handlers->name != NULL; handlers++) { if (!strcasecmp(handlers->name, str_name)) { reply = handlers->handler_func(msg, data); error = 0; break; } } if (error) reply = bluez_new_failure_msg(msg, error); return reply;}static void send_property_changed_signal(const int devid, const char *prop_name, const int prop_type, void *value){ DBusMessage *message = NULL; char path[MAX_PATH_LENGTH]; snprintf(path, sizeof(path)-1, "%s/hci%d", DEVICE_PATH, devid); path[MAX_PATH_LENGTH-1]='\0'; message = dbus_message_new_signal(path, DEVICE_INTERFACE, BLUEZ_HCI_PROPERTY_CHANGED); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); goto failed; } dbus_message_append_args(message, DBUS_TYPE_STRING, &prop_name, prop_type, value, DBUS_TYPE_INVALID); if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS PropertChanged(%s) signal", prop_name); goto failed; }failed: if (message) dbus_message_unref(message);}static DBusMessage* handle_device_set_property_req_name(DBusMessage *msg, void *data){ struct hci_dbus_data *dbus_data = data; DBusMessageIter iter; DBusMessage *reply = NULL; char *str_name; int dd = -1; uint8_t status; change_local_name_cp cp; struct hci_request rq; dbus_message_iter_init(msg, &iter); dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &str_name); if (strlen(str_name) == 0) { syslog(LOG_ERR, "HCI change name failed - Invalid Name!"); 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, "HCI device open failed: hci%d", dbus_data->dev_id); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } memset(&rq, 0, sizeof(rq)); strncpy((char *) cp.name, str_name, sizeof(cp.name)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_CHANGE_LOCAL_NAME; rq.cparam = &cp; rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; rq.rparam = &status; rq.rlen = sizeof(status); if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending change name command failed: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (status) { syslog(LOG_ERR, "Setting name 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;}void hcid_dbus_setname_complete(bdaddr_t *local){ char *local_addr; bdaddr_t tmp; int id; int dd = -1; read_local_name_rp rp; struct hci_request rq; const char *pname = (char*) rp.name; char name[249]; baswap(&tmp, local); local_addr = batostr(&tmp); id = hci_devid(local_addr); if (id < 0) { syslog(LOG_ERR, "No matching device id for %s", local_addr); goto failed; } dd = hci_open_dev(id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed: hci%d", id); memset(&rq, 0, sizeof(rq)); } else { memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LOCAL_NAME; rq.rparam = &rp; rq.rlen = READ_LOCAL_NAME_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending getting name command failed: %s (%d)", strerror(errno), errno); rp.name[0] = '\0'; } if (rp.status) { syslog(LOG_ERR, "Getting name failed with status 0x%02x", rp.status); rp.name[0] = '\0'; } } strncpy(name, pname, sizeof(name) - 1); name[248] = '\0'; pname = name; send_property_changed_signal(id, DEV_PROPERTY_NAME, DBUS_TYPE_STRING, &pname); dbus_connection_flush(connection);failed: if (dd >= 0) close(dd); bt_free(local_addr);}static DBusMessage* handle_device_get_property_req_name(DBusMessage *msg, void *data){ struct hci_dbus_data *dbus_data = data; DBusMessage *reply = NULL; int dd = -1; read_local_name_rp rp; struct hci_request rq; const char *pname = (char*) rp.name; char name[249]; dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LOCAL_NAME; rq.rparam = &rp; rq.rlen = READ_LOCAL_NAME_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending getting name command failed: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (rp.status) { syslog(LOG_ERR, "Getting name failed with status 0x%02x", rp.status); reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status); 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; } strncpy(name,pname,sizeof(name)-1); name[248]='\0'; pname = name; dbus_message_append_args(reply, DBUS_TYPE_STRING, &pname, DBUS_TYPE_INVALID);failed: if (dd >= 0) close(dd); return reply;}static DBusMessage* write_scan_enable(DBusMessage *msg, void *data, gboolean ispscan){ struct hci_dbus_data *dbus_data = data; DBusMessageIter iter; DBusMessage *reply = NULL; int dd = -1; read_scan_enable_rp rp; uint8_t enable; uint8_t status; uint8_t scan_change, scan_keep; struct hci_request rq; gboolean prop_value; /* new requested value for the iscan or pscan */ dbus_message_iter_init(msg, &iter); dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &prop_value); dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_SCAN_ENABLE; rq.rparam = &rp; rq.rlen = READ_SCAN_ENABLE_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending read scan enable command failed: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (rp.status) { syslog(LOG_ERR, "Getting scan enable failed with status 0x%02x", rp.status); reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status); goto failed; } if (ispscan) { /* Page scan */ scan_change = SCAN_PAGE; scan_keep = SCAN_INQUIRY; } else { /* Inquiry scan */ scan_change = SCAN_INQUIRY; scan_keep = SCAN_PAGE; } /* This is an optimization. We want to avoid overwrite the value if the requested scan property will not change. */ if (prop_value && !(rp.enable & scan_change)) /* Enable the requested scan type (e.g. page scan). Keep the the other type untouched. */ enable = (rp.enable & scan_keep) | scan_change; else if (!prop_value && (rp.enable & scan_change)) /* Disable the requested scan type (e.g. page scan). Keep the the other type untouched. */ enable = (rp.enable & scan_keep); else { /* Property not changed. Do nothing. Return ok. */ reply = dbus_message_new_method_return(msg); goto failed; } memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_SCAN_ENABLE; rq.cparam = &enable; rq.clen = sizeof(enable); rq.rparam = &status; rq.rlen = sizeof(status); if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending write scan enable command failed: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (status) { syslog(LOG_ERR, "Setting scan enable failed with status 0x%02x", rp.status); reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status); goto failed; } reply = dbus_message_new_method_return(msg);failed: if (dd >= 0) close(dd); return reply;}void hcid_dbus_setscan_enable_complete(bdaddr_t *local){ char *local_addr; char path[MAX_PATH_LENGTH]; bdaddr_t tmp; int id; int dd = -1; gboolean se; read_scan_enable_rp rp; struct hci_request rq; struct hci_dbus_data *pdata = NULL; uint32_t old_data; baswap(&tmp, local); local_addr = batostr(&tmp); id = hci_devid(local_addr); if (id < 0) { syslog(LOG_ERR, "No matching device id for %s", local_addr); goto failed; } snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); dd = hci_open_dev(id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed: hci%d", id); goto failed; } memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_SCAN_ENABLE; rq.rparam = &rp; rq.rlen = READ_SCAN_ENABLE_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending read scan enable command failed: %s (%d)", strerror(errno), errno); goto failed; } if (rp.status) { syslog(LOG_ERR, "Getting scan enable failed with status 0x%02x", rp.status); goto failed; } if (!dbus_connection_get_object_path_data(connection, path, (void*) &pdata)) { syslog(LOG_ERR, "Getting path data failed!"); goto failed; } old_data = pdata->path_data; pdata->path_data = rp.enable; /* If the new page scan flag is different from what we had, send a signal. */ if((rp.enable & SCAN_PAGE) != (old_data & SCAN_PAGE)) { se = (rp.enable & SCAN_PAGE); send_property_changed_signal(id, DEV_PROPERTY_PSCAN, DBUS_TYPE_BOOLEAN, &se); } /* If the new inquity scan flag is different from what we had, send a signal. */ if ((rp.enable & SCAN_INQUIRY) != (old_data & SCAN_INQUIRY)) { se = (rp.enable & SCAN_INQUIRY); send_property_changed_signal(id, DEV_PROPERTY_ISCAN, DBUS_TYPE_BOOLEAN, &se); } dbus_connection_flush(connection);failed: if (dd >= 0) close(dd); bt_free(local_addr);}static DBusMessage* handle_device_set_property_req_pscan(DBusMessage *msg, void *data){ return write_scan_enable(msg, data, TRUE);}static DBusMessage* handle_device_set_property_req_iscan(DBusMessage *msg, void *data){ return write_scan_enable(msg, data, FALSE);}static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data){ DBusMessageIter iter; DBusMessageIter array_iter; DBusMessage *reply = NULL; struct hci_dev_list_req *dl = NULL; struct hci_dev_req *dr = NULL; int sk = -1; int i; const char array_sig[] = MGR_GET_DEV_REPLY_STRUCT_SIGNATURE; /* Create and bind HCI socket */ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), e
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -