diff options
Diffstat (limited to 'hcid/dbus.c')
-rw-r--r-- | hcid/dbus.c | 1145 |
1 files changed, 10 insertions, 1135 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c index f123a993..fadc98d8 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -45,7 +45,6 @@ #include "hcid.h" #include "dbus.h" -#include "textfile.h" #ifndef DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT #define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT 0x00 @@ -56,7 +55,6 @@ static int default_dev = -1; #define TIMEOUT (30 * 1000) /* 30 seconds */ #define DBUS_RECONNECT_TIMER (5 * 1000 * 1000) /* 5 sec */ -#define MAX_PATH_LENGTH 64 #define MAX_CONN_NUMBER 10 #define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" @@ -69,35 +67,14 @@ struct pin_request { bdaddr_t bda; }; -typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *); - -struct service_data { - const char *name; - service_handler_func_t *handler_func; - const char *signature; -}; - -struct hci_dbus_data { - uint16_t dev_id; - uint16_t path_id; - uint32_t path_data; -}; - -typedef int register_function_t(DBusConnection *conn, uint16_t id); -typedef int unregister_function_t(DBusConnection *conn, uint16_t id); - -/* - * Utility functions - */ -static char *get_peer_name(const bdaddr_t *local, const bdaddr_t *peer) +DBusConnection *get_dbus_connection(void) { - char filename[PATH_MAX + 1], addr[18]; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); + return connection; +} - ba2str(peer, addr); - return textfile_get(filename, addr); +int get_default_dev_id(void) +{ + return default_dev; } static int8_t dev_append_signal_args(DBusMessage *signal, int first, va_list var_args) @@ -126,7 +103,7 @@ failed: return retval; } -static DBusMessage *dev_signal_factory(const int devid, const char *prop_name, const int first, ...) +DBusMessage *dev_signal_factory(const int devid, const char *prop_name, const int first, ...) { DBusMessage *signal = NULL; char path[MAX_PATH_LENGTH]; @@ -152,137 +129,8 @@ static DBusMessage *dev_signal_factory(const int devid, const char *prop_name, c } /* - * D-Bus error messages functions and declarations. - * This section should be moved to a common file - * in the future - * - */ - -typedef struct { - uint32_t code; - const char *str; -} bluez_error_t; - -static const bluez_error_t dbus_error_array[] = { - { BLUEZ_EDBUS_UNKNOWN_METHOD, "Method not found" }, - { BLUEZ_EDBUS_WRONG_SIGNATURE, "Wrong method signature" }, - { BLUEZ_EDBUS_WRONG_PARAM, "Invalid parameters" }, - { BLUEZ_EDBUS_RECORD_NOT_FOUND, "No record found" }, - { BLUEZ_EDBUS_NO_MEM, "No memory" }, - { BLUEZ_EDBUS_CONN_NOT_FOUND, "Connection not found" }, - { BLUEZ_EDBUS_UNKNOWN_PATH, "Unknown D-BUS path" }, - { BLUEZ_EDBUS_NOT_IMPLEMENTED, "Method not implemented" }, - { 0, NULL } -}; - -static const bluez_error_t hci_error_array[] = { - { HCI_UNKNOWN_COMMAND, "Unknown HCI Command" }, - { HCI_NO_CONNECTION, "Unknown Connection Identifier" }, - { HCI_HARDWARE_FAILURE, "Hardware Failure" }, - { HCI_PAGE_TIMEOUT, "Page Timeout" }, - { HCI_AUTHENTICATION_FAILURE, "Authentication Failure" }, - { HCI_PIN_OR_KEY_MISSING, "PIN Missing" }, - { HCI_MEMORY_FULL, "Memory Capacity Exceeded" }, - { HCI_CONNECTION_TIMEOUT, "Connection Timeout" }, - { HCI_MAX_NUMBER_OF_CONNECTIONS, "Connection Limit Exceeded" }, - { HCI_MAX_NUMBER_OF_SCO_CONNECTIONS, "Synchronous Connection Limit To A Device Exceeded" }, - { HCI_ACL_CONNECTION_EXISTS, "ACL Connection Already Exists" }, - { HCI_COMMAND_DISALLOWED, "Command Disallowed" }, - { HCI_REJECTED_LIMITED_RESOURCES, "Connection Rejected due to Limited Resources" }, - { HCI_REJECTED_SECURITY, "Connection Rejected Due To Security Reasons" }, - { HCI_REJECTED_PERSONAL, "Connection Rejected due to Unacceptable BD_ADDR" }, - { HCI_HOST_TIMEOUT, "Connection Accept Timeout Exceeded" }, - { HCI_UNSUPPORTED_FEATURE, "Unsupported Feature or Parameter Value" }, - { HCI_INVALID_PARAMETERS, "Invalid HCI Command Parameters" }, - { HCI_OE_USER_ENDED_CONNECTION, "Remote User Terminated Connection" }, - { HCI_OE_LOW_RESOURCES, "Remote Device Terminated Connection due to Low Resources" }, - { HCI_OE_POWER_OFF, "Remote Device Terminated Connection due to Power Off" }, - { HCI_CONNECTION_TERMINATED, "Connection Terminated By Local Host" }, - { HCI_REPEATED_ATTEMPTS, "Repeated Attempts" }, - { HCI_PAIRING_NOT_ALLOWED, "Pairing Not Allowed" }, - { HCI_UNKNOWN_LMP_PDU, "Unknown LMP PDU" }, - { HCI_UNSUPPORTED_REMOTE_FEATURE, "Unsupported Remote Feature" }, - { HCI_SCO_OFFSET_REJECTED, "SCO Offset Rejected" }, - { HCI_SCO_INTERVAL_REJECTED, "SCO Interval Rejected" }, - { HCI_AIR_MODE_REJECTED, "SCO Air Mode Rejected" }, - { HCI_INVALID_LMP_PARAMETERS, "Invalid LMP Parameters" }, - { HCI_UNSPECIFIED_ERROR, "Unspecified Error" }, - { HCI_UNSUPPORTED_LMP_PARAMETER_VALUE, "Unsupported LMP Parameter Value" }, - { HCI_ROLE_CHANGE_NOT_ALLOWED, "Role Change Not Allowed" }, - { HCI_LMP_RESPONSE_TIMEOUT, "LMP Response Timeout" }, - { HCI_LMP_ERROR_TRANSACTION_COLLISION, "LMP Error Transaction Collision" }, - { HCI_LMP_PDU_NOT_ALLOWED, "LMP PDU Not Allowed" }, - { HCI_ENCRYPTION_MODE_NOT_ACCEPTED, "Encryption Mode Not Acceptable" }, - { HCI_UNIT_LINK_KEY_USED, "Link Key Can Not be Changed" }, - { HCI_QOS_NOT_SUPPORTED, "Requested QoS Not Supported" }, - { HCI_INSTANT_PASSED, "Instant Passed" }, - { HCI_PAIRING_NOT_SUPPORTED, "Pairing With Unit Key Not Supported" }, - { HCI_TRANSACTION_COLLISION, "Different Transaction Collision" }, - { HCI_QOS_UNACCEPTABLE_PARAMETER, "QoS Unacceptable Parameter" }, - { HCI_QOS_REJECTED, "QoS Rejected" }, - { HCI_CLASSIFICATION_NOT_SUPPORTED, "Channel Classification Not Supported" }, - { HCI_INSUFFICIENT_SECURITY, "Insufficient Security" }, - { HCI_PARAMETER_OUT_OF_RANGE, "Parameter Out Of Mandatory Range" }, - { HCI_ROLE_SWITCH_PENDING, "Role Switch Pending" }, - { HCI_SLOT_VIOLATION, "Reserved Slot Violation" }, - { HCI_ROLE_SWITCH_FAILED, "Role Switch Failed" }, - { 0, NULL }, -}; - -static const char *bluez_dbus_error_to_str(const uint32_t ecode) -{ - const bluez_error_t *ptr; - uint32_t raw_code = 0; - - if (ecode & BLUEZ_ESYSTEM_OFFSET) { - /* System error */ - raw_code = (~BLUEZ_ESYSTEM_OFFSET) & ecode; - syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code)); - return strerror(raw_code); - } else if (ecode & BLUEZ_EDBUS_OFFSET) { - /* D-Bus error */ - for (ptr = dbus_error_array; ptr->code; ptr++) { - if (ptr->code == ecode) { - syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); - return ptr->str; - } - } - } else { - /* BLUEZ_EBT_OFFSET - Bluetooth HCI errors */ - for (ptr = hci_error_array; ptr->code; ptr++) { - if (ptr->code == ecode) { - syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); - return ptr->str; - } - } - } - - return NULL; -} - -static DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode) -{ - DBusMessageIter iter; - DBusMessage *reply; - const char *error_msg; - - error_msg = bluez_dbus_error_to_str(ecode); - if (!error_msg) - return NULL; - - reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg); - - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode); - - return reply; -} - -/* * Virtual table that handle the object path hierarchy */ -static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data); -static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data); static const DBusObjectPathVTable obj_dev_vtable = { .message_function = &msg_func_device, @@ -295,108 +143,6 @@ static const DBusObjectPathVTable obj_mgr_vtable = { }; /* - * Services provided under the path DEVICE_PATH - */ - -static DBusMessage* handle_dev_get_address_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_alias_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_company_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_discoverable_to_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_features_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_manufacturer_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_mode_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_name_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_get_revision_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_version_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_is_connectable_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_is_discoverable_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_set_alias_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_class_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_discoverable_to_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_mode_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_name_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_discover_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_discover_cache_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_discover_cancel_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_discover_service_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_last_seen_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_last_used_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_remote_alias_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_remote_name_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_remote_version_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_create_bonding_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_list_bondings_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_has_bonding_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_remove_bonding_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_pin_code_length_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_encryption_key_size_req(DBusMessage *msg, void *data); - - -static const struct service_data dev_services[] = { - { DEV_GET_ADDRESS, handle_dev_get_address_req, DEV_GET_ADDRESS_SIGNATURE }, - { DEV_GET_ALIAS, handle_dev_get_alias_req, DEV_GET_ALIAS_SIGNATURE }, - { DEV_GET_COMPANY, handle_dev_get_company_req, DEV_GET_COMPANY_SIGNATURE }, - { DEV_GET_DISCOVERABLE_TO, handle_dev_get_discoverable_to_req, DEV_GET_DISCOVERABLE_TO_SIGNATURE }, - { DEV_GET_FEATURES, handle_dev_get_features_req, DEV_GET_FEATURES_SIGNATURE }, - { DEV_GET_MANUFACTURER, handle_dev_get_manufacturer_req, DEV_GET_MANUFACTURER_SIGNATURE }, - { DEV_GET_MODE, handle_dev_get_mode_req, DEV_GET_MODE_SIGNATURE }, - { DEV_GET_NAME, handle_dev_get_name_req, DEV_GET_NAME_SIGNATURE }, - { DEV_GET_REVISION, handle_dev_get_revision_req, DEV_GET_REVISION_SIGNATURE }, - { DEV_GET_VERSION, handle_dev_get_version_req, DEV_GET_VERSION_SIGNATURE }, - - { DEV_IS_CONNECTABLE, handle_dev_is_connectable_req, DEV_IS_CONNECTABLE_SIGNATURE }, - { DEV_IS_DISCOVERABLE, handle_dev_is_discoverable_req, DEV_IS_DISCOVERABLE_SIGNATURE }, - - { DEV_SET_ALIAS, handle_dev_set_alias_req, DEV_SET_ALIAS_SIGNATURE }, - { DEV_SET_CLASS, handle_dev_set_class_req, DEV_SET_CLASS_SIGNATURE }, - { DEV_SET_DISCOVERABLE_TO, handle_dev_set_discoverable_to_req, DEV_SET_DISCOVERABLE_TO_SIGNATURE }, - { DEV_SET_MODE, handle_dev_set_mode_req, DEV_SET_MODE_SIGNATURE }, - { DEV_SET_NAME, handle_dev_set_name_req, DEV_SET_NAME_SIGNATURE }, - - { DEV_DISCOVER, handle_dev_discover_req, DEV_DISCOVER_SIGNATURE }, - { DEV_DISCOVER_CACHE, handle_dev_discover_cache_req, DEV_DISCOVER_CACHE_SIGNATURE }, - { DEV_DISCOVER_CANCEL, handle_dev_discover_cancel_req, DEV_DISCOVER_CANCEL_SIGNATURE }, - { DEV_DISCOVER_SERVICE, handle_dev_discover_service_req, DEV_DISCOVER_SERVICE_SIGNATURE }, - - { DEV_LAST_SEEN, handle_dev_last_seen_req, DEV_LAST_SEEN_SIGNATURE }, - { DEV_LAST_USED, handle_dev_last_used_req, DEV_LAST_USED_SIGNATURE }, - - { DEV_REMOTE_ALIAS, handle_dev_remote_alias_req, DEV_REMOTE_ALIAS_SIGNATURE }, - { DEV_REMOTE_NAME, handle_dev_remote_name_req, DEV_REMOTE_NAME_SIGNATURE }, - { DEV_REMOTE_VERSION, handle_dev_remote_version_req, DEV_REMOTE_VERSION_SIGNATURE }, - - { DEV_CREATE_BONDING, handle_dev_create_bonding_req, DEV_CREATE_BONDING_SIGNATURE }, - { DEV_LIST_BONDINGS, handle_dev_list_bondings_req, DEV_LIST_BONDINGS_SIGNATURE }, - { DEV_HAS_BONDING_NAME, handle_dev_has_bonding_req, DEV_HAS_BONDING_SIGNATURE }, - { DEV_REMOVE_BONDING, handle_dev_remove_bonding_req, DEV_REMOVE_BONDING_SIGNATURE }, - - { DEV_PIN_CODE_LENGTH, handle_dev_pin_code_length_req, DEV_PIN_CODE_LENGTH_SIGNATURE }, - { DEV_ENCRYPTION_KEY_SIZE, handle_dev_encryption_key_size_req, DEV_ENCRYPTION_KEY_SIZE_SIGNATURE }, - - { NULL, NULL, NULL} -}; - -/* - * Services provided under the path MANAGER_PATH - */ -static DBusMessage* handle_mgr_device_list_req(DBusMessage *msg, void *data); -static DBusMessage* handle_mgr_default_device_req(DBusMessage *msg, void *data); - -static const struct service_data mgr_services[] = { - { MGR_DEVICE_LIST, handle_mgr_device_list_req, MGR_DEVICE_LIST_SIGNATURE }, - { MGR_DEFAULT_DEVICE, handle_mgr_default_device_req, MGR_DEFAULT_DEVICE_SIGNATURE }, - { NULL, NULL, NULL } -}; - -/* * HCI D-Bus services */ static DBusHandlerResult hci_dbus_signal_filter(DBusConnection *conn, DBusMessage *msg, void *data); @@ -734,7 +480,7 @@ failed: bt_free(peer_addr); } -void hcid_dbus_discover_start(bdaddr_t *local) +void hcid_dbus_inquiry_start(bdaddr_t *local) { DBusMessage *message = NULL; char path[MAX_PATH_LENGTH]; @@ -771,7 +517,7 @@ failed: bt_free(local_addr); } -void hcid_dbus_discover_complete(bdaddr_t *local) +void hcid_dbus_inquiry_complete(bdaddr_t *local) { DBusMessage *message = NULL; char path[MAX_PATH_LENGTH]; @@ -808,7 +554,7 @@ failed: bt_free(local_addr); } -void hcid_dbus_discover_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { DBusMessage *message = NULL; char path[MAX_PATH_LENGTH]; @@ -1164,7 +910,6 @@ failed: if (dl) free(dl); - } static void reconnect_timer_start(void) @@ -1225,780 +970,6 @@ static DBusHandlerResult hci_dbus_signal_filter (DBusConnection *conn, DBusMessa return ret; } -static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data) -{ - const struct service_data *handlers = dev_services; - DBusMessage *reply = NULL; - struct hci_dbus_data *dbus_data = data; - const char *method; - const char *signature; - uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; - DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - method = dbus_message_get_member(msg); - signature = dbus_message_get_signature(msg); - - syslog(LOG_INFO, "[%s,%d] path:%s, method:%s", __PRETTY_FUNCTION__, __LINE__, dbus_message_get_path(msg), method); - - 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; - } - - /* It's a device path id */ - 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; - uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; - DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - iface = dbus_message_get_interface(msg); - method = dbus_message_get_member(msg); - signature = dbus_message_get_signature(msg); - - syslog(LOG_INFO, "[%s,%d] path:%s, method:%s", __PRETTY_FUNCTION__, __LINE__, dbus_message_get_path(msg), method); - - if (strcmp(iface, MANAGER_INTERFACE) != 0) - return ret; - - for (handlers = mgr_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; -} - -/***************************************************************** - * - * Section reserved to device D-Bus services implementation - * - *****************************************************************/ - -static DBusMessage* handle_dev_get_address_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessage *reply; - char str[18], *str_ptr = str; - - get_device_address(dbus_data->dev_id, str, sizeof(str)); - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_get_version_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessage *reply; - char str[20], *str_ptr = str; - - get_device_version(dbus_data->dev_id, str, sizeof(str)); - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_get_revision_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessage *reply; - char str[20], *str_ptr = str; - - get_device_revision(dbus_data->dev_id, str, sizeof(str)); - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_get_manufacturer_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessage *reply; - char str[64], *str_ptr = str; - - get_device_manufacturer(dbus_data->dev_id, str, sizeof(str)); - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_get_company_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessage *reply; - char str[64], *str_ptr = str; - - get_device_company(dbus_data->dev_id, str, sizeof(str)); - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_get_features_req(DBusMessage *msg, void *data) -{ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_get_name_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessage *reply; - char str[249], *str_ptr = str; - - get_device_name(dbus_data->dev_id, str, sizeof(str)); - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_set_name_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessageIter iter; - DBusMessage *reply; - char *str_ptr; - - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &str_ptr); - - if (strlen(str_ptr) == 0) { - syslog(LOG_ERR, "Name change failed: Invalid parameter"); - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); - } - - set_device_name(dbus_data->dev_id, str_ptr); - - reply = dbus_message_new_method_return(msg); - - return reply; -} - -static DBusMessage* handle_dev_get_alias_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessageIter iter; - DBusMessage *reply; - char str[249], *str_ptr = str, *addr_ptr; - bdaddr_t bdaddr; - - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &addr_ptr); - - str2ba(addr_ptr, &bdaddr); - - get_device_alias(dbus_data->dev_id, &bdaddr, str, sizeof(str)); - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_set_alias_req(DBusMessage *msg, void *data) -{ - struct hci_dbus_data *dbus_data = data; - DBusMessageIter iter; - DBusMessage *reply, *signal; - char *str_ptr, *addr_ptr; - bdaddr_t bdaddr; - - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &addr_ptr); - dbus_message_iter_next(&iter); - dbus_message_iter_get_basic(&iter, &str_ptr); - - if (strlen(str_ptr) == 0) { - syslog(LOG_ERR, "Alias change failed: Invalid parameter"); - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); - } - - str2ba(addr_ptr, &bdaddr); - - set_device_alias(dbus_data->dev_id, &bdaddr, str_ptr); - - signal = dev_signal_factory(dbus_data->dev_id, "AliasChanged", - DBUS_TYPE_STRING, &addr_ptr, - DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - if (signal) { - dbus_connection_send(connection, signal, NULL); - dbus_connection_flush(connection); - dbus_message_unref(signal); - } - - signal = dev_signal_factory(dbus_data->dev_id, "RemoteAlias", - DBUS_TYPE_STRING, &addr_ptr, - DBUS_TYPE_STRING, &str_ptr, - DBUS_TYPE_INVALID); - if (signal) { - dbus_connection_send(connection, signal, NULL); - dbus_connection_flush(connection); - dbus_message_unref(signal); - } - - reply = dbus_message_new_method_return(msg); - - return reply; -} - -static DBusMessage* handle_dev_get_discoverable_to_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_get_mode_req(DBusMessage *msg, void *data) -{ - const struct hci_dbus_data *dbus_data = data; - DBusMessage *reply = NULL; - const uint8_t hci_mode = dbus_data->path_data; - uint8_t scan_mode; - - switch (hci_mode) { - case SCAN_DISABLED: - scan_mode = MODE_OFF; - break; - case SCAN_PAGE: - scan_mode = MODE_CONNECTABLE; - break; - case (SCAN_PAGE | SCAN_INQUIRY): - scan_mode = MODE_DISCOVERABLE; - break; - case SCAN_INQUIRY: - /* inquiry scan mode is not handled, return 0xff */ - default: - /* reserved */ - scan_mode = 0xff; - } - - reply = dbus_message_new_method_return(msg); - - dbus_message_append_args(reply, - DBUS_TYPE_BYTE, &scan_mode, - DBUS_TYPE_INVALID); - - return reply; -} - -static DBusMessage* handle_dev_is_connectable_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_is_discoverable_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_set_class_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_set_discoverable_to_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_set_mode_req(DBusMessage *msg, void *data) -{ - const struct hci_dbus_data *dbus_data = data; - DBusMessage *reply = NULL; - struct hci_request rq; - int dd = -1; - const uint8_t scan_mode; - uint8_t hci_mode; - uint8_t status = 0; - const uint8_t current_mode = dbus_data->path_data; - - dbus_message_get_args(msg, NULL, - DBUS_TYPE_BYTE, &scan_mode, - DBUS_TYPE_INVALID); - - switch (scan_mode) { - case MODE_OFF: - hci_mode = SCAN_DISABLED; - break; - case MODE_CONNECTABLE: - hci_mode = SCAN_PAGE; - break; - case MODE_DISCOVERABLE: - hci_mode = (SCAN_PAGE | SCAN_INQUIRY); - break; - default: - /* invalid mode */ - 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; - } - - /* Check if the new requested mode is different from the current */ - if (current_mode != hci_mode) { - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_SCAN_ENABLE; - rq.cparam = &hci_mode; - rq.clen = sizeof(hci_mode); - 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", 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_dev_discover_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; - - 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_dev_discover_cache_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_discover_cancel_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_dev_discover_service_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_last_seen_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_last_used_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_remote_alias_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_remote_name_req(DBusMessage *msg, void *data) -{ - DBusMessage *reply = NULL; - DBusMessage *signal = NULL; - struct hci_dbus_data *dbus_data = data; - const char *str_bdaddr; - char *name; - char path[MAX_PATH_LENGTH]; - bdaddr_t bdaddr; - struct hci_dev_info di; - struct hci_request rq; - remote_name_req_cp cp; - evt_cmd_status rp; - int dd = -1; - - dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &str_bdaddr, - DBUS_TYPE_INVALID); - - str2ba(str_bdaddr, &bdaddr); - if (hci_devinfo(dbus_data->dev_id, &di) < 0) { - syslog(LOG_ERR, "Can't get device info"); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto failed; - } - - /* Try retrieve from local cache */ - name = get_peer_name(&di.bdaddr, &bdaddr); - if (name) { - - reply = dbus_message_new_method_return(msg); - - snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, dbus_data->dev_id); - - signal = dbus_message_new_signal(path, DEVICE_INTERFACE, - DEV_SIG_REMOTE_NAME); - - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &str_bdaddr, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); - - if (dbus_connection_send(connection, signal, NULL) == FALSE) { - syslog(LOG_ERR, "Can't send D-BUS remote name signal message"); - goto failed; - } - - dbus_message_unref(signal); - free(name); - - } else { - - /* Send HCI command */ - 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 = 0x02; - - 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; - } - - if (rp.status) { - syslog(LOG_ERR, "Remote name request failed"); - reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET | rp.status); - goto failed; - } - } - - reply = dbus_message_new_method_return(msg); -failed: - if (dd >= 0) - hci_close_dev(dd); - - return reply; -} - -static DBusMessage* handle_dev_remote_version_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_create_bonding_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; -} - -static DBusMessage* handle_dev_list_bondings_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_has_bonding_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_remove_bonding_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - - -static DBusMessage* handle_dev_pin_code_length_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_encryption_key_size_req(DBusMessage *msg, void *data) -{ - /*FIXME: */ - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - /***************************************************************** * * Section reserved to device HCI callbacks @@ -2173,99 +1144,3 @@ failed: bt_free(local_addr); } - -/***************************************************************** - * - * Section reserved to Manager D-Bus services implementation - * - *****************************************************************/ -static DBusMessage* handle_mgr_device_list_req(DBusMessage *msg, void *data) -{ - DBusMessageIter iter; - DBusMessageIter array_iter; - DBusMessage *reply; - struct hci_dev_list_req *dl = NULL; - struct hci_dev_req *dr = NULL; - int i, sk = -1; - - 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 bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - } - - dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); - if (!dl) { - syslog(LOG_ERR, "Can't allocate memory"); - close(sk); - return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); - } - - dl->dev_num = HCI_MAX_DEV; - dr = dl->dev_req; - - if (ioctl(sk, HCIGETDEVLIST, dl) < 0) { - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - goto failed; - } - - dr = dl->dev_req; - - 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, - DBUS_TYPE_STRING_AS_STRING, &array_iter); - - for (i = 0; i < dl->dev_num; i++, dr++) { - char path[MAX_PATH_LENGTH], *path_ptr = path; - struct hci_dev_info di; - - memset(&di, 0 , sizeof(struct hci_dev_info)); - di.dev_id = dr->dev_id; - - if (ioctl(sk, HCIGETDEVINFO, &di) < 0) - continue; - - snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, di.name); - - dbus_message_iter_append_basic(&array_iter, - DBUS_TYPE_STRING, &path_ptr); - } - - dbus_message_iter_close_container(&iter, &array_iter); - -failed: - free(dl); - - close(sk); - - return reply; -} - -static DBusMessage* handle_mgr_default_device_req(DBusMessage *msg, void *data) -{ - DBusMessage *reply; - char path[MAX_PATH_LENGTH], *path_ptr = path; - - if (default_dev < 0) - return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - - reply = dbus_message_new_method_return(msg); - if (!reply) { - syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); - return reply; - } - - snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, default_dev); - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path_ptr, - DBUS_TYPE_INVALID); - - return reply; -} |