📄 dbus.c
字号:
char path[MAX_PATH_LENGTH]; char *pptr = path; gboolean ret; DBusMessage *message = NULL; snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE, BLUEZ_MGR_DEV_ADDED); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; } dbus_message_append_args(message, DBUS_TYPE_STRING, &pptr, DBUS_TYPE_INVALID); if (!dbus_connection_send(connection, message, NULL)) { syslog(LOG_ERR, "Can't send D-BUS added device message"); goto failed; } dbus_connection_flush(connection);failed: dbus_message_unref(message); ret = register_dbus_path(path, DEVICE_PATH_ID, id, &obj_dev_vtable, FALSE); if (ret && default_dev < 0) default_dev = id; return ret;}gboolean hcid_dbus_unregister_device(uint16_t id){ gboolean ret; DBusMessage *message = NULL; char path[MAX_PATH_LENGTH]; char *pptr = path; snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE, BLUEZ_MGR_DEV_REMOVED); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; } dbus_message_append_args(message, DBUS_TYPE_STRING, &pptr, DBUS_TYPE_INVALID); if (!dbus_connection_send(connection, message, NULL)) { syslog(LOG_ERR, "Can't send D-BUS added device message"); goto failed; } dbus_connection_flush(connection);failed: dbus_message_unref(message); ret = unregister_device_path(path); /* FIXME: If there are any devices left after this removal the default * device should be changed to one of them */ if (ret && default_dev == id) default_dev = -1; return ret;}gboolean hcid_dbus_dev_up(uint16_t id){ char path[MAX_PATH_LENGTH]; struct profile_obj_path_data *ptr = obj_path_table; DBusMessage *message = NULL; if (!connection) return FALSE; for (; ptr->id != INVALID_PATH_ID; ptr++) { if (ptr->reg_func(connection, id) < 0) goto failed; } snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_UP); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; } if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS added device message"); goto failed; } dbus_connection_flush(connection);failed: /* if the signal can't be sent ignore the error */ dbus_message_unref(message); return TRUE;}gboolean hcid_dbus_dev_down(uint16_t id){ char path[MAX_PATH_LENGTH]; struct profile_obj_path_data *ptr = obj_path_table; DBusMessage *message = NULL; if (!connection) return FALSE; for (; ptr->id != INVALID_PATH_ID; ptr++) { if (ptr->unreg_func(connection, id) < 0) syslog(LOG_ERR, "Unregistering profile id 0x%04x failed", ptr->id); } snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_DOWN); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS device removed message"); goto failed; } if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS removed device message"); goto failed; } dbus_connection_flush(connection);failed: /* if the signal can't be sent ignore the error */ dbus_message_unref(message); return TRUE;}/* * @brief HCI object path register function * Detailed description: function responsible for register a new hci * D-Bus path. If necessary the default path must be registered too. * @param conn D-Bus connection * @param id hci device identification * @return (0-Success/-1 failure) */static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id){ char path[MAX_PATH_LENGTH]; /* register the default path*/ snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); if (!register_dbus_path(path, HCI_PATH_ID, id, &obj_dev_vtable, FALSE)) return -1; return 0;}/* * @brief HCI object path unregister function * Detailed description: function responsible for unregister HCI D-Bus * path for a detached hci device. If necessary the default path must * be registered too. * @param conn D-Bus connection * @param unreg_dft register the default path(0 or !0) * @param id hci device identification * @return (0-Success/-1 failure) */static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id) { char path[MAX_PATH_LENGTH]; snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); if (!unregister_dbus_path(path)) return -1; return 0;}const struct service_data *get_hci_table(void){ return device_hci_services;}/***************************************************************** * * Section reserved to re-connection timer * *****************************************************************/static void reconnect_timer_handler(int signum){ struct hci_dev_list_req *dl = NULL; struct hci_dev_req *dr; int sk; int i; if (hcid_dbus_init() == FALSE) return; /* stop the timer */ sigaction(SIGALRM, NULL, NULL); setitimer(ITIMER_REAL, NULL, NULL); /* register the device based paths */ /* 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); return; } dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); if (!dl) { syslog(LOG_ERR, "Can't allocate memory"); goto failed; } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) { syslog(LOG_INFO, "Can't get device list: %s (%d)", strerror(errno), errno); goto failed; } /* reset the default device */ default_dev = -1; for (i = 0; i < dl->dev_num; i++, dr++) { hcid_dbus_register_device(dr->dev_id); if (hci_test_bit(HCI_UP, &dr->dev_opt)) hcid_dbus_dev_up(dr->dev_id); }failed: if (sk >= 0) close(sk); if (dl) free(dl);}static void reconnect_timer_start(void){ struct sigaction sa; struct itimerval timer; memset (&sa, 0, sizeof (sa)); sa.sa_handler = &reconnect_timer_handler; sigaction(SIGALRM, &sa, NULL); /* expire after X msec... */ timer.it_value.tv_sec = 0; timer.it_value.tv_usec = DBUS_RECONNECT_TIMER; /* ... and every x msec after that. */ timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = DBUS_RECONNECT_TIMER; setitimer(ITIMER_REAL, &timer, NULL);}/***************************************************************** * * Section reserved to HCI D-Bus services * *****************************************************************/static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data){ DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; const char *iface; const char *method; if (!msg || !conn) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_SIGNAL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; iface = dbus_message_get_interface(msg); method = dbus_message_get_member(msg); if ((strcmp(iface, DBUS_INTERFACE_LOCAL) == 0) && (strcmp(method, "Disconnected") == 0)) { syslog(LOG_ERR, "Got disconnected from the system message bus"); dbus_connection_dispatch(conn); dbus_connection_close(conn); dbus_connection_unref(conn); reconnect_timer_start(); ret = DBUS_HANDLER_RESULT_HANDLED; } else if (strcmp(iface, DBUS_INTERFACE_DBUS) == 0) { if (strcmp(method, "NameOwnerChanged") == 0) ret = DBUS_HANDLER_RESULT_HANDLED; else if (strcmp(method, "NameAcquired") == 0) ret = DBUS_HANDLER_RESULT_HANDLED; } return ret;}static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data){ const struct service_data *handlers = NULL; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; const char *method; const char *signature; const char *path; uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; path = dbus_message_get_path(msg); method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); if (dbus_data->path_id == DEVICE_ROOT_ID) { /* Device is down(path unregistered) or the path is wrong */ ret = DBUS_HANDLER_RESULT_HANDLED; error = BLUEZ_EDBUS_UNKNOWN_PATH; goto failed; } if (dbus_data->path_id == DEVICE_PATH_ID) handlers = device_services; else { struct profile_obj_path_data *profile; for (profile = obj_path_table; profile->id != INVALID_PATH_ID; profile++) { if (profile->id == dbus_data->path_id) { handlers = profile->get_svc_table(); break; } } } if (!handlers) goto failed; for (; handlers->name != NULL; handlers++) { if (strcmp(handlers->name, method)) continue; ret = DBUS_HANDLER_RESULT_HANDLED; if (!strcmp(handlers->signature, signature)) { reply = handlers->handler_func(msg, data); error = 0; break; } else { /* Set the error, but continue looping incase there is * another method with the same name but a different * signature */ error = BLUEZ_EDBUS_WRONG_SIGNATURE; continue; } }failed: if (error) reply = bluez_new_failure_msg(msg, error); if (reply) { if (!dbus_connection_send (conn, reply, NULL)) syslog(LOG_ERR, "Can't send reply message!"); dbus_message_unref(reply); } return ret;}static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data){ const struct service_data *handlers; DBusMessage *reply = NULL; const char *iface; const char *method; const char *signature; const char *path; uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; path = dbus_message_get_path(msg); iface = dbus_message_get_interface(msg); method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); if (strcmp(iface, MANAGER_INTERFACE) != 0) return ret; for (handlers = manager_services; handlers->name != NULL; handlers++) { if (strcmp(handlers->name, method)) continue; if (strcmp(handlers->signature, signature) != 0) error = BLUEZ_EDBUS_WRONG_SIGNATURE; else { reply = handlers->handler_func(msg, data); error = 0; } ret = DBUS_HANDLER_RESULT_HANDLED; } if (error) reply = bluez_new_failure_msg(msg, error); if (reply) { if (!dbus_connection_send (conn, reply, NULL)) syslog(LOG_ERR, "Can't send reply message!"); dbus_message_unref(reply); } return ret;}static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data){ periodic_inquiry_cp inq_param; struct hci_request rq; uint8_t status; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; uint8_t length, num_rsp = 0; uint16_t max_period; uint16_t min_period; uint32_t lap = 0x9e8b33; 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; } if (dbus_message_has_signature(msg, HCI_PERIODIC_INQ_EXT_SIGNATURE)) dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &length, DBUS_TYPE_UINT16, &min_period, DBUS_TYPE_UINT16, &max_period, DBUS_TYPE_UINT32, &lap, DBUS_TYPE_INVALID); else dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &length, DBUS_TYPE_UINT16, &min_period, DBUS_TYPE_UINT16, &max_period, DBUS_TYPE_INVALID);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -