From 9641b1d6e4c6b8a25dc3b1c83785f5d7c1ab9690 Mon Sep 17 00:00:00 2001 From: DoHyun Pyun Date: Tue, 7 Feb 2017 12:44:54 +0900 Subject: [PATCH] Merge latest tizen_3.0 bug fix codes -------------------------------------------------- commit 2eebae6d9922f8c3f7c759db0f98ce5156426a69 Author: Lee Hyuk Date: Wed Jan 25 17:16:28 2017 +0900 Fix the memory leak in bt-core -------------------------------------------------- Change-Id: I4a3060bb1740e16e59e7dc8788a8c6f1b63a0126 Signed-off-by: DoHyun Pyun --- bt-api/CMakeLists.txt | 4 +- bt-api/bt-common.c | 354 +++- bt-api/bt-dpm.c | 3 + bt-api/bt-event-handler.c | 506 +++++- bt-api/bt-gatt-client.c | 71 +- bt-api/bt-gatt-service.c | 394 +++-- bt-api/bt-map-client.c | 374 ++++ bt-api/bt-request-sender.c | 58 +- bt-api/bt-rfcomm-client.c | 2 +- bt-api/bt-rfcomm-server.c | 4 +- bt-api/bt-tds.c | 313 ++++ bt-api/bt-telephony.c | 36 + bt-api/include/bt-common.h | 7 + bt-api/include/bt-dpm.h | 1 + bt-core/bt-core-dbus-handler.c | 17 +- bt-httpproxy/bt-httpproxy.c | 24 +- bt-service-emul/bt-request-handler.c | 3 + bt-service-emul/bt-service-event-sender.c | 11 + bt-service-emul/include/bt-service-common.h | 3 +- bt-service/CMakeLists.txt | 4 +- bt-service/bt-request-handler.c | 367 +++- bt-service/bt-service-adapter-le.c | 96 +- bt-service/bt-service-adapter.c | 28 +- bt-service/bt-service-agent.c | 2 + bt-service/bt-service-audio.c | 53 + bt-service/bt-service-avrcp-controller.c | 1 + bt-service/bt-service-common.c | 491 +++++- bt-service/bt-service-device.c | 65 +- bt-service/bt-service-dpm.c | 26 +- bt-service/bt-service-event-receiver.c | 429 ++++- bt-service/bt-service-event-sender.c | 49 + bt-service/bt-service-headset-connection.c | 1 + bt-service/bt-service-main.c | 7 - bt-service/bt-service-map-client.c | 763 +++++++++ bt-service/bt-service-pbap.c | 2 +- bt-service/bt-service-tds.c | 1787 ++++++++++++++++++++ bt-service/include/bt-service-adapter-le.h | 12 +- bt-service/include/bt-service-audio.h | 3 + bt-service/include/bt-service-common.h | 17 +- bt-service/include/bt-service-event.h | 3 + bt-service/include/bt-service-headset-connection.h | 4 +- bt-service/include/bt-service-map-client.h | 106 ++ bt-service/include/bt-service-tds.h | 72 + include/bluetooth-api.h | 489 +++++- include/bluetooth-media-control.h | 2 +- include/bluetooth-telephony-api.h | 10 + include/bt-internal-types.h | 86 +- packaging/bluetooth-frwk.spec | 3 + 48 files changed, 6610 insertions(+), 553 deletions(-) create mode 100644 bt-api/bt-map-client.c create mode 100644 bt-api/bt-tds.c mode change 100755 => 100644 bt-core/bt-core-dbus-handler.c create mode 100644 bt-service/bt-service-map-client.c create mode 100644 bt-service/bt-service-tds.c mode change 100755 => 100644 bt-service/include/bt-service-headset-connection.h create mode 100644 bt-service/include/bt-service-map-client.h create mode 100644 bt-service/include/bt-service-tds.h diff --git a/bt-api/CMakeLists.txt b/bt-api/CMakeLists.txt index 17a23ef..32024cd 100644 --- a/bt-api/CMakeLists.txt +++ b/bt-api/CMakeLists.txt @@ -15,6 +15,7 @@ bt-hdp.c bt-avrcp.c bt-telephony.c bt-opp-client.c +bt-map-client.c bt-obex-server.c bt-rfcomm-client.c bt-rfcomm-server.c @@ -27,7 +28,8 @@ bt-hid-device.c bt-gatt-client.c bt-ipsp.c bt-dpm.c -bt-proximity.c) +bt-proximity.c +bt-tds.c) SET(HEADERS bluetooth-api.h diff --git a/bt-api/bt-common.c b/bt-api/bt-common.c index d7a9e49..5b48930 100644 --- a/bt-api/bt-common.c +++ b/bt-api/bt-common.c @@ -126,6 +126,7 @@ bt_user_info_t *_bt_get_user_data(int type) void _bt_common_event_cb(int event, int result, void *param, void *callback, void *user_data) { + BT_DBG("bt_common_event_cb, event: %d", event); bluetooth_event_param_t bt_event = { 0, }; bt_event.event = event; bt_event.result = result; @@ -267,6 +268,350 @@ void _bt_convert_addr_type_to_string(char *address, addr[3], addr[4], addr[5]); } +const char *_bt_convert_error_to_string(int error) +{ + switch (error) { + case BLUETOOTH_ERROR_CANCEL: + return "CANCELLED"; + case BLUETOOTH_ERROR_INVALID_PARAM: + return "INVALID_PARAMETER"; + case BLUETOOTH_ERROR_INVALID_DATA: + return "INVALID DATA"; + case BLUETOOTH_ERROR_MEMORY_ALLOCATION: + case BLUETOOTH_ERROR_OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + case BLUETOOTH_ERROR_TIMEOUT: + return "TIMEOUT"; + case BLUETOOTH_ERROR_NO_RESOURCES: + return "NO_RESOURCES"; + case BLUETOOTH_ERROR_INTERNAL: + return "INTERNAL"; + case BLUETOOTH_ERROR_NOT_SUPPORT: + return "NOT_SUPPORT"; + case BLUETOOTH_ERROR_DEVICE_NOT_ENABLED: + return "NOT_ENABLED"; + case BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED: + return "ALREADY_ENABLED"; + case BLUETOOTH_ERROR_DEVICE_BUSY: + return "DEVICE_BUSY"; + case BLUETOOTH_ERROR_ACCESS_DENIED: + return "ACCESS_DENIED"; + case BLUETOOTH_ERROR_MAX_CLIENT: + return "MAX_CLIENT"; + case BLUETOOTH_ERROR_NOT_FOUND: + return "NOT_FOUND"; + case BLUETOOTH_ERROR_SERVICE_SEARCH_ERROR: + return "SERVICE_SEARCH_ERROR"; + case BLUETOOTH_ERROR_PARING_FAILED: + return "PARING_FAILED"; + case BLUETOOTH_ERROR_NOT_PAIRED: + return "NOT_PAIRED"; + case BLUETOOTH_ERROR_SERVICE_NOT_FOUND: + return "SERVICE_NOT_FOUND"; + case BLUETOOTH_ERROR_NOT_CONNECTED: + return "NOT_CONNECTED"; + case BLUETOOTH_ERROR_ALREADY_CONNECT: + return "ALREADY_CONNECT"; + case BLUETOOTH_ERROR_CONNECTION_BUSY: + return "CONNECTION_BUSY"; + case BLUETOOTH_ERROR_CONNECTION_ERROR: + return "CONNECTION_ERROR"; + case BLUETOOTH_ERROR_MAX_CONNECTION: + return "MAX_CONNECTION"; + case BLUETOOTH_ERROR_NOT_IN_OPERATION: + return "NOT_IN_OPERATION"; + case BLUETOOTH_ERROR_CANCEL_BY_USER: + return "CANCEL_BY_USER"; + case BLUETOOTH_ERROR_REGISTRATION_FAILED: + return "REGISTRATION_FAILED"; + case BLUETOOTH_ERROR_IN_PROGRESS: + return "IN_PROGRESS"; + case BLUETOOTH_ERROR_AUTHENTICATION_FAILED: + return "AUTHENTICATION_FAILED"; + case BLUETOOTH_ERROR_HOST_DOWN: + return "HOST_DOWN"; + case BLUETOOTH_ERROR_END_OF_DEVICE_LIST: + return "END_OF_DEVICE_LIST"; + case BLUETOOTH_ERROR_AGENT_ALREADY_EXIST: + return "AGENT_ALREADY_EXIST"; + case BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST: + return "AGENT_DOES_NOT_EXIST"; + case BLUETOOTH_ERROR_ALREADY_INITIALIZED: + return "ALREADY_INITIALIZED"; + case BLUETOOTH_ERROR_PERMISSION_DEINED: + return "PERMISSION_DEINED"; + case BLUETOOTH_ERROR_ALREADY_DEACTIVATED: + return "ALREADY_DEACTIVATED"; + case BLUETOOTH_ERROR_NOT_INITIALIZED: + return "NOT_INITIALIZED"; + case BLUETOOTH_ERROR_AUTHENTICATION_REJECTED: + return "AUTHENTICATION REJECTED"; + default: + return "UNKNOWN"; + } +} + +const char *_bt_convert_service_function_to_string(int function) +{ + int i; + + typedef struct { + int function; + const char *function_name; + } bt_function_name_t; + + const bt_function_name_t bt_functions[] = { + {BT_CHECK_ADAPTER, "BT_CHECK_ADAPTER"}, + {BT_ENABLE_ADAPTER, "BT_ENABLE_ADAPTER"}, + {BT_DISABLE_ADAPTER, "BT_DISABLE_ADAPTER"}, + {BT_RECOVER_ADAPTER, "BT_RECOVER_ADAPTER"}, + {BT_SET_DISCOVERABLE_TIME, "BT_SET_DISCOVERABLE_TIME"}, + {BT_GET_DISCOVERABLE_TIME, "BT_GET_DISCOVERABLE_TIME"}, + {BT_IGNORE_AUTO_PAIRING, "BT_IGNORE_AUTO_PAIRING"}, + {BT_GET_LOCAL_ADDRESS, "BT_GET_LOCAL_ADDRESS"}, + {BT_GET_LOCAL_VERSION, "BT_GET_LOCAL_VERSION"}, + {BT_GET_LOCAL_NAME, "BT_GET_LOCAL_NAME"}, + {BT_SET_LOCAL_NAME, "BT_SET_LOCAL_NAME"}, + {BT_IS_SERVICE_USED, "BT_IS_SERVICE_USED"}, + {BT_GET_DISCOVERABLE_MODE, "BT_GET_DISCOVERABLE_MODE"}, + {BT_SET_DISCOVERABLE_MODE, "BT_SET_DISCOVERABLE_MODE"}, + {BT_START_DISCOVERY, "BT_START_DISCOVERY"}, + {BT_START_CUSTOM_DISCOVERY, "BT_START_CUSTOM_DISCOVERY"}, + {BT_CANCEL_DISCOVERY, "BT_CANCEL_DISCOVERY"}, + {BT_START_LE_DISCOVERY, "BT_START_LE_DISCOVERY"}, + {BT_STOP_LE_DISCOVERY, "BT_STOP_LE_DISCOVERY"}, + {BT_IS_DISCOVERYING, "BT_IS_DISCOVERYING"}, + {BT_IS_LE_DISCOVERYING, "BT_IS_LE_DISCOVERYING"}, + {BT_ENABLE_RSSI, "BT_ENABLE_RSSI"}, + {BT_GET_RSSI, "BT_GET_RSSI"}, + {BT_IS_CONNECTABLE, "BT_IS_CONNECTABLE"}, + {BT_SET_CONNECTABLE, "BT_SET_CONNECTABLE"}, + {BT_GET_BONDED_DEVICES, "BT_GET_BONDED_DEVICES"}, + {BT_RESET_ADAPTER, "BT_RESET_ADAPTER"}, + {BT_SET_ADVERTISING, "BT_SET_ADVERTISING"}, + {BT_SET_CUSTOM_ADVERTISING, "BT_SET_CUSTOM_ADVERTISING"}, + {BT_SET_ADVERTISING_PARAMETERS, "BT_SET_ADVERTISING_PARAMETERS"}, + {BT_GET_ADVERTISING_DATA, "BT_GET_ADVERTISING_DATA"}, + {BT_SET_ADVERTISING_DATA, "BT_SET_ADVERTISING_DATA"}, + {BT_SET_SCAN_PARAMETERS, "BT_SET_SCAN_PARAMETERS"}, + {BT_GET_SCAN_RESPONSE_DATA, "BT_GET_SCAN_RESPONSE_DATA"}, + {BT_SET_SCAN_RESPONSE_DATA, "BT_SET_SCAN_RESPONSE_DATA"}, + {BT_IS_ADVERTISING, "BT_IS_ADVERTISING"}, + {BT_SET_MANUFACTURER_DATA, "BT_SET_MANUFACTURER_DATA"}, + {BT_LE_CONN_UPDATE, "BT_LE_CONN_UPDATE"}, + {BT_LE_READ_MAXIMUM_DATA_LENGTH, "BT_LE_READ_MAXIMUM_DATA_LENGTH"}, + {BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, "BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH"}, + {BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH, "BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH"}, + {BT_LE_SET_DATA_LENGTH, "BT_LE_SET_DATA_LENGTH"}, + {BT_ADD_WHITE_LIST, "BT_ADD_WHITE_LIST"}, + {BT_REMOVE_WHITE_LIST, "BT_REMOVE_WHITE_LIST"}, + {BT_CLEAR_WHITE_LIST, "BT_CLEAR_WHITE_LIST"}, + {BT_REGISTER_SCAN_FILTER, "BT_REGISTER_SCAN_FILTER"}, + {BT_UNREGISTER_SCAN_FILTER, "BT_UNREGISTER_SCAN_FILTER"}, + {BT_UNREGISTER_ALL_SCAN_FILTERS, "BT_UNREGISTER_ALL_SCAN_FILTERS"}, + {BT_IS_SCAN_FILTER_SUPPORTED, "BT_IS_SCAN_FILTER_SUPPORTED"}, + {BT_GET_PROFILE_CONNECTED_DEVICES, "BT_GET_PROFILE_CONNECTED_DEVICES"}, + {BT_ENABLE_FORCE_HCI_DUMP, "BT_ENABLE_FORCE_HCI_DUMP"}, + {BT_SET_PASSKEY_NOTIFICATION, "BT_SET_PASSKEY_NOTIFICATION"}, + {BT_BOND_DEVICE, "BT_BOND_DEVICE"}, + {BT_BOND_DEVICE_BY_TYPE, "BT_BOND_DEVICE_BY_TYPE"}, + {BT_CANCEL_BONDING, "BT_CANCEL_BONDING"}, + {BT_PASSKEY_REPLY, "BT_PASSKEY_REPLY"}, + {BT_PASSKEY_CONFIRMATION_REPLY, "BT_PASSKEY_CONFIRMATION_REPLY"}, + {BT_UNBOND_DEVICE, "BT_UNBOND_DEVICE"}, + {BT_SEARCH_SERVICE, "BT_SEARCH_SERVICE"}, + {BT_CANCEL_SEARCH_SERVICE, "BT_CANCEL_SEARCH_SERVICE"}, + {BT_GET_BONDED_DEVICE, "BT_GET_BONDED_DEVICE"}, + {BT_GET_IS_ALIAS_SET, "BT_GET_IS_ALIAS_SET"}, + {BT_SET_ALIAS, "BT_SET_ALIAS"}, + {BT_SET_AUTHORIZATION, "BT_SET_AUTHORIZATION"}, + {BT_UNSET_AUTHORIZATION, "BT_UNSET_AUTHORIZATION"}, + {BT_IS_DEVICE_CONNECTED, "BT_IS_DEVICE_CONNECTED"}, + {BT_GET_CONNECTED_LINK_TYPE, "BT_GET_CONNECTED_LINK_TYPE"}, + {BT_SET_PIN_CODE, "BT_SET_PIN_CODE"}, + {BT_UNSET_PIN_CODE, "BT_UNSET_PIN_CODE"}, + {BT_UPDATE_LE_CONNECTION_MODE, "BT_UPDATE_LE_CONNECTION_MODE"}, + {BT_SET_PROFILE_TRUSTED, "BT_SET_PROFILE_TRUSTED"}, + {BT_GET_PROFILE_TRUSTED, "BT_GET_PROFILE_TRUSTED"}, + {BT_SET_PROFILE_RESTRICTED, "BT_SET_PROFILE_RESTRICTED"}, + {BT_GET_PROFILE_RESTRICTED, "BT_GET_PROFILE_RESTRICTED"}, + {BT_HID_CONNECT, "BT_HID_CONNECT"}, + {BT_HID_DISCONNECT, "BT_HID_DISCONNECT"}, + {BT_HID_DEVICE_ACTIVATE, "BT_HID_DEVICE_ACTIVATE"}, + {BT_HID_DEVICE_DEACTIVATE, "BT_HID_DEVICE_DEACTIVATE"}, + {BT_HID_DEVICE_CONNECT, "BT_HID_DEVICE_CONNECT"}, + {BT_HID_DEVICE_DISCONNECT, "BT_HID_DEVICE_DISCONNECT"}, + {BT_HID_DEVICE_SEND_MOUSE_EVENT, "BT_HID_DEVICE_SEND_MOUSE_EVENT"}, + {BT_HID_DEVICE_SEND_KEY_EVENT, "BT_HID_DEVICE_SEND_KEY_EVENT"}, + {BT_HID_DEVICE_SEND_CUSTOM_EVENT, "BT_HID_DEVICE_SEND_CUSTOM_EVENT"}, + {BT_HID_DEVICE_SEND_REPLY_TO_REPORT, "BT_HID_DEVICE_SEND_REPLY_TO_REPORT"}, + {BT_HID_ENABLE_BARCODE_FEATURE, "BT_HID_ENABLE_BARCODE_FEATURE"}, + {BT_NETWORK_ACTIVATE, "BT_NETWORK_ACTIVATE"}, + {BT_NETWORK_DEACTIVATE, "BT_NETWORK_DEACTIVATE"}, + {BT_NETWORK_CONNECT, "BT_NETWORK_CONNECT"}, + {BT_NETWORK_DISCONNECT, "BT_NETWORK_DISCONNECT"}, + {BT_NETWORK_SERVER_DISCONNECT, "BT_NETWORK_SERVER_DISCONNECT"}, + {BT_AUDIO_CONNECT, "BT_AUDIO_CONNECT"}, + {BT_AUDIO_DISCONNECT, "BT_AUDIO_DISCONNECT"}, + {BT_AG_CONNECT, "BT_AG_CONNECT"}, + {BT_AG_DISCONNECT, "BT_AG_DISCONNECT"}, + {BT_AV_CONNECT, "BT_AV_CONNECT"}, + {BT_AV_DISCONNECT, "BT_AV_DISCONNECT"}, + {BT_AV_SOURCE_CONNECT, "BT_AV_SOURCE_CONNECT"}, + {BT_AV_SOURCE_DISCONNECT, "BT_AV_SOURCE_DISCONNECT"}, + {BT_HF_CONNECT, "BT_HF_CONNECT"}, + {BT_HF_DISCONNECT, "BT_HF_DISCONNECT"}, + {BT_GET_SPEAKER_GAIN, "BT_GET_SPEAKER_GAIN"}, + {BT_SET_SPEAKER_GAIN, "BT_SET_SPEAKER_GAIN"}, + {BT_SET_CONTENT_PROTECT, "BT_SET_CONTENT_PROTECT"}, + {BT_OOB_READ_LOCAL_DATA, "BT_OOB_READ_LOCAL_DATA"}, + {BT_OOB_ADD_REMOTE_DATA, "BT_OOB_ADD_REMOTE_DATA"}, + {BT_OOB_REMOVE_REMOTE_DATA, "BT_OOB_REMOVE_REMOTE_DATA"}, + {BT_AVRCP_SET_TRACK_INFO, "BT_AVRCP_SET_TRACK_INFO"}, + {BT_AVRCP_SET_PROPERTY, "BT_AVRCP_SET_PROPERTY"}, + {BT_AVRCP_SET_PROPERTIES, "BT_AVRCP_SET_PROPERTIES"}, + {BT_AVRCP_CONTROL_CONNECT, "BT_AVRCP_CONTROL_CONNECT"}, + {BT_AVRCP_CONTROL_DISCONNECT, "BT_AVRCP_CONTROL_DISCONNECT"}, + {BT_AVRCP_TARGET_CONNECT, "BT_AVRCP_TARGET_CONNECT"}, + {BT_AVRCP_TARGET_DISCONNECT, "BT_AVRCP_TARGET_DISCONNECT"}, + {BT_AVRCP_HANDLE_CONTROL, "BT_AVRCP_HANDLE_CONTROL"}, + {BT_AVRCP_CONTROL_SET_PROPERTY, "BT_AVRCP_CONTROL_SET_PROPERTY"}, + {BT_AVRCP_CONTROL_GET_PROPERTY, "BT_AVRCP_CONTROL_GET_PROPERTY"}, + {BT_AVRCP_GET_TRACK_INFO, "BT_AVRCP_GET_TRACK_INFO"}, + {BT_OPP_PUSH_FILES, "BT_OPP_PUSH_FILES"}, + {BT_OPP_CANCEL_PUSH, "BT_OBT_OPP_IS_PUSHING_FILESPP_CANCEL_PUSH"}, + {BT_OPP_IS_PUSHING_FILES, "BT_OPP_IS_PUSHING_FILES"}, + {BT_OPP_GET_TRANSFER_PROGRESS, "BT_OPP_GET_TRANSFER_PROGRESS"}, + {BT_MAP_CREATE_SESSION, "BT_MAP_CREATE_SESSION"}, + {BT_MAP_DESTROY_SESSION, "BT_MAP_DESTROY_SESSION"}, + {BT_MAP_SET_FOLDER, "BT_MAP_SET_FOLDER"}, + {BT_MAP_LIST_FOLDERS, "BT_MAP_LIST_FOLDERS"}, + {BT_MAP_LIST_FILTER_FIELDS, "BT_MAP_LIST_FILTER_FIELDS"}, + {BT_MAP_LIST_MESSAGES, "BT_MAP_LIST_MESSAGES"}, + {BT_MAP_UPDATE_INBOX, "BT_MAP_UPDATE_INBOX"}, + {BT_MAP_PUSH_MESSAGE, "BT_MAP_PUSH_MESSAGE"}, + {BT_MAP_GET_MESSAGE, "BT_MAP_GET_MESSAGE"}, + {BT_OBEX_SERVER_ALLOCATE, "BT_OBEX_SERVER_ALLOCATE"}, + {BT_OBEX_SERVER_DEALLOCATE, "BT_OBEX_SERVER_DEALLOCATE"}, + {BT_OBEX_SERVER_IS_ACTIVATED, "BT_OBEX_SERVER_IS_ACTIVATED"}, + {BT_OBEX_SERVER_ACCEPT_CONNECTION, "BT_OBEX_SERVER_ACCEPT_CONNECTION"}, + {BT_OBEX_SERVER_REJECT_CONNECTION, "BT_OBEX_SERVER_REJECT_CONNECTION"}, + {BT_OBEX_SERVER_ACCEPT_FILE, "BT_OBEX_SERVER_ACCEPT_FILE"}, + {BT_OBEX_SERVER_REJECT_FILE, "BT_OBEX_SERVER_REJECT_FILE"}, + {BT_OBEX_SERVER_SET_PATH, "BT_OBEX_SERVER_SET_PATH"}, + {BT_OBEX_SERVER_SET_ROOT, "BT_OBEX_SERVER_SET_ROOT"}, + {BT_OBEX_SERVER_CANCEL_TRANSFER, "BT_OBEX_SERVER_CANCEL_TRANSFER"}, + {BT_OBEX_SERVER_CANCEL_ALL_TRANSFERS, "BT_OBEX_SERVER_CANCEL_ALL_TRANSFERS"}, + {BT_OBEX_SERVER_IS_RECEIVING, "BT_OBEX_SERVER_IS_RECEIVING"}, + {BT_RFCOMM_CLIENT_CONNECT, "BT_RFCOMM_CLIENT_CONNECT"}, + {BT_RFCOMM_CLIENT_CANCEL_CONNECT, "BT_RFCOMM_CLIENT_CANCEL_CONNECT"}, + {BT_RFCOMM_CLIENT_IS_CONNECTED, "BT_RFCOMM_CLIENT_IS_CONNECTED"}, + {BT_RFCOMM_SOCKET_DISCONNECT, "BT_RFCOMM_SOCKET_DISCONNECT"}, + {BT_RFCOMM_SOCKET_WRITE, "BT_RFCOMM_SOCKET_WRITE"}, + {BT_RFCOMM_CREATE_SOCKET, "BT_RFCOMM_CREATE_SOCKET"}, + {BT_RFCOMM_REMOVE_SOCKET, "BT_RFCOMM_REMOVE_SOCKET"}, + {BT_RFCOMM_LISTEN, "BT_RFCOMM_LISTEN"}, + {BT_RFCOMM_IS_UUID_AVAILABLE, "BT_RFCOMM_IS_UUID_AVAILABLE"}, + {BT_RFCOMM_ACCEPT_CONNECTION, "BT_RFCOMM_ACCEPT_CONNECTION"}, + {BT_RFCOMM_REJECT_CONNECTION, "BT_RFCOMM_REJECT_CONNECTION"}, + {BT_RFCOMM_CREATE_SOCKET_EX, "BT_RFCOMM_CREATE_SOCKET_EX"}, + {BT_RFCOMM_REMOVE_SOCKET_EX, "BT_RFCOMM_REMOVE_SOCKET_EX"}, + {BT_PBAP_CONNECT, "BT_PBAP_CONNECT"}, + {BT_PBAP_DISCONNECT, "BT_PBAP_DISCONNECT"}, + {BT_PBAP_GET_PHONEBOOK_SIZE, "BT_PBAP_GET_PHONEBOOK_SIZE"}, + {BT_PBAP_GET_PHONEBOOK, "BT_PBAP_GET_PHONEBOOK"}, + {BT_PBAP_GET_LIST, "BT_PBAP_GET_LIST"}, + {BT_PBAP_PULL_VCARD, "BT_PBAP_PULL_VCARD"}, + {BT_PBAP_PHONEBOOK_SEARCH, "BT_PBAP_PHONEBOOK_SEARCH"}, + {BT_ENABLE_ADAPTER_LE, "BT_ENABLE_ADAPTER_LE"}, + {BT_DISABLE_ADAPTER_LE, "BT_DISABLE_ADAPTER_LE"}, + {BT_CONNECT_LE, "BT_CONNECT_LE"}, + {BT_DISCONNECT_LE, "BT_DISCONNECT_LE"}, + {BT_SET_LE_PRIVACY, "BT_SET_LE_PRIVACY"}, + {BT_REQ_ATT_MTU, "BT_REQ_ATT_MTU"}, + {BT_GET_ATT_MTU, "BT_GET_ATT_MTU"}, + {BT_GET_DEVICE_IDA, "BT_GET_DEVICE_IDA"}, + {BT_SET_LE_STATIC_RANDOM_ADDRESS, "BT_SET_LE_STATIC_RANDOM_ADDRESS"}, + {BT_HDP_CONNECT, "BT_HDP_CONNECT"}, + {BT_HDP_DISCONNECT, "BT_HDP_DISCONNECT"}, + {BT_HDP_SEND_DATA, "BT_HDP_SEND_DATA"}, + {BT_HDP_REGISTER_SINK_APP, "BT_HDP_REGISTER_SINK_APP"}, + {BT_HDP_UNREGISTER_SINK_APP, "BT_HDP_UNREGISTER_SINK_APP"}, + {BT_GATT_GET_PRIMARY_SERVICES, "BT_GATT_GET_PRIMARY_SERVICES"}, + {BT_GATT_DISCOVER_CHARACTERISTICS, "BT_GATT_DISCOVER_CHARACTERISTICS"}, + {BT_GATT_SET_PROPERTY_REQUEST, "BT_GATT_SET_PROPERTY_REQUEST"}, + {BT_GATT_READ_CHARACTERISTIC, "BT_GATT_READ_CHARACTERISTIC"}, + {BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR, "BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR"}, + {BT_GATT_REGISTER_APPLICATION, "BT_GATT_REGISTER_APPLICATION"}, + {BT_GATT_REGISTER_SERVICE, "BT_GATT_REGISTER_SERVICE"}, + {BT_GATT_SEND_RESPONSE, "BT_GATT_SEND_RESPONSE"}, + {BT_LE_IPSP_INIT, "BT_LE_IPSP_INIT"}, + {BT_LE_IPSP_DEINIT, "BT_LE_IPSP_DEINIT"}, + {BT_LE_IPSP_CONNECT, "BT_LE_IPSP_CONNECT"}, + {BT_LE_IPSP_DISCONNECT, "BT_LE_IPSP_DISCONNECT"}, + {BT_DPM_SET_ALLOW_BT_MODE, "BT_DPM_SET_ALLOW_BT_MODE"}, + {BT_DPM_GET_ALLOW_BT_MODE, "BT_DPM_GET_ALLOW_BT_MODE"}, + {BT_DPM_SET_DEVICE_RESTRITION, "BT_DPM_SET_DEVICE_RESTRITION"}, + {BT_DPM_GET_DEVICE_RESTRITION, "BT_DPM_GET_DEVICE_RESTRITION"}, + {BT_DPM_SET_UUID_RESTRITION, "BT_DPM_SET_UUID_RESTRITION"}, + {BT_DPM_GET_UUID_RESTRITION, "BT_DPM_GET_UUID_RESTRITION"}, + {BT_DPM_ADD_DEVICES_BLACKLIST, "BT_DPM_ADD_DEVICES_BLACKLIST"}, + {BT_DPM_ADD_DEVICES_WHITELIST, "BT_DPM_ADD_DEVICES_WHITELIST"}, + {BT_DPM_ADD_UUIDS_BLACKLIST, "BT_DPM_ADD_UUIDS_BLACKLIST"}, + {BT_DPM_ADD_UUIDS_WHITELIST, "BT_DPM_ADD_UUIDS_WHITELIST"}, + {BT_DPM_CLEAR_DEVICES_BLACKLIST, "BT_DPM_CLEAR_DEVICES_BLACKLIST"}, + {BT_DPM_CLEAR_DEVICES_WHITELIST, "BT_DPM_CLEAR_DEVICES_WHITELIST"}, + {BT_DPM_CLEAR_UUIDS_BLACKLIST, "BT_DPM_CLEAR_UUIDS_BLACKLIST"}, + {BT_DPM_CLEAR_UUIDS_WHITELIST, "BT_DPM_CLEAR_UUIDS_WHITELIST"}, + {BT_DPM_REMOVE_DEVICE_BLACKLIST, "BT_DPM_REMOVE_DEVICE_BLACKLIST"}, + {BT_DPM_REMOVE_DEVICE_WHITELIST, "BT_DPM_REMOVE_DEVICE_WHITELIST"}, + {BT_DPM_REMOVE_UUID_BLACKLIST, "BT_DPM_REMOVE_UUID_BLACKLIST"}, + {BT_DPM_REMOVE_UUID_WHITELIST, "BT_DPM_REMOVE_UUID_WHITELIST"}, + {BT_DPM_GET_DEVICES_BLACKLIST, "BT_DPM_GET_DEVICES_BLACKLIST"}, + {BT_DPM_GET_DEVICES_WHITELIST, "BT_DPM_GET_DEVICES_WHITELIST"}, + {BT_DPM_GET_UUIDS_BLACKLIST, "BT_DPM_GET_UUIDS_BLACKLIST"}, + {BT_DPM_GET_UUIDS_WHITELIST, "BT_DPM_GET_UUIDS_WHITELIST"}, + {BT_DPM_SET_ALLOW_OUTGOING_CALL, "BT_DPM_SET_ALLOW_OUTGOING_CALL"}, + {BT_DPM_GET_ALLOW_OUTGOING_CALL, "BT_DPM_GET_ALLOW_OUTGOING_CALL"}, + {BT_DPM_SET_PAIRING_STATE, "BT_DPM_SET_PAIRING_STATE"}, + {BT_DPM_GET_PAIRING_STATE, "BT_DPM_GET_PAIRING_STATE"}, + {BT_DPM_SET_PROFILE_STATE, "BT_DPM_SET_PROFILE_STATE"}, + {BT_DPM_GET_PROFILE_STATE, "BT_DPM_GET_PROFILE_STATE"}, + {BT_DPM_SET_DESKROP_CONNECTIVITY_STATE, "BT_DPM_SET_DESKROP_CONNECTIVITY_STATE"}, + {BT_DPM_GET_DESKROP_CONNECTIVITY_STATE, "BT_DPM_GET_DESKROP_CONNECTIVITY_STATE"}, + {BT_DPM_SET_DISCOVERABLE_STATE, "BT_DPM_SET_DISCOVERABLE_STATE"}, + {BT_DPM_GET_DISCOVERABLE_STATE, "BT_DPM_GET_DISCOVERABLE_STATE"}, + {BT_DPM_SET_LIMITED_DISCOVERABLE_STATE, "BT_DPM_SET_LIMITED_DISCOVERABLE_STATE"}, + {BT_DPM_GET_LIMITED_DISCOVERABLE_STATE, "BT_DPM_GET_LIMITED_DISCOVERABLE_STATE"}, + {BT_DPM_SET_DATA_TRANSFER_STATE, "BT_DPM_SET_DATA_TRANSFER_STATE"}, + {BT_DPM_GET_DATA_TRANSFER_STATE, "BT_DPM_GET_DATA_TRANSFER_STATE"}, + {BT_PXP_MONITOR_SET_PROPERTY, "BT_PXP_MONITOR_SET_PROPERTY"}, + {BT_PXP_MONITOR_GET_PROPERTY, "BT_PXP_MONITOR_GET_PROPERTY"}, + {BT_PXP_MONITOR_GET_SUPPORTED_SERIVCES, "BT_PXP_MONITOR_GET_SUPPORTED_SERIVCES"}, + {BT_PXP_REPORTER_REGISTER, "BT_PXP_REPORTER_REGISTER"}, + {BT_PXP_REPORTER_UNREGISTER, "BT_PXP_REPORTER_UNREGISTER"}, + {BT_PXP_REPORTER_GET_PROPERTY, "BT_PXP_REPORTER_GET_PROPERTY"}, + {BT_TDS_PROVIDER_REGISTER, "BT_TDS_PROVIDER_REGISTER"}, + {BT_TDS_PROVIDER_UNREGISTER, "BT_TDS_PROVIDER_UNREGISTER"}, + {BT_TDS_PROVIDER_SET_MANUF_DATA, "BT_TDS_PROVIDER_SET_MANUF_DATA"}, + {BT_TDS_PROVIDER_CREATE, "BT_TDS_PROVIDER_CREATE"}, + {BT_TDS_PROVIDER_DESTROY, "BT_TDS_PROVIDER_DESTROY"}, + {BT_TDS_PROVIDER_SET_TRANSPORT_DATA, "BT_TDS_PROVIDER_SET_TRANSPORT_DATA"}, + {BT_TDS_SEND_ACTIVATION_RESPONSE, "BT_TDS_SEND_ACTIVATION_RESPONSE"}, + {BT_TDS_READ_TRANSPORT_DATA, "BT_TDS_READ_TRANSPORT_DATA"}, + {BT_TDS_ENABLE_CONTROL_POINT, "BT_TDS_ENABLE_CONTROL_POINT"}, + {BT_TDS_ACTIVATE_CONTROL_POINT, "BT_TDS_ACTIVATE_CONTROL_POINT"}, + {-1, ""}, + }; + + for (i = 0; bt_functions[i].function != -1; i++) { + if (bt_functions[i].function == function) + return bt_functions[i].function_name; + } + + return NULL; +} + int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length) { int i; @@ -364,6 +709,7 @@ static void __new_connection_method(GDBusConnection *connection, msg = g_dbus_method_invocation_get_message(invocation); fd_list = g_dbus_message_get_unix_fd_list(msg); if (fd_list == NULL) { + BT_ERR("fd_list is NULL"); GQuark quark = g_quark_from_string("rfcomm-app"); GError *err = g_error_new(quark, 0, "No fd in message"); g_dbus_method_invocation_return_gerror(invocation, err); @@ -1754,12 +2100,12 @@ BT_EXPORT_API int bluetooth_register_callback(bluetooth_cb_func_ptr callback_ptr ret = _bt_register_event(BT_RFCOMM_SERVER_EVENT, (void *)callback_ptr, user_data); if (ret != BLUETOOTH_ERROR_NONE) goto fail; - -#ifdef GATT_NO_RELAY ret = _bt_register_event(BT_GATT_BLUEZ_EVENT, (void *)callback_ptr, user_data); if (ret != BLUETOOTH_ERROR_NONE) goto fail; -#endif + ret = _bt_register_event(BT_TDS_EVENT, (void *)callback_ptr, user_data); + if (ret != BLUETOOTH_ERROR_NONE) + goto fail; } _bt_register_name_owner_changed(); @@ -1784,6 +2130,8 @@ BT_EXPORT_API int bluetooth_unregister_callback(void) _bt_set_user_data(BT_COMMON, NULL, NULL); + _bt_set_obex_server_id(BT_NO_SERVER); + _bt_gdbus_deinit_proxys(); if (system_gconn) { diff --git a/bt-api/bt-dpm.c b/bt-api/bt-dpm.c index bbf4d6c..3c78062 100644 --- a/bt-api/bt-dpm.c +++ b/bt-api/bt-dpm.c @@ -154,6 +154,7 @@ static bt_dpm_status_e _bt_check_dpm_blacklist_uuid(char *uuid) bluetooth_dpm_get_data_transfer_state(&dpm_status); return (dpm_status == BLUETOOTH_DPM_RESTRICTED ? BT_DPM_RESTRICTED : BT_DPM_ALLOWED); } + /* TODO: MAP? see above */ /* ++ check MDM profile restriction ++ */ if (g_strcmp0(BT_A2DP_UUID, uuid) == 0) @@ -182,6 +183,7 @@ static bt_dpm_status_e _bt_check_dpm_transfer_restriction(void) bt_dpm_status_t dpm_value = BLUETOOTH_DPM_ALLOWED; dpm_status = _bt_check_dpm_blacklist_uuid(BT_OPP_UUID); + /* TODO: MAP? see above */ if (dpm_status == BT_DPM_NO_SERVICE || dpm_status == BT_DPM_RESTRICTED) return dpm_status; @@ -273,6 +275,7 @@ int _bt_check_dpm(int service, void *param) case BT_DPM_OPP: status = _bt_check_dpm_transfer_restriction(); break; + /* TODO: MAP? see above */ case BT_DPM_HSP: status = _bt_check_dpm_hsp_restriction(); break; diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c index b861402..8290950 100644 --- a/bt-api/bt-event-handler.c +++ b/bt-api/bt-event-handler.c @@ -70,6 +70,7 @@ static gboolean __bt_is_request_id_exist(int request_id) if (info == NULL) continue; + BT_DBG("compare %d with %d", info->request_id, request_id); if (info->request_id == request_id) return TRUE; } @@ -748,7 +749,6 @@ void __bt_device_event_filter(GDBusConnection *connection, event_info = (bt_event_info_t *)user_data; ret_if(event_info == NULL); -#ifdef GATT_NO_RELAY gboolean gatt_interface = FALSE; if (strcasecmp(interface_name, BT_GATT_CHARACTERISTIC_INTERFACE) == 0) @@ -760,12 +760,6 @@ void __bt_device_event_filter(GDBusConnection *connection, if (strcasecmp(interface_name, BT_EVENT_SERVICE) != 0 && gatt_interface == FALSE) return; -#else - if (strcasecmp(object_path, BT_DEVICE_PATH) != 0) - return; - if (strcasecmp(interface_name, BT_EVENT_SERVICE) != 0) - return; -#endif ret_if(signal_name == NULL); @@ -811,11 +805,7 @@ void __bt_device_event_filter(GDBusConnection *connection, _bt_common_event_cb(BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED, result, &att_mtu_info, event_info->cb, event_info->user_data); -#ifdef GATT_NO_RELAY } else if (strcasecmp(signal_name, BT_GATT_BLUEZ_CHAR_VAL_CHANGED) == 0) { -#else - } else if (strcasecmp(signal_name, BT_GATT_CHAR_VAL_CHANGED) == 0) { -#endif const char *char_handle = NULL; int len = 0; const char * value = NULL; @@ -1596,7 +1586,7 @@ void __bt_avrcp_control_event_filter(GDBusConnection *connection, metadata.genre = genre; metadata.total_tracks = total_tracks; metadata.number = number; - metadata.duration = (int64_t)duration; + metadata.duration = duration; _bt_avrcp_event_cb(BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED, result, &metadata, @@ -1975,6 +1965,333 @@ void __bt_opp_server_event_filter(GDBusConnection *connection, } } +void __bt_map_client_event_filter(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + BT_DBG("Entered __bt_map_client_event_filter"); + bt_event_info_t *event_info; + int result = BLUETOOTH_ERROR_NONE; + event_info = (bt_event_info_t *)user_data; + ret_if(event_info == NULL); + + if (strcasecmp(object_path, BT_MAP_CLIENT_PATH) != 0) + return; + if (strcasecmp(interface_name, BT_EVENT_SERVICE) != 0) + return; + + ret_if(signal_name == NULL); + + if (strcasecmp(signal_name, BT_MAP_CONNECTED) == 0) { + const char *address = NULL; + int request_id = 0; + bluetooth_device_address_t dev_address = { {0} }; + + g_variant_get(parameters, "(i&si)", &result, + &address, &request_id); + + if (__bt_is_request_id_exist(request_id) == FALSE) { + BT_ERR("Different request id!"); + return; + } + + _bt_convert_addr_string_to_type(dev_address.addr, + address); + + _bt_common_event_cb(BLUETOOTH_EVENT_MAP_CONNECTED, + result, &dev_address, + event_info->cb, event_info->user_data); + + if (result != BLUETOOTH_ERROR_NONE) + __bt_remove_push_request_id(request_id); + } else if (strcasecmp(signal_name, BT_MAP_DISCONNECTED) == 0) { + const char *address = NULL; + int request_id = 0; + bluetooth_device_address_t dev_address = { {0} }; + + g_variant_get(parameters, "(i&si)", &result, &address, + &request_id); + + if (__bt_is_request_id_exist(request_id) == FALSE) { + BT_ERR("Different request id!"); + return; + } + + _bt_convert_addr_string_to_type(dev_address.addr, + address); + + _bt_common_event_cb(BLUETOOTH_EVENT_MAP_DISCONNECTED, + result, &dev_address, + event_info->cb, event_info->user_data); + + __bt_remove_push_request_id(request_id); + } else if (strcasecmp(signal_name, BT_MAP_LIST_FOLDERS_COMPLETE) == 0) { + int request_id = 0; + GVariant* folder_list_var = NULL; + + g_variant_get(parameters, "(iiv)", &result, &request_id, &folder_list_var); + if (__bt_is_request_id_exist(request_id) == FALSE) { + BT_ERR("Different request id!"); + return; + } + + GVariantIter* iter; + + bt_map_client_folders_s folders_struct = {0,}; + g_variant_get(folder_list_var, "(aa{sv})", &iter); + + folders_struct.size = g_variant_iter_n_children(iter); + folders_struct.names = (char**) malloc(folders_struct.size * sizeof(*(folders_struct.names))); + BT_DBG("g_variant_iter_n_children: %d", folders_struct.size); + GVariantIter* res = NULL; + int i = 0; + while (g_variant_iter_loop(iter, "a{sv}", &res)) { + char* key = NULL; + GVariant* value = NULL; + while (g_variant_iter_loop(res, "{sv}", &key, &value)) { + char* string_value = NULL; + g_variant_get(value, "s", &string_value); + BT_DBG("got folder name: %s", string_value); + folders_struct.names[i] = strdup(string_value); + } + ++i; + } + _bt_common_event_cb(BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, + result, &folders_struct, + event_info->cb, event_info->user_data); + + __bt_remove_push_request_id(request_id); + + // freeing resources + while (--i >= 0) { + free(folders_struct.names[i]); + folders_struct.names[i] = NULL; + } + free(folders_struct.names); + + g_variant_unref(folder_list_var); + + } else if (strcasecmp(signal_name, BT_MAP_FILTER_FIELDS_COMPLETE) == 0) { + BT_DBG("BT_MAP_LIST_FOLDERS_COMPLETE"); + + GVariant *value; + int request_id = 0; + int i = 0; + bt_map_list_filter_fields_info_t fields_info = {0,}; + + g_variant_get(parameters, "(ivi)", &result, &value, &request_id); + + if (__bt_is_request_id_exist(request_id) == FALSE) { + BT_ERR("Different request id!"); + return; + } + + if (value) { + GVariantIter *iter = NULL; + g_variant_get(value, "(as)", &iter); + fields_info.size = g_variant_iter_n_children(iter); + char* field = NULL; + + fields_info.fields = malloc(fields_info.size * sizeof(char*)); + while (g_variant_iter_loop(iter, "s", &field)) { + fields_info.fields[i] = strdup(field); + i++; + } + } + + _bt_common_event_cb(BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE, + request_id, &fields_info, + event_info->cb, event_info->user_data); + + while (--i >= 0) { + free(fields_info.fields[i]); + fields_info.fields[i] = NULL; + } + free(fields_info.fields); + + __bt_remove_push_request_id(request_id); + g_variant_unref(value); + } else if (strcasecmp(signal_name, BT_MAP_LIST_MESSAGES_COMPLETE) == 0) { + int request_id = 0; + GVariant* messages_list_var = NULL; + g_variant_get(parameters, "(iiv)", &result, &request_id, &messages_list_var); + if (__bt_is_request_id_exist(request_id) == FALSE) { + BT_ERR("Different request id!"); + return; + } + + bt_map_client_message_items_s messages_struct = {0,}; + + GVariantIter* iter; + g_variant_get(messages_list_var, "(a{oa{sv}})", &iter); + messages_struct.size = g_variant_iter_n_children(iter); + messages_struct.message_items = (bt_map_client_message_item_t*) + malloc(messages_struct.size * sizeof(*(messages_struct.message_items))); + BT_DBG("g_variant_iter_n_children: %d", messages_struct.size); + + char *object = NULL; + GVariantIter *properites = NULL; + int i = 0; + while (g_variant_iter_loop(iter, "{oa{sv}}", &object, &properites)) { + messages_struct.message_items[i].message_object = strdup(object); + BT_DBG("Message found: %s", messages_struct.message_items[i].message_object); + messages_struct.message_items[i].folder = NULL; + messages_struct.message_items[i].subject = NULL; + messages_struct.message_items[i].timestamp = NULL; + messages_struct.message_items[i].sender = NULL; + messages_struct.message_items[i].sender_address = NULL; + messages_struct.message_items[i].reply_to = NULL; + messages_struct.message_items[i].recipient = NULL; + messages_struct.message_items[i].recipient_address = NULL; + messages_struct.message_items[i].type = NULL; + messages_struct.message_items[i].size = -1; + messages_struct.message_items[i].is_text = -1; + messages_struct.message_items[i].status = NULL; + messages_struct.message_items[i].attachment_size = -1; + messages_struct.message_items[i].is_priority = -1; + messages_struct.message_items[i].is_read = -1; + messages_struct.message_items[i].is_sent = -1; + messages_struct.message_items[i].is_protected = -1; + char *key = NULL; + GVariant *value = NULL; + while (g_variant_iter_loop(properites, "{sv}", &key, &value)) { + char *value_string = NULL; + uint64_t value_int = -1; + bool value_bool = false; + if (strcmp(key, "Folder") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].folder = strdup(value_string); + BT_DBG(" Folder: %s", value_string); + } else if (strcmp(key, "Subject") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].subject = strdup(value_string); + BT_DBG(" Subject: %s", value_string); + } else if (strcmp(key, "Timestamp") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].timestamp = strdup(value_string); + BT_DBG(" Timestamp: %s", value_string); + } else if (strcmp(key, "Sender") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].sender = strdup(value_string); + BT_DBG(" Sender: %s", value_string); + } else if (strcmp(key, "SenderAddress") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].sender_address = strdup(value_string); + BT_DBG(" SenderAddress: %s", value_string); + } else if (strcmp(key, "ReplyTo") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].reply_to = strdup(value_string); + BT_DBG(" ReplyTo: %s", value_string); + } else if (strcmp(key, "Recipient") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].recipient = strdup(value_string); + BT_DBG(" Recipient: %s", value_string); + } else if (strcmp(key, "RecipientAddress") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].recipient_address = strdup(value_string); + BT_DBG(" RecipientAddress: %s", value_string); + } else if (strcmp(key, "Type") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].type = strdup(value_string); + BT_DBG(" Type: %s", value_string); + } else if (strcmp(key, "Size") == 0) { + g_variant_get(value, "t", &value_int); + messages_struct.message_items[i].size = value_int; + BT_DBG(" Size: %d", value_int); + } else if (strcmp(key, "Text") == 0) { + g_variant_get(value, "b", &value_bool); + messages_struct.message_items[i].is_text = value_bool ? 1 : 0; + BT_DBG(" Text: %s", value_bool ? "true" : "false"); + } else if (strcmp(key, "Status") == 0) { + g_variant_get(value, "s", &value_string); + messages_struct.message_items[i].status = strdup(value_string); + BT_DBG(" Status: %s", value_string); + } else if (strcmp(key, "AttachmentSize") == 0) { + g_variant_get(value, "t", &value_int); + messages_struct.message_items[i].attachment_size = value_int; + BT_DBG(" AttachmentSize: %d", value_int); + } else if (strcmp(key, "Priority") == 0) { + g_variant_get(value, "b", &value_bool); + messages_struct.message_items[i].is_priority = value_bool ? 1 : 0; + BT_DBG(" Priority: %s", value_bool ? "true" : "false"); + } else if (strcmp(key, "Read") == 0) { + g_variant_get(value, "b", &value_bool); + messages_struct.message_items[i].is_read = value_bool ? 1 : 0; + BT_DBG(" Read: %s", value_bool ? "true" : "false"); + } else if (strcmp(key, "Sent") == 0) { + g_variant_get(value, "b", &value_bool); + messages_struct.message_items[i].is_sent = value_bool ? 1 : 0; + BT_DBG(" Sent: %s", value_bool ? "true" : "false"); + } else if (strcmp(key, "Protected") == 0) { + g_variant_get(value, "b", &value_bool); + messages_struct.message_items[i].is_protected = value_bool ? 1 : 0; + BT_DBG(" Protected: %s", value_bool ? "true" : "false"); + } + } + ++i; + } + + _bt_common_event_cb(BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, + result, &messages_struct, + event_info->cb, event_info->user_data); + + __bt_remove_push_request_id(request_id); + + while (--i >= 0) { + free(messages_struct.message_items[i].folder); + free(messages_struct.message_items[i].subject); + free(messages_struct.message_items[i].timestamp); + free(messages_struct.message_items[i].sender); + free(messages_struct.message_items[i].sender_address); + free(messages_struct.message_items[i].reply_to); + free(messages_struct.message_items[i].recipient); + free(messages_struct.message_items[i].recipient_address); + free(messages_struct.message_items[i].type); + free(messages_struct.message_items[i].status); + } + free(messages_struct.message_items); + + g_variant_unref(messages_list_var); + } else if (strcasecmp(signal_name, BT_MAP_GET_MESSAGE_COMPLETE) == 0) { + BT_DBG("BT_MAP_GET_MESSAGE_COMPLETE"); + int request_id = 0; + + g_variant_get(parameters, "(ii)", &result, &request_id); + if (__bt_is_request_id_exist(request_id) == FALSE) { + BT_ERR("Different request id!"); + return; + } + + // currently there is no result value passed from here, just passing NULL + void* some_result_value = NULL; + _bt_common_event_cb(BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE, + result, some_result_value, event_info->cb, event_info->user_data); + + __bt_remove_push_request_id(request_id); + } else if (strcasecmp(signal_name, BT_MAP_PUSH_MESSAGE_COMPLETE) == 0) { + BT_DBG("BT_MAP_PUSH_MESSAGE_COMPLETE"); + int request_id = 0; + + g_variant_get(parameters, "(ii)", &result, &request_id); + if (__bt_is_request_id_exist(request_id) == FALSE) { + BT_ERR("Different request id!"); + return; + } + + // currently there is no result value passed from here, just passing NULL + void* some_result_value = NULL; + _bt_common_event_cb(BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE, + result, some_result_value, event_info->cb, event_info->user_data); + + __bt_remove_push_request_id(request_id); + } + +} + void __bt_pbap_client_event_filter(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, @@ -2547,6 +2864,160 @@ void __bt_hf_agent_event_filter(GDBusConnection *connection, BT_DBG("-\n"); } +static void __bt_tds_event_filter(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + bt_event_info_t *event_info; + event_info = (bt_event_info_t *)user_data; + int result = BLUETOOTH_ERROR_NONE; + + ret_if(event_info == NULL); + + if (strcasecmp(object_path, BT_TDS_PATH) != 0) + return; + if (strcasecmp(interface_name, BT_EVENT_SERVICE) != 0) + return; + + ret_if(signal_name == NULL); + + BT_DBG("+"); + + if (strcasecmp(signal_name, BT_TDS_ACTIVATION_REQUESTED) == 0) { + bluetooth_tds_activation_req_t act_req; + const char *address = NULL; + char *buffer = NULL; + int transport = 0; + GVariant *byte_var; + + g_variant_get(parameters, "(&si@ay)", &address, + &transport, &byte_var); + + memset(&act_req, 0x00, sizeof(bluetooth_tds_activation_req_t)); + + act_req.transport = transport; + + act_req.tds_data.length = g_variant_get_size(byte_var); + if (act_req.tds_data.length > BLUETOOTH_TDS_DATA_LENGTH_MAX) { + BT_INFO("tds data length > BLUETOOTH_TDS_DATA_LENGTH_MAX"); + act_req.tds_data.length = BLUETOOTH_TDS_DATA_LENGTH_MAX; + } + buffer = (char *) g_variant_get_data(byte_var); + memcpy(act_req.tds_data.data, buffer, act_req.tds_data.length); + + _bt_convert_addr_string_to_type(act_req.rem_addr.addr, address); + + _bt_common_event_cb(BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED, + BLUETOOTH_ERROR_NONE, &act_req, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_TDS_TRANSPORT_DATA_RECEIVED) == 0) { + BT_DBG("TDS Complete Block Data received"); + const char *address = NULL; + char *data; + int data_len = 0; + int k; + GVariant *var = NULL; + bluetooth_tds_transport_data_info_t *info = NULL; + + /* Extract data from DBUS params */ + g_variant_get(parameters, "(i&sn@ay)", &result, &address, &data_len, &var); + data = (char *)g_variant_get_data(var); + + BT_DBG("Address [%s]", address); + BT_DBG("Data len [%d]", data_len); + + /* DEBUG */ + for (k = 0; k < data_len ; k++) + BT_DBG("Data[%d] [0x%x]", k, data[k]); + + if (data_len == 0) { + BT_ERR("No data"); + if (var) + g_variant_unref(var); + return; + } + + info = g_malloc0(sizeof(bluetooth_tds_transport_data_info_t)); + info->data_length = data_len; + info->data = g_memdup(data, data_len); + + _bt_convert_addr_string_to_type(info->device_address.addr, + address); + + _bt_common_event_cb(BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED, + result, info, + event_info->cb, event_info->user_data); + + if (info->data) { + g_free(info->data); + g_free(info); + } + if (var) + g_variant_unref(var); + } else if (strcasecmp(signal_name, BT_TDS_ACTIVATION_RESULT) == 0) { + BT_DBG("TDS Control point Activation result"); + const char *address = NULL; + bluetooth_device_address_t dev_address = { {0} }; + + /* Extract data from DBUS params */ + g_variant_get(parameters, "(i&s)", &result, &address); + BT_DBG("Address [%s]", address); + BT_DBG("Result [%d]", result); + + _bt_convert_addr_string_to_type(dev_address.addr, + address); + + _bt_common_event_cb(BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT, + result, &dev_address, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_TDS_ACTIVATION_INDICATION) == 0) { + BT_DBG("TDS Control point Indication Response"); + bluetooth_tds_indication_res_t ind_res; + const char *address = NULL; + char *buffer = NULL; + GVariant *byte_var = NULL; + + g_variant_get(parameters, "(&s@ay)", &address, &byte_var); + + memset(&ind_res, 0x00, sizeof(bluetooth_tds_indication_res_t)); + + ind_res.tds_data.length = g_variant_get_size(byte_var); + + buffer = (char *) g_variant_get_data(byte_var); + memcpy(ind_res.tds_data.data, buffer, ind_res.tds_data.length); + + _bt_convert_addr_string_to_type(ind_res.rem_addr.addr, address); + + _bt_common_event_cb(BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION, + BLUETOOTH_ERROR_NONE, &ind_res, + event_info->cb, event_info->user_data); + if (byte_var) + g_variant_unref(byte_var); + } else if (strcasecmp(signal_name, BT_TDS_CONTROL_POINT_ENABLED) == 0) { + BT_DBG("TDS Control point Enabled event"); + const char *address = NULL; + bluetooth_device_address_t dev_address = { {0} }; + + /* Extract data from DBUS params */ + g_variant_get(parameters, "(i&s)", &result, &address); + BT_DBG("Address [%s]", address); + BT_DBG("Result [%d]", result); + + _bt_convert_addr_string_to_type(dev_address.addr, + address); + + _bt_common_event_cb(BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED, + result, &dev_address, + event_info->cb, event_info->user_data); + } + + BT_DBG("-"); +} + static void __bt_remove_all_events(void) { bt_event_info_t *info; @@ -2730,6 +3201,10 @@ int _bt_register_event(int event_type, void *event_cb, void *user_data) event_func = __bt_opp_server_event_filter; path = BT_OPP_SERVER_PATH; break; + case BT_MAP_CLIENT_EVENT: + event_func = __bt_map_client_event_filter; + path = BT_MAP_CLIENT_PATH; + break; case BT_PBAP_CLIENT_EVENT: event_func = __bt_pbap_client_event_filter; path = BT_PBAP_CLIENT_PATH; @@ -2758,14 +3233,17 @@ int _bt_register_event(int event_type, void *event_cb, void *user_data) event_func = __bt_hid_device_event_filter; path = BT_HID_DEVICE_PATH; break; -#ifdef GATT_NO_RELAY case BT_GATT_BLUEZ_EVENT: BT_DBG("BT_GATT_BLUEZ_EVENT"); event_func = __bt_device_event_filter; interface = BT_GATT_CHARACTERISTIC_INTERFACE; path = NULL; break; -#endif + case BT_TDS_EVENT: + BT_DBG("BT_TDS_EVENT"); + event_func = __bt_tds_event_filter; + path = BT_TDS_PATH; + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; diff --git a/bt-api/bt-gatt-client.c b/bt-api/bt-gatt-client.c index 3a7fe59..5d3abdc 100644 --- a/bt-api/bt-gatt-client.c +++ b/bt-api/bt-gatt-client.c @@ -158,21 +158,12 @@ BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher( BT_INFO("The watcher is already set"); return BLUETOOTH_ERROR_NONE; } - - if (service_monitor_list == NULL) { - BT_ERR("There is NO watcher"); - return BLUETOOTH_ERROR_NONE; - } addr = g_malloc0(sizeof(bluetooth_device_address_t)); memcpy(addr, address, sizeof(bluetooth_device_address_t)); service_monitor_list = g_slist_append(service_monitor_list, addr); } else { - if (service_monitor_list == NULL) { - BT_ERR("There is NO watcher"); - return BLUETOOTH_ERROR_NONE; - } for (l = service_monitor_list; l != NULL; l = l->next) { addr = l->data; @@ -476,7 +467,7 @@ static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy, g_variant_get(char_value, "ao", &char_iter); gp_array = g_ptr_array_new(); - while (g_variant_iter_loop(char_iter, "&o", &char_handle)) + while (g_variant_iter_loop(char_iter, "&o", &char_handle)); g_ptr_array_add(gp_array, (gpointer)char_handle); if (gp_array->len != 0) { @@ -664,9 +655,10 @@ BT_EXPORT_API int bluetooth_gatt_get_characteristics_property( } else if (!g_strcmp0(key, "Flags")) { g_variant_get(value, "as", &char_perm_iter); characteristic->permission = 0x00; - while (g_variant_iter_loop(char_perm_iter, "s", &permission)) { + + while (g_variant_iter_loop(char_perm_iter, "s", &permission)) characteristic->permission |= __get_permission_flag(permission); - } + g_variant_iter_free(char_perm_iter); } else if (!g_strcmp0(key, "Descriptors")) { g_variant_get(value, "ao", &char_desc_iter); @@ -1522,27 +1514,6 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value( return BLUETOOTH_ERROR_NONE; } -#ifndef GATT_NO_RELAY -static int __bluetooth_gatt_watch_characteristics(void) -{ - int result = BLUETOOTH_ERROR_NONE; - - BT_INIT_PARAMS(); - BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - result = _bt_send_request(BT_BLUEZ_SERVICE, - BT_GATT_WATCH_CHARACTERISTIC, - in_param1, in_param2, in_param3, in_param4, &out_param); - - if (result != BLUETOOTH_ERROR_NONE) - BT_ERR("Watch Characteristic request failed !"); - - BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - return result; -} -#endif - BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle) { GDBusConnection *conn; @@ -1589,37 +1560,10 @@ BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle) g_clear_error(&error); } -#ifndef GATT_NO_RELAY - else { - /* Register the client sender to bt-service */ - ret = __bluetooth_gatt_watch_characteristics(); - } -#endif return ret; } -#ifndef GATT_NO_RELAY -static int __bluetooth_gatt_unwatch_characteristics(void) -{ - int result = BLUETOOTH_ERROR_NONE; - - BT_INIT_PARAMS(); - BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - result = _bt_send_request(BT_BLUEZ_SERVICE, - BT_GATT_UNWATCH_CHARACTERISTIC, - in_param1, in_param2, in_param3, in_param4, &out_param); - - if (result != BLUETOOTH_ERROR_NONE) - BT_ERR("Unwatch Characteristic request failed !"); - - BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - - return result; -} -#endif - BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle) { @@ -1650,11 +1594,6 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle g_clear_error(&error); ret = BLUETOOTH_ERROR_INTERNAL; } -#ifndef GATT_NO_RELAY - else { - /* Unregister the client sender to bt-service */ - ret = __bluetooth_gatt_unwatch_characteristics(); - } -#endif + return ret; } diff --git a/bt-api/bt-gatt-service.c b/bt-api/bt-gatt-service.c index 3a5659c..81a6ecc 100644 --- a/bt-api/bt-gatt-service.c +++ b/bt-api/bt-gatt-service.c @@ -60,14 +60,15 @@ static const gchar characteristics_introspection_xml[] = " " " " " " -" " +" " " " " " " " " " " " -" " +" " " " +" " " " " " " " @@ -103,14 +104,15 @@ static const gchar descriptor_introspection_xml[] = " " " " " " -" " +" " " " " " " " " " " " -" " +" " " " +" " " " " " " " @@ -632,74 +634,72 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, if (g_strcmp0(method_name, "ReadValue") == 0) { gchar *addr = NULL; - guint8 req_id = 1; + guint req_id = 0; guint16 offset = 0; bt_gatt_read_req_t read_req = {0, }; bt_user_info_t *user_info = NULL; struct gatt_req_info *req_info = NULL; struct gatt_service_info *svc_info = NULL; - - BT_DBG("ReadValue"); - - g_variant_get(parameters, "(&syq)", &addr, &req_id, &offset); +#ifdef TIZEN_FEATURE_BT_HPS + GVariant *param = NULL; +#endif BT_DBG("Application path = %s", object_path); + BT_DBG("Sender = %s", sender); - BT_DBG("Remote Device address number = %s", addr); - BT_DBG("Request id = %d, Offset = %d", req_id, offset); + user_info = _bt_get_user_data(BT_COMMON); + if (user_info == NULL) { + BT_INFO("No callback is set for %s", object_path); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } - BT_DBG("Sender = %s", sender); + svc_info = __bt_gatt_find_gatt_service_from_char(object_path); + if (svc_info == NULL) { + BT_ERR("Coudn't find service for %s", object_path); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } - read_req.att_handle = g_strdup(object_path); - read_req.address = g_strdup(addr); + g_variant_get(parameters, "(&suq)", &addr, &req_id, &offset); + BT_DBG("Request id = %u, Offset = %u", req_id, offset); + + read_req.att_handle = (char *)object_path; + read_req.address = addr; read_req.req_id = req_id; read_req.offset = offset; - svc_info = __bt_gatt_find_gatt_service_from_char(object_path); - if (svc_info != NULL) { - read_req.service_handle = g_strdup(svc_info->serv_path); - user_info = _bt_get_user_data(BT_COMMON); -#ifdef TIZEN_FEATURE_BT_HPS - GVariant *param = NULL; -#endif + read_req.service_handle = svc_info->serv_path; - /* Store requets information */ - req_info = g_new0(struct gatt_req_info, 1); - req_info->attr_path = g_strdup(object_path); - req_info->svc_path = g_strdup(read_req.service_handle); - req_info->request_id = req_id; - req_info->offset = offset; - req_info->context = invocation; - gatt_requests = g_slist_append(gatt_requests, req_info); + /* Store requets information */ + req_info = g_new0(struct gatt_req_info, 1); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(read_req.service_handle); + req_info->request_id = req_id; + req_info->offset = offset; + req_info->context = invocation; + gatt_requests = g_slist_append(gatt_requests, req_info); - if (user_info != NULL) { - _bt_common_event_cb( - BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, + _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, BLUETOOTH_ERROR_NONE, &read_req, user_info->cb, user_info->user_data); - } + #ifdef TIZEN_FEATURE_BT_HPS - param = g_variant_new("(sssyq)", - read_req.att_handle, - read_req.service_handle, - read_req.address, - read_req.req_id, - read_req.offset); - __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, param); + param = g_variant_new("(sssyq)", + read_req.att_handle, + read_req.service_handle, + read_req.address, + read_req.req_id, + read_req.offset); + __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, param); #endif - } - if (read_req.att_handle) - g_free(read_req.att_handle); - if (read_req.address) - g_free(read_req.address); - if (read_req.service_handle) - g_free(read_req.service_handle); return; } else if (g_strcmp0(method_name, "WriteValue") == 0) { GVariant *var = NULL; gchar *addr = NULL; - guint8 req_id = 0; + guint req_id = 0; guint16 offset = 0; + gboolean response_needed = FALSE; bt_gatt_value_change_t value_change = {0, }; bt_user_info_t *user_info = NULL; int len = 0; @@ -713,55 +713,68 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, BT_DBG("Application path = %s", object_path); BT_DBG("Sender = %s", sender); - g_variant_get(parameters, "(&syq@ay)", &addr, &req_id, &offset, &var); + g_variant_get(parameters, "(&suqb@ay)", + &addr, &req_id, &offset, &response_needed, &var); + BT_DBG("Request id = %u, Offset = %u", req_id, offset); + + user_info = _bt_get_user_data(BT_COMMON); + if (!user_info) { + BT_INFO("No callback is set for %s", object_path); + g_variant_unref(var); + if (response_needed) + g_dbus_method_invocation_return_value(invocation, NULL); + else + g_object_unref(invocation); + return; + } - value_change.att_handle = g_strdup(object_path); - value_change.address = g_strdup(addr); svc_info = __bt_gatt_find_gatt_service_from_char(object_path); if (svc_info == NULL) { + BT_ERR("Coudn't find service for %s", object_path); g_variant_unref(var); - g_dbus_method_invocation_return_value(invocation, NULL); + if (response_needed) + g_dbus_method_invocation_return_value(invocation, NULL); + else + g_object_unref(invocation); return; } - value_change.service_handle = g_strdup(svc_info->serv_path); + value_change.att_handle = (char *)object_path; + value_change.address = addr; + value_change.service_handle = svc_info->serv_path; value_change.offset = offset; value_change.req_id = req_id; + value_change.response_needed = response_needed; len = g_variant_get_size(var); if (len > 0) { char *data; - value_change.att_value = (guint8 *)malloc(len); - if (!value_change.att_value) { - BT_ERR("att_value is NULL"); - g_variant_unref(var); - g_dbus_method_invocation_return_value(invocation, NULL); - return; - } + value_change.att_value = (guint8 *)g_malloc(len); data = (char *)g_variant_get_data(var); memcpy(value_change.att_value, data, len); } - value_change.val_len = len; - /* Store requets information */ - req_info = g_new0(struct gatt_req_info, 1); - req_info->attr_path = g_strdup(object_path); - req_info->svc_path = g_strdup(value_change.service_handle); - req_info->request_id = req_id; - req_info->offset = offset; - req_info->context = invocation; - gatt_requests = g_slist_append(gatt_requests, req_info); - - user_info = _bt_get_user_data(BT_COMMON); - if (user_info != NULL) { - _bt_common_event_cb( - BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, - BLUETOOTH_ERROR_NONE, &value_change, - user_info->cb, user_info->user_data); + if (response_needed) { + /* Store requets information */ + req_info = g_new0(struct gatt_req_info, 1); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(value_change.service_handle); + req_info->request_id = req_id; + req_info->offset = offset; + req_info->context = invocation; + gatt_requests = g_slist_append(gatt_requests, req_info); + } else { + g_object_unref(invocation); } + + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, + BLUETOOTH_ERROR_NONE, &value_change, + user_info->cb, user_info->user_data); + #ifdef TIZEN_FEATURE_BT_HPS if (len > 0) { gchar *svc_path; @@ -778,6 +791,8 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, g_free(svc_path); } #endif + + g_free(value_change.att_value); g_variant_unref(var); return; } else if (g_strcmp0(method_name, "StartNotify") == 0) { @@ -789,8 +804,8 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, struct gatt_service_info *svc_info = NULL; svc_info = __bt_gatt_find_gatt_service_from_char(object_path); if (svc_info) { - notify_change.service_handle = g_strdup(svc_info->serv_path); - notify_change.att_handle = g_strdup(object_path); + notify_change.service_handle = svc_info->serv_path; + notify_change.att_handle = (char *)object_path; notify_change.att_notify = TRUE; _bt_common_event_cb( BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED, @@ -807,8 +822,8 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, struct gatt_service_info *svc_info = NULL; svc_info = __bt_gatt_find_gatt_service_from_char(object_path); if (svc_info) { - notify_change.service_handle = g_strdup(svc_info->serv_path); - notify_change.att_handle = g_strdup(object_path); + notify_change.service_handle = svc_info->serv_path; + notify_change.att_handle = (char *)object_path; notify_change.att_notify = FALSE; _bt_common_event_cb( BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED, @@ -820,7 +835,7 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, gchar *addr = NULL; bt_gatt_indicate_confirm_t confirm = {0, }; bt_user_info_t *user_info = NULL; - gboolean complete = 0; + gboolean complete = FALSE; struct gatt_service_info *svc_info = NULL; BT_DBG("IndicateConfirm"); @@ -828,17 +843,17 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, BT_DBG("Sender = %s", sender); g_variant_get(parameters, "(&sb)", &addr, &complete); - BT_DBG("Remote Device address number = %s", addr); - confirm.att_handle = g_strdup(object_path); - confirm.address = g_strdup(addr); + + confirm.att_handle = (char *)object_path; + confirm.address = addr; confirm.complete = complete; svc_info = __bt_gatt_find_gatt_service_from_char(object_path); if (svc_info != NULL) { - confirm.service_handle = g_strdup(svc_info->serv_path); - user_info = _bt_get_user_data(BT_COMMON); + confirm.service_handle = svc_info->serv_path; + user_info = _bt_get_user_data(BT_COMMON); if (user_info != NULL) { _bt_common_event_cb( BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED, @@ -847,6 +862,7 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, } } } + g_dbus_method_invocation_return_value(invocation, NULL); } @@ -861,62 +877,61 @@ static void __bt_gatt_desc_method_call(GDBusConnection *connection, { if (g_strcmp0(method_name, "ReadValue") == 0) { gchar *addr = NULL; - guint8 req_id = 1; + guint req_id = 0; guint16 offset = 0; bt_gatt_read_req_t read_req = {0, }; bt_user_info_t *user_info = NULL; struct gatt_req_info *req_info = NULL; struct gatt_service_info *svc_info = NULL; - BT_DBG("ReadValue"); - - g_variant_get(parameters, "(&syq)", &addr, &req_id, &offset); + BT_DBG("ReadValue"); BT_DBG("Application path = %s", object_path); + BT_DBG("Sender = %s", sender); - BT_DBG("Remote Device address number = %s", addr); - BT_DBG("Request id = %d, Offset = %d", req_id, offset); + user_info = _bt_get_user_data(BT_COMMON); + if (user_info == NULL) { + BT_INFO("No callback is set for %s", object_path); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } - BT_DBG("Sender = %s", sender); + svc_info = __bt_gatt_find_gatt_service_from_desc(object_path); + if (svc_info == NULL) { + BT_ERR("Coudn't find service for %s", object_path); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + + g_variant_get(parameters, "(&suq)", &addr, &req_id, &offset); + BT_DBG("Request id = %u, Offset = %u", req_id, offset); - read_req.att_handle = g_strdup(object_path); - read_req.address = g_strdup(addr); + read_req.att_handle = (char *)object_path; + read_req.address = addr; read_req.req_id = req_id; read_req.offset = offset; - svc_info = __bt_gatt_find_gatt_service_from_desc(object_path); - if (svc_info != NULL) { - read_req.service_handle = g_strdup(svc_info->serv_path); - user_info = _bt_get_user_data(BT_COMMON); + read_req.service_handle = svc_info->serv_path; - /* Store requets information */ - req_info = g_new0(struct gatt_req_info, 1); - req_info->attr_path = g_strdup(object_path); - req_info->svc_path = g_strdup(read_req.service_handle); - req_info->request_id = req_id; - req_info->offset = offset; - req_info->context = invocation; - gatt_requests = g_slist_append(gatt_requests, req_info); - - if (user_info != NULL) { - _bt_common_event_cb( - BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, - BLUETOOTH_ERROR_NONE, &read_req, - user_info->cb, user_info->user_data); - } - } + /* Store requets information */ + req_info = g_new0(struct gatt_req_info, 1); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(read_req.service_handle); + req_info->request_id = req_id; + req_info->offset = offset; + req_info->context = invocation; + gatt_requests = g_slist_append(gatt_requests, req_info); - if (read_req.att_handle) - g_free(read_req.att_handle); - if (read_req.address) - g_free(read_req.address); - if (read_req.service_handle) - g_free(read_req.service_handle); + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, + BLUETOOTH_ERROR_NONE, &read_req, + user_info->cb, user_info->user_data); return; } else if (g_strcmp0(method_name, "WriteValue") == 0) { GVariant *var = NULL; gchar *addr = NULL; - guint8 req_id = 0; + guint req_id = 0; guint16 offset = 0; + gboolean response_needed = FALSE; bt_gatt_value_change_t value_change = {0, }; bt_user_info_t *user_info = NULL; int len = 0; @@ -927,58 +942,72 @@ static void __bt_gatt_desc_method_call(GDBusConnection *connection, BT_DBG("Application path = %s", object_path); BT_DBG("Sender = %s", sender); - g_variant_get(parameters, "(&syq@ay)", &addr, &req_id, &offset, &var); + g_variant_get(parameters, "(&suqb@ay)", + &addr, &req_id, &offset, &response_needed, &var); + BT_DBG("Request id = %u, Offset = %u", req_id, offset); + + user_info = _bt_get_user_data(BT_COMMON); + if (user_info == NULL) { + BT_INFO("No callback is set for %s", object_path); + g_variant_unref(var); + if (response_needed) + g_dbus_method_invocation_return_value(invocation, NULL); + else + g_object_unref(invocation); + return; + } - value_change.att_handle = g_strdup(object_path); - value_change.address = g_strdup(addr); svc_info = __bt_gatt_find_gatt_service_from_desc(object_path); if (svc_info == NULL) { + BT_ERR("Coudn't find service for %s", object_path); g_variant_unref(var); - g_dbus_method_invocation_return_value(invocation, NULL); + if (response_needed) + g_dbus_method_invocation_return_value(invocation, NULL); + else + g_object_unref(invocation); return; } - value_change.service_handle = g_strdup(svc_info->serv_path); + value_change.att_handle = (char *)object_path; + value_change.address = addr; + value_change.service_handle = svc_info->serv_path; value_change.offset = offset; value_change.req_id = req_id; + value_change.response_needed = response_needed; len = g_variant_get_size(var); if (len > 0) { char *data; - value_change.att_value = (guint8 *)malloc(len); - if (!value_change.att_value) { - BT_ERR("att_value is NULL"); - g_variant_unref(var); - g_dbus_method_invocation_return_value(invocation, NULL); - return; - } + value_change.att_value = (guint8 *)g_malloc(len); + data = (char *)g_variant_get_data(var); memcpy(value_change.att_value, data, len); } - g_variant_unref(var); - value_change.val_len = len; - /* Store requets information */ - req_info = g_new0(struct gatt_req_info, 1); - req_info->attr_path = g_strdup(object_path); - req_info->svc_path = g_strdup(value_change.service_handle); - req_info->request_id = req_id; - req_info->offset = offset; - req_info->context = invocation; - gatt_requests = g_slist_append(gatt_requests, req_info); - - user_info = _bt_get_user_data(BT_COMMON); - if (user_info != NULL) { - _bt_common_event_cb( - BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, - BLUETOOTH_ERROR_NONE, &value_change, - user_info->cb, user_info->user_data); + if (response_needed) { + /* Store requets information */ + req_info = g_new0(struct gatt_req_info, 1); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(value_change.service_handle); + req_info->request_id = req_id; + req_info->offset = offset; + req_info->context = invocation; + gatt_requests = g_slist_append(gatt_requests, req_info); + } else { + g_object_unref(invocation); } + + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, + BLUETOOTH_ERROR_NONE, &value_change, + user_info->cb, user_info->user_data); + + g_free(value_change.att_value); + g_variant_unref(var); return; } - g_dbus_method_invocation_return_value(invocation, NULL); } gboolean __bt_gatt_emit_interface_removed(gchar *object_path, gchar *interface) @@ -2458,37 +2487,17 @@ BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, guint req_type, } req_info = __bt_gatt_find_request_info(request_id); + if (req_info == NULL) { + BT_ERR("Coundn't find request id [%d]", request_id); + return BLUETOOTH_ERROR_INTERNAL; + } - if (req_info) { - if (resp_state != BLUETOOTH_ERROR_NONE) { - g_dbus_method_invocation_return_dbus_error(req_info->context, - "org.bluez.Error.Failed", "Application Error"); - - gatt_requests = g_slist_remove(gatt_requests, req_info); + if (resp_state != BLUETOOTH_ERROR_NONE) { + BT_ERR("resp_state is 0x%X", resp_state); - req_info->context = NULL; - if (req_info->attr_path) - g_free(req_info->attr_path); - if (req_info->svc_path) - g_free(req_info->svc_path); - g_free(req_info); + g_dbus_method_invocation_return_dbus_error(req_info->context, + "org.bluez.Error.Failed", "Application Error"); - return BLUETOOTH_ERROR_NONE; - } - if (req_type == BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ) { - int i; - GVariantBuilder *inner_builder = NULL; - inner_builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); - if (value_length > 0 && value != NULL) { - for (i = 0; i < value_length; i++) - g_variant_builder_add(inner_builder, "y", value[i]); - } - g_dbus_method_invocation_return_value(req_info->context, - g_variant_new("(ay)", inner_builder)); - g_variant_builder_unref(inner_builder); - } else { - g_dbus_method_invocation_return_value(req_info->context, NULL); - } gatt_requests = g_slist_remove(gatt_requests, req_info); req_info->context = NULL; @@ -2497,9 +2506,32 @@ BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, guint req_type, if (req_info->svc_path) g_free(req_info->svc_path); g_free(req_info); + + return BLUETOOTH_ERROR_NONE; + } + + if (req_type == BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ) { + int i; + GVariantBuilder *inner_builder = NULL; + inner_builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); + if (value_length > 0 && value != NULL) { + for (i = 0; i < value_length; i++) + g_variant_builder_add(inner_builder, "y", value[i]); + } + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(ay)", inner_builder)); + g_variant_builder_unref(inner_builder); } else { - return BLUETOOTH_ERROR_INTERNAL; + g_dbus_method_invocation_return_value(req_info->context, NULL); } + gatt_requests = g_slist_remove(gatt_requests, req_info); + + req_info->context = NULL; + if (req_info->attr_path) + g_free(req_info->attr_path); + if (req_info->svc_path) + g_free(req_info->svc_path); + g_free(req_info); return BLUETOOTH_ERROR_NONE; } diff --git a/bt-api/bt-map-client.c b/bt-api/bt-map-client.c new file mode 100644 index 0000000..e7a15dd --- /dev/null +++ b/bt-api/bt-map-client.c @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "bluetooth-api.h" +#include "bt-internal-types.h" + +#include "bt-common.h" +#include "bt-request-sender.h" +#include "bt-event-handler.h" + +#ifdef TIZEN_DPM_ENABLE +#include "bt-dpm.h" +#endif + +GVariant *__g_variant_new_array_split(char *str) +{ + GVariantBuilder b; + g_variant_builder_init(&b, (const GVariantType*) "a{s}"); + char *pos = str; + char *item; + + while ((item = strsep(&pos, ","))) + g_variant_builder_add(&b, "{s}", item); + + return g_variant_builder_end(&b); +} + +BT_EXPORT_API int bluetooth_map_client_init(void) +{ + BT_DBG("bluetooth_map_client_init"); + bt_user_info_t *user_info; + + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + return _bt_register_event(BT_MAP_CLIENT_EVENT, user_info->cb, user_info->user_data); +} + +BT_EXPORT_API int bluetooth_map_client_deinit(void) +{ + BT_DBG("bluetooth_map_client_deinit"); + return _bt_unregister_event(BT_MAP_CLIENT_EVENT); +} + +BT_EXPORT_API int bluetooth_map_client_create_session( + bt_map_client_session_info_s *session) +{ + BT_DBG("bluetooth_map_client_create_session"); + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session->remote_address, return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, session->remote_address, strlen(session->remote_address)+1); + + result = _bt_send_request(BT_OBEX_SERVICE, BT_MAP_CREATE_SESSION, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result == BLUETOOTH_ERROR_NONE) { + if (out_param->len > 0) { + session->session_path = strdup(&g_array_index(out_param, char, 0)); + BT_DBG("session id: %s", session->session_path); + } else { + BT_ERR("out_param length is 0!!"); + return BLUETOOTH_ERROR_INTERNAL; + } + } + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + return result; +} + +BT_EXPORT_API int bluetooth_map_client_destroy_session( + bt_map_client_session_info_s *session) +{ + BT_DBG("bluetooth_map_client_destroy_session"); + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session->session_path, return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1); + + result = _bt_send_request(BT_OBEX_SERVICE, BT_MAP_DESTROY_SESSION, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result == BLUETOOTH_ERROR_NONE) { + BT_DBG("session (%s) was destroyed", session->session_path); + free(session->remote_address); + free(session->session_path); + free(session); + } + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + return result; +} + +BT_EXPORT_API int bluetooth_map_client_set_folder( + bt_map_client_session_info_s *session, + const char *name) +{ + BT_DBG("bluetooth_map_client_set_folder"); + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session->session_path, return); + BT_CHECK_PARAMETER(name, return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, session->session_path, strlen(session->session_path) + 1); + g_array_append_vals(in_param2, name, strlen(name) + 1); + + result = _bt_send_request(BT_OBEX_SERVICE, BT_MAP_SET_FOLDER, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("bluetooth_map_client_set_folder failed"); + return BLUETOOTH_ERROR_INTERNAL; + } + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_map_client_list_folders( + bt_map_client_session_info_s *session, + bt_map_client_list_folders_filter_t *filter) +{ + BT_DBG("bluetooth_map_list_folders"); + int result = 0; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session->session_path, return); + + bt_user_info_t *user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + GVariantBuilder b; + g_variant_builder_init(&b, (const GVariantType*) "a{sv}"); + if (filter->offset > -1) + g_variant_builder_add(&b, "{sv}", "Offset", g_variant_new_uint16(filter->offset)); + if (filter->max_count > -1) + g_variant_builder_add(&b, "{sv}", "MaxCount", g_variant_new_uint16(filter->max_count)); + GVariant *filter_variant = g_variant_builder_end(&b); + char *filter_serialized = g_variant_print(filter_variant, TRUE); + + g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1); + g_array_append_vals(in_param2, filter_serialized, strlen(filter_serialized)+1); + + result = _bt_send_request_async(BT_OBEX_SERVICE, BT_MAP_LIST_FOLDERS, + in_param1, in_param2, in_param3, in_param4, user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + free(filter_serialized); + + return result; +} + +BT_EXPORT_API int bluetooth_map_client_list_filter_fields(bt_map_client_session_info_s *session) +{ + BT_DBG("bluetooth_map_client_list_filter_fields"); + int result = BLUETOOTH_ERROR_NONE; + bt_user_info_t *user_info; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session->session_path, return); + + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1); + + result = _bt_send_request_async(BT_OBEX_SERVICE, BT_MAP_LIST_FILTER_FIELDS, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_map_client_list_messages(bt_map_client_session_info_s *session, + const char *folder, + bt_map_client_list_messages_filter_t *filter) +{ + BT_DBG("bluetooth_map_client_list_messages"); + int result = 0; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session->session_path, return); + BT_CHECK_PARAMETER(folder, return); + BT_CHECK_PARAMETER(filter, return); + + bt_user_info_t *user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + GVariantBuilder b; + g_variant_builder_init(&b, (const GVariantType*) "a{sv}"); + if (filter->offset > -1) + g_variant_builder_add(&b, "{sv}", "Offset", g_variant_new_uint16(filter->offset)); + if (filter->max_count > -1) + g_variant_builder_add(&b, "{sv}", "MaxCount", g_variant_new_uint16(filter->max_count)); + if (filter->subject_length > -1) + g_variant_builder_add(&b, "{sv}", "SubjectLength", g_variant_new_byte(filter->subject_length)); + if (filter->fields != NULL) + g_variant_builder_add(&b, "{sv}", "Fields", __g_variant_new_array_split(filter->fields)); + if (filter->types != NULL) + g_variant_builder_add(&b, "{sv}", "Types", __g_variant_new_array_split(filter->types)); + if (filter->period_begin != NULL) + g_variant_builder_add(&b, "{sv}", "PeriodBegin", g_variant_new_string(filter->period_begin)); + if (filter->period_end != NULL) + g_variant_builder_add(&b, "{sv}", "PeriodEnd", g_variant_new_string(filter->period_end)); + if (filter->is_read > -1) + g_variant_builder_add(&b, "{sv}", "Read", g_variant_new_boolean(filter->is_read == 1 ? TRUE : FALSE)); + if (filter->recipient != NULL) + g_variant_builder_add(&b, "{sv}", "Recipient", g_variant_new_string(filter->recipient)); + if (filter->sender != NULL) + g_variant_builder_add(&b, "{sv}", "Sender", g_variant_new_string(filter->sender)); + if (filter->is_priority > -1) + g_variant_builder_add(&b, "{sv}", "Priority", g_variant_new_boolean(filter->is_priority == 1 ? TRUE : FALSE)); + GVariant *filter_variant = g_variant_builder_end(&b); + char *filter_serialized = g_variant_print(filter_variant, TRUE); + + g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1); + g_array_append_vals(in_param2, folder, strlen(folder)+1); + g_array_append_vals(in_param3, filter_serialized, strlen(filter_serialized)+1); + + result = _bt_send_request_async(BT_OBEX_SERVICE, BT_MAP_LIST_MESSAGES, + in_param1, in_param2, in_param3, in_param4, user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + free(filter_serialized); + + return result; +} + +BT_EXPORT_API int bluetooth_map_client_update_inbox(bt_map_client_session_info_s *session) +{ + BT_DBG("bluetooth_map_client_update_inbox"); + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session->session_path, return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1); + + result = _bt_send_request(BT_OBEX_SERVICE, BT_MAP_UPDATE_INBOX, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("bluetooth_map_client_update_inbox failed"); + return BLUETOOTH_ERROR_INTERNAL; + } + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_map_client_push_message(bt_map_client_session_info_s *session, + const char *source_file, + const char *folder, + bt_map_client_push_message_args_t *args) +{ + BT_DBG("Entered bluetooth_map_client_push_message"); + int result = 0; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session, return); + BT_CHECK_PARAMETER(session->session_path, return); + BT_CHECK_PARAMETER(source_file, return); + BT_CHECK_PARAMETER(folder, return); + + bt_user_info_t *user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + GVariantBuilder b; + g_variant_builder_init(&b, (const GVariantType*) "a{sv}"); + if (args->is_transparent > -1) + g_variant_builder_add(&b, "{sv}", "Transparent", g_variant_new_boolean(args->is_transparent == 1 ? TRUE : FALSE)); + if (args->is_retry > -1) + g_variant_builder_add(&b, "{sv}", "Retry", g_variant_new_boolean(args->is_retry == 1 ? TRUE : FALSE)); + if (args->charset != NULL) + g_variant_builder_add(&b, "{sv}", "Charset", g_variant_new_string(args->charset)); + GVariant *args_variant = g_variant_builder_end(&b); + char *args_serialized = g_variant_print(args_variant, TRUE); + + g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1); + g_array_append_vals(in_param2, source_file, strlen(source_file)+1); + g_array_append_vals(in_param3, folder, strlen(folder)+1); + g_array_append_vals(in_param4, args_serialized, strlen(args_serialized)+1); + + result = _bt_send_request_async(BT_OBEX_SERVICE, BT_MAP_PUSH_MESSAGE, + in_param1, in_param2, in_param3, in_param4, user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_map_client_get_message(bt_map_client_session_info_s *session, + const bt_map_client_message_object_t message_object, + const char *target_file, + bool attachment) +{ + BT_DBG("Entered bluetooth_map_client_get_message"); + int result = 0; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(session, return); + BT_CHECK_PARAMETER(session->session_path, return); + BT_CHECK_PARAMETER(message_object, return); + BT_CHECK_PARAMETER(target_file, return); + + bt_user_info_t *user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + // TODO session currently is not used, but should be valid + //g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1); + g_array_append_vals(in_param2, message_object, strlen(message_object)+1); + g_array_append_vals(in_param3, target_file, strlen(target_file)+1); + g_array_append_vals(in_param4, &attachment, sizeof(attachment)); + + result = _bt_send_request_async(BT_OBEX_SERVICE, BT_MAP_GET_MESSAGE, + in_param1, in_param2, in_param3, in_param4, user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} diff --git a/bt-api/bt-request-sender.c b/bt-api/bt-request-sender.c index 5f1ace5..69f1da2 100644 --- a/bt-api/bt-request-sender.c +++ b/bt-api/bt-request-sender.c @@ -83,7 +83,9 @@ static void __bt_get_event_info(int service_function, GArray *output, { ret_if(event == NULL); - BT_DBG("service_function : %x", service_function); + BT_DBG("service_function : %s (0x%x)", + _bt_convert_service_function_to_string(service_function), + service_function); switch (service_function) { case BT_BOND_DEVICE: case BT_BOND_DEVICE_BY_TYPE: @@ -225,6 +227,27 @@ static void __bt_get_event_info(int service_function, GArray *output, *param_data = &g_array_index(output, bluetooth_device_address_t, 0); break; + case BT_TDS_READ_TRANSPORT_DATA: + *event_type = BT_TDS_EVENT; + *event = BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED; + ret_if(output == NULL); + *param_data = &g_array_index(output, + bluetooth_device_address_t, 0); + break; + case BT_TDS_ENABLE_CONTROL_POINT: + *event_type = BT_TDS_EVENT; + *event = BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED; + ret_if(output == NULL); + *param_data = &g_array_index(output, + bluetooth_device_address_t, 0); + break; + case BT_TDS_ACTIVATE_CONTROL_POINT: + *event_type = BT_TDS_EVENT; + *event = BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION; + ret_if(output == NULL); + *param_data = &g_array_index(output, + bluetooth_device_address_t, 0); + break; default: BT_ERR("Unknown function"); return; @@ -254,6 +277,7 @@ static void __send_request_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) { + BT_DBG("Entered __send_request_cb"); bluetooth_event_param_t bt_event; bt_req_info_t *cb_data = user_data; int result = BLUETOOTH_ERROR_NONE; @@ -310,11 +334,32 @@ static void __send_request_cb(GDBusProxy *proxy, &bt_event.event, &event_type, &bt_event.param_data); + BT_DBG("service_function [%d]", cb_data->service_function); if (result == BLUETOOTH_ERROR_NONE && out_param1) { if (cb_data->service_function == BT_OPP_PUSH_FILES) { request_id = g_array_index(out_param1, int, 0); BT_DBG("request_id : %d", request_id); _bt_add_push_request_id(request_id); + } else if (cb_data->service_function == BT_MAP_LIST_FOLDERS) { + request_id = g_array_index(out_param1, int, 0); + BT_DBG("request_id : %d", request_id); + _bt_add_push_request_id(request_id); + } else if (cb_data->service_function == BT_MAP_LIST_FILTER_FIELDS) { + request_id = g_array_index(out_param1, int, 0); + BT_DBG("request_id : %d", request_id); + _bt_add_push_request_id(request_id); + } else if (cb_data->service_function == BT_MAP_LIST_MESSAGES) { + request_id = g_array_index(out_param1, int, 0); + BT_DBG("request_id : %d", request_id); + _bt_add_push_request_id(request_id); + } else if (cb_data->service_function == BT_MAP_GET_MESSAGE) { + request_id = g_array_index(out_param1, int, 0); + BT_DBG("request_id : %d", request_id); + _bt_add_push_request_id(request_id); + } else if (cb_data->service_function == BT_MAP_PUSH_MESSAGE) { + request_id = g_array_index(out_param1, int, 0); + BT_DBG("request_id : %d", request_id); + _bt_add_push_request_id(request_id); } goto done; @@ -326,7 +371,8 @@ static void __send_request_cb(GDBusProxy *proxy, /* Only if fail case, call the callback function*/ bt_event.result = result; - BT_INFO("event_type[%d], result=[%d]", event_type, result); + BT_INFO("event_type[%d], result= %s [0x%x]", event_type, + _bt_convert_error_to_string(result), result); if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) { ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event, @@ -356,6 +402,10 @@ static void __send_request_cb(GDBusProxy *proxy, ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event, &bt_event, cb_data->user_data); + } else if (event_type == BT_TDS_EVENT) { + ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event, + &bt_event, + cb_data->user_data); } else { BT_INFO("Not handled event type : %d", event_type); } @@ -492,7 +542,9 @@ int _bt_async_send_request(int service_type, int service_function, GVariant *param4; GVariant *param5; - BT_DBG("service_function : %x", service_function); + BT_DBG("service_function : %s (0x%x)", + _bt_convert_service_function_to_string(service_function), + service_function); cb_data = g_new0(bt_req_info_t, 1); diff --git a/bt-api/bt-rfcomm-client.c b/bt-api/bt-rfcomm-client.c index 21b3fea..ec57e1e 100644 --- a/bt-api/bt-rfcomm-client.c +++ b/bt-api/bt-rfcomm-client.c @@ -452,7 +452,7 @@ void _bt_rfcomm_client_disconnect_all(void) conn_info->disconnected = TRUE; _bt_disconnect_profile(conn_info->bt_addr, info->uuid, - NULL,NULL); + NULL, NULL); } diff --git a/bt-api/bt-rfcomm-server.c b/bt-api/bt-rfcomm-server.c index 5053387..aa59276 100644 --- a/bt-api/bt-rfcomm-server.c +++ b/bt-api/bt-rfcomm-server.c @@ -367,7 +367,7 @@ int new_server_connection(const char *path, int fd, bluetooth_device_address_t * close(fd); _bt_convert_addr_type_to_string(addr_str, addr->addr); - _bt_disconnect_profile(addr_str, info->uuid, NULL,NULL); + _bt_disconnect_profile(addr_str, info->uuid, NULL, NULL); return -1; } @@ -505,7 +505,7 @@ void _bt_rfcomm_server_disconnect_all(void) _bt_convert_addr_type_to_string(addr, conn_info->addr.addr); - _bt_disconnect_profile(addr, info->uuid, NULL,NULL); + _bt_disconnect_profile(addr, info->uuid, NULL, NULL); } server = server->next; diff --git a/bt-api/bt-tds.c b/bt-api/bt-tds.c new file mode 100644 index 0000000..c7b983b --- /dev/null +++ b/bt-api/bt-tds.c @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "bluetooth-api.h" +#include "bt-internal-types.h" + +#include "bt-common.h" +#include "bt-request-sender.h" +#include "bt-event-handler.h" + +static int _bluetooth_handle_get_len(const char *str) +{ + int i; + for (i = 0; str && str[i] != '\0'; i++); + return i; +} + +BT_EXPORT_API int bluetooth_tds_provider_register(void) +{ + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + BT_DBG(""); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_TDS_PROVIDER_REGISTER, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_tds_provider_unregister(void) +{ + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + BT_DBG(""); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_TDS_PROVIDER_UNREGISTER, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_set_tds_provider_manuf_data(unsigned char *buf, unsigned int length) +{ + int result; + bluetooth_advertising_data_t manuf_data; + + BT_CHECK_ENABLED_LE(return); + + retv_if(length > 0 && NULL == buf, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(length > BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX, BLUETOOTH_ERROR_INVALID_PARAM); + + memcpy(manuf_data.data, buf, length); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, &length, sizeof(unsigned int)); + g_array_append_vals(in_param2, &manuf_data, sizeof(bluetooth_advertising_data_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_TDS_PROVIDER_SET_MANUF_DATA, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_tds_provider_create(int transport, unsigned int handle) +{ + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + BT_DBG(""); + + g_array_append_vals(in_param1, &handle, sizeof(unsigned int)); + g_array_append_vals(in_param2, &transport, sizeof(unsigned int)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_TDS_PROVIDER_CREATE, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_tds_provider_destroy(unsigned int handle) +{ + int result = BLUETOOTH_ERROR_INTERNAL; + + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + BT_DBG(""); + + g_array_append_vals(in_param1, &handle, sizeof(unsigned int)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_TDS_PROVIDER_DESTROY, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_set_tds_provider_transport_data(unsigned int tds_handle, + bluetooth_tds_transport_state_t state, unsigned char *buf, unsigned int length) +{ + int result; + bluetooth_tds_data_t tds_data; + + BT_CHECK_ENABLED_LE(return); + + retv_if(length > 0 && NULL == buf, BLUETOOTH_ERROR_INVALID_PARAM); + tds_data.length = length; + memcpy(tds_data.data, buf, length); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, &tds_handle, sizeof(unsigned int)); + g_array_append_vals(in_param2, &state, sizeof(int)); + g_array_append_vals(in_param3, &tds_data, sizeof(bluetooth_tds_data_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_TDS_PROVIDER_SET_TRANSPORT_DATA, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_send_tds_activation_response(bluetooth_device_address_t *device_address, + unsigned int tds_handle, int response, unsigned char *buf, unsigned int length) +{ + int result; + bluetooth_tds_data_t tds_data; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_ENABLED_LE(return); + + retv_if(length > 0 && NULL == buf, BLUETOOTH_ERROR_INVALID_PARAM); + tds_data.length = length; + memcpy(tds_data.data, buf, length); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, &tds_handle, sizeof(unsigned int)); + g_array_append_vals(in_param2, &response, sizeof(int)); + g_array_append_vals(in_param3, device_address, sizeof(bluetooth_device_address_t)); + g_array_append_vals(in_param4, &tds_data, sizeof(bluetooth_tds_data_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_TDS_SEND_ACTIVATION_RESPONSE, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_tds_read_transport_data(const bluetooth_device_address_t *device_address, + const char *handle) +{ + char *path; + int path_len = 0; + bt_user_info_t *user_info; + int result = BLUETOOTH_ERROR_INTERNAL; + BT_DBG("+"); + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_ENABLED_LE(return); + + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + path = g_strdup(handle); + path_len = _bluetooth_handle_get_len(path); + g_array_append_vals(in_param1, path, path_len); + g_free(path); + + g_array_append_vals(in_param2, device_address, + sizeof(bluetooth_device_address_t)); + + result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_TDS_READ_TRANSPORT_DATA, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + BT_DBG("-"); + return result; +} + +BT_EXPORT_API int bluetooth_tds_enable_control_point(const bluetooth_device_address_t *device_address, + const char *handle) +{ + char *path; + int path_len = 0; + bt_user_info_t *user_info; + int result = BLUETOOTH_ERROR_INTERNAL; + BT_DBG("+"); + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_ENABLED_LE(return); + + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + path = g_strdup(handle); + path_len = _bluetooth_handle_get_len(path); + g_array_append_vals(in_param1, path, path_len); + g_free(path); + + g_array_append_vals(in_param2, device_address, + sizeof(bluetooth_device_address_t)); + + result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_TDS_ENABLE_CONTROL_POINT, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + BT_DBG("-"); + return result; +} + +BT_EXPORT_API int bluetooth_tds_activate_control_point(const bluetooth_device_address_t *device_address, + const char *handle, unsigned char *buf, + int length) +{ + char *path; + int path_len = 0; + bt_user_info_t *user_info; + int result = BLUETOOTH_ERROR_INTERNAL; + bluetooth_control_point_data_t data; + BT_DBG("+"); + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_PARAMETER(buf, return); + BT_CHECK_ENABLED_LE(return); + + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + memset(&data, 0x00, sizeof(bluetooth_control_point_data_t)); + + data.length = length; + if (length > 0) + memcpy(data.data, buf, length); + + path = g_strdup(handle); + path_len = _bluetooth_handle_get_len(path); + + /*Fill parameters*/ + g_array_append_vals(in_param1, path, path_len); + + g_array_append_vals(in_param2, device_address, + sizeof(bluetooth_device_address_t)); + + g_array_append_vals(in_param3, &data, sizeof(bluetooth_control_point_data_t)); + + result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_TDS_ACTIVATE_CONTROL_POINT, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_free(path); + BT_DBG("-"); + return result; +} diff --git a/bt-api/bt-telephony.c b/bt-api/bt-telephony.c index ababe28..6dd2edd 100644 --- a/bt-api/bt-telephony.c +++ b/bt-api/bt-telephony.c @@ -2270,6 +2270,42 @@ BT_EXPORT_API int bluetooth_telephony_is_connected(gboolean *ag_connected) return BLUETOOTH_ERROR_NONE; } +BT_EXPORT_API int bluetooth_telephony_set_active_headset(const char *remote_addr) +{ +#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT + GVariant *reply; + GVariant *param; + GError *err = NULL; + int ret; + + BT_CHECK_ENABLED(return); + + if (NULL == remote_addr) + return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM; + + param = g_variant_new("(s)", remote_addr); + reply = __bluetooth_telephony_dbus_method_send( + HFP_AGENT_PATH, HFP_AGENT_INTERFACE, + "SwapHeadset", &err, param); + + if (!reply) { + BT_ERR("Error returned in method call\n"); + if (err) { + g_dbus_error_strip_remote_error(err); + ret = __bt_telephony_get_error(err->message); + g_error_free(err); + return ret; + } + return BLUETOOTH_TELEPHONY_ERROR_INTERNAL; + } + + g_variant_unref(reply); + return BLUETOOTH_TELEPHONY_ERROR_NONE; +#else + return BLUETOOTH_ERROR_NOT_SUPPORT; +#endif +} + static void __bt_telephony_adapter_filter(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, diff --git a/bt-api/include/bt-common.h b/bt-api/include/bt-common.h index b863d34..e3a2af4 100644 --- a/bt-api/include/bt-common.h +++ b/bt-api/include/bt-common.h @@ -274,6 +274,9 @@ void _bt_avrcp_event_cb(int event, int result, void *param, void _bt_opp_client_event_cb(int event, int result, void *param, void *callback, void *user_data); +void _bt_map_client_event_cb(int event, int result, void *param, + void *callback, void *user_data); + void _bt_divide_device_class(bluetooth_device_class_t *device_class, unsigned int cod); @@ -286,6 +289,10 @@ void _bt_convert_addr_string_to_secure_string(char *addr, void _bt_convert_addr_type_to_string(char *address, unsigned char *addr); +const char *_bt_convert_error_to_string(int error); + +const char *_bt_convert_service_function_to_string(int function); + int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length); gboolean _bt_utf8_validate(char *name); diff --git a/bt-api/include/bt-dpm.h b/bt-api/include/bt-dpm.h index ae64f97..6750506 100644 --- a/bt-api/include/bt-dpm.h +++ b/bt-api/include/bt-dpm.h @@ -45,6 +45,7 @@ typedef enum { BT_DPM_A2DP, BT_DPM_AVRCP, BT_DPM_SPP, + /* TODO: MAP? see above */ } bt_dpm_service_e; int _bt_check_dpm(int service, void *param); diff --git a/bt-core/bt-core-dbus-handler.c b/bt-core/bt-core-dbus-handler.c old mode 100755 new mode 100644 index c9c07c3..34c34c7 --- a/bt-core/bt-core-dbus-handler.c +++ b/bt-core/bt-core-dbus-handler.c @@ -113,7 +113,7 @@ int _bt_core_start_httpproxy(void) { GVariant *variant = NULL; unsigned char enabled; - + GError *err = NULL; BT_DBG(" "); hps_gproxy = _bt_core_gdbus_get_hps_proxy(); @@ -123,7 +123,11 @@ int _bt_core_start_httpproxy(void) } variant = g_dbus_proxy_call_sync(hps_gproxy, "enable", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (err) { + BT_ERR("Error : %s" , err->message); + g_clear_error(&err); + } if (variant) { g_variant_get(variant, "(y)", &enabled); BT_ERR("HPS enabled status 0x%x", enabled); @@ -135,7 +139,7 @@ int _bt_core_stop_httpproxy(void) { GVariant *variant = NULL; unsigned char enabled; - + GError *err = NULL; BT_DBG(" "); hps_gproxy = _bt_core_gdbus_get_hps_proxy(); @@ -145,7 +149,11 @@ int _bt_core_stop_httpproxy(void) } variant = g_dbus_proxy_call_sync(hps_gproxy, "disable", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (err) { + BT_ERR("Error : %s" , err->message); + g_clear_error(&err); + } if (variant) { g_variant_get(variant, "(y)", &enabled); BT_ERR("HPS disabled status 0x%x", enabled); @@ -534,6 +542,7 @@ gboolean _bt_core_register_dbus(void) node_info->interfaces[0], &method_table, NULL, NULL, &error); + g_dbus_node_info_unref(node_info); if (obj_id == 0) { BT_ERR("Failed to register: %s", error->message); g_error_free(error); diff --git a/bt-httpproxy/bt-httpproxy.c b/bt-httpproxy/bt-httpproxy.c index 5efd71a..471aeb2 100644 --- a/bt-httpproxy/bt-httpproxy.c +++ b/bt-httpproxy/bt-httpproxy.c @@ -118,15 +118,18 @@ static char *__hps_convert_uuid_to_uuid128(const char *uuid) len = strlen(uuid); switch (len) { - case 4: /* UUID 16bits */ + case 4: + /* UUID 16bits */ uuid128 = g_strdup_printf("0000%s-0000-1000-8000-00805F9B34FB", uuid); break; - case 8: /* UUID 32bits */ + case 8: + /* UUID 32bits */ uuid128 = g_strdup_printf("%s-0000-1000-8000-00805F9B34FB", uuid); break; - case 36: /* UUID 128bits */ + case 36: + /* UUID 128bits */ uuid128 = strdup(uuid); break; @@ -633,9 +636,10 @@ void _bt_hps_head_response_cb(SoupSession *session, // Write Data to Status Code Characteristic #ifdef HPS_GATT_DB data_status = (hdr_len > MAX_ENTITY_LENGTH) ? DS_HEADER_TRUNCATED : DS_HEADER_RECEIVED; - if (data_status == DS_BODY_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) { + + if (data_status == DS_BODY_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) _bt_hps_set_notify_read_status(http_hdr_obj_path, 0, data_status, http_status); - } + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); #else status[0] = http_status & 0x0F; @@ -755,9 +759,10 @@ void _bt_hps_get_response_cb(SoupSession *session, // Write Data to Status Code Characteristic #ifdef HPS_GATT_DB data_status = (body->length > MAX_ENTITY_LENGTH) ? DS_BODY_TRUNCATED : DS_BODY_RECEIVED; - if (data_status == DS_BODY_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) { + + if (data_status == DS_BODY_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) _bt_hps_set_notify_read_status(http_entity_obj_path, 0, data_status, http_status); - } + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); #else @@ -806,9 +811,10 @@ void _bt_hps_get_response_cb(SoupSession *session, // Write Data to Status Code Characteristic #ifdef HPS_GATT_DB data_status = (hdr_len > MAX_HEADER_LENGTH) ? DS_HEADER_TRUNCATED : DS_HEADER_RECEIVED; - if (data_status == DS_HEADER_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) { + + if (data_status == DS_HEADER_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) _bt_hps_set_notify_read_status(http_hdr_obj_path, 0, data_status, http_status); - } + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); #else status[0] = http_status & 0x0F; diff --git a/bt-service-emul/bt-request-handler.c b/bt-service-emul/bt-request-handler.c index 9b2443d..a68c921 100644 --- a/bt-service-emul/bt-request-handler.c +++ b/bt-service-emul/bt-request-handler.c @@ -260,6 +260,7 @@ static void __bt_service_method(GDBusConnection *connection, out_param1 = NULL; } } + /* TODO: MAP? see the if{}else{} above */ g_variant_unref(param1); g_variant_unref(param2); @@ -2029,6 +2030,7 @@ int __bt_obexd_request(int function_name, sizeof(gboolean)); break; } + /* TODO: MAP? MAP functions, see above */ case BT_OBEX_SERVER_ALLOCATE: { int app_pid; gboolean is_native; @@ -2467,6 +2469,7 @@ gboolean __bt_service_check_privilege(int function_name, case BT_OPP_PUSH_FILES: case BT_OPP_CANCEL_PUSH: + /* TODO: MAP? MAP functions, see above */ case BT_OBEX_SERVER_ACCEPT_CONNECTION: case BT_OBEX_SERVER_REJECT_CONNECTION: diff --git a/bt-service-emul/bt-service-event-sender.c b/bt-service-emul/bt-service-event-sender.c index 101f8ac..582f9ff 100644 --- a/bt-service-emul/bt-service-event-sender.c +++ b/bt-service-emul/bt-service-event-sender.c @@ -68,6 +68,9 @@ int _bt_send_event(int event_type, int event, GVariant *param) case BT_OPP_SERVER_EVENT: path = BT_OPP_SERVER_PATH; break; + case BT_MAP_CLIENT_EVENT: + path = BT_MAP_CLIENT_PATH; + break; case BT_PBAP_CLIENT_EVENT: path = BT_PBAP_CLIENT_PATH; break; @@ -264,6 +267,14 @@ int _bt_send_event(int event_type, int event, GVariant *param) signal = BT_OPP_DISCONNECTED; BT_INFO_C("Disconnected [OPP]"); break; + case BLUETOOTH_EVENT_MAP_CONNECTED: + signal = BT_MAP_CONNECTED; + BT_INFO_C("Connected [MAP]"); + break; + case BLUETOOTH_EVENT_MAP_DISCONNECTED: + signal = BT_MAP_DISCONNECTED; + BT_INFO_C("Disconnected [MAP]"); + break; case BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED: signal = BT_TRANSFER_CONNECTED; break; diff --git a/bt-service-emul/include/bt-service-common.h b/bt-service-emul/include/bt-service-common.h index 0bc594d..a056b58 100644 --- a/bt-service-emul/include/bt-service-common.h +++ b/bt-service-emul/include/bt-service-common.h @@ -98,7 +98,7 @@ extern "C" { #define BT_MAX_DBUS_TIMEOUT 45000 -#define BT_ENABLE_TIMEOUT ((TIZEN_PROFILE_TV)?5000:20000) /* 5(TV) / 20(others) seconds */ +#define BT_ENABLE_TIMEOUT ((TIZEN_PROFILE_TV) ? 5000 : 20000) /* 5(TV) / 20(others) seconds */ #define BT_DISCOVERY_FINISHED_DELAY 200 #define MANAGER_EVENT_MATCH_RULE \ @@ -216,6 +216,7 @@ extern "C" { #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb" #define OBEX_OPP_UUID "00001105-0000-1000-8000-00805f9b34fb" +#define OBEX_MAP_UUID "00001134-0000-1000-8000-00805f9b34fb" #define OBEX_PSE_UUID "0000112f-0000-1000-8000-00805f9b34fb" #define GATT_UUID "00001801-0000-1000-8000-00805f9b34fb" diff --git a/bt-service/CMakeLists.txt b/bt-service/CMakeLists.txt index 1d33d18..7d2ee01 100644 --- a/bt-service/CMakeLists.txt +++ b/bt-service/CMakeLists.txt @@ -19,6 +19,7 @@ bt-service-audio.c bt-service-oob.c bt-service-obex-agent.c bt-service-opp-client.c +bt-service-map-client.c bt-service-obex-server.c bt-service-rfcomm-client.c bt-service-rfcomm-server.c @@ -30,6 +31,7 @@ bt-service-gap-agent.c bt-service-pbap.c bt-service-dpm.c bt-service-proximity.c +bt-service-tds.c ) IF(LIBNOTIFY_SUPPORT) @@ -77,7 +79,7 @@ FOREACH(flag ${service_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag} -Wall") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") SET(CMAKE_C_FLAGS_RELEASE "-O2") SET(APP_SYSCONFDIR /opt/var/lib/bluetooth) diff --git a/bt-service/bt-request-handler.c b/bt-service/bt-request-handler.c index 90d706b..070e972 100644 --- a/bt-service/bt-request-handler.c +++ b/bt-service/bt-request-handler.c @@ -36,6 +36,7 @@ #include "bt-service-avrcp.h" #include "bt-service-avrcp-controller.h" #include "bt-service-opp-client.h" +#include "bt-service-map-client.h" #include "bt-service-obex-server.h" #include "bt-service-rfcomm-client.h" #include "bt-service-rfcomm-server.h" @@ -44,6 +45,7 @@ #include "bt-service-dpm.h" #include "bt-service-agent.h" #include "bt-service-proximity.h" +#include "bt-service-tds.h" static GDBusConnection *bt_service_conn; static guint owner_id = 0; @@ -153,6 +155,7 @@ static void __bt_service_method(GDBusConnection *connection, gpointer user_data) { FN_START; + BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]", method_name, object_path, interface_name); @@ -202,8 +205,9 @@ static void __bt_service_method(GDBusConnection *connection, } } - BT_DBG("SERVICE TYPE [%d] SERVICE FUNC [%d]", - service_type, service_function); + BT_DBG("Service type = %d, fn = %s (0x%x)", + service_type, _bt_convert_service_function_to_string(service_function), + service_function); switch (service_type) { case BT_BLUEZ_SERVICE: result = __bt_bluez_request(service_function, @@ -263,6 +267,7 @@ static void __bt_service_method(GDBusConnection *connection, out_param1 = NULL; } } + /* TODO: MAP? see the if{}else{} above */ g_variant_unref(param1); g_variant_unref(param2); @@ -273,7 +278,7 @@ static void __bt_service_method(GDBusConnection *connection, FN_END; return; fail: - BT_ERR_C("Request is failed [%s] [%x]", + BT_ERR_C("Request is failed [%s] [0x%x]", _bt_convert_error_to_string(result), result); out_var = g_variant_new_from_data((const GVariantType *)"ay", @@ -1723,26 +1728,6 @@ int __bt_bluez_request(int function_name, case BT_HID_DEVICE_SEND_REPLY_TO_REPORT: /* Just call to check the privilege */ break; -#ifndef GATT_NO_RELAY - case BT_GATT_WATCH_CHARACTERISTIC: { - char *sender = NULL; - - sender = (char *)g_dbus_method_invocation_get_sender(context); - - result = _bt_insert_gatt_client_sender(sender); - - break; - } - case BT_GATT_UNWATCH_CHARACTERISTIC: { - char *sender = NULL; - - sender = (char *)g_dbus_method_invocation_get_sender(context); - - result = _bt_delete_gatt_client_sender(sender); - - break; - } -#endif case BT_LE_IPSP_INIT: result = _bt_initialize_ipsp(); break; @@ -2163,6 +2148,192 @@ int __bt_bluez_request(int function_name, } break; } + case BT_TDS_PROVIDER_REGISTER: { + char *sender = NULL; + + sender = (char *)g_dbus_method_invocation_get_sender(context); + result = _bt_tds_provider_register(sender); + + break; + } + case BT_TDS_PROVIDER_UNREGISTER: { + char *sender = NULL; + + sender = (char *)g_dbus_method_invocation_get_sender(context); + result = _bt_tds_provider_unregister(sender); + + break; + } + case BT_TDS_PROVIDER_SET_MANUF_DATA: { + char *sender = NULL; + unsigned int length = 0; + bluetooth_advertising_data_t manuf_data; + + __bt_service_get_parameters(in_param1, + &length, sizeof(unsigned int)); + __bt_service_get_parameters(in_param2, + &manuf_data, sizeof(bluetooth_advertising_data_t)); + sender = (char *)g_dbus_method_invocation_get_sender(context); + + result = _bt_tds_provider_set_manuf_data(sender, manuf_data.data, length); + break; + } + case BT_TDS_PROVIDER_CREATE: { + char *sender = NULL; + unsigned int tds_handle = 0; + int transport; + + __bt_service_get_parameters(in_param1, + &tds_handle, sizeof(unsigned int)); + __bt_service_get_parameters(in_param2, + &transport, sizeof(int)); + sender = (char *)g_dbus_method_invocation_get_sender(context); + result = _bt_tds_provider_transport_create(sender, transport, tds_handle); + + break; + } + case BT_TDS_PROVIDER_DESTROY: { + char *sender = NULL; + unsigned int tds_handle = 0; + + __bt_service_get_parameters(in_param1, + &tds_handle, sizeof(unsigned int)); + sender = (char *)g_dbus_method_invocation_get_sender(context); + result = _bt_tds_provider_transport_remove(sender, tds_handle); + + break; + } + case BT_TDS_PROVIDER_SET_TRANSPORT_DATA: { + char *sender = NULL; + unsigned int tds_handle = 0; + int transport_state = 0; + bluetooth_tds_data_t tds_data; + + __bt_service_get_parameters(in_param1, + &tds_handle, sizeof(unsigned int)); + __bt_service_get_parameters(in_param2, + &transport_state, sizeof(int)); + __bt_service_get_parameters(in_param3, + &tds_data, sizeof(bluetooth_tds_data_t)); + sender = (char *)g_dbus_method_invocation_get_sender(context); + + result = _bt_tds_provider_set_transport_data(sender, tds_handle, + transport_state, tds_data.data, tds_data.length); + break; + } + case BT_TDS_SEND_ACTIVATION_RESPONSE: { + bluetooth_device_address_t address = { {0} }; + bluetooth_tds_data_t tds_data; + char *sender = NULL; + unsigned int tds_handle = 0; + int response; + + __bt_service_get_parameters(in_param1, + &tds_handle, sizeof(unsigned int)); + __bt_service_get_parameters(in_param2, + &response, sizeof(int)); + __bt_service_get_parameters(in_param3, &address, + sizeof(bluetooth_device_address_t)); + __bt_service_get_parameters(in_param4, + &tds_data, sizeof(bluetooth_tds_data_t)); + sender = (char *)g_dbus_method_invocation_get_sender(context); + + result = _bt_tds_provider_send_activation_response(sender, tds_handle, + &address, response, tds_data.data, tds_data.length); + break; + } + case BT_TDS_READ_TRANSPORT_DATA: { + char *handle; + char *data = NULL; + guint data_len = 0; + + char *sender = NULL; + sender = (char *)g_dbus_method_invocation_get_sender(context); + + bluetooth_device_address_t address = { {0} }; + __bt_service_get_parameters(in_param2, + &address, sizeof(bluetooth_device_address_t)); + + data_len = g_variant_get_size(in_param1); + data = (char *)g_variant_get_data(in_param1); + + handle = g_strndup(data, data_len); + BT_DBG("Read TDS Transport Block [%s]", handle); + + result = _bt_tds_read_transport_data(request_id, sender, &address, handle); + + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("Reading TDS Transport data failed result [%d]", result); + g_array_append_vals(*out_param1, &address, + sizeof(bluetooth_device_address_t)); + } + if (handle) + g_free(handle); + break; + } + case BT_TDS_ENABLE_CONTROL_POINT: { + char *handle; + char *data = NULL; + guint data_len = 0; + bluetooth_device_address_t address = { {0} }; + + char *sender = NULL; + sender = (char *)g_dbus_method_invocation_get_sender(context); + + data_len = g_variant_get_size(in_param1); + data = (char *)g_variant_get_data(in_param1); + __bt_service_get_parameters(in_param2, + &address, sizeof(bluetooth_device_address_t)); + + handle = g_strndup(data, data_len); + BT_DBG("TDS Control point CCCD handle [%s]", handle); + + result = _bt_tds_enable_control_point(request_id, sender, &address, handle); + + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("Enabling TDS CCCD failed result [%d]", result); + g_array_append_vals(*out_param1, &address, + sizeof(bluetooth_device_address_t)); + } + if (handle) + g_free(handle); + break; + } + case BT_TDS_ACTIVATE_CONTROL_POINT: { + char *handle; + char *data = NULL; + guint data_len = 0; + bluetooth_control_point_data_t tds_data; + char *sender = NULL; + + sender = (char *)g_dbus_method_invocation_get_sender(context); + + bluetooth_device_address_t address = { {0} }; + + data_len = g_variant_get_size(in_param1); + data = (char *)g_variant_get_data(in_param1); + + __bt_service_get_parameters(in_param2, + &address, sizeof(bluetooth_device_address_t)); + + __bt_service_get_parameters(in_param3, + &tds_data, sizeof(bluetooth_control_point_data_t)); + + handle = g_strndup(data, data_len); + BT_DBG("TDS Activate Control point handle [%s]", handle); + + result = _bt_tds_activate_control_point(request_id, sender, &address, handle, + tds_data.data, tds_data.length); + + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("Activating TDS Control Point request failed result [%d]", result); + g_array_append_vals(*out_param1, &address, + sizeof(bluetooth_device_address_t)); + } + if (handle) + g_free(handle); + break; + } default: result = BLUETOOTH_ERROR_INTERNAL; break; @@ -2257,6 +2428,117 @@ int __bt_obexd_request(int function_name, break; } + + case BT_MAP_CREATE_SESSION: { + BT_DBG("BT_MAP_CREATE_SESSION"); + char *address = (char *)g_variant_get_data(in_param1); + char *session_id = NULL; + result = _bt_create_session_sync(address, &session_id); + if (result == BLUETOOTH_ERROR_NONE) + g_array_append_vals(*out_param1, session_id, strlen(session_id)+1); + break; + } + + case BT_MAP_DESTROY_SESSION: { + BT_DBG("BT_MAP_DESTROY_SESSION"); + char* session_id = (char *)g_variant_get_data(in_param1); + result = _bt_destroy_session_sync(session_id); + if (result == BLUETOOTH_ERROR_NONE) + BT_DBG("successfully destroyed session"); + break; + } + + case BT_MAP_SET_FOLDER: { + BT_DBG("BT_MAP_SET_FOLDER"); + char *session_id = (char *)g_variant_get_data(in_param1); + char *name = (char *)g_variant_get_data(in_param2); + result = _bt_map_client_set_folder(session_id, name); + break; + } + + case BT_MAP_LIST_FOLDERS: { + BT_DBG("BT_MAP_LIST_FOLDERS"); + + char* session_id = (char *)g_variant_get_data(in_param1); + char* filter_serialized = (char*)g_variant_get_data(in_param2); + + result = _bt_map_client_list_folders(request_id, context, session_id, filter_serialized); + if (result == BLUETOOTH_ERROR_NONE) + BT_DBG("_bt_map_client_list_folders succeed"); + + break; + } + + case BT_MAP_LIST_FILTER_FIELDS: { + BT_DBG("BT_MAP_LIST_FILTER_FIELDS"); + + char* session_id = (char *)g_variant_get_data(in_param1); + + result = _bt_map_client_list_filter_fields(request_id, context, session_id); + if (result == BLUETOOTH_ERROR_NONE) + BT_DBG("_bt_map_client_list_filter_fields succeed"); + + break; + } + + case BT_MAP_LIST_MESSAGES: { + BT_DBG("BT_MAP_LIST_MESSAGES"); + + char* session_id = (char*)g_variant_get_data(in_param1); + char* folder = (char*)g_variant_get_data(in_param2); + char* filter_serialized = (char*)g_variant_get_data(in_param3); + + result = _bt_map_client_list_messages(request_id, context, session_id, folder, filter_serialized); + if (result == BLUETOOTH_ERROR_NONE) + BT_DBG("_bt_map_client_list_messages succeed"); + else + BT_DBG("_bt_map_client_list_messages failed"); + + break; + } + + case BT_MAP_UPDATE_INBOX: { + BT_DBG("BT_MAP_UPDATE_INBOX"); + char* session_id = (char *)g_variant_get_data(in_param1); + result = _bt_map_client_update_inbox(session_id); + break; + } + + case BT_MAP_PUSH_MESSAGE: { + BT_DBG("BT_MAP_PUSH_MESSAGE"); + + char* session_id = (char *)g_variant_get_data(in_param1); + char* source_file = (char *)g_variant_get_data(in_param2); + char* folder = (char *)g_variant_get_data(in_param3); + char* args_serialized = (char *)g_variant_get_data(in_param4); + + result = _bt_map_client_push_message( + request_id, context, session_id, source_file, folder, args_serialized); + if (result == BLUETOOTH_ERROR_NONE) + BT_DBG("_bt_map_client_push_message succeed"); + else + BT_ERR("_bt_map_client_push_message failed"); + + break; + } + + case BT_MAP_GET_MESSAGE: { + BT_DBG("BT_MAP_GET_MESSAGE"); + // TODO session currently is not used, but should be valid + //char* session_id = (char *)g_variant_get_data(in_param1); + char* message_object = (char *)g_variant_get_data(in_param2); + char* target_file = (char *)g_variant_get_data(in_param3); + bool attachment = false; + __bt_service_get_parameters(in_param4, &attachment, sizeof(bool)); + + result = _bt_map_client_get_message(request_id, context, message_object, + target_file, attachment); + if (result == BLUETOOTH_ERROR_NONE) + BT_DBG("_bt_map_client_get_message succeed"); + + break; + } + case BT_OBEX_SERVER_ALLOCATE: { int app_pid; gboolean is_native; @@ -2697,6 +2979,7 @@ gboolean __bt_service_check_privilege(int function_name, case BT_OPP_PUSH_FILES: case BT_OPP_CANCEL_PUSH: + /* TODO: MAP? MAP functions, see above */ case BT_OBEX_SERVER_ACCEPT_CONNECTION: case BT_OBEX_SERVER_REJECT_CONNECTION: @@ -2801,6 +3084,7 @@ gboolean __bt_service_check_privilege(int function_name, case BT_GATT_REGISTER_APPLICATION: case BT_GATT_REGISTER_SERVICE: case BT_GATT_SEND_RESPONSE: + case BT_PBAP_CONNECT: case BT_PBAP_DISCONNECT: case BT_PBAP_GET_PHONEBOOK_SIZE: @@ -2857,7 +3141,11 @@ gboolean __bt_service_check_privilege(int function_name, case BT_SET_CONTENT_PROTECT: case BT_BOND_DEVICE_BY_TYPE: case BT_SET_LE_PRIVACY: + case BT_SET_LE_STATIC_RANDOM_ADDRESS: case BT_LE_CONN_UPDATE: + case BT_UPDATE_LE_CONNECTION_MODE: + case BT_REQ_ATT_MTU: + case BT_GET_DEVICE_IDA: case BT_LE_READ_MAXIMUM_DATA_LENGTH: case BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH: case BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH: @@ -2875,6 +3163,29 @@ gboolean __bt_service_check_privilege(int function_name, case BT_PXP_REPORTER_REGISTER: case BT_PXP_REPORTER_UNREGISTER: case BT_PXP_REPORTER_GET_PROPERTY: + + /* TDS */ + case BT_TDS_PROVIDER_REGISTER: + case BT_TDS_PROVIDER_UNREGISTER: + case BT_TDS_PROVIDER_SET_MANUF_DATA: + case BT_TDS_PROVIDER_CREATE: + case BT_TDS_PROVIDER_DESTROY: + case BT_TDS_PROVIDER_SET_TRANSPORT_DATA: + case BT_TDS_SEND_ACTIVATION_RESPONSE: + case BT_TDS_READ_TRANSPORT_DATA: + case BT_TDS_ENABLE_CONTROL_POINT: + case BT_TDS_ACTIVATE_CONTROL_POINT: + + case BT_MAP_CREATE_SESSION: + case BT_MAP_DESTROY_SESSION: + case BT_MAP_SET_FOLDER: + case BT_MAP_LIST_FOLDERS: + case BT_MAP_LIST_FILTER_FIELDS: + case BT_MAP_LIST_MESSAGES: + case BT_MAP_UPDATE_INBOX: + case BT_MAP_PUSH_MESSAGE: + case BT_MAP_GET_MESSAGE: + ret_val = cynara_check(p_cynara, client_creds, client_session, user_creds, BT_PRIVILEGE_PLATFORM); @@ -2897,9 +3208,13 @@ gboolean __bt_service_check_privilege(int function_name, case BT_IS_LE_DISCOVERYING: case BT_IS_CONNECTABLE: case BT_GET_BONDED_DEVICES: + case BT_GET_PROFILE_CONNECTED_DEVICES: case BT_GET_BONDED_DEVICE: case BT_GET_IS_ALIAS_SET: case BT_IS_DEVICE_CONNECTED: + case BT_GET_CONNECTED_LINK_TYPE: + case BT_SET_PROFILE_TRUSTED: + case BT_GET_PROFILE_TRUSTED: case BT_GET_SPEAKER_GAIN: case BT_SET_SPEAKER_GAIN: case BT_OOB_READ_LOCAL_DATA: @@ -2909,9 +3224,15 @@ gboolean __bt_service_check_privilege(int function_name, case BT_GET_SCAN_RESPONSE_DATA: case BT_IS_ADVERTISING: case BT_GET_PROFILE_RESTRICTED: + case BT_REGISTER_SCAN_FILTER: + case BT_UNREGISTER_SCAN_FILTER: + case BT_UNREGISTER_ALL_SCAN_FILTERS: + case BT_IS_SCAN_FILTER_SUPPORTED: case BT_OBEX_SERVER_ALLOCATE: case BT_OBEX_SERVER_DEALLOCATE: + case BT_OBEX_SERVER_IS_ACTIVATED: + case BT_OPP_GET_TRANSFER_PROGRESS: /* Non-privilege control */ break; default: diff --git a/bt-service/bt-service-adapter-le.c b/bt-service/bt-service-adapter-le.c index 2afe345..29ab7f9 100644 --- a/bt-service/bt-service-adapter-le.c +++ b/bt-service/bt-service-adapter-le.c @@ -80,83 +80,7 @@ static gboolean is_le_scanning = FALSE; static gboolean scan_filter_enabled = FALSE; static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN; -static GSList *gatt_client_senders = NULL; - - -gboolean _bt_is_set_scan_parameter(void) -{ - return is_le_set_scan_parameter; -} - -void _bt_init_gatt_client_senders(void) -{ - _bt_clear_request_list(); -} - -int _bt_insert_gatt_client_sender(char *sender) -{ - char *info; - - retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM); - - info = g_strdup(sender); - retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION); - - gatt_client_senders = g_slist_append(gatt_client_senders, info); - - BT_DBG("insert sender: %s", sender); - - return BLUETOOTH_ERROR_NONE; -} - -int _bt_delete_gatt_client_sender(char *sender) -{ - GSList *l; - char *info; - - BT_DBG("remove sender: %s", sender); - - for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) { - info = l->data; - if (info == NULL) - continue; - - if (g_strcmp0(info, sender) == 0) { - BT_DBG("remove info"); - gatt_client_senders = g_slist_remove(gatt_client_senders, info); - g_free(info); - return BLUETOOTH_ERROR_NONE; - } - } - - return BLUETOOTH_ERROR_NOT_FOUND; -} - -void _bt_clear_gatt_client_senders(void) -{ - if (gatt_client_senders) { - g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL); - g_slist_free(gatt_client_senders); - gatt_client_senders = NULL; - } -} - -static void __bt_send_foreach_event(gpointer data, gpointer user_data) -{ - char *sender = data; - GVariant *param = user_data; - - _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, - param); -} - -void _bt_send_char_value_changed_event(void *param) -{ - g_slist_foreach(gatt_client_senders, __bt_send_foreach_event, - (gpointer)param); -} - -void __bt_free_le_adv_slot(void) +static void __bt_free_le_adv_slot(void) { int i; @@ -267,6 +191,9 @@ int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id) { + if (le_adv_slot == NULL) + return; + if (le_adv_slot[slot_id].sender == NULL) { le_adv_slot[slot_id].sender = strdup(sender); le_adv_slot[slot_id].adv_handle = adv_handle; @@ -275,6 +202,9 @@ static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int void _bt_unregister_adv_slot_owner(int slot_id) { + if (le_adv_slot == NULL) + return; + g_free(le_adv_slot[slot_id].sender); le_adv_slot[slot_id].sender = NULL; le_adv_slot[slot_id].adv_handle = 0; @@ -298,6 +228,9 @@ int _bt_get_adv_slot_adv_handle(int slot_id) void _bt_set_advertising_status(int slot_id, gboolean mode) { + if (le_adv_slot == NULL) + return; + le_adv_slot[slot_id].is_advertising = mode; } @@ -314,6 +247,11 @@ gboolean _bt_is_advertising(void) return status; } +gboolean _bt_is_multi_adv_supported(void) +{ + return (le_feature_info.adv_inst_max > 1) ? TRUE : FALSE; +} + void _bt_stop_advertising_by_terminated_process(const char* terminated_name) { int i; @@ -1921,12 +1859,8 @@ void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info, scan_data_len, scan_data_param); -#if 0 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param); -#else - _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param); -#endif } } diff --git a/bt-service/bt-service-adapter.c b/bt-service/bt-service-adapter.c index 7efb4f6..99ea837 100644 --- a/bt-service/bt-service-adapter.c +++ b/bt-service/bt-service-adapter.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include #include @@ -39,6 +37,7 @@ #include "bt-service-network.h" #include "bt-service-obex-server.h" #include "bt-service-opp-client.h" +#include "bt-service-map-client.h" #include "bt-service-agent.h" #include "bt-service-main.h" #include "bt-service-avrcp.h" @@ -223,7 +222,7 @@ int __bt_set_visible_time(int timeout) if (!TIZEN_PROFILE_WEARABLE) { #ifdef TIZEN_FEATURE_BT_DPM _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state); - if(discoverable_state != DPM_RESTRICTED) { + if (discoverable_state != DPM_RESTRICTED) { #endif if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0) BT_ERR("Set vconf failed"); @@ -867,6 +866,17 @@ void _bt_handle_adapter_removed(void) if (0 != ret) ERR("vconf_ignore_key_changed failed\n"); +/* unregister all the services/servers/profiles registered on bluez-adapter + once adapter is removed, reinitializing of the state-varaibles becomes + a problem */ + if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE) + BT_ERR("Fail to unregister obex server"); + + if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE) + BT_ERR("Fail to unregister media player"); + +/* Other unregister APIs should be placed here */ + if (!TIZEN_FEATURE_BT_USB_DONGLE) { _bt_destroy_agent(adapter_agent); adapter_agent = NULL; @@ -1067,8 +1077,7 @@ int _bt_enable_adapter(void) _bt_adapter_set_status(BT_ACTIVATING); -if (TIZEN_PROFILE_TV) -{ +if (TIZEN_PROFILE_TV) { int adapter_status = BT_ADAPTER_DISABLED; if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0) @@ -1318,7 +1327,16 @@ int _bt_disable_adapter(void) g_source_remove(timer_id); timer_id = 0; } +/* unregister all the services/servers/profiles registered on bluez-adapter + once adapter is removed, reinitializing of the state-varaibles becomes + a problem */ + if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE) + BT_ERR("Fail to unregister obex server"); + + if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE) + BT_ERR("Fail to unregister media player"); +/* Other unregister APIs should be placed here */ __bt_disconnect_all(); ret = _bt_disable_cb(); diff --git a/bt-service/bt-service-agent.c b/bt-service/bt-service-agent.c index 05957d1..3224d32 100644 --- a/bt-service/bt-service-agent.c +++ b/bt-service/bt-service-agent.c @@ -711,6 +711,7 @@ fail: goto done; } + /* TODO: MAP? see above */ if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER, (char *)uuid) == TRUE) { @@ -734,6 +735,7 @@ fail: request_type = BT_AGENT_EVENT_PBAP_REQUEST; else if (!strcasecmp(uuid, MAP_UUID)) request_type = BT_AGENT_EVENT_MAP_REQUEST; + /* TODO: MAP is already here */ if (trust) { BT_INFO("Trusted device, so authorize\n"); diff --git a/bt-service/bt-service-audio.c b/bt-service/bt-service-audio.c index 524a5d2..0bbb8c9 100644 --- a/bt-service/bt-service-audio.c +++ b/bt-service/bt-service-audio.c @@ -309,6 +309,41 @@ static void __bt_set_headset_disconnection_type(const char *address) } } +#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT +void _bt_check_already_connected_headset(int type, char *address) +{ + GList *node; + char connected_address[BT_ADDRESS_STRING_SIZE + 1]; + bluetooth_device_address_t device_address; + int device_count = 0; + + if (address != NULL) { + node = g_list_first(g_connected_list); + while (node != NULL) { + bt_connected_headset_data_t *connected_device = node->data; + if ((connected_device->type & type) && + (g_strcmp0(connected_device->device_address, address) != 0)) { + device_count++; + /* Disconnect the earliest(1st) connected headset */ + if (device_count == 1) { + g_strlcpy(connected_address, + connected_device->device_address, + BT_ADDRESS_STRING_SIZE + 1); + BT_DBG("Earliest/First Connected headset %s", + connected_address); + } else if (device_count == MAX_CONNECTED_HEADSET) { + _bt_convert_addr_string_to_type(device_address.addr, + connected_address); + _bt_audio_disconnect(0, type, &device_address, NULL); + return; + } + } + node = g_list_next(node); + } + } +} +#endif + gboolean _bt_is_headset_type_connected(int type, char *address) { GList *node; @@ -374,8 +409,19 @@ static int __bt_is_headset_connected(int type, int req_id, while (node != NULL) { connected_device = node->data; if ((connected_device->type & type)) { +#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT + device_count++; + /* Disconnect the earliest(1st) connected headset */ + if (device_count == 1) + g_strlcpy(connected_address, connected_device->device_address, + BT_ADDRESS_STRING_SIZE + 1); + + if (g_strcmp0(connected_device->device_address, address) == 0) + return BLUETOOTH_ERROR_ALREADY_CONNECT; +#else g_strlcpy(connected_address, connected_device->device_address, BT_ADDRESS_STRING_SIZE + 1); +#endif #ifdef TIZEN_SUPPORT_DUAL_HF is_companion_device = __bt_is_companion_device(connected_address); BT_INFO(" is_companion_device[%d]", is_companion_device); @@ -385,9 +431,16 @@ static int __bt_is_headset_connected(int type, int req_id, break; } #else +#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT + if (device_count == MAX_CONNECTED_HEADSET) { + connected = TRUE; + break; + } +#else connected = TRUE; break; #endif +#endif } node = g_list_next(node); } diff --git a/bt-service/bt-service-avrcp-controller.c b/bt-service/bt-service-avrcp-controller.c index ba406f0..9c87873 100644 --- a/bt-service/bt-service-avrcp-controller.c +++ b/bt-service/bt-service-avrcp-controller.c @@ -496,6 +496,7 @@ static int __bt_avrcp_control_parse_properties( metadata->genre = g_strdup(value_string); } else if (strcasecmp(key, "Duration") == 0) { value_uint = g_variant_get_uint32(value); + BT_DBG("Duration : %d", value_uint); metadata->duration = value_uint; } else if (strcasecmp(key, "NumberOfTracks") == 0) { value_uint = g_variant_get_uint32(value); diff --git a/bt-service/bt-service-common.c b/bt-service/bt-service-common.c index d02e90c..44d7679 100644 --- a/bt-service/bt-service-common.c +++ b/bt-service/bt-service-common.c @@ -35,11 +35,13 @@ #include "bluetooth-api.h" #include "bt-service-common.h" #include "bt-service-agent.h" +#include "bt-internal-types.h" static GDBusConnection *system_conn; static GDBusConnection *session_conn; static GDBusProxy *manager_proxy; static GDBusProxy *adapter_proxy; +static GDBusProxy *ipsp_proxy; static void *net_conn; static GDBusProxy *adapter_properties_proxy; @@ -171,6 +173,32 @@ static GDBusProxy *__bt_init_adapter_proxy(void) return proxy; } +static GDBusProxy *__bt_init_ipsp_proxy(void) +{ + BT_DBG("+"); + + GDBusConnection *g_conn; + GDBusProxy *proxy; + + + g_conn = _bt_gdbus_get_system_gconn(); + retv_if(g_conn == NULL, NULL); + + proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_IPSP_NAME, + "/org/projectx/bt_ipsp", BT_IPSP_INTERFACE, NULL, NULL); + + if (!proxy) { + BT_ERR("Unable to get proxy"); + return NULL; + } + + ipsp_proxy = proxy; + + BT_DBG("-"); + return proxy; +} + static GDBusProxy *__bt_init_adapter_properties_proxy(void) { GDBusConnection *g_conn; @@ -213,6 +241,21 @@ GDBusProxy *_bt_get_manager_proxy(void) return __bt_init_manager_proxy(); } +GDBusProxy *_bt_get_ipsp_proxy(void) +{ + if (ipsp_proxy) { + const char *path = g_dbus_proxy_get_object_path(ipsp_proxy); + if (path == NULL) { + BT_ERR("Already proxy released hence creating new proxy"); + return __bt_init_ipsp_proxy(); + } + + return ipsp_proxy; + } + return __bt_init_ipsp_proxy(); + +} + static void *__bt_init_net_conn(void) { int result; @@ -674,7 +717,182 @@ char *_bt_get_profile_uuid128(bt_profile_type_t profile_type) }; } -char *_bt_convert_error_to_string(int error) +const char *_bt_convert_uuid_to_string(const char *uuid) +{ + if (!uuid) + return NULL; + + int i; + int offset = 0; + int uuid_len = 4; + static struct { + const char *uuid; + const char *specification_name; + } bt_uuid_name[] = { + /* BT Classic Services */ + {"1101", "Serial Port Service"}, + {"1102", "LAN Access Using PPP Service"}, + {"1103", "Dialup Networking Service"}, + {"1104", "IrMCSync Service"}, + {"1105", "OBEX Object Push Service"}, + {"1106", "OBEX File Transfer Service"}, + {"1107", "IrMC Sync Command Service"}, + {"1108", "Headset Service"}, + {"1109", "Cordless Telephony Service"}, + {"110A", "Audio Source Service"}, + {"110B", "Audio Sink Service"}, + {"110C", "AV Remote Control Target Service"}, + {"110D", "Advanced Audio Distribution Profile"}, + {"110E", "AV Remote Control Service"}, + {"110F", "Video Conferencing Service"}, + {"1110", "Intercom Service"}, + {"1111", "Fax Service"}, + {"1112", "Headset Audio Gateway Service"}, + {"1113", "WAP Service"}, + {"1114", "WAP Client Service"}, + {"1115", "PANU Service"}, + {"1116", "NAP Service"}, + {"1117", "GN Service"}, + {"1118", "Direct Printing Service"}, + {"1119", "Reference Printing Service"}, + {"111A", "Basic Imaging Profile"}, + {"111B", "Imaging Responder Service"}, + {"111C", "Imaging Automatic Archive Service"}, + {"111D", "Imaging Reference Objects Service"}, + {"111E", "Handsfree Service"}, + {"111F", "Handsfree Audio Gateway Service"}, + {"1120", "Direct Printing Reference Objects Service"}, + {"1121", "Reflected UI Service"}, + {"1122", "Basic Printing Profile"}, + {"1123", "Printing Status Service"}, + {"1124", "Human Interface Device Service"}, + {"1125", "Hardcopy Cable Replacement Profile"}, + {"1126", "HCR Print Service"}, + {"1127", "HCR Scan Service"}, + {"112D", "SIM Access Service"}, + {"112E", "Phonebook Access PCE Service"}, + {"112F", "Phonebook Access PSE Service"}, + {"1130", "Phonebook Access Profile"}, + {"1132", "Message Access Server Service"}, + {"1133", "Message Notification Server Service"}, + {"1134", "Message Access Profile"}, + {"1200", "PnP Information Service"}, + {"1201", "Generic Networking Service"}, + {"1202", "Generic File Transfer Service"}, + {"1203", "Generic Audio Service"}, + {"1204", "Generic Telephony Service"}, + {"1205", "UPnP Service"}, + {"1206", "UPnP Ip Service"}, + {"1303", "Video Source Service"}, + {"1304", "Video Sink Service"}, + {"1305", "Video Distribution Profile"}, + {"1400", "Health Device Profile"}, + {"1401", "HDP Source Service"}, + {"1402", "HDP Sink Service"}, + + /* GATT Services */ + {"1800", "Generic Access"}, + {"1801", "Generic Attribute"}, + {"1802", "Immediate Alert"}, + {"1803", "Link Loss"}, + {"1804", "Tx Power"}, + {"1805", "Current Time Service"}, + {"1806", "Reference Time Update Service"}, + {"1807", "Next DST Change Service"}, + {"1808", "Glucose"}, + {"1809", "Health Thermometer"}, + {"180A", "Device Information"}, + {"180D", "Heart Rate"}, + {"180F", "Battery Service"}, + {"1810", "Blood Pressure"}, + {"1811", "Alert Notification Service"}, + {"1812", "Human Interface Device"}, + + /* GATT Declarations */ + {"2800", "Primary Service Declaration"}, + {"2801", "Secondary Service Declaration"}, + {"2802", "Include Declaration"}, + {"2803", "Characteristic Declaration"}, + + /* GATT Descriptors */ + {"2900", "Characteristic Extended Properties"}, + {"2901", "Characteristic User Description"}, + {"2902", "Client Characteristic Configuration"}, + {"2903", "Server Characteristic Configuration"}, + {"2904", "Characteristic Format"}, + {"2905", "Characteristic Aggregate Formate"}, + {"2906", "Valid Range"}, + {"2907", "External Report Reference"}, + {"2908", "Report Reference"}, + + /* GATT Characteristics */ + {"2A00", "Device Name"}, + {"2A01", "Appearance"}, + {"2A02", "Peripheral Privacy Flag"}, + {"2A03", "Reconnection Address"}, + {"2A04", "Peripheral Preferred Connection Parameters"}, + {"2A05", "Service Changed"}, + {"2A06", "Alert Level"}, + {"2A07", "Tx Power Level"}, + {"2A08", "Date Time"}, + {"2A09", "Day of Week"}, + {"2A0A", "Day Date Time"}, + {"2A19", "Battery Level"}, + {"2A1E", "Intermediate Temperature"}, + {"2A23", "System ID"}, + {"2A24", "Model Number String"}, + {"2A25", "Serial Number String"}, + {"2A26", "Firmware Revision String"}, + {"2A27", "Hardware Revision String"}, + {"2A28", "Software Revision String"}, + {"2A29", "Manufacturer Name String"}, + {"2A2A", "IEEE 11073-20601 Regulatory Certification Data List"}, + {"2A2B", "Current Time"}, + {"2A37", "Heart Rate Measurement"}, + {"2A38", "Body Sensor Location"}, + {"2A3F", "Alert Status"}, + {"2A46", "New Alert"}, + {"2A4A", "HID Information"}, + {"2A4C", "HID Control Point"}, + {"2A50", "PnP ID"}, + + /* Custom uuids */ + {"7905F431-B5CE-4E99-A40F-4B1E122D00D0", "Apple Notification Center Service"}, + {"9FBF120D-6301-42D9-8C58-25E699A21DBD", "Notifications Source"}, + {"69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9", "Control Point"}, + {"22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB", "Data Source"}, + {"89D3502B-0F36-433A-8EF4-C502AD55F8DC", "Apple Media Service"}, + {"9B3C81D8-57B1-4A8A-B8DF-0E56F7CA51C2", "Remote Command"}, + {"2F7CABCE-808D-411F-9A0C-BB92BA96C102", "Entity Update"}, + {"C6B2F38C-23AB-46D8-A6AB-A3A870BBD5D7", "Entity Attribute"}, + {"9A3F68E0-86CE-11E5-A309-0002A5D5C51B", "Samsung Gear Manager Service"}, + {"c2f2cc0f-c085-4dd4-be5a-aca3074bbc72", "Control Point"}, + {"cece518b-28d7-4171-92d5-76a1e249a3b9", "Notifications Source"}, + {"32D1955A-E5AA-4A96-9A49-08538DA8B8F6", "Samsung Gear Fit Manager Service"}, + {"FE53FF98-B259-4337-B56A-0EC9F82C6BAD", "Control Point"}, + {"C2051EE0-804D-4D50-A12C-15E243852100", "Notifications Source"}, + {NULL, NULL} + }; + + if (strlen(uuid) == 36) { + if (!g_ascii_strncasecmp(uuid + 9, "0000-1000-8000-00805F9B34FB", 27)) + offset = 4; + else { + offset = 0; + uuid_len = 36; + } + } else if (strlen(uuid) >= 8) + offset = 4; + + for (i = 0; bt_uuid_name[i].uuid; i++) { + if (!g_ascii_strncasecmp(uuid + offset, bt_uuid_name[i].uuid, uuid_len)) + return (char *)bt_uuid_name[i].specification_name; + } + + return "Unknown"; +} + +const char *_bt_convert_error_to_string(int error) { switch (error) { case BLUETOOTH_ERROR_CANCEL: @@ -757,7 +975,7 @@ char *_bt_convert_error_to_string(int error) } } -char * _bt_convert_disc_reason_to_string(int reason) +const char *_bt_convert_disc_reason_to_string(int reason) { switch (reason) { case (int)BLUETOOTH_ERROR_PAGE_TIMEOUT: @@ -778,6 +996,14 @@ char * _bt_convert_disc_reason_to_string(int reason) return "Repeated attempts"; case (int)BLUETOOTH_ERROR_LMP_RESPONSE_TIMEOUT: return "LMP response timeout"; + case (int)BLUETOOTH_ERROR_LMP_TRANSACTION_COLLISION: + return "LMP transaction collision"; + case (int)BLUETOOTH_ERROR_INSTANT_PASSED: + return "Instant passed"; + case (int)BLUETOOTH_ERROR_INSUFFICIENT_SECURITY: + return "Insufficient security"; + case (int)BLUETOOTH_ERROR_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE: + return "Connection terminated due to MIC failure"; case (int)BLUETOOTH_ERROR_CONNECTION_FAILED_TO_BE_ESTABLISHED: return "Connection failed to be established"; default: @@ -785,6 +1011,267 @@ char * _bt_convert_disc_reason_to_string(int reason) } } +const char *_bt_convert_service_function_to_string(int function) +{ + int i; + + typedef struct { + int function; + const char *function_name; + } bt_function_name_t; + + const bt_function_name_t bt_functions[] = { + {BT_CHECK_ADAPTER, "BT_CHECK_ADAPTER"}, + {BT_ENABLE_ADAPTER, "BT_ENABLE_ADAPTER"}, + {BT_DISABLE_ADAPTER, "BT_DISABLE_ADAPTER"}, + {BT_RECOVER_ADAPTER, "BT_RECOVER_ADAPTER"}, + {BT_SET_DISCOVERABLE_TIME, "BT_SET_DISCOVERABLE_TIME"}, + {BT_GET_DISCOVERABLE_TIME, "BT_GET_DISCOVERABLE_TIME"}, + {BT_IGNORE_AUTO_PAIRING, "BT_IGNORE_AUTO_PAIRING"}, + {BT_GET_LOCAL_ADDRESS, "BT_GET_LOCAL_ADDRESS"}, + {BT_GET_LOCAL_VERSION, "BT_GET_LOCAL_VERSION"}, + {BT_GET_LOCAL_NAME, "BT_GET_LOCAL_NAME"}, + {BT_SET_LOCAL_NAME, "BT_SET_LOCAL_NAME"}, + {BT_IS_SERVICE_USED, "BT_IS_SERVICE_USED"}, + {BT_GET_DISCOVERABLE_MODE, "BT_GET_DISCOVERABLE_MODE"}, + {BT_SET_DISCOVERABLE_MODE, "BT_SET_DISCOVERABLE_MODE"}, + {BT_START_DISCOVERY, "BT_START_DISCOVERY"}, + {BT_START_CUSTOM_DISCOVERY, "BT_START_CUSTOM_DISCOVERY"}, + {BT_CANCEL_DISCOVERY, "BT_CANCEL_DISCOVERY"}, + {BT_START_LE_DISCOVERY, "BT_START_LE_DISCOVERY"}, + {BT_STOP_LE_DISCOVERY, "BT_STOP_LE_DISCOVERY"}, + {BT_IS_DISCOVERYING, "BT_IS_DISCOVERYING"}, + {BT_IS_LE_DISCOVERYING, "BT_IS_LE_DISCOVERYING"}, + {BT_ENABLE_RSSI, "BT_ENABLE_RSSI"}, + {BT_GET_RSSI, "BT_GET_RSSI"}, + {BT_IS_CONNECTABLE, "BT_IS_CONNECTABLE"}, + {BT_SET_CONNECTABLE, "BT_SET_CONNECTABLE"}, + {BT_GET_BONDED_DEVICES, "BT_GET_BONDED_DEVICES"}, + {BT_RESET_ADAPTER, "BT_RESET_ADAPTER"}, + {BT_SET_ADVERTISING, "BT_SET_ADVERTISING"}, + {BT_SET_CUSTOM_ADVERTISING, "BT_SET_CUSTOM_ADVERTISING"}, + {BT_SET_ADVERTISING_PARAMETERS, "BT_SET_ADVERTISING_PARAMETERS"}, + {BT_GET_ADVERTISING_DATA, "BT_GET_ADVERTISING_DATA"}, + {BT_SET_ADVERTISING_DATA, "BT_SET_ADVERTISING_DATA"}, + {BT_SET_SCAN_PARAMETERS, "BT_SET_SCAN_PARAMETERS"}, + {BT_GET_SCAN_RESPONSE_DATA, "BT_GET_SCAN_RESPONSE_DATA"}, + {BT_SET_SCAN_RESPONSE_DATA, "BT_SET_SCAN_RESPONSE_DATA"}, + {BT_IS_ADVERTISING, "BT_IS_ADVERTISING"}, + {BT_SET_MANUFACTURER_DATA, "BT_SET_MANUFACTURER_DATA"}, + {BT_LE_CONN_UPDATE, "BT_LE_CONN_UPDATE"}, + {BT_LE_READ_MAXIMUM_DATA_LENGTH, "BT_LE_READ_MAXIMUM_DATA_LENGTH"}, + {BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, "BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH"}, + {BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH, "BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH"}, + {BT_LE_SET_DATA_LENGTH, "BT_LE_SET_DATA_LENGTH"}, + {BT_ADD_WHITE_LIST, "BT_ADD_WHITE_LIST"}, + {BT_REMOVE_WHITE_LIST, "BT_REMOVE_WHITE_LIST"}, + {BT_CLEAR_WHITE_LIST, "BT_CLEAR_WHITE_LIST"}, + {BT_REGISTER_SCAN_FILTER, "BT_REGISTER_SCAN_FILTER"}, + {BT_UNREGISTER_SCAN_FILTER, "BT_UNREGISTER_SCAN_FILTER"}, + {BT_UNREGISTER_ALL_SCAN_FILTERS, "BT_UNREGISTER_ALL_SCAN_FILTERS"}, + {BT_IS_SCAN_FILTER_SUPPORTED, "BT_IS_SCAN_FILTER_SUPPORTED"}, + {BT_GET_PROFILE_CONNECTED_DEVICES, "BT_GET_PROFILE_CONNECTED_DEVICES"}, + {BT_ENABLE_FORCE_HCI_DUMP, "BT_ENABLE_FORCE_HCI_DUMP"}, + {BT_SET_PASSKEY_NOTIFICATION, "BT_SET_PASSKEY_NOTIFICATION"}, + {BT_BOND_DEVICE, "BT_BOND_DEVICE"}, + {BT_BOND_DEVICE_BY_TYPE, "BT_BOND_DEVICE_BY_TYPE"}, + {BT_CANCEL_BONDING, "BT_CANCEL_BONDING"}, + {BT_PASSKEY_REPLY, "BT_PASSKEY_REPLY"}, + {BT_PASSKEY_CONFIRMATION_REPLY, "BT_PASSKEY_CONFIRMATION_REPLY"}, + {BT_UNBOND_DEVICE, "BT_UNBOND_DEVICE"}, + {BT_SEARCH_SERVICE, "BT_SEARCH_SERVICE"}, + {BT_CANCEL_SEARCH_SERVICE, "BT_CANCEL_SEARCH_SERVICE"}, + {BT_GET_BONDED_DEVICE, "BT_GET_BONDED_DEVICE"}, + {BT_GET_IS_ALIAS_SET, "BT_GET_IS_ALIAS_SET"}, + {BT_SET_ALIAS, "BT_SET_ALIAS"}, + {BT_SET_AUTHORIZATION, "BT_SET_AUTHORIZATION"}, + {BT_UNSET_AUTHORIZATION, "BT_UNSET_AUTHORIZATION"}, + {BT_IS_DEVICE_CONNECTED, "BT_IS_DEVICE_CONNECTED"}, + {BT_GET_CONNECTED_LINK_TYPE, "BT_GET_CONNECTED_LINK_TYPE"}, + {BT_SET_PIN_CODE, "BT_SET_PIN_CODE"}, + {BT_UNSET_PIN_CODE, "BT_UNSET_PIN_CODE"}, + {BT_UPDATE_LE_CONNECTION_MODE, "BT_UPDATE_LE_CONNECTION_MODE"}, + {BT_SET_PROFILE_TRUSTED, "BT_SET_PROFILE_TRUSTED"}, + {BT_GET_PROFILE_TRUSTED, "BT_GET_PROFILE_TRUSTED"}, + {BT_SET_PROFILE_RESTRICTED, "BT_SET_PROFILE_RESTRICTED"}, + {BT_GET_PROFILE_RESTRICTED, "BT_GET_PROFILE_RESTRICTED"}, + {BT_HID_CONNECT, "BT_HID_CONNECT"}, + {BT_HID_DISCONNECT, "BT_HID_DISCONNECT"}, + {BT_HID_DEVICE_ACTIVATE, "BT_HID_DEVICE_ACTIVATE"}, + {BT_HID_DEVICE_DEACTIVATE, "BT_HID_DEVICE_DEACTIVATE"}, + {BT_HID_DEVICE_CONNECT, "BT_HID_DEVICE_CONNECT"}, + {BT_HID_DEVICE_DISCONNECT, "BT_HID_DEVICE_DISCONNECT"}, + {BT_HID_DEVICE_SEND_MOUSE_EVENT, "BT_HID_DEVICE_SEND_MOUSE_EVENT"}, + {BT_HID_DEVICE_SEND_KEY_EVENT, "BT_HID_DEVICE_SEND_KEY_EVENT"}, + {BT_HID_DEVICE_SEND_CUSTOM_EVENT, "BT_HID_DEVICE_SEND_CUSTOM_EVENT"}, + {BT_HID_DEVICE_SEND_REPLY_TO_REPORT, "BT_HID_DEVICE_SEND_REPLY_TO_REPORT"}, + {BT_HID_ENABLE_BARCODE_FEATURE, "BT_HID_ENABLE_BARCODE_FEATURE"}, + {BT_NETWORK_ACTIVATE, "BT_NETWORK_ACTIVATE"}, + {BT_NETWORK_DEACTIVATE, "BT_NETWORK_DEACTIVATE"}, + {BT_NETWORK_CONNECT, "BT_NETWORK_CONNECT"}, + {BT_NETWORK_DISCONNECT, "BT_NETWORK_DISCONNECT"}, + {BT_NETWORK_SERVER_DISCONNECT, "BT_NETWORK_SERVER_DISCONNECT"}, + {BT_AUDIO_CONNECT, "BT_AUDIO_CONNECT"}, + {BT_AUDIO_DISCONNECT, "BT_AUDIO_DISCONNECT"}, + {BT_AG_CONNECT, "BT_AG_CONNECT"}, + {BT_AG_DISCONNECT, "BT_AG_DISCONNECT"}, + {BT_AV_CONNECT, "BT_AV_CONNECT"}, + {BT_AV_DISCONNECT, "BT_AV_DISCONNECT"}, + {BT_AV_SOURCE_CONNECT, "BT_AV_SOURCE_CONNECT"}, + {BT_AV_SOURCE_DISCONNECT, "BT_AV_SOURCE_DISCONNECT"}, + {BT_HF_CONNECT, "BT_HF_CONNECT"}, + {BT_HF_DISCONNECT, "BT_HF_DISCONNECT"}, + {BT_GET_SPEAKER_GAIN, "BT_GET_SPEAKER_GAIN"}, + {BT_SET_SPEAKER_GAIN, "BT_SET_SPEAKER_GAIN"}, + {BT_SET_CONTENT_PROTECT, "BT_SET_CONTENT_PROTECT"}, + {BT_OOB_READ_LOCAL_DATA, "BT_OOB_READ_LOCAL_DATA"}, + {BT_OOB_ADD_REMOTE_DATA, "BT_OOB_ADD_REMOTE_DATA"}, + {BT_OOB_REMOVE_REMOTE_DATA, "BT_OOB_REMOVE_REMOTE_DATA"}, + {BT_AVRCP_SET_TRACK_INFO, "BT_AVRCP_SET_TRACK_INFO"}, + {BT_AVRCP_SET_PROPERTY, "BT_AVRCP_SET_PROPERTY"}, + {BT_AVRCP_SET_PROPERTIES, "BT_AVRCP_SET_PROPERTIES"}, + {BT_AVRCP_CONTROL_CONNECT, "BT_AVRCP_CONTROL_CONNECT"}, + {BT_AVRCP_CONTROL_DISCONNECT, "BT_AVRCP_CONTROL_DISCONNECT"}, + {BT_AVRCP_TARGET_CONNECT, "BT_AVRCP_TARGET_CONNECT"}, + {BT_AVRCP_TARGET_DISCONNECT, "BT_AVRCP_TARGET_DISCONNECT"}, + {BT_AVRCP_HANDLE_CONTROL, "BT_AVRCP_HANDLE_CONTROL"}, + {BT_AVRCP_CONTROL_SET_PROPERTY, "BT_AVRCP_CONTROL_SET_PROPERTY"}, + {BT_AVRCP_CONTROL_GET_PROPERTY, "BT_AVRCP_CONTROL_GET_PROPERTY"}, + {BT_AVRCP_GET_TRACK_INFO, "BT_AVRCP_GET_TRACK_INFO"}, + {BT_OPP_PUSH_FILES, "BT_OPP_PUSH_FILES"}, + {BT_OPP_CANCEL_PUSH, "BT_OBT_OPP_IS_PUSHING_FILESPP_CANCEL_PUSH"}, + {BT_OPP_IS_PUSHING_FILES, "BT_OPP_IS_PUSHING_FILES"}, + {BT_OPP_GET_TRANSFER_PROGRESS, "BT_OPP_GET_TRANSFER_PROGRESS"}, + {BT_MAP_CREATE_SESSION, "BT_MAP_CREATE_SESSION"}, + {BT_MAP_DESTROY_SESSION, "BT_MAP_DESTROY_SESSION"}, + {BT_MAP_SET_FOLDER, "BT_MAP_SET_FOLDER"}, + {BT_MAP_LIST_FOLDERS, "BT_MAP_LIST_FOLDERS"}, + {BT_MAP_LIST_FILTER_FIELDS, "BT_MAP_LIST_FILTER_FIELDS"}, + {BT_MAP_LIST_MESSAGES, "BT_MAP_LIST_MESSAGES"}, + {BT_MAP_UPDATE_INBOX, "BT_MAP_UPDATE_INBOX"}, + {BT_MAP_PUSH_MESSAGE, "BT_MAP_PUSH_MESSAGE"}, + {BT_MAP_GET_MESSAGE, "BT_MAP_GET_MESSAGE"}, + {BT_OBEX_SERVER_ALLOCATE, "BT_OBEX_SERVER_ALLOCATE"}, + {BT_OBEX_SERVER_DEALLOCATE, "BT_OBEX_SERVER_DEALLOCATE"}, + {BT_OBEX_SERVER_IS_ACTIVATED, "BT_OBEX_SERVER_IS_ACTIVATED"}, + {BT_OBEX_SERVER_ACCEPT_CONNECTION, "BT_OBEX_SERVER_ACCEPT_CONNECTION"}, + {BT_OBEX_SERVER_REJECT_CONNECTION, "BT_OBEX_SERVER_REJECT_CONNECTION"}, + {BT_OBEX_SERVER_ACCEPT_FILE, "BT_OBEX_SERVER_ACCEPT_FILE"}, + {BT_OBEX_SERVER_REJECT_FILE, "BT_OBEX_SERVER_REJECT_FILE"}, + {BT_OBEX_SERVER_SET_PATH, "BT_OBEX_SERVER_SET_PATH"}, + {BT_OBEX_SERVER_SET_ROOT, "BT_OBEX_SERVER_SET_ROOT"}, + {BT_OBEX_SERVER_CANCEL_TRANSFER, "BT_OBEX_SERVER_CANCEL_TRANSFER"}, + {BT_OBEX_SERVER_CANCEL_ALL_TRANSFERS, "BT_OBEX_SERVER_CANCEL_ALL_TRANSFERS"}, + {BT_OBEX_SERVER_IS_RECEIVING, "BT_OBEX_SERVER_IS_RECEIVING"}, + {BT_RFCOMM_CLIENT_CONNECT, "BT_RFCOMM_CLIENT_CONNECT"}, + {BT_RFCOMM_CLIENT_CANCEL_CONNECT, "BT_RFCOMM_CLIENT_CANCEL_CONNECT"}, + {BT_RFCOMM_CLIENT_IS_CONNECTED, "BT_RFCOMM_CLIENT_IS_CONNECTED"}, + {BT_RFCOMM_SOCKET_DISCONNECT, "BT_RFCOMM_SOCKET_DISCONNECT"}, + {BT_RFCOMM_SOCKET_WRITE, "BT_RFCOMM_SOCKET_WRITE"}, + {BT_RFCOMM_CREATE_SOCKET, "BT_RFCOMM_CREATE_SOCKET"}, + {BT_RFCOMM_REMOVE_SOCKET, "BT_RFCOMM_REMOVE_SOCKET"}, + {BT_RFCOMM_LISTEN, "BT_RFCOMM_LISTEN"}, + {BT_RFCOMM_IS_UUID_AVAILABLE, "BT_RFCOMM_IS_UUID_AVAILABLE"}, + {BT_RFCOMM_ACCEPT_CONNECTION, "BT_RFCOMM_ACCEPT_CONNECTION"}, + {BT_RFCOMM_REJECT_CONNECTION, "BT_RFCOMM_REJECT_CONNECTION"}, + {BT_RFCOMM_CREATE_SOCKET_EX, "BT_RFCOMM_CREATE_SOCKET_EX"}, + {BT_RFCOMM_REMOVE_SOCKET_EX, "BT_RFCOMM_REMOVE_SOCKET_EX"}, + {BT_PBAP_CONNECT, "BT_PBAP_CONNECT"}, + {BT_PBAP_DISCONNECT, "BT_PBAP_DISCONNECT"}, + {BT_PBAP_GET_PHONEBOOK_SIZE, "BT_PBAP_GET_PHONEBOOK_SIZE"}, + {BT_PBAP_GET_PHONEBOOK, "BT_PBAP_GET_PHONEBOOK"}, + {BT_PBAP_GET_LIST, "BT_PBAP_GET_LIST"}, + {BT_PBAP_PULL_VCARD, "BT_PBAP_PULL_VCARD"}, + {BT_PBAP_PHONEBOOK_SEARCH, "BT_PBAP_PHONEBOOK_SEARCH"}, + {BT_ENABLE_ADAPTER_LE, "BT_ENABLE_ADAPTER_LE"}, + {BT_DISABLE_ADAPTER_LE, "BT_DISABLE_ADAPTER_LE"}, + {BT_CONNECT_LE, "BT_CONNECT_LE"}, + {BT_DISCONNECT_LE, "BT_DISCONNECT_LE"}, + {BT_SET_LE_PRIVACY, "BT_SET_LE_PRIVACY"}, + {BT_REQ_ATT_MTU, "BT_REQ_ATT_MTU"}, + {BT_GET_ATT_MTU, "BT_GET_ATT_MTU"}, + {BT_GET_DEVICE_IDA, "BT_GET_DEVICE_IDA"}, + {BT_SET_LE_STATIC_RANDOM_ADDRESS, "BT_SET_LE_STATIC_RANDOM_ADDRESS"}, + {BT_HDP_CONNECT, "BT_HDP_CONNECT"}, + {BT_HDP_DISCONNECT, "BT_HDP_DISCONNECT"}, + {BT_HDP_SEND_DATA, "BT_HDP_SEND_DATA"}, + {BT_HDP_REGISTER_SINK_APP, "BT_HDP_REGISTER_SINK_APP"}, + {BT_HDP_UNREGISTER_SINK_APP, "BT_HDP_UNREGISTER_SINK_APP"}, + {BT_GATT_GET_PRIMARY_SERVICES, "BT_GATT_GET_PRIMARY_SERVICES"}, + {BT_GATT_DISCOVER_CHARACTERISTICS, "BT_GATT_DISCOVER_CHARACTERISTICS"}, + {BT_GATT_SET_PROPERTY_REQUEST, "BT_GATT_SET_PROPERTY_REQUEST"}, + {BT_GATT_READ_CHARACTERISTIC, "BT_GATT_READ_CHARACTERISTIC"}, + {BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR, "BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR"}, + {BT_GATT_REGISTER_APPLICATION, "BT_GATT_REGISTER_APPLICATION"}, + {BT_GATT_REGISTER_SERVICE, "BT_GATT_REGISTER_SERVICE"}, + {BT_GATT_SEND_RESPONSE, "BT_GATT_SEND_RESPONSE"}, + {BT_LE_IPSP_INIT, "BT_LE_IPSP_INIT"}, + {BT_LE_IPSP_DEINIT, "BT_LE_IPSP_DEINIT"}, + {BT_LE_IPSP_CONNECT, "BT_LE_IPSP_CONNECT"}, + {BT_LE_IPSP_DISCONNECT, "BT_LE_IPSP_DISCONNECT"}, + {BT_DPM_SET_ALLOW_BT_MODE, "BT_DPM_SET_ALLOW_BT_MODE"}, + {BT_DPM_GET_ALLOW_BT_MODE, "BT_DPM_GET_ALLOW_BT_MODE"}, + {BT_DPM_SET_DEVICE_RESTRITION, "BT_DPM_SET_DEVICE_RESTRITION"}, + {BT_DPM_GET_DEVICE_RESTRITION, "BT_DPM_GET_DEVICE_RESTRITION"}, + {BT_DPM_SET_UUID_RESTRITION, "BT_DPM_SET_UUID_RESTRITION"}, + {BT_DPM_GET_UUID_RESTRITION, "BT_DPM_GET_UUID_RESTRITION"}, + {BT_DPM_ADD_DEVICES_BLACKLIST, "BT_DPM_ADD_DEVICES_BLACKLIST"}, + {BT_DPM_ADD_DEVICES_WHITELIST, "BT_DPM_ADD_DEVICES_WHITELIST"}, + {BT_DPM_ADD_UUIDS_BLACKLIST, "BT_DPM_ADD_UUIDS_BLACKLIST"}, + {BT_DPM_ADD_UUIDS_WHITELIST, "BT_DPM_ADD_UUIDS_WHITELIST"}, + {BT_DPM_CLEAR_DEVICES_BLACKLIST, "BT_DPM_CLEAR_DEVICES_BLACKLIST"}, + {BT_DPM_CLEAR_DEVICES_WHITELIST, "BT_DPM_CLEAR_DEVICES_WHITELIST"}, + {BT_DPM_CLEAR_UUIDS_BLACKLIST, "BT_DPM_CLEAR_UUIDS_BLACKLIST"}, + {BT_DPM_CLEAR_UUIDS_WHITELIST, "BT_DPM_CLEAR_UUIDS_WHITELIST"}, + {BT_DPM_REMOVE_DEVICE_BLACKLIST, "BT_DPM_REMOVE_DEVICE_BLACKLIST"}, + {BT_DPM_REMOVE_DEVICE_WHITELIST, "BT_DPM_REMOVE_DEVICE_WHITELIST"}, + {BT_DPM_REMOVE_UUID_BLACKLIST, "BT_DPM_REMOVE_UUID_BLACKLIST"}, + {BT_DPM_REMOVE_UUID_WHITELIST, "BT_DPM_REMOVE_UUID_WHITELIST"}, + {BT_DPM_GET_DEVICES_BLACKLIST, "BT_DPM_GET_DEVICES_BLACKLIST"}, + {BT_DPM_GET_DEVICES_WHITELIST, "BT_DPM_GET_DEVICES_WHITELIST"}, + {BT_DPM_GET_UUIDS_BLACKLIST, "BT_DPM_GET_UUIDS_BLACKLIST"}, + {BT_DPM_GET_UUIDS_WHITELIST, "BT_DPM_GET_UUIDS_WHITELIST"}, + {BT_DPM_SET_ALLOW_OUTGOING_CALL, "BT_DPM_SET_ALLOW_OUTGOING_CALL"}, + {BT_DPM_GET_ALLOW_OUTGOING_CALL, "BT_DPM_GET_ALLOW_OUTGOING_CALL"}, + {BT_DPM_SET_PAIRING_STATE, "BT_DPM_SET_PAIRING_STATE"}, + {BT_DPM_GET_PAIRING_STATE, "BT_DPM_GET_PAIRING_STATE"}, + {BT_DPM_SET_PROFILE_STATE, "BT_DPM_SET_PROFILE_STATE"}, + {BT_DPM_GET_PROFILE_STATE, "BT_DPM_GET_PROFILE_STATE"}, + {BT_DPM_SET_DESKROP_CONNECTIVITY_STATE, "BT_DPM_SET_DESKROP_CONNECTIVITY_STATE"}, + {BT_DPM_GET_DESKROP_CONNECTIVITY_STATE, "BT_DPM_GET_DESKROP_CONNECTIVITY_STATE"}, + {BT_DPM_SET_DISCOVERABLE_STATE, "BT_DPM_SET_DISCOVERABLE_STATE"}, + {BT_DPM_GET_DISCOVERABLE_STATE, "BT_DPM_GET_DISCOVERABLE_STATE"}, + {BT_DPM_SET_LIMITED_DISCOVERABLE_STATE, "BT_DPM_SET_LIMITED_DISCOVERABLE_STATE"}, + {BT_DPM_GET_LIMITED_DISCOVERABLE_STATE, "BT_DPM_GET_LIMITED_DISCOVERABLE_STATE"}, + {BT_DPM_SET_DATA_TRANSFER_STATE, "BT_DPM_SET_DATA_TRANSFER_STATE"}, + {BT_DPM_GET_DATA_TRANSFER_STATE, "BT_DPM_GET_DATA_TRANSFER_STATE"}, + {BT_PXP_MONITOR_SET_PROPERTY, "BT_PXP_MONITOR_SET_PROPERTY"}, + {BT_PXP_MONITOR_GET_PROPERTY, "BT_PXP_MONITOR_GET_PROPERTY"}, + {BT_PXP_MONITOR_GET_SUPPORTED_SERIVCES, "BT_PXP_MONITOR_GET_SUPPORTED_SERIVCES"}, + {BT_PXP_REPORTER_REGISTER, "BT_PXP_REPORTER_REGISTER"}, + {BT_PXP_REPORTER_UNREGISTER, "BT_PXP_REPORTER_UNREGISTER"}, + {BT_PXP_REPORTER_GET_PROPERTY, "BT_PXP_REPORTER_GET_PROPERTY"}, + {BT_TDS_PROVIDER_REGISTER, "BT_TDS_PROVIDER_REGISTER"}, + {BT_TDS_PROVIDER_UNREGISTER, "BT_TDS_PROVIDER_UNREGISTER"}, + {BT_TDS_PROVIDER_SET_MANUF_DATA, "BT_TDS_PROVIDER_SET_MANUF_DATA"}, + {BT_TDS_PROVIDER_CREATE, "BT_TDS_PROVIDER_CREATE"}, + {BT_TDS_PROVIDER_DESTROY, "BT_TDS_PROVIDER_DESTROY"}, + {BT_TDS_PROVIDER_SET_TRANSPORT_DATA, "BT_TDS_PROVIDER_SET_TRANSPORT_DATA"}, + {BT_TDS_SEND_ACTIVATION_RESPONSE, "BT_TDS_SEND_ACTIVATION_RESPONSE"}, + {BT_TDS_READ_TRANSPORT_DATA, "BT_TDS_READ_TRANSPORT_DATA"}, + {BT_TDS_ENABLE_CONTROL_POINT, "BT_TDS_ENABLE_CONTROL_POINT"}, + {BT_TDS_ACTIVATE_CONTROL_POINT, "BT_TDS_ACTIVATE_CONTROL_POINT"}, + {-1, ""}, + }; + + for (i = 0; bt_functions[i].function != -1; i++) { + if (bt_functions[i].function == function) + return bt_functions[i].function_name; + } + + return NULL; +} + void _bt_logging_connection(gboolean connect, int addr_type) { static int le_conn = 0; diff --git a/bt-service/bt-service-device.c b/bt-service/bt-service-device.c index dcc02a3..f63a5b9 100644 --- a/bt-service/bt-service-device.c +++ b/bt-service/bt-service-device.c @@ -315,8 +315,12 @@ static void __bt_get_uuids(GVariant *value, bt_remote_dev_info_t *info) ret_if(value == NULL); ret_if(info == NULL); - info->uuid_count = g_variant_get_size(value); - info->uuids = g_variant_dup_strv(value, (gsize *)&info->uuid_count); + gsize uuid_count = 0; + + info->uuids = g_variant_dup_strv(value, &uuid_count); + info->uuid_count = (unsigned int)uuid_count; + + BT_DBG("uuid count : %d", uuid_count); } bt_remote_dev_info_t *_bt_get_remote_device_info(char *address) @@ -1631,6 +1635,7 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, { char *object_path = NULL; char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 }; GDBusProxy *device_proxy = NULL; GDBusProxy *adapter_proxy = NULL; GDBusConnection *conn; @@ -1643,8 +1648,12 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM); retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + _bt_convert_addr_type_to_string(address, device_address->addr); + _bt_convert_addr_string_to_secure_string(secure_address, address); + *is_connected = FALSE; - BT_DBG("connection_type: %d", connection_type); + BT_DBG("%s connection_type: 0x%02x", secure_address, connection_type); + if (connection_type == BLUETOOTH_RFCOMM_SERVICE) return _bt_rfcomm_is_device_connected(device_address, is_connected); @@ -1708,15 +1717,18 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, } else { uuid = _bt_get_profile_uuid128(connection_type); if (uuid == NULL) { - BT_ERR("uuid is NULL"); + BT_ERR("connection_type: %d, uuid is NULL", connection_type); return BLUETOOTH_ERROR_INTERNAL; } - - BT_DBG("uuid: %s", uuid); + BT_DBG("uuid %s [%s]", uuid, _bt_convert_uuid_to_string(uuid)); object_path = _bt_get_device_object_path(address); - retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED); - BT_DBG("object_path: %s", object_path); + if (!object_path) { + BT_ERR("object_path is NULL"); + g_free(uuid); + return BLUETOOTH_ERROR_NOT_PAIRED; + } + device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, BT_BLUEZ_NAME, object_path, BT_DEVICE_INTERFACE, NULL, NULL); @@ -1882,6 +1894,7 @@ static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_ad gboolean auto_connect) { char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 }; gchar *device_path = NULL; GDBusProxy *device_proxy = NULL; GDBusConnection *conn; @@ -1916,6 +1929,9 @@ static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_ad goto fail; } + _bt_convert_addr_string_to_secure_string(secure_address, device_address); + BT_INFO("Connect LE [%s]", secure_address); + func_data->req_id = req_id; g_dbus_proxy_call(device_proxy, "ConnectLE", @@ -1930,10 +1946,10 @@ static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_ad fail: if (device_proxy) g_object_unref(device_proxy); - if (func_data) { - g_free(func_data->address); - g_free(func_data); - } + + g_free(func_data->address); + g_free(func_data); + return ret; } @@ -1992,6 +2008,7 @@ int _bt_disconnect_le_device(int req_id, const bluetooth_device_address_t *bd_addr) { char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 }; gchar *device_path; GDBusProxy *device_proxy; GDBusConnection *conn; @@ -2028,6 +2045,9 @@ int _bt_disconnect_le_device(int req_id, goto fail; } + _bt_convert_addr_string_to_secure_string(secure_address, device_address); + BT_INFO("Disconnect LE [%s]", secure_address); + func_data->req_id = req_id; g_dbus_proxy_call(device_proxy, "DisconnectLE", @@ -2041,10 +2061,10 @@ int _bt_disconnect_le_device(int req_id, fail: if (device_proxy) g_object_unref(device_proxy); - if (func_data) { - g_free(func_data->address); - g_free(func_data); - } + + g_free(func_data->address); + g_free(func_data); + return ret; } @@ -2096,9 +2116,18 @@ int _bt_connect_le_ipsp_device(const bluetooth_device_address_t *bd_addr) g_object_unref(device_proxy); return BLUETOOTH_ERROR_INTERNAL; } - g_object_unref(device_proxy); + /* IPSP daemon launch */ + GDBusProxy *ipsp_proxy; + + ipsp_proxy = _bt_get_ipsp_proxy(); + retv_if(ipsp_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + g_dbus_proxy_call(ipsp_proxy, "EnableIpsp", + NULL, G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + return ret; } @@ -3084,7 +3113,7 @@ int _bt_request_att_mtu(int request_id, bluetooth_device_address_t *device_addre NULL, (GAsyncReadyCallback)__bt_request_att_mtu_device_cb, NULL); -fail: + return ret; } diff --git a/bt-service/bt-service-dpm.c b/bt-service/bt-service-dpm.c index 908f12c..685acbb 100644 --- a/bt-service/bt-service-dpm.c +++ b/bt-service/bt-service-dpm.c @@ -32,19 +32,19 @@ #include "bt-service-dpm.h" static dpm_policy_t policy_table[DPM_POLICY_END] = { - [DPM_POLICY_ALLOW_BLUETOOTH] = { {DPM_BT_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_DEVICE_RESTRICTION] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_UUID_RESTRICTION] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_DEVICES_WHITELIST] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_DEVICES_BLACKLIST] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_UUIDS_WHITELIST] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_UUIDS_BLACKLIST] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_ALLOW_BLUETOOTH_OUTGOING_CALL] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_PAIRING_STATE] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_DESKTOP_CONNECTIVITY_STATE] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_DISCOVERABLE_STATE] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_LIMITED_DISCOVERABLE_STATE] = { {DPM_STATUS_ERROR, NULL} }, - [DPM_POLICY_BLUETOOTH_DATA_TRANSFER_STATE] = { {DPM_STATUS_ERROR, NULL} }, + [DPM_POLICY_ALLOW_BLUETOOTH] = { {DPM_BT_ERROR} }, + [DPM_POLICY_BLUETOOTH_DEVICE_RESTRICTION] = { {DPM_STATUS_ERROR} }, + [DPM_POLICY_BLUETOOTH_UUID_RESTRICTION] = { {DPM_STATUS_ERROR} }, + [DPM_POLICY_BLUETOOTH_DEVICES_WHITELIST] = { { } }, + [DPM_POLICY_BLUETOOTH_DEVICES_BLACKLIST] = { { } }, + [DPM_POLICY_BLUETOOTH_UUIDS_WHITELIST] = { { } }, + [DPM_POLICY_BLUETOOTH_UUIDS_BLACKLIST] = { { } }, + [DPM_POLICY_ALLOW_BLUETOOTH_OUTGOING_CALL] = { {DPM_STATUS_ERROR} }, + [DPM_POLICY_BLUETOOTH_PAIRING_STATE] = { {DPM_STATUS_ERROR} }, + [DPM_POLICY_BLUETOOTH_DESKTOP_CONNECTIVITY_STATE] = { {DPM_STATUS_ERROR} }, + [DPM_POLICY_BLUETOOTH_DISCOVERABLE_STATE] = { {DPM_STATUS_ERROR} }, + [DPM_POLICY_BLUETOOTH_LIMITED_DISCOVERABLE_STATE] = { {DPM_STATUS_ERROR} }, + [DPM_POLICY_BLUETOOTH_DATA_TRANSFER_STATE] = { {DPM_STATUS_ERROR} }, }; diff --git a/bt-service/bt-service-event-receiver.c b/bt-service/bt-service-event-receiver.c index e305de5..05e723c 100644 --- a/bt-service/bt-service-event-receiver.c +++ b/bt-service/bt-service-event-receiver.c @@ -42,6 +42,8 @@ #include "bt-service-proximity.h" #include "bt-service-opp-client.h" +#include "bt-service-map-client.h" +#include "bt-service-tds.h" #ifdef TIZEN_FEATURE_BT_DPM #include "bt-service-dpm.h" @@ -51,6 +53,7 @@ static GDBusConnection *manager_conn; static GDBusConnection *obexd_conn; static GDBusConnection *opc_obexd_conn; +static GDBusConnection *map_obexd_conn; static GList *p_cache_list = NULL; @@ -77,17 +80,21 @@ typedef enum { OBEX_PCSUITE = (1 << 6), OBEX_SYNCEVOLUTION = (1 << 7), OBEX_MAS = (1 << 8), + OBEX_MAP = (1 << 9), } bluetooth_obex_connection_type_t; void _bt_handle_property_changed_event(GVariant *msg, const char *object_path); void _bt_opc_property_changed_event(GVariant *msg, char *path); +void _bt_map_property_changed_event(GVariant *msg, const char *path); int _bt_register_service_event(GDBusConnection *g_conn, int event_type); void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type); void _bt_opp_client_event_deinit(void); +void _bt_map_client_event_deinit(void); void _bt_handle_network_client_event(GVariant *msg_iter, const char *path); void __bt_gatt_char_property_changed_event(GVariant *msg_iter, const char *path); +void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error); static void __bt_free_bt_le_adv_info_t(gpointer data) { @@ -540,8 +547,15 @@ void _bt_handle_adapter_event(GVariant *msg, const char *member) event, param); - if (event == BLUETOOTH_EVENT_ADVERTISING_STOPPED) + if (event == BLUETOOTH_EVENT_ADVERTISING_STOPPED) { + char *name = g_strdup(sender); + _bt_unregister_adv_slot_owner(slot_id); + + /* Advertising disabled, notify TDS */ + _bt_tds_handle_adv_disabled(name, adv_handle); + g_free(name); + } } else if (strcasecmp(member, "RssiEnabled") == 0) { BT_DBG("RSSI Enabled"); gboolean status = FALSE; @@ -588,13 +602,13 @@ void _bt_handle_adapter_event(GVariant *msg, const char *member) param); g_free(address); } else if (strcasecmp(member, BT_HARDWARE_ERROR) == 0) { - BT_ERR_C("Hardware error received from BLUEZ"); + BT_ERR_C("### Hardware error received from BLUEZ"); /* Don't add the recovery logic into platform */ #if 0 _bt_recover_adapter(); #endif } else if (strcasecmp(member, BT_TX_TIMEOUT_ERROR) == 0) { - BT_ERR_C("Tx timeout error received from BLUEZ"); + BT_ERR_C("### Tx timeout error received from BLUEZ"); /* Don't add the recovery logic into platform */ #if 0 _bt_recover_adapter(); @@ -888,6 +902,7 @@ static void __bt_obex_property_changed_event(GVariant *msg, const char *path) _bt_obex_transfer_progress(path, transferred); } + /* TODO: MAP, "Complete"? see above */ g_free(property); g_variant_unref(val); g_variant_unref(child); @@ -952,11 +967,12 @@ static void __bt_device_property_changed_event(GVariant *msg, const char *path) _bt_convert_device_path_to_address(path, address); BT_DBG("address: %s", address); + g_free(address); + remote_dev_info = _bt_get_remote_device_info_by_object_path(path); if (remote_dev_info == NULL) { g_free(property); g_variant_unref(val); - g_free(address); return; } BT_DBG("Address type %d", remote_dev_info->addr_type); @@ -975,7 +991,6 @@ static void __bt_device_property_changed_event(GVariant *msg, const char *path) _bt_free_device_info(remote_dev_info); g_free(property); g_variant_unref(val); - g_free(address); return; } } @@ -1012,7 +1027,6 @@ static void __bt_device_property_changed_event(GVariant *msg, const char *path) _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND, param); - g_free(address); } _bt_free_device_info(remote_dev_info); } else if (strcasecmp(property, "GattConnected") == 0) { @@ -1318,7 +1332,7 @@ static void _bt_handle_pxp_property_changed_event(GVariant *msg, const char *pat { int result = BLUETOOTH_ERROR_NONE; int service_type; - int alert_lvl; + int alert_lvl = -1; GVariantIter value_iter; char *property = NULL; char *address; @@ -1345,7 +1359,8 @@ static void _bt_handle_pxp_property_changed_event(GVariant *msg, const char *pat service_type = BT_PXP_PROPERTY_IAS; g_variant_get(val, "s", &alert_str); - alert_lvl = get_alert_level_enum(alert_str); + if (alert_str) + alert_lvl = get_alert_level_enum(alert_str); param = g_variant_new("(isiii)", result, address, role, service_type, alert_lvl); @@ -1410,7 +1425,7 @@ void __bt_opc_property_changed_event(GVariant *msg, GVariant *child = NULL; g_variant_iter_init(&value_iter, msg); - while ((child = g_variant_iter_next_value(&value_iter))) { + if ((child = g_variant_iter_next_value(&value_iter))) { g_variant_get(child, "{sv}", &property, &val); ret_if(property == NULL); @@ -1457,6 +1472,68 @@ void _bt_opc_property_changed_event(GVariant *msg, char *path) } +void __bt_map_property_changed_event(GVariant *msg, + const char *path) +{ + BT_DBG("Entered"); + GVariantIter value_iter; + char *property = NULL; + GVariant *val = NULL; + GVariant *child = NULL; + + g_variant_iter_init(&value_iter, msg); + while ((child = g_variant_iter_next_value(&value_iter))) { + g_variant_get(child, "{sv}", &property, &val); + ret_if(property == NULL); + + if (strcasecmp(property, "Status") == 0) { + char *status = NULL; + g_variant_get(val, "s", &status); + BT_DBG("Status is %s", status); + + if (strcasecmp(status, "active") == 0) { + BT_DBG("EVENT : STARTED"); + // currently doing nothing + } else if (strcasecmp(status, "complete") == 0) { + BT_DBG("EVENT : COMPLETED"); + _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_NONE); + } else if (strcasecmp(status, "error") == 0) { + BT_DBG("EVENT : FAILED"); + _bt_map_on_transfer_finished(path, BLUETOOTH_ERROR_INTERNAL); + } + g_free(status); + } else if (strcasecmp(property, "Transferred") == 0) { + guint64 transferred = 0; + g_variant_get(val, "t", &transferred); + + BT_DBG("EVENT : PROGRESS CALLBACK"); + // currently doing nothing - progress callback type is not used + } else { + BT_DBG("OTHER EVENT : property : [%s]", property); + } + g_free(property); + g_variant_unref(child); + g_variant_unref(val); + } +} + +void _bt_map_property_changed_event(GVariant *msg, const char *path) +{ + BT_DBG("Entered _bt_map_property_changed_event"); + char *interface_name = NULL; + GVariant *value = NULL; + g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &value, NULL); + BT_INFO("interface_name = %s", interface_name); + if (strcasecmp(interface_name, BT_OBEX_TRANSFER_INTERFACE) == 0) { + __bt_map_property_changed_event(value, + path); + } else { + BT_DBG("interface_name : [%s]", interface_name); + } + g_variant_unref(value); +} + + void _bt_handle_input_event(GVariant *msg, const char *path) { int result = BLUETOOTH_ERROR_NONE; @@ -1607,12 +1684,8 @@ void __bt_gatt_char_property_changed_event(GVariant *msg, { GVariantIter value_iter; char *property = NULL; - char * char_handle = NULL; GVariant *val = NULL; - int result = BLUETOOTH_ERROR_NONE; - GVariant *param = NULL; g_variant_iter_init(&value_iter, msg); - char_handle = g_strdup(path); while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val))) { BT_INFO("Property %s", property); @@ -1625,73 +1698,21 @@ void __bt_gatt_char_property_changed_event(GVariant *msg, BT_DBG("notifying is enabled"); else BT_DBG("notifying is disabled"); - } else if (strcasecmp(property, "ChangedValue") == 0) { - int len = 0; - GByteArray *gp_byte_array = NULL; - BT_INFO("Type '%s'\n", g_variant_get_type_string(val)); - - if (val) { - gp_byte_array = g_byte_array_new(); - len = g_variant_get_size(val); - BT_DBG("Len = %d", len); - g_byte_array_append(gp_byte_array, - (const guint8 *) g_variant_get_data(val), len); - if (gp_byte_array->len != 0) { - GVariant *byte_array = NULL; - byte_array = g_variant_new_from_data( - G_VARIANT_TYPE_BYTESTRING, - gp_byte_array->data, - gp_byte_array->len, - TRUE, NULL, NULL); - param = g_variant_new("(is@ay)", result, char_handle, - byte_array); - - /* Send event only registered client */ - _bt_send_char_value_changed_event(param); - } - g_byte_array_free(gp_byte_array, TRUE); - } } } - g_free(char_handle); } void _bt_handle_gatt_event(GVariant *msg, const char *member, const char *path) { ret_if(path == NULL); - if (strcasecmp(member, "GattValueChanged") == 0) { - -#if 0 // Debug Only - /*** Debug only ***/ - GVariant *value = NULL; - int value_len = 0; - char *buffer = NULL; - - g_variant_get(msg, "(is@ay)", NULL, NULL, &value); - value_len = g_variant_get_size(value); - if (value_len > 0) { - char buf[8 * 5 + 1] = { 0 }; - int i; - int to; - buffer = (char *)g_variant_get_data(value); - to = value_len > (sizeof(buf) / 5) ? sizeof(buf) / 5 : value_len; - - for (i = 0; i < to; i++) - snprintf(&buf[i * 5], 6, "0x%02x ", buffer[i]); - buf[i * 5] = '\0'; - BT_DBG("GATT Val[%d] %s", value_len, buf); - } - g_variant_unref(value); - /******/ -#endif - - /* Send event only registered client */ - _bt_send_char_value_changed_event(msg); + /* Check TDS seekers waiting for Indication */ + _bt_tds_check_indication(path, msg); + } else { + BT_INFO("Unhandled event"); } } - void _bt_handle_device_event(GVariant *msg, const char *member, const char *path) { int event = 0; @@ -1922,6 +1943,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member, const char *path _bt_opp_client_is_sending(&sending); if (sending == TRUE) _bt_opp_client_check_pending_transfer(address); + /* TODO: MAP? see above */ } param = g_variant_new("(isy)", result, address, addr_type); _bt_send_event(BT_DEVICE_EVENT, @@ -1950,9 +1972,11 @@ void _bt_handle_device_event(GVariant *msg, const char *member, const char *path (state == BT_PROFILE_STATE_CONNECTED)) { int event = BLUETOOTH_EVENT_AV_CONNECTED; - char connected_address[BT_ADDRESS_STRING_SIZE + 1]; +#ifndef TIZEN_BT_DUAL_HEADSET_CONNECT bluetooth_device_address_t device_address; + char connected_address[BT_ADDRESS_STRING_SIZE + 1]; gboolean connected; +#endif bt_headset_wait_t *wait_list; guint restricted = 0x0; @@ -1974,6 +1998,10 @@ void _bt_handle_device_event(GVariant *msg, const char *member, const char *path param = g_variant_new("(is)", result, address); _bt_send_event(BT_HEADSET_EVENT, event, param); +#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT + _bt_check_already_connected_headset(BT_AUDIO_A2DP, + address); +#else connected = _bt_is_headset_type_connected(BT_AUDIO_A2DP, connected_address); if (connected) { @@ -1985,7 +2013,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member, const char *path &device_address, NULL); } } - +#endif _bt_add_headset_to_list(BT_AUDIO_A2DP, BT_STATE_CONNECTED, address); @@ -2125,6 +2153,18 @@ void _bt_handle_device_event(GVariant *msg, const char *member, const char *path param = g_variant_new("(is)", result, address); _bt_send_event(BT_HID_EVENT, event, param); + + /* Set the vconf value for device */ + if (state == BT_PROFILE_STATE_CONNECTED) { + hid_connected_device_count++; + __bt_set_device_values(TRUE, + VCONFKEY_BT_DEVICE_HID_CONNECTED); + } else { + hid_connected_device_count--; + if (hid_connected_device_count == 0) + __bt_set_device_values(FALSE, + VCONFKEY_BT_DEVICE_HID_CONNECTED); + } } else if (strcmp(profile_uuid, HID_DEVICE_UUID) == 0) { if (state == BT_PROFILE_STATE_CONNECTED) { int event; @@ -2226,6 +2266,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member, const char *path } else if (strcasecmp(member, "IpspStateChanged") == 0) { gboolean connected = FALSE; char *ifname = NULL; + GVariant *ipsp_param = NULL; g_variant_get(msg, "(bs)", &connected, &ifname); @@ -2238,12 +2279,64 @@ void _bt_handle_device_event(GVariant *msg, const char *member, const char *path BT_DBG("Ipsp BT Interface Name: %s", ifname); BT_DBG("address: %s", address); param = g_variant_new("(iss)", result, address, ifname); + ipsp_param = g_variant_new("(ss)", ifname, address); + + /* Set Ipv6 Addr */ + GDBusProxy *ipsp_proxy; + if (connected) { + BT_DBG("IPSP connected, Set Ipv6 Addr"); + ipsp_proxy = _bt_get_ipsp_proxy(); + if (ipsp_proxy == NULL) { + BT_ERR("can not get ipsp proxy"); + return; + } + + g_dbus_proxy_call(ipsp_proxy, "SetIpv6Addr", + ipsp_param, G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + } else { + BT_DBG("IPSP disconnected"); + ipsp_proxy = _bt_get_ipsp_proxy(); + if (ipsp_proxy == NULL) { + BT_ERR("can not get ipsp proxy"); + return; + } + + g_dbus_proxy_call(ipsp_proxy, "DisableIpsp", + NULL, G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + } /* Send event to application */ _bt_send_event(BT_DEVICE_EVENT, event, param); g_free(address); + } else if (strcasecmp(member, "AttMtuChanged") == 0) { + int result = BLUETOOTH_ERROR_NONE; + guint16 mtu = 0; + guint8 status = 0; + + g_variant_get(msg, "(q)", &mtu); + + address = g_malloc0(BT_ADDRESS_STRING_SIZE); + + _bt_convert_device_path_to_address(path, address); + _bt_convert_addr_string_to_secure_string(secure_address, address); + BT_DBG("Address : %s MTU changed : %d", secure_address, mtu); + + param = g_variant_new("(isqy)", + result, + address, + mtu, + status); + + /* Send the event to application */ + _bt_send_event(BT_DEVICE_EVENT, + BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED, + param); + + g_free(address); } } @@ -2556,6 +2649,7 @@ void _bt_handle_agent_event(GVariant *msg, const char *member) _bt_send_event(BT_OPP_SERVER_EVENT, BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE, param); + /* TODO: MAP? see above */ g_free(address); g_free(name); } else if (strcasecmp(member, "RfcommAuthorize") == 0) { @@ -2577,6 +2671,34 @@ void _bt_handle_agent_event(GVariant *msg, const char *member) } } +void _bt_handle_tds_provider_event(GVariant *msg, const char *member, const char *path) +{ + BT_INFO("member: %s, path: %s", member, path); + + ret_if(path == NULL); + + if (strcasecmp(member, "TdsActivationRequested") == 0) { + GVariant *value = NULL; + int len = 0; + unsigned char *buffer = NULL; + unsigned char org_id; + + g_variant_get(msg, "(y@ay)", &org_id, &value); + BT_DBG("org_id: %.2x", org_id); + len = g_variant_get_size(value); + if (len > 0) { + int i; + buffer = (unsigned char *)g_variant_get_data(value); + for (i = 0; i < len; i++) + BT_DBG("%.2x", buffer[i]); + } + + /* Send event only registered client */ + _bt_tds_handle_activation_request(path, org_id, buffer, len); + g_variant_unref(value); + } +} + static int __bt_get_object_path(GVariant *msg, char **path) { g_variant_get(msg, "(o*)", path, NULL); @@ -2825,6 +2947,9 @@ static void __bt_manager_event_filter(GDBusConnection *connection, /* Stop the Proximity reporter service */ _bt_proximity_reporter_stop_by_terminated_process(name); + /* Stop the Transport Discovery service */ + _bt_tds_stop_by_terminated_process(name); + g_free(name); g_free(previous); g_free(current); @@ -2850,6 +2975,8 @@ static void __bt_manager_event_filter(GDBusConnection *connection, _bt_handle_agent_event(parameters, signal_name); } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) { _bt_handle_device_event(parameters, signal_name, object_path); + } else if (g_strcmp0(interface_name, BT_TDS_PROVIDER_INTERFACE) == 0) { + _bt_handle_tds_provider_event(parameters, signal_name, object_path); } else if (g_strcmp0(interface_name, BT_GATT_CHAR_INTERFACE) == 0) { _bt_handle_gatt_event(parameters, signal_name, object_path); } @@ -2895,6 +3022,7 @@ static void __bt_obexd_event_filter(GDBusConnection *connection, BT_INFO("object_path = [%s]", obj_path); /*Handle OPP_SERVER_CONNECTED_EVENT here */ + /* TODO: MAP? see above */ if (strncmp(obj_path, BT_SESSION_BASEPATH_SERVER, strlen(BT_SESSION_BASEPATH_SERVER)) != 0) { g_free(obj_path); @@ -2908,6 +3036,7 @@ static void __bt_obexd_event_filter(GDBusConnection *connection, g_free(obj_path); } else if (strcasecmp(member, "InterfacesRemoved") == 0) { /*Handle OPP_SERVER_DISCONNECTED_EVENT here */ + /* TODO: MAP? see above */ if (__bt_get_object_path(parameters, &obj_path)) { BT_ERR("Fail to get the path"); return; @@ -3058,6 +3187,68 @@ void _bt_opp_client_event_deinit(void) } } +static void __bt_map_event_filter(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + BT_DBG("Entered __bt_map_event_filter"); + const char *member = signal_name; + + if (strcasecmp(member, "InterfacesAdded") == 0) { + BT_DBG("------------------------------------ADDED------------------------------------"); + // currently doing nothing + } else if (strcasecmp(member, "InterfacesRemoved") == 0) { + BT_DBG("------------------------------------REMOVED------------------------------------"); + // TODO check if something should be called here? + //_bt_map_on_transfer_finished(object_path, error); + } else if (__bt_is_obexd_client_event(parameters, interface_name) == TRUE) { + BT_DBG("------------------------------------CLIENT EVENT------------------------------------"); + _bt_map_property_changed_event(parameters, object_path); + } + + return; +} + +int _bt_map_client_event_init(void) +{ + GError *error = NULL; + + if (map_obexd_conn == NULL) { + map_obexd_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + + if (!map_obexd_conn) { + if (error) { + BT_ERR("Unable to connect to dbus: %s", error->message); + g_clear_error(&error); + } + return BLUETOOTH_ERROR_INTERNAL; + } + } + + if (_bt_register_service_event(map_obexd_conn, + BT_MAP_CLIENT_EVENT) != BLUETOOTH_ERROR_NONE) { + g_object_unref(map_obexd_conn); + map_obexd_conn = NULL; + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} + +void _bt_map_client_event_deinit(void) +{ + if (map_obexd_conn) { + _bt_unregister_service_event(map_obexd_conn, + BT_MAP_CLIENT_EVENT); + g_object_unref(map_obexd_conn); + map_obexd_conn = NULL; + } +} + int _bt_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe) { @@ -3383,6 +3574,59 @@ int _bt_register_opp_client_subscribe_signal(GDBusConnection *conn, return 0; } +int _bt_register_map_client_subscribe_signal(GDBusConnection *conn, + int subscribe) +{ + if (conn == NULL) + return -1; + + static int subs_map_client_interface_added_id = -1; + static int subs_map_client_interface_removed_id = -1; + static int subs_map_client_property_id = -1; + + + if (subscribe) { + if (subs_map_client_interface_added_id == -1) { + subs_map_client_interface_added_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_MANAGER_INTERFACE, + BT_INTERFACES_ADDED, NULL, NULL, 0, + __bt_map_event_filter, + NULL, NULL); + } + if (subs_map_client_interface_removed_id == -1) { + subs_map_client_interface_removed_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_MANAGER_INTERFACE, + BT_INTERFACES_REMOVED, NULL, NULL, 0, + __bt_map_event_filter, + NULL, NULL); + } + if (subs_map_client_property_id == -1) { + subs_map_client_property_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_PROPERTIES_INTERFACE, + BT_PROPERTIES_CHANGED, NULL, NULL, 0, + __bt_map_event_filter, + NULL, NULL); + } + } else { + if (subs_map_client_interface_added_id != -1) { + g_dbus_connection_signal_unsubscribe(conn, + subs_map_client_interface_added_id); + subs_map_client_interface_added_id = -1; + } + if (subs_map_client_interface_removed_id != -1) { + g_dbus_connection_signal_unsubscribe(conn, + subs_map_client_interface_removed_id); + subs_map_client_interface_removed_id = -1; + } + if (subs_map_client_property_id != -1) { + g_dbus_connection_signal_unsubscribe(conn, + subs_map_client_property_id); + subs_map_client_property_id = -1; + } + } + return 0; +} + int _bt_register_a2dp_subscribe_signal(GDBusConnection *conn, int subscribe) { @@ -3422,6 +3666,32 @@ int _bt_register_a2dp_subscribe_signal(GDBusConnection *conn, return 0; } +int _bt_register_tds_provider_subscribe_signal(GDBusConnection *conn, int subscribe) +{ + if (conn == NULL) + return -1; + + static int subs_custom_id = -1; + + if (subscribe) { + if (subs_custom_id == -1) { + subs_custom_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_TDS_PROVIDER_INTERFACE, + NULL, NULL, NULL, 0, + __bt_manager_event_filter, + NULL, NULL); + } + } else { + if (subs_custom_id != -1) { + g_dbus_connection_signal_unsubscribe(conn, + subs_custom_id); + subs_custom_id = -1; + } + } + + return 0; +} + static void __bt_dump_event_filter(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, @@ -3481,19 +3751,27 @@ int _bt_register_service_event(GDBusConnection *g_conn, int event_type) case BT_HEADSET_EVENT: _bt_register_audio_subscribe_signal(g_conn, TRUE); break; - case BT_OPP_SERVER_EVENT: BT_ERR("BT_OPP_SERVER_EVENT: register service event"); _bt_register_opp_server_subscribe_signal(g_conn, TRUE); break; + case BT_OPP_CLIENT_EVENT: BT_ERR("BT_OPP_CLIENT_EVENT: register service event"); _bt_register_opp_client_subscribe_signal(g_conn, TRUE); break; + case BT_MAP_CLIENT_EVENT: + BT_ERR("BT_MAP_CLIENT_EVENT: register service event"); + _bt_register_map_client_subscribe_signal(g_conn, TRUE); + break; case BT_A2DP_SOURCE_EVENT: BT_INFO("A2dp Source event"); _bt_register_a2dp_subscribe_signal(g_conn, TRUE); break; + case BT_TDS_EVENT: + BT_INFO("TDS provider event"); + _bt_register_tds_provider_subscribe_signal(g_conn, TRUE); + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; @@ -3522,6 +3800,9 @@ void _bt_unregister_service_event(GDBusConnection *g_conn, int event_type) case BT_OPP_CLIENT_EVENT: _bt_register_opp_client_subscribe_signal(g_conn, FALSE); break; + case BT_MAP_CLIENT_EVENT: + _bt_register_map_client_subscribe_signal(g_conn, FALSE); + break; default: BT_ERR("Unknown event"); return; @@ -3564,6 +3845,10 @@ static int __bt_init_manager_receiver(void) BT_NETWORK_EVENT) != BLUETOOTH_ERROR_NONE) goto fail; + if (_bt_register_service_event(manager_conn, + BT_TDS_EVENT) != BLUETOOTH_ERROR_NONE) + goto fail; + __bt_register_dump_subscribe_signal(manager_conn, TRUE); return BLUETOOTH_ERROR_NONE; fail: diff --git a/bt-service/bt-service-event-sender.c b/bt-service/bt-service-event-sender.c index 089d174..a7d3328 100644 --- a/bt-service/bt-service-event-sender.c +++ b/bt-service/bt-service-event-sender.c @@ -100,6 +100,9 @@ int _bt_send_event(int event_type, int event, GVariant *param) case BT_OPP_SERVER_EVENT: path = BT_OPP_SERVER_PATH; break; + case BT_MAP_CLIENT_EVENT: + path = BT_MAP_CLIENT_PATH; + break; case BT_PBAP_CLIENT_EVENT: path = BT_PBAP_CLIENT_PATH; break; @@ -317,6 +320,34 @@ int _bt_send_event(int event_type, int event, GVariant *param) signal = BT_OPP_DISCONNECTED; BT_INFO_C("Disconnected [OPP]"); break; + case BLUETOOTH_EVENT_MAP_CONNECTED: + signal = BT_MAP_CONNECTED; + BT_INFO_C("Connected [MAP]"); + break; + case BLUETOOTH_EVENT_MAP_DISCONNECTED: + signal = BT_MAP_DISCONNECTED; + BT_INFO_C("Disconnected [MAP]"); + break; + case BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE: + signal = BT_MAP_LIST_FOLDERS_COMPLETE; + BT_INFO_C("Completed list folders operation[MAP]"); + break; + case BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE: + signal = BT_MAP_FILTER_FIELDS_COMPLETE; + BT_INFO_C("Completed list filters field operation[MAP]"); + break; + case BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE: + signal = BT_MAP_LIST_MESSAGES_COMPLETE; + BT_INFO_C("Completed list messages operation [MAP]"); + break; + case BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE: + signal = BT_MAP_GET_MESSAGE_COMPLETE; + BT_INFO_C("Completed get message operation [MAP]"); + break; + case BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE: + signal = BT_MAP_PUSH_MESSAGE_COMPLETE; + BT_INFO_C("Completed push message operation [MAP]"); + break; case BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED: signal = BT_TRANSFER_CONNECTED; break; @@ -468,6 +499,9 @@ int _bt_send_event_to_dest(const char* dest, int event_type, case BT_DEVICE_EVENT: path = BT_DEVICE_PATH; break; + case BT_TDS_EVENT: + path = BT_TDS_PATH; + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; @@ -495,6 +529,21 @@ int _bt_send_event_to_dest(const char* dest, int event_type, case BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED: signal = BT_GATT_CHAR_VAL_CHANGED; break; + case BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED: + signal = BT_TDS_ACTIVATION_REQUESTED; + break; + case BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED: + signal = BT_TDS_TRANSPORT_DATA_RECEIVED; + break; + case BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION: + signal = BT_TDS_ACTIVATION_INDICATION; + break; + case BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED: + signal = BT_TDS_CONTROL_POINT_ENABLED; + break; + case BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT: + signal = BT_TDS_ACTIVATION_RESULT; + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; diff --git a/bt-service/bt-service-headset-connection.c b/bt-service/bt-service-headset-connection.c index f88ffce..4fa18d7 100644 --- a/bt-service/bt-service-headset-connection.c +++ b/bt-service/bt-service-headset-connection.c @@ -33,6 +33,7 @@ #include "bt-service-headset-connection.h" #include "bt-service-opp-client.h" +#include "bt-service-map-client.h" diff --git a/bt-service/bt-service-main.c b/bt-service/bt-service-main.c index a626be6..ebfecfe 100644 --- a/bt-service/bt-service-main.c +++ b/bt-service/bt-service-main.c @@ -57,9 +57,6 @@ static void __bt_release_service(void) _bt_clear_request_list(); -#ifndef GATT_NO_RELAY - _bt_clear_gatt_client_senders(); -#endif is_initialized = FALSE; _bt_service_cynara_deinit(); @@ -239,10 +236,6 @@ int _bt_service_initialize(void) _bt_init_request_list(); -#ifndef GATT_NO_RELAY - _bt_init_gatt_client_senders(); -#endif - is_initialized = TRUE; return BLUETOOTH_ERROR_NONE; diff --git a/bt-service/bt-service-map-client.c b/bt-service/bt-service-map-client.c new file mode 100644 index 0000000..d6bc887 --- /dev/null +++ b/bt-service/bt-service-map-client.c @@ -0,0 +1,763 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "bluetooth-api.h" +#include "bt-internal-types.h" + +#include "bt-service-common.h" +#include "bt-service-event.h" +#include "bt-service-util.h" +#include "bt-service-map-client.h" +#include "bt-service-obex-agent.h" +#include "bt-service-adapter.h" + +#define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */ + +enum bt_map_transfer_type { + BT_MAP_TRANSFER_GET_MESSAGE = 0, + BT_MAP_TRANSFER_PUSH_MESSAGE +}; + +typedef struct { + enum bt_map_transfer_type transfer_type; + char *transfer_path; + int request_id; +} bt_map_callback_data_t; + +static GSList *transfer_list = NULL; + +bt_session_info_t *session_info; + +static void __bt_free_session_info(bt_session_info_t *info) +{ + ret_if(info == NULL); + g_free(info->address); + g_free(info); +} + +void _bt_map_disconnected(const char *session_path) +{ + BT_DBG("+"); + GVariant *param = NULL; + ret_if(session_info == NULL); + + if (g_strcmp0(session_info->session_path, + session_path) != 0) { + BT_INFO("Path mismatch, previous transfer failed! Returning"); + return; + } + + param = g_variant_new("(isi)", session_info->result, + session_info->address, + session_info->request_id); + _bt_send_event(BT_MAP_CLIENT_EVENT, + BLUETOOTH_EVENT_MAP_DISCONNECTED, + param); + + __bt_free_session_info(session_info); + session_info = NULL; + + BT_DBG("-"); +} + +int _bt_create_session_sync(const char* address, char** session_id) +{ + BT_DBG("Entered SERVICE create session"); + GDBusConnection *g_conn; + GDBusProxy *session_proxy; + GError *err = NULL; + + retv_if(address == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_OBEX_SERVICE_NAME, + BT_OBEX_CLIENT_PATH, + BT_OBEX_CLIENT_INTERFACE, + NULL, &err); + if (err) { + BT_ERR("Unable to create session_proxy: %s", err->message); + g_clear_error(&err); + return BLUETOOTH_ERROR_INTERNAL; + } + retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); + g_variant_builder_add(builder, "{sv}", "Target", + g_variant_new("s", "map")); + GVariant *args = g_variant_builder_end(builder); + g_variant_builder_unref(builder); + GVariant *param = g_variant_new("(s@a{sv})", address, args); + + GVariant *value = g_dbus_proxy_call_sync(session_proxy, "CreateSession", param, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (err != NULL) { + BT_ERR("Could not create session: %s\n", err->message); + g_error_free(err); + return BLUETOOTH_ERROR_INTERNAL; + } else { + if (NULL == value) { + BT_ERR("create session returned value is null\n"); + return BLUETOOTH_ERROR_INTERNAL; + } else { + BT_DBG("create session succeed\n"); + } + } + + g_variant_get(value, "(&o)", session_id); + BT_DBG("session_id = \"%s\"\n", *session_id); + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_destroy_session_sync(const char* session_id) +{ + BT_DBG("Entered SERVICE destroy session with id: \"%s\"", session_id); + GDBusConnection *g_conn; + GDBusProxy *session_proxy; + GError *err = NULL; + + retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_OBEX_SERVICE_NAME, + BT_OBEX_CLIENT_PATH, + BT_OBEX_CLIENT_INTERFACE, + NULL, &err); + if (err) { + BT_ERR("Unable to create session_proxy: %s", err->message); + g_clear_error(&err); + return BLUETOOTH_ERROR_INTERNAL; + } + retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariant *param = g_variant_new("(o)", session_id); + + g_dbus_proxy_call_sync(session_proxy, "RemoveSession", param, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (err != NULL) { + BT_ERR("Could not remove session: %s\n", err->message); + g_error_free(err); + return BLUETOOTH_ERROR_INTERNAL; + } else { + BT_DBG("remove session succeed\n"); + } + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_map_client_set_folder(const char* session_id, const char* name) +{ + BT_DBG("+"); + + GError *err = NULL; + GDBusConnection *g_conn; + GDBusProxy *message_proxy; + GVariant *ret = NULL; + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + message_proxy = g_dbus_proxy_new_sync(g_conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_OBEX_SERVICE_NAME, session_id, + BT_OBEX_MESSAGE_INTERFACE, NULL, &err); + + retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + ret = g_dbus_proxy_call_sync(message_proxy, + "SetFolder", g_variant_new("(s)", name), + G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, + NULL, &err); + + if (ret == NULL) { + if (err != NULL) { + BT_ERR("SetFolder Error: %s\n", err->message); + g_error_free(err); + } + } else { + g_variant_unref(ret); + } + + g_object_unref(message_proxy); + + BT_DBG("-"); + + return BLUETOOTH_ERROR_NONE; +} + +static void __bt_list_folders_cb(GDBusProxy *proxy, + GAsyncResult *res, gpointer user_data) +{ + BT_DBG("+"); + + GError *error = NULL; + GVariant *value, *in_param, *param; + + int result = BLUETOOTH_ERROR_NONE; + int request_id; + + in_param = (GVariant*) user_data; + g_variant_get(in_param, "(i)", &request_id); + + value = g_dbus_proxy_call_finish(proxy, res, &error); + + if (error) { + BT_ERR("%s", error->message); + g_clear_error(&error); + result = BLUETOOTH_ERROR_INTERNAL; + } + + param = g_variant_new("(iiv)", result, request_id, value); + BT_DBG("RequestID[%d]", request_id); + result = _bt_send_event(BT_MAP_CLIENT_EVENT, + BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, param); + + g_variant_unref(value); + g_variant_unref(in_param); + + BT_DBG("-"); +} + +int _bt_map_client_list_folders( + int request_id, + GDBusMethodInvocation *context, + const char* session_id, + const char* filter_serialized) +{ + BT_DBG("Entered _bt_map_list_folders with session id: \"%s\"", session_id); + GDBusConnection *g_conn; + GDBusProxy *message_access_proxy; + GError *error = NULL; + int result = BLUETOOTH_ERROR_NONE; + + retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &request_id, sizeof(int), + TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(context, + g_variant_new("(iv)", result, out_param1)); + + // create message access proxy + g_clear_error(&error); + message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1", + NULL, &error); + if (error != NULL) { + BT_ERR("Could not create message access proxy: %s\n", error->message); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + if (!message_access_proxy) { + BT_ERR("message proxy handle is null\n"); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + BT_DBG("message proxy set"); + + GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL); + + GVariant *params = g_variant_new("(@a{sv})", filter_variant); + GVariant *param = g_variant_new("(i)", request_id); + + g_dbus_proxy_call(message_access_proxy, + "ListFolders", params, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + (GAsyncReadyCallback)__bt_list_folders_cb, + (void*)param); + } + } + + g_object_unref(message_access_proxy); + BT_DBG("-"); + + return result; +} + +static void __bt_list_filter_fields_cb(GDBusProxy *proxy, + GAsyncResult *res, gpointer user_data) +{ + BT_DBG("+"); + + GError *error = NULL; + GVariant *value, *in_param, *param; + + int result = BLUETOOTH_ERROR_NONE; + int request_id; + + in_param = (GVariant*) user_data; + g_variant_get(in_param, "(i)", &request_id); + + value = g_dbus_proxy_call_finish(proxy, res, &error); + + if (error) { + BT_ERR("%s", error->message); + g_clear_error(&error); + result = BLUETOOTH_ERROR_INTERNAL; + } + + param = g_variant_new("(ivi)", result, value, request_id); + + _bt_send_event(BT_MAP_CLIENT_EVENT, BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE, + param); + + g_variant_unref(value); + g_variant_unref(in_param); + + BT_DBG("-"); +} + +int _bt_map_client_list_filter_fields(int request_id, GDBusMethodInvocation *context, const char* session_id) +{ + BT_DBG("+"); + + GError *err = NULL; + GDBusConnection *g_conn; + GDBusProxy *message_proxy; + int result = BLUETOOTH_ERROR_NONE; + + retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariant *out_param = g_variant_new_from_data((const GVariantType *)"ay", + &request_id, sizeof(int), + TRUE, NULL, NULL); + + g_dbus_method_invocation_return_value(context, + g_variant_new("(iv)", result, out_param)); + + + message_proxy = g_dbus_proxy_new_sync(g_conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_OBEX_SERVICE_NAME, session_id, + BT_OBEX_MESSAGE_INTERFACE, NULL, &err); + + retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariant *param = g_variant_new("(i)", request_id); + + g_dbus_proxy_call(message_proxy, + "ListFilterFields", g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + (GAsyncReadyCallback)__bt_list_filter_fields_cb, + (void*)param); + + g_object_unref(message_proxy); + + BT_DBG("-"); + + return BLUETOOTH_ERROR_NONE; +} + +static void __bt_list_messages_cb( + GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) +{ + BT_DBG("+"); + + GError *error = NULL; + GVariant *value, *in_param, *param; + + int result = BLUETOOTH_ERROR_NONE; + int request_id; + + in_param = (GVariant*) user_data; + g_variant_get(in_param, "(i)", &request_id); + + value = g_dbus_proxy_call_finish(proxy, res, &error); + + if (error) { + BT_ERR("%s", error->message); + g_clear_error(&error); + result = BLUETOOTH_ERROR_INTERNAL; + } + + param = g_variant_new("(iiv)", result, request_id, value); + BT_DBG("RequestID[%d]", request_id); + result = _bt_send_event(BT_MAP_CLIENT_EVENT, + BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, param); + + g_variant_unref(value); + g_variant_unref(in_param); + + BT_DBG("-"); +} + +int _bt_map_client_list_messages( + int request_id, + GDBusMethodInvocation *context, + const char* session_id, + const char* folder, + const char* filter_serialized) +{ + BT_DBG("Entered _bt_map_client_list_messages with session id: \"%s\"", session_id); + BT_DBG("Entered folder: %s", folder); + GDBusConnection *g_conn; + GDBusProxy *message_access_proxy; + GError *error = NULL; + int result = BLUETOOTH_ERROR_NONE; + + retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &request_id, sizeof(int), + TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(context, + g_variant_new("(iv)", result, out_param1)); + + // create message access proxy + g_clear_error(&error); + message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1", + NULL, &error); + if (error != NULL) { + BT_ERR("Could not create message access proxy: %s\n", error->message); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + if (!message_access_proxy) { + BT_ERR("message proxy handle is null\n"); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + BT_DBG("message proxy set"); + + GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL); + + GVariant *params = g_variant_new("(s@a{sv})", folder, filter_variant); + GVariant *param = g_variant_new("(i)", request_id); + + g_dbus_proxy_call(message_access_proxy, + "ListMessages", params, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + (GAsyncReadyCallback)__bt_list_messages_cb, + (void*)param); + } + } + + g_object_unref(message_access_proxy); + BT_DBG("-"); + + return result; +} + +int _bt_map_client_update_inbox(const char* session_id) +{ + BT_DBG("+"); + + GError *err = NULL; + GDBusConnection *g_conn; + GDBusProxy *message_proxy; + GVariant *ret = NULL; + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + message_proxy = g_dbus_proxy_new_sync(g_conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_OBEX_SERVICE_NAME, session_id, + BT_OBEX_MESSAGE_INTERFACE, NULL, &err); + + retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + ret = g_dbus_proxy_call_sync(message_proxy, + "UpdateInbox", g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &err); + + if (ret == NULL) { + if (err != NULL) { + BT_ERR("UpdateInbox Error: %s\n", err->message); + g_error_free(err); + } + } else { + g_variant_unref(ret); + } + + g_object_unref(message_proxy); + + BT_DBG("-"); + + return BLUETOOTH_ERROR_NONE; +} + +void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error) +{ + BT_DBG("Entered _bt_map_on_transfer_finished"); + BT_DBG("Looking for transfer %s id", transfer_object_path); + + bt_map_callback_data_t *callback_data = NULL; + GSList* transfer = NULL; + for (transfer = transfer_list; transfer != NULL; transfer = g_slist_next(transfer)) { + callback_data = transfer->data; + if (NULL == callback_data) + continue; + + if (0 == strcmp(transfer_object_path, callback_data->transfer_path)) { + BT_DBG("request id FOUND - triggering event"); + + GVariant *param = g_variant_new("(ii)", error, callback_data->request_id); + + int event = -1; + switch (callback_data->transfer_type) { + case BT_MAP_TRANSFER_GET_MESSAGE: + event = BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE; + break; + case BT_MAP_TRANSFER_PUSH_MESSAGE: + event = BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE; + break; + } + + _bt_send_event(BT_MAP_CLIENT_EVENT, event, param); + + // remove callback data from list + transfer_list = g_slist_remove(transfer_list, transfer); + + //free memory and break loop + free(callback_data->transfer_path); + callback_data->transfer_path = NULL; + free(callback_data); + break; + } + + } +} + +static void __bt_push_message_cb(GDBusProxy *proxy, + GAsyncResult *res, gpointer user_data) +{ + BT_DBG("+"); + + GError *error = NULL; + GVariant *value, *in_param; + + char *transfer_object_path = NULL; + GVariantIter *iter = NULL; + + int request_id; + + in_param = (GVariant*) user_data; + g_variant_get(in_param, "(i)", &request_id); + + value = g_dbus_proxy_call_finish(proxy, res, &error); + if (error) { + BT_ERR("%s", error->message); + g_clear_error(&error); + } + + if (value) { + g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter); + g_variant_unref(value); + } + + BT_DBG("transfer object path: [%s]", transfer_object_path); + + BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path); + bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data)); + callback_data->transfer_type = BT_MAP_TRANSFER_PUSH_MESSAGE; + callback_data->request_id = request_id; + callback_data->transfer_path = transfer_object_path; + + transfer_list = g_slist_append(transfer_list, callback_data); + + g_variant_unref(value); + g_variant_unref(in_param); + + BT_DBG("-"); +} + +int _bt_map_client_push_message( + int request_id, + GDBusMethodInvocation *context, + const char* session_id, + const char* source_file, + const char* folder, + const char* args_serialized) +{ + BT_DBG("Entered _bt_map_client_push_message with session id: \"%s\"", session_id); + BT_DBG("Entered source_file: %s", source_file); + BT_DBG("Entered folder: %s", folder); + + GDBusConnection *g_conn; + GDBusProxy *message_access_proxy; + GError *error = NULL; + int result = BLUETOOTH_ERROR_NONE; + + retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + // TODO event listeners registration on first call, where should it be unregistered?? + _bt_map_client_event_init(); + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &request_id, sizeof(int), + TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1)); + + // create message access proxy + g_clear_error(&error); + message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_OBEX_SERVICE_NAME, session_id, BT_OBEX_MESSAGE_INTERFACE, + NULL, &error); + if (error != NULL) { + BT_ERR("Could not create message access proxy: %s\n", error->message); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + if (!message_access_proxy) { + BT_ERR("message proxy handle is null\n"); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + BT_DBG("message proxy set"); + + GVariant *args_variant = g_variant_parse(NULL, args_serialized, NULL, NULL, NULL); + + GVariant *params = g_variant_new("(ss@a{sv})", source_file, folder, args_variant); + GVariant *req_id = g_variant_new("(i)", request_id); + + g_dbus_proxy_call(message_access_proxy, + "PushMessage", params, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, (GAsyncReadyCallback)__bt_push_message_cb, + (void*)req_id); + } + } + + g_object_unref(message_access_proxy); + BT_DBG("-"); + + return result; +} + +static void __bt_get_message_cb(GDBusProxy *proxy, + GAsyncResult *res, gpointer user_data) +{ + BT_DBG("+"); + + GError *error = NULL; + GVariant *value, *in_param; + + char *transfer_object_path = NULL; + GVariantIter *iter = NULL; + + int request_id; + + in_param = (GVariant*) user_data; + g_variant_get(in_param, "(i)", &request_id); + + value = g_dbus_proxy_call_finish(proxy, res, &error); + if (error) { + BT_ERR("%s", error->message); + g_clear_error(&error); + } + + if (value) { + g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter); + g_variant_unref(value); + } + + BT_DBG("transfer object path: [%s]", transfer_object_path); + + BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path); + bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data)); + callback_data->transfer_type = BT_MAP_TRANSFER_GET_MESSAGE; + callback_data->request_id = request_id; + callback_data->transfer_path = transfer_object_path; + + transfer_list = g_slist_append(transfer_list, callback_data); + + g_variant_unref(value); + g_variant_unref(in_param); + + BT_DBG("-"); +} + +int _bt_map_client_get_message( + int request_id, + GDBusMethodInvocation *context, + const char* message_object, + const char* target_file, + bool attachment) +{ + BT_DBG("Entered _bt_map_client_get_message"); + + GDBusConnection *g_conn; + GDBusProxy *message_proxy; + GError *error = NULL; + int result = BLUETOOTH_ERROR_NONE; + + retv_if(message_object == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + // TODO event listeners registration on first call, where should it be unregistered?? + _bt_map_client_event_init(); + + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &request_id, sizeof(int), + TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1)); + + // create message proxy + g_clear_error(&error); + message_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_OBEX_SERVICE_NAME, message_object, "org.bluez.obex.Message1", + NULL, &error); + if (error != NULL) { + BT_ERR("Could not create message proxy: %s\n", error->message); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + if (!message_proxy) { + BT_ERR("message proxy handle is null\n"); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + BT_DBG("message proxy set"); + GVariant *params = g_variant_new("(sb)", target_file, attachment); + GVariant *req_id = g_variant_new("(i)", request_id); + + g_dbus_proxy_call(message_proxy, "Get", params, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, (GAsyncReadyCallback)__bt_get_message_cb, (void*)req_id); + } + } + + g_object_unref(message_proxy); + BT_DBG("-"); + + return result; +} diff --git a/bt-service/bt-service-pbap.c b/bt-service/bt-service-pbap.c index d69b66a..335f3de 100644 --- a/bt-service/bt-service-pbap.c +++ b/bt-service/bt-service-pbap.c @@ -998,7 +998,7 @@ int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data) // //**************************** - sprintf(vcard, "%d.vcf", app_param->index); + snprintf(vcard, 20, "%d.vcf", app_param->index); BT_DBG("Handle: %s", vcard); vcard_handle = g_strdup(vcard); BT_DBG("vcard_handle: %s", vcard_handle); diff --git a/bt-service/bt-service-tds.c b/bt-service/bt-service-tds.c new file mode 100644 index 0000000..5ae0880 --- /dev/null +++ b/bt-service/bt-service-tds.c @@ -0,0 +1,1787 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "bluetooth-api.h" +#include "bt-internal-types.h" + +#include "bt-service-common.h" +#include "bt-service-adapter-le.h" +#include "bt-service-event.h" +#include "bt-service-adapter.h" +#include "bt-service-util.h" +#include "bt-service-tds.h" + +#define GATT_SERV_INTERFACE "org.bluez.GattService1" +#define GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1" +#define GATT_DESC_INTERFACE "org.bluez.GattDescriptor1" + +#define GATT_DEFAULT_TIMEOUT (6 * 1000) /* Dependent on supervision timeout 6 sec */ +#define BT_MAX_DBUS_SENDER_PATH 100 +#define BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX 15000 /* Timeout for Indication from Provider in msec */ + +#define TDS_CONTROL_POINT_RESPONSE_SUCCESS 0x00 +#define TDS_CONTROL_POINT_RESPONSE_OP_CODE_NOT_SUPPORTED 0x01 +#define TDS_CONTROL_POINT_RESPONSE_INVALID_PARAMETER 0x02 +#define TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID 0x03 +#define TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED 0x04 + +#define BT_ADV_FLAG_LEN 3 +#define TDS_DATA_LEN_MAX 1024 +#define NUM_TDS_PROVIDER_MAX 10 + +typedef enum { + BT_AD_TYPE_LOCAL_NAME = 0x09, /**= NUM_TDS_PROVIDER_MAX) + index = 0; + + while (adv_handle_used[index] == TRUE) { + if (index == assigned_adv_handle) { + /* No available ID */ + BT_ERR("All adv_handles are used"); + return -1; + } + + index++; + + if (index >= NUM_TDS_PROVIDER_MAX) + index = 0; + } + + assigned_adv_handle = index; + adv_handle_used[index] = TRUE; + + return assigned_adv_handle; +} + +static void __bt_provider_delete_adv_handle(int handle) +{ + ret_if(handle >= NUM_TDS_PROVIDER_MAX); + ret_if(handle < 0); + + adv_handle_used[handle] = FALSE; +} + +static unsigned char __bt_tds_get_organization_id(int transport) +{ + BT_INFO("transport: %d", transport); + + switch (transport) { + case BLUETOOTH_TDS_TRANSPORT_BT: + return 0x01; + case BLUETOOTH_TDS_TRANSPORT_CUSTOM: + return 0x02; + default: + BT_ERR("Invaid transport"); + return 0x00; + } +} + +static int __bt_tds_get_transport(unsigned char org_id) +{ + BT_INFO("org_id: %d", org_id); + + switch (org_id) { + case 0x01: + return BLUETOOTH_TDS_TRANSPORT_BT; + case 0x02: + return BLUETOOTH_TDS_TRANSPORT_CUSTOM; + default: + BT_ERR("Invaid org_id"); + return BLUETOOTH_TDS_TRANSPORT_INVALID; + } +} + +static unsigned char __bt_tds_set_role(unsigned char flag, bt_tds_role_t role) +{ + + BT_INFO("Flag: %.2X, Role: %d", flag, role); + + switch (role) { + case TDS_ROLE_UNSPECIFIED: + flag = flag & 0xFC; + break; + case TDS_ROLE_SEEKER: + flag = flag & 0xFC; + flag = flag | 0x01; + break; + case TDS_ROLE_PROVIDER: + flag = flag & 0xFC; + flag = flag | 0x02; + break; + case TDS_ROLE_SEEKER_PROVIDER: + flag = flag & 0xFC; + flag = flag | 0x03; + break; + default: + BT_ERR("Invalid role received"); + } + + return flag; +} + +static int __bt_tds_get_role(unsigned char flag) +{ + + BT_INFO("Flag: %.2X", flag); + + if (0x03 == (flag & 0x03)) + return TDS_ROLE_SEEKER_PROVIDER; + else if (0x02 == (flag & 0x02)) + return TDS_ROLE_PROVIDER; + else if (0x01 == (flag & 0x01)) + return TDS_ROLE_SEEKER; + else + return TDS_ROLE_UNSPECIFIED; +} + +static unsigned char __bt_tds_set_transport_data_incomplete( + unsigned char flag, gboolean state) +{ + BT_INFO("Flag: %.2X, Data state: %d", flag, state); + + if (state) + flag = flag | 0x04; /* Set incomplete bit to 1 */ + else + flag = flag & 0xFB; /* Set incomplete bit to 0 */ + + return flag; +} + +static unsigned char __bt_tds_set_transport_state( + unsigned char flag, bluetooth_tds_transport_state_t state) +{ + BT_INFO("Flag: %.2X, Transport state: %d", flag, state); + + switch (state) { + case BLUETOOTH_TDS_TRANSPORT_STATE_OFF: + flag = flag & 0xE7; + break; + case BLUETOOTH_TDS_TRANSPORT_STATE_ON: + flag = flag & 0xE7; + flag = flag | 0x08; + break; + case BLUETOOTH_TDS_TRANSPORT_STATE_UNAVAILABLE: + flag = flag & 0xE7; + flag = flag | 0x10; + break; + case BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED: + flag = flag & 0xE7; + flag = flag | 0x18; + break; + default: + BT_ERR("Invalid transport state received"); + } + + return flag; +} + +static unsigned char __bt_tds_get_activation_response_code(int result) +{ + unsigned char resp; + + switch (result) { + case BLUETOOTH_ERROR_NONE: + resp = TDS_CONTROL_POINT_RESPONSE_SUCCESS; /* Success */ + break; + case BLUETOOTH_ERROR_INVALID_PARAM: + resp = TDS_CONTROL_POINT_RESPONSE_INVALID_PARAMETER; /*Invalid Parameter */ + break; + case BLUETOOTH_ERROR_NOT_SUPPORT: + resp = TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID; /* Unsupported Organization ID*/ + break; + case BLUETOOTH_ERROR_INTERNAL: + resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED; /* */ + break; + default: + BT_INFO("Unknown response code: %d received", result); + resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED; + } + + return resp; +} + +static bt_tds_provider_t* __bt_tds_provider_find_from_list(const char *sender) +{ + GSList *l; + + retv_if(NULL == sender, NULL); + + for (l = provider_list; l != NULL; l = g_slist_next(l)) { + bt_tds_provider_t *provider = l->data; + if (provider && (g_strcmp0(provider->sender, sender) == 0)) + return provider; + } + + return NULL; +} + +static unsigned char* __bt_tds_provider_get_tds_blocks(unsigned int *length) +{ + GSList *l; + GSList *l1; + unsigned int len = 0; + unsigned char data[TDS_DATA_LEN_MAX]; + + retv_if(NULL == length, NULL); + + for (l = provider_list; NULL != l; l = g_slist_next(l)) { + bt_tds_provider_t *provider = l->data; + + if (!provider) + continue; + + for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) { + bt_tds_transport_info_t *transport_info = l1->data; + + if (!transport_info || !transport_info->data) + continue; + + if (len + transport_info->data_len > sizeof(data)) { + BT_ERR("Could not set complete the tds data, size exceeded"); + break; + } + + memcpy(&(data[len]), transport_info->data, transport_info->data_len); + len += transport_info->data_len; + } + } + + *length = len; + BT_INFO("length = %d", *length); + return g_memdup(data, *length); +} + +static void __bt_tds_set_scan_resp_data(bt_tds_provider_t *provider) +{ + bluetooth_scan_resp_data_t scan_resp; + char *name = "bt-service"; + int adv_handle = 0; + int len = 0; + int ret; + + BT_DBG("+"); + + if (provider) { + name = provider->sender; + adv_handle = provider->adv_handle; + + if (provider->manuf_data_len > 0) { + scan_resp.data[len++] = provider->manuf_data_len + 1; + scan_resp.data[len++] = BT_AD_TYPE_MANUF_DATA; + memcpy(&(scan_resp.data[len]), provider->manuf_data, provider->manuf_data_len); + len += provider->manuf_data_len; + } + } else { + if (manuf_data_len > 0) { + scan_resp.data[len++] = manuf_data_len + 1; + scan_resp.data[len++] = BT_AD_TYPE_MANUF_DATA; + memcpy(&(scan_resp.data[len]), manuf_data, manuf_data_len); + len += manuf_data_len; + } + } + + if (len <= (BLUETOOTH_SCAN_RESP_DATA_LENGTH_MAX - 2)) { + /* Include name */ + scan_resp.data[len++] = 1; + scan_resp.data[len++] = BT_AD_TYPE_LOCAL_NAME; + } + + ret = _bt_set_scan_response_data(name, adv_handle, &scan_resp, len, FALSE); + if (ret != BLUETOOTH_ERROR_NONE) + BT_ERR("Failed to set_scan response data with error: %d", ret); + + BT_DBG("-"); +} + +/* + * Multi adv not supported (Lagacy device/chip) then, and it is difficult to add all the + * tds block in single adv pkt. So for each supported orgId, add only 1 tds blocks with + * incomplte tds flag bit set, in adv data. + */ +static int __bt_tds_provider_get_tds_adv_data(bt_tds_provider_t *provider, guint8 *adv_data) +{ + GSList *l; + GSList *l1; + unsigned int len = 0; + unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN; + int transport; + + retv_if(NULL == provider, -1); + retv_if(NULL == adv_data, -1); + + adv_data[1] = 0x26; + len = 2; + + for (transport = BLUETOOTH_TDS_TRANSPORT_BT; + transport < BLUETOOTH_TDS_TRANSPORT_INVALID; transport++) { + gboolean flag = FALSE; + + if (len > max_adv_len - 3) + break; + + for (l = provider_list; l != NULL; l = g_slist_next(l)) { + bt_tds_provider_t *provider = l->data; + + if (!provider) + continue; + + for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) { + bt_tds_transport_info_t *transport_info = l1->data; + + if (!transport_info || !transport_info->data || + transport_info->transport != transport) + continue; + + adv_data[len++] = transport_info->data[0]; /* Organization Id */ + adv_data[len++] = __bt_tds_set_transport_data_incomplete( + transport_info->data[1], TRUE); + adv_data[len++] = 0; /* Set Transport data len = 0 */ + flag = true; + break; + } + + if (flag) + break; + } + } + + BT_INFO("len = %d", len); + if (len <= 2) + return -1; /* No data */ + + adv_data[0] = len - 1; + return len; +} + +/* If multi adv supported set each provider's data in seperate adv slot */ +static int __bt_tds_provider_get_tds_multi_adv_data(bt_tds_provider_t *provider, guint8 *adv_data) +{ + GSList *l; + unsigned int len = 0; + unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN; + int count; + + retv_if(NULL == provider, -1); + retv_if(NULL == adv_data, -1); + + count = g_slist_length(provider->transports); + adv_data[1] = 0x26; + len = 2; + + for (l = provider->transports; l != NULL; l = g_slist_next(l)) { + bt_tds_transport_info_t *transport_info = l->data; + + if (!transport_info || !transport_info->data) + continue; + + if ((len + transport_info->data_len < max_adv_len - 3) || + (count <= 1 && (len + transport_info->data_len < max_adv_len))) { + memcpy(&(adv_data[len]), transport_info->data, transport_info->data_len); + len += transport_info->data_len; + } else { + /* Not able to accomodated complete data in adv pkt */ + adv_data[len++] = transport_info->data[0]; /* Organization Id */ + adv_data[len++] = __bt_tds_set_transport_data_incomplete( + transport_info->data[1], TRUE); + adv_data[len++] = 0; /* Set Transport data len = 0 */ + break; + } + + count--; + } + + BT_INFO("len = %d", len); + if (len <= 2) + return -1; /* No data */ + + adv_data[0] = len - 1; + return len; +} + +static int __bt_tds_set_advertising(bt_tds_provider_t *provider) +{ + bluetooth_advertising_data_t adv; + bluetooth_advertising_params_t param; + char *name = "bt-service"; + int adv_handle = 0; + int length; + int ret; + int i; + + BT_DBG("+"); + + if (provider) { + name = provider->sender; + adv_handle = provider->adv_handle; + + /* Get updated TDS advertising data */ + length = __bt_tds_provider_get_tds_multi_adv_data(provider, adv.data); + if (0 == length) + BT_INFO("No adv data found, return"); + } else { + /* No provider is present, no need to enable advertising */ + if (0 == g_slist_length(provider_list)) + return BLUETOOTH_ERROR_NONE; + + /* Get updated TDS advertising data */ + length = __bt_tds_provider_get_tds_adv_data(provider, adv.data); + if (0 == length) + BT_INFO("No adv data found, return"); + } + + /* If length <= 0, no need to start advertisement */ + if (0 >= length) + return BLUETOOTH_ERROR_NONE; + + for (i = 0; i < length; i++) + BT_DBG("adv_data: %.2X", adv.data[i]); + + ret = _bt_set_advertising_data(name, adv_handle, &adv, length, FALSE); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to set ADV %d", ret); + return ret; + } + + /* set scan response data */ + __bt_tds_set_scan_resp_data(provider); + + param.interval_min = 500; + param.interval_max = 500; + param.filter_policy = BLUETOOTH_ALLOW_SCAN_CONN_ALL; + param.type = BLUETOOTH_ADV_CONNECTABLE; + + ret = _bt_set_custom_advertising(name, adv_handle, TRUE, ¶m, FALSE); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to enable advertising with error: %d", ret); + return ret; + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +static int __bt_tds_disable_advertising(bt_tds_provider_t *provider) +{ + char *name = "bt-service"; + int adv_handle = 0; + int ret; + + BT_DBG("+"); + + if (provider) { + name = provider->sender; + adv_handle = provider->adv_handle; + } + + /* First try to disable adv in case already advertising */ + ret = _bt_set_advertising(name, adv_handle, FALSE, FALSE); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to disable advertising with error: %d", ret); + ret = __bt_tds_set_advertising(provider); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to enable advertising with error: %d", ret); + return ret; + } + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +static int __bt_tds_provider_update_transport_data(bt_tds_provider_t *provider) +{ + GDBusProxy *proxy; + GDBusConnection *conn; + char *adapter_path = NULL; + GError *error = NULL; + GVariant *result = NULL; + GVariantBuilder *builder; + GVariant *temp; + unsigned char *buf = NULL; + unsigned int length = 0; + int i; + + BT_DBG("+"); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + adapter_path = _bt_get_adapter_path(); + if (adapter_path == NULL) { + BT_ERR("Could not get adapter path\n"); + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } + + BT_INFO("Adapter path [%s]", adapter_path); + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, adapter_path, + BT_TDS_PROVIDER_INTERFACE, NULL, NULL); + g_free(adapter_path); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + buf = __bt_tds_provider_get_tds_blocks(&length); + retv_if(length == 0, BLUETOOTH_ERROR_NONE); + retv_if(NULL == buf, BLUETOOTH_ERROR_INTERNAL); + builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); + for (i = 0; i < length; i++) + g_variant_builder_add(builder, "y", buf[i]); + g_free(buf); + + temp = g_variant_new("ay", builder); + g_variant_builder_unref(builder); + result = g_dbus_proxy_call_sync(proxy, "SetTdsBlockData", + g_variant_new("(@ay)", temp), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref(proxy); + if (result == NULL) { + if (error != NULL) { + BT_ERR("Error occured in Proxy call [%s]\n", error->message); + g_error_free(error); + } else { + BT_ERR("Error occured in Proxy call: SetData"); + } + return BLUETOOTH_ERROR_INTERNAL; + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +static void __bt_free_tds_transport_info(gpointer data, gpointer user_data) +{ + bt_tds_transport_info_t *transport_info = data; + + ret_if(NULL == transport_info); + + BT_DBG("+"); + + g_free(transport_info->data); + g_free(transport_info); + + BT_DBG("-"); +} + +static bt_tds_transport_info_t * __bt_tds_find_transport_info( + bt_tds_provider_t *provider, unsigned int handle) +{ + GSList *l; + + retv_if(!provider, NULL); + + for (l = provider->transports; l != NULL; l = g_slist_next(l)) { + bt_tds_transport_info_t *transport_info = l->data; + + if (!transport_info) + continue; + + if (transport_info->tds_handle == handle) + return transport_info; + } + + return NULL; +} + +int _bt_tds_provider_register(const char *sender) +{ + GDBusProxy *proxy; + GDBusConnection *conn; + char *adapter_path = NULL; + GError *error = NULL; + GVariant *result = NULL; + bt_tds_provider_t *provider; + + retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM); + + BT_DBG("+"); + + if (__bt_tds_provider_find_from_list(sender)) + return BLUETOOTH_ERROR_ALREADY_INITIALIZED; + + if (0 == g_slist_length(provider_list)) { + /* Init adv_handle list */ + __bt_init_adv_handle(); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + adapter_path = _bt_get_adapter_path(); + if (adapter_path == NULL) { + BT_ERR("Could not get adapter path\n"); + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } + + BT_INFO("Adapter path [%s]", adapter_path); + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, adapter_path, + BT_TDS_PROVIDER_INTERFACE, NULL, NULL); + g_free(adapter_path); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + result = g_dbus_proxy_call_sync(proxy, "RegisterTdsProvider", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref(proxy); + if (result == NULL) { + if (error != NULL) { + BT_ERR("Error occured in Proxy call [%s]", error->message); + g_error_free(error); + } else { + BT_ERR("Error occured in Proxy call: RegisterTdsProvider"); + } + return BLUETOOTH_ERROR_INTERNAL; + } + } + + provider = g_malloc0(sizeof(bt_tds_provider_t)); + provider->sender = g_strdup(sender); + provider->adv_handle = __bt_provider_get_adv_handle(); + if (0 > provider->adv_handle) { + g_free(provider->sender); + g_free(provider); + return BLUETOOTH_ERROR_INTERNAL; + } + + provider_list = g_slist_append(provider_list, provider); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_tds_provider_unregister(const char *sender) +{ + GDBusProxy *proxy; + GDBusConnection *conn; + char *adapter_path = NULL; + GError *error = NULL; + GVariant *result = NULL; + bt_tds_provider_t *provider = NULL; + int ret; + + retv_if(NULL == sender, BLUETOOTH_ERROR_NOT_INITIALIZED); + + BT_DBG("+"); + + provider = __bt_tds_provider_find_from_list(sender); + if (!provider) + return BLUETOOTH_ERROR_NOT_INITIALIZED; + + if (1 == g_slist_length(provider_list)) { + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + adapter_path = _bt_get_adapter_path(); + if (adapter_path == NULL) { + BT_ERR("Could not get adapter path\n"); + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } + + BT_INFO("Adapter path [%s]", adapter_path); + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, adapter_path, + BT_TDS_PROVIDER_INTERFACE, NULL, NULL); + + g_free(adapter_path); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + result = g_dbus_proxy_call_sync(proxy, "UnregisterTdsProvider", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref(proxy); + if (result == NULL) { + if (error != NULL) { + BT_ERR("Error occured in Proxy call [%s]\n", error->message); + g_error_free(error); + } else { + BT_ERR("Error occured in Proxy call: UnregisterTdsProvider"); + } + return BLUETOOTH_ERROR_INTERNAL; + } + } + + if (_bt_is_multi_adv_supported()) { + /* Disable advertisement for sender */ + ret = _bt_set_advertising(provider->sender, provider->adv_handle, FALSE, FALSE); + if (ret != BLUETOOTH_ERROR_NONE) + BT_ERR("Failed to disable advertising with error: %d", ret); + } else { + /* + * Disable advertising here. Later on receiving advertising disabled event, + * advertising will be enabled again with updated advertising data + */ + ret = __bt_tds_disable_advertising(NULL); + if (ret != BLUETOOTH_ERROR_NONE) + BT_ERR("Failed to disable advertising with error: %d", ret); + } + + provider_list = g_slist_remove(provider_list, provider); + g_slist_foreach(provider->transports, __bt_free_tds_transport_info, NULL); + g_slist_free(provider->transports); + __bt_provider_delete_adv_handle(provider->adv_handle); + g_free(provider->sender); + g_free(provider); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_tds_provider_transport_create(const char *sender, int transport, unsigned int tds_handle) +{ + bt_tds_transport_info_t *transport_info; + bt_tds_provider_t *provider = NULL; + + retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM); + + if (BLUETOOTH_TDS_TRANSPORT_BT > transport || + BLUETOOTH_TDS_TRANSPORT_INVALID <= transport) { + BT_ERR("transport value: %d not in range", transport); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + + BT_DBG("+"); + + provider = __bt_tds_provider_find_from_list(sender); + if (!provider) + return BLUETOOTH_ERROR_NOT_INITIALIZED; + + transport_info = g_malloc0(sizeof(bt_tds_transport_info_t)); + transport_info->transport = transport; + transport_info->tds_handle = tds_handle; + transport_info->role = TDS_ROLE_PROVIDER; + transport_info->state = BLUETOOTH_TDS_TRANSPORT_STATE_OFF; + provider->transports = g_slist_append(provider->transports, transport_info); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_tds_provider_transport_remove(const char *sender, unsigned int tds_handle) +{ + bt_tds_provider_t *provider = NULL; + bt_tds_transport_info_t *transport_info; + int ret; + + retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM); + + BT_DBG("+"); + + provider = __bt_tds_provider_find_from_list(sender); + if (!provider) + return BLUETOOTH_ERROR_INVALID_PARAM; + + transport_info = __bt_tds_find_transport_info(provider, tds_handle); + if (!transport_info) + return BLUETOOTH_ERROR_INVALID_PARAM; + + provider->transports = g_slist_remove(provider->transports, transport_info); + __bt_free_tds_transport_info(transport_info, NULL); + + /* Set/update transport data in gatt db */ + ret = __bt_tds_provider_update_transport_data(provider); + if (BLUETOOTH_ERROR_NONE != ret) { + BT_ERR("Failed to update transport data with error: %d", ret); + return ret; + } + + /* + * Disable advertising here. Later on receiving advertising disabled event, + * advertising will be enabled again with updated advertising data. + */ + if (_bt_is_multi_adv_supported()) + __bt_tds_disable_advertising(provider); + else + __bt_tds_disable_advertising(NULL); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to enable advertising with error: %d", ret); + return ret; + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_tds_provider_set_manuf_data(char *sender, unsigned char *data, unsigned int len) +{ + bt_tds_provider_t *provider; + int ret; + + retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(len == 0 || len > TDS_MANUF_DATA_LEN_MAX, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(NULL == data, BLUETOOTH_ERROR_INVALID_PARAM); + + BT_DBG("+"); + + BT_INFO("sender: %s", sender); + provider = __bt_tds_provider_find_from_list(sender); + if (!provider) + return BLUETOOTH_ERROR_INVALID_PARAM; + + /* + * Set manufacturer data and disable advertising here. Later on receiving advertising + * disabled event, advertising will be enabled again with updated advertising data. + */ + if (_bt_is_multi_adv_supported()) { + g_free(provider->manuf_data); + provider->manuf_data_len = len; + provider->manuf_data = g_malloc0(provider->manuf_data_len); + memcpy(provider->manuf_data, data, len); + + ret = __bt_tds_disable_advertising(provider); + } else { + manuf_data_len = len; + memcpy(manuf_data, data, len); + ret = __bt_tds_disable_advertising(NULL); + } + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to enable advertising with error: %d", ret); + return ret; + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_tds_provider_set_transport_data(char *sender, int tds_handle, + int transport_state, unsigned char *data, unsigned int len) +{ + bt_tds_provider_t *provider; + bt_tds_transport_info_t *transport_info; + int ret; + + retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(len > 0 && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM); + + BT_DBG("+"); + + if (BLUETOOTH_TDS_TRANSPORT_STATE_OFF > transport_state || + BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED <= transport_state) { + BT_ERR("transport_state value: %d not in range", transport_state); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + + BT_INFO("sender: %s, tds_handle: %X", sender, tds_handle); + provider = __bt_tds_provider_find_from_list(sender); + if (!provider) + return BLUETOOTH_ERROR_INVALID_PARAM; + + transport_info = __bt_tds_find_transport_info(provider, tds_handle); + if (!transport_info) + return BLUETOOTH_ERROR_INVALID_PARAM; + + transport_info->state = transport_state; + g_free(transport_info->data); + transport_info->data_len = len + 3; + transport_info->data = g_malloc0(transport_info->data_len); + /* TDS Orgnazition Id */ + transport_info->data[0] = __bt_tds_get_organization_id(transport_info->transport); + /* TDS block flag */ + if (TDS_ROLE_SEEKER_PROVIDER != __bt_tds_get_role(transport_info->data[1])) + transport_info->data[1] = __bt_tds_set_role(transport_info->data[1], transport_info->role); + transport_info->data[1] = __bt_tds_set_transport_data_incomplete(transport_info->data[1], FALSE); + transport_info->data[1] = __bt_tds_set_transport_state(transport_info->data[1], transport_state); + /* TDS block data length */ + transport_info->data[2] = len; + memcpy(&(transport_info->data[3]), data, len); + + /* Set/update transport data in gatt db */ + ret = __bt_tds_provider_update_transport_data(provider); + if (BLUETOOTH_ERROR_NONE != ret) { + BT_ERR("Failed to update transport data with error: %d", ret); + return ret; + } + + /* + * Disable advertising here. Later on receiving advertising disabled event, + * advertising will be enabled again with updated advertising data. + */ + if (_bt_is_multi_adv_supported()) + ret = __bt_tds_disable_advertising(provider); + else + ret = __bt_tds_disable_advertising(NULL); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to enable advertising with error: %d", ret); + return ret; + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +static int __bt_tds_send_activation_response(char *address, + unsigned char response, unsigned char *data, unsigned int len) +{ + GDBusProxy *proxy; + GDBusConnection *conn; + char *device_path; + GError *error = NULL; + GVariant *result = NULL; + GVariantBuilder *builder; + GVariant *temp; + int i; + + retv_if(NULL == address, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(0 > len && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM); + + BT_DBG("+"); + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + device_path = _bt_get_device_object_path(address); + if (NULL == device_path) { + BT_ERR("Could not get device path\n"); + return BLUETOOTH_ERROR_INTERNAL; + } + + BT_INFO("Device path [%s]", device_path); + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, device_path, + BT_TDS_PROVIDER_INTERFACE, NULL, NULL); + g_free(device_path); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); + for (i = 0; i < len; i++) + g_variant_builder_add(builder, "y", data[i]); + + temp = g_variant_new("ay", builder); + g_variant_builder_unref(builder); + result = g_dbus_proxy_call_sync(proxy, "TdsActivationResponse", + g_variant_new("(y@ay)", response, temp), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref(proxy); + if (result == NULL) { + if (error != NULL) { + BT_ERR("Error occured in Proxy call [%s]\n", error->message); + g_error_free(error); + } else { + BT_ERR("Error occured in Proxy call: SetData"); + } + return BLUETOOTH_ERROR_INTERNAL; + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_tds_provider_send_activation_response(char *sender, unsigned int tds_handle, + bluetooth_device_address_t *address, int response, unsigned char *data, unsigned int len) +{ + bt_tds_provider_t *provider; + bt_tds_transport_info_t *transport_info; + unsigned char resp; + char addr[BT_ADDRESS_STRING_SIZE]; + int ret; + + retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(NULL == address, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(0 > len && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM); + + BT_DBG("+"); + + BT_INFO("sender: %s, tds_handle: 0x%X", sender, tds_handle); + provider = __bt_tds_provider_find_from_list(sender); + if (!provider) + return BLUETOOTH_ERROR_NOT_INITIALIZED; + + transport_info = __bt_tds_find_transport_info(provider, tds_handle); + if (!transport_info) + return BLUETOOTH_ERROR_INVALID_PARAM; + + if (BLUETOOTH_ERROR_NONE == response) { + /* Activation success, set transport state enabled */ + _bt_tds_provider_set_transport_data(provider->sender, + transport_info->transport, BLUETOOTH_TDS_TRANSPORT_STATE_ON, + transport_info->data, transport_info->data_len); + } + + _bt_convert_addr_type_to_string(addr, address->addr); + resp = __bt_tds_get_activation_response_code(response); + + ret = __bt_tds_send_activation_response(addr, resp, data, len); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to send activation response with error: %d", ret); + return ret; + } + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +void _bt_tds_handle_activation_request(const char *path, + unsigned char org_id, unsigned char *buf, int len) +{ + int transport; + char *address; + GVariant *tds_data; + GVariant *param; + int count = 0; + GSList *l; + GSList *l1; + + ret_if(NULL == path); + ret_if(len > 0 && NULL == buf); + + BT_DBG("+"); + + address = g_malloc0(BT_ADDRESS_STRING_SIZE); + _bt_convert_device_path_to_address(path, address); + transport = __bt_tds_get_transport(org_id); + BT_DBG("Address: %s, transport: %.2X", address, transport); + + if (BLUETOOTH_TDS_TRANSPORT_INVALID == transport) + goto err; + + tds_data = g_variant_new_from_data((const GVariantType *)"ay", + buf, len, TRUE, NULL, NULL); + param = g_variant_new("(si@ay)", address, transport, tds_data); + + /* Find provider with transport type in list and send event to them */ + for (l = provider_list; l != NULL; l = g_slist_next(l)) { + bt_tds_provider_t *provider = l->data; + + if (!provider) + continue; + + for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) { + bt_tds_transport_info_t *transport_info = l1->data; + + if (transport_info && transport_info->transport == transport) { + _bt_send_event_to_dest(provider->sender, BT_TDS_EVENT, + BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED, param); + count++; + } + } + } + + /* If no provider found for transport type, send error */ + if (0 == count) + goto err; + + BT_DBG("-"); + return; +err: + /* send activation response as error to bluez */ + __bt_tds_send_activation_response(address, + TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID, NULL, 0); +} + +void _bt_tds_stop_by_terminated_process(char *name) +{ + bt_tds_provider_t *provider = NULL; + + provider = __bt_tds_provider_find_from_list(name); + if (!provider) + return; + + _bt_tds_provider_unregister(provider->sender); +} + +void _bt_tds_handle_adv_disabled(const char *sender, int adv_handle) +{ + bt_tds_provider_t *provider = NULL; + + BT_INFO("sender: %s, adv_handle:%d", sender, adv_handle); + + ret_if(NULL == sender); + + if (g_strcmp0(sender, "bt-service") != 0) { + provider = __bt_tds_provider_find_from_list(sender); + if (!provider || provider->adv_handle != adv_handle) { + BT_INFO("Provider not found"); + return; + } + } else { + if (adv_handle != 0) + return; + } + + __bt_tds_set_advertising(provider); +} + +static void __bt_tds_transport_data_read_desc_cb(GObject *source_object, + GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + bt_gatt_char_descriptor_property_t att_value = { 0, }; + GDBusConnection *system_gconn = NULL; + GVariant *value = NULL; + GByteArray *gp_byte_array = NULL; + GVariantIter *iter = NULL; + guint8 g_byte; + bt_tds_data_read_req_info *info = NULL; + GVariant *out_param1; + request_info_t *req_info = NULL; + bluetooth_device_address_t device_addr = { {0} }; + int result = BLUETOOTH_ERROR_NONE; + int k; + + GVariant *var_data, *param = NULL; + char *tds_data = NULL; + char *address; + + BT_DBG("+"); + system_gconn = _bt_gdbus_get_system_gconn(); + + address = (char *)user_data; + info = __bt_tds_data_read_info_by_address(address); + + value = g_dbus_connection_call_finish(system_gconn, res, &error); + + if (error) { + BT_ERR("Error : %s \n", error->message); + g_free(address); + if (info) { + req_info = _bt_get_request_info(info->req_id); + __bt_tds_remove_data_read_req_info(info); + } + result = BLUETOOTH_ERROR_INTERNAL; + goto dbus_return; + } + + gp_byte_array = g_byte_array_new(); + g_variant_get(value, "(ay)", &iter); + + while (g_variant_iter_loop(iter, "y", &g_byte)) + g_byte_array_append(gp_byte_array, &g_byte, 1); + + if (gp_byte_array->len != 0) { + att_value.val_len = (unsigned int)gp_byte_array->len; + att_value.val = (unsigned char *)gp_byte_array->data; + } + + tds_data = (char *)g_memdup(att_value.val, att_value.val_len); + + var_data = g_variant_new_from_data((const GVariantType *)"ay", + tds_data, att_value.val_len, TRUE, NULL, NULL); + + if (info) { + param = g_variant_new("(isn@ay)", result, address, att_value.val_len, var_data); + _bt_send_event_to_dest(info->sender, BT_TDS_EVENT, + BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED, + param); + req_info = _bt_get_request_info(info->req_id); + __bt_tds_remove_data_read_req_info(info); + } + + /* DEBUG */ + for (k = 0; k < att_value.val_len; k++) + BT_DBG("Transport Data[%d] = [0x%x]", k, att_value.val[k]); + +dbus_return: + if (req_info == NULL) { + BT_ERR("TDS Complete data read Request is not found!!"); + goto done; + } + + if (req_info->context == NULL) + goto done; + + _bt_convert_addr_string_to_type(device_addr.addr, + (const char *)address); + + out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(iv)", result, out_param1)); + + _bt_delete_request_list(req_info->req_id); + +done: + /* Data free */ + if (error) + g_clear_error(&error); + if (gp_byte_array) + g_byte_array_free(gp_byte_array, TRUE); + if (address) + g_free(address); + if (value) + g_variant_unref(value); + if (iter) + g_variant_iter_free(iter); + if (tds_data) + g_free(tds_data); + BT_DBG("-"); +} + +int _bt_tds_read_transport_data(int request_id, char *sender, + bluetooth_device_address_t *dev_addr, char *handle) +{ + GDBusConnection *conn; + char *address = NULL; + bt_tds_data_read_req_info *info = NULL; + + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_PARAMETER(sender, return); + BT_CHECK_PARAMETER(dev_addr, return); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_DBG("Read Complete TDS block from Provider [Handle] [%s]", handle); + address = g_malloc0(BT_ADDRESS_STRING_SIZE); + _bt_convert_addr_type_to_string(address, dev_addr->addr); + + /* If TDS data read already pending on same Provider, then return In progress */ + if (__bt_tds_data_read_info_by_address(address) != NULL) { + BT_ERR("TDS Data Read Req is ongoing in remote provider [%s]", address); + g_free(address); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + g_dbus_connection_call(conn, + BT_BLUEZ_NAME, + handle, + GATT_DESC_INTERFACE, + "ReadValue", + NULL, + G_VARIANT_TYPE("(ay)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback)__bt_tds_transport_data_read_desc_cb, + (gpointer)address); + + /* Save Info in pending list */ + info = g_malloc0(sizeof(bt_tds_data_read_req_info)); + info->remote_address = g_strdup(address); + info->sender = g_strdup(sender); + info->req_id = request_id; + tds_data_read_req_info_list = g_slist_append(tds_data_read_req_info_list, info); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +static void __bluetooth_internal_control_point_enable_request_cb(GObject *source_object, + GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + GDBusConnection *system_gconn = NULL; + GVariant *value = NULL; + GVariant *param = NULL; + GVariant *out_param1 = NULL; + int result = BLUETOOTH_ERROR_NONE; + char *address = NULL; + bt_tds_activation_info *info = NULL; + request_info_t *req_info = NULL; + bluetooth_device_address_t device_addr = { {0} }; + BT_DBG("+"); + + system_gconn = _bt_gdbus_get_system_gconn(); + value = g_dbus_connection_call_finish(system_gconn, res, &error); + + if (error) { + BT_ERR("Error : %s \n", error->message); + if (g_strrstr(error->message, "Already notifying")) + result = BLUETOOTH_ERROR_NONE; + else if (g_strrstr(error->message, "In Progress")) + result = BLUETOOTH_ERROR_IN_PROGRESS; + else if (g_strrstr(error->message, "Operation is not supported")) + result = BLUETOOTH_ERROR_NOT_SUPPORT; + else if (g_strrstr(error->message, "Write not permitted") || + g_strrstr(error->message, "Operation Not Authorized")) + result = BLUETOOTH_ERROR_PERMISSION_DEINED; + else if (g_strrstr(error->message, "Not paired")) + result = BLUETOOTH_ERROR_NOT_PAIRED; + else + result = BLUETOOTH_ERROR_INTERNAL; + } else { + BT_DBG("TDS CCCD enable request successful, send event to BT App"); + } + + address = (char *)user_data; + info = __bt_tds_activation_info_by_address(address); + + if (info) + req_info = _bt_get_request_info(info->req_id); + + /* If CCCD Enable request failed for any reason, reset timer */ + if (result != BLUETOOTH_ERROR_NONE && info != NULL) { + BT_ERR("Activation Request failed"); + /* Reset Timer */ + if (info->activation_timeout_id > 0) { + g_source_remove(info->activation_timeout_id); + info->activation_timeout_id = 0; + } + + /* Remove Indication Info */ + __bt_tds_remove_indication_info(info); + } else { + /* CCCD Enable Request successful */ + if (info) { + param = g_variant_new("(is)", result, address); + _bt_send_event_to_dest(info->sender, BT_TDS_EVENT, + BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED, + param); + } + } + + if (req_info == NULL) { + BT_ERR("TDS Control Point CCCD Enable Request is not found!!"); + goto done; + } + + if (req_info->context == NULL) + goto done; + + _bt_convert_addr_string_to_type(device_addr.addr, + (const char *)address); + + out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(iv)", result, out_param1)); + + _bt_delete_request_list(req_info->req_id); + +done: + if (value) + g_variant_unref(value); + if (error) + g_clear_error(&error); + if (address) + g_free(address); + + BT_DBG("-"); + return; +} + +int _bt_tds_enable_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr, + char *handle) +{ + GDBusConnection *conn; + char *address = NULL; + bt_tds_activation_info *info = NULL; + + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_PARAMETER(sender, return); + BT_CHECK_PARAMETER(dev_addr, return); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_DBG("TDS Control point CCCD Handle [%s]", handle); + + address = g_malloc0(BT_ADDRESS_STRING_SIZE); + _bt_convert_addr_type_to_string(address, dev_addr->addr); + + if (__bt_tds_activation_info_by_address(address) != NULL) { + BT_ERR("Activation is already ongoing for same remote provider"); + g_free(address); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + BT_INFO("Start Notify to Bluez"); + g_dbus_connection_call(conn, + BT_BLUEZ_NAME, + handle, + GATT_CHAR_INTERFACE, + "StartNotify", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + GATT_DEFAULT_TIMEOUT, NULL, + (GAsyncReadyCallback)__bluetooth_internal_control_point_enable_request_cb, + (gpointer)address); + + info = g_malloc0(sizeof(bt_tds_activation_info)); + info->remote_address = g_strdup(address); + info->sender = g_strdup(sender); + info->req_id = request_id; + tds_activation_info_list = g_slist_append(tds_activation_info_list, info); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +static void __bluetooth_internal_activation_request_cb(GObject *source_object, + GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + GDBusConnection *system_gconn = NULL; + GVariant *value = NULL; + GVariant *param = NULL; + GVariant *out_param1 = NULL; + int result = BLUETOOTH_ERROR_NONE; + guint8 att_ecode = 0; + char *address = NULL; + bt_tds_activation_info *info = NULL; + request_info_t *req_info = NULL; + bluetooth_device_address_t device_addr = { {0} }; + BT_DBG("+"); + + system_gconn = _bt_gdbus_get_system_gconn(); + value = g_dbus_connection_call_finish(system_gconn, res, &error); + + if (error) { + BT_ERR("Error : %s \n", error->message); + result = BLUETOOTH_ERROR_INTERNAL; + } else { + g_variant_get(value, "(y)", &att_ecode); + if (att_ecode) { + result = BLUETOOTH_ERROR_INTERNAL; + BT_ERR("ATT Error code: %d \n", att_ecode); + } + } + + address = (char *)user_data; + info = __bt_tds_activation_info_by_address(address); + if (info) + req_info = _bt_get_request_info(info->req_id); + + /* Is Activation request failed for any reason, reset timer */ + if (result != BLUETOOTH_ERROR_NONE && info != NULL) { + BT_ERR("Activation Request failed"); + /* Reset Timer */ + if (info->activation_timeout_id > 0) { + g_source_remove(info->activation_timeout_id); + info->activation_timeout_id = 0; + } + + /* Remove Indication Info */ + __bt_tds_remove_indication_info(info); + } else { + /* Activation Request successful */ + if (info) { + param = g_variant_new("(is)", result, address); + _bt_send_event_to_dest(info->sender, BT_TDS_EVENT, + BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT, + param); + } + } + + if (req_info == NULL) { + BT_ERR("TDS Control Point Activation Request is not found!!"); + goto done; + } + + if (req_info->context == NULL) + goto done; + + _bt_convert_addr_string_to_type(device_addr.addr, + (const char *)address); + + out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(iv)", result, out_param1)); + + _bt_delete_request_list(req_info->req_id); + +done: + if (value) + g_variant_unref(value); + if (error) + g_clear_error(&error); + if (address) + g_free(address); + + BT_DBG("-"); + return; +} + +static bool __bt_tds_indication_timeout_cb(gpointer user_data) +{ + char *address = NULL; + address = (char*) user_data; + bt_tds_activation_info *info = NULL; + /* Indication:Fail*/ + unsigned char buffer[2] = {0x01, 0x04}; + + BT_DBG("Activation timer Expired [Provider] [%s]", address); + + info = __bt_tds_activation_info_by_address(address); + if (info) + __bt_tds_send_indication_event(info, buffer, sizeof(buffer)); + return FALSE; +} + +int _bt_tds_activate_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr, + char *handle, unsigned char *param, int length) +{ + GVariant *val; + GVariantBuilder *builder; + int i; + bt_tds_activation_info *info = NULL; + GDBusConnection *conn; + char *address = NULL; + BT_DBG("+"); + + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_PARAMETER(sender, return); + BT_CHECK_PARAMETER(dev_addr, return); + BT_CHECK_PARAMETER(param, return); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_DBG("TDS Control point Activate handle [%s] data length [%d]", handle, length); + /* Check if activation is ongoing for the same Remote Provider */ + address = g_malloc0(BT_ADDRESS_STRING_SIZE); + _bt_convert_addr_type_to_string(address, dev_addr->addr); + + info = __bt_tds_activation_info_by_address(address); + if (info && info->activation_timeout_id > 0) { + BT_ERR("Activation is already ongoing in remote provider"); + g_free(address); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); + + for (i = 0; i < length; i++) + g_variant_builder_add(builder, "y", param[i]); + + val = g_variant_new("(ay)", builder); + + /* Activate Control Point */ + g_dbus_connection_call(conn, + BT_BLUEZ_NAME, + handle, + GATT_CHAR_INTERFACE, + "WriteValue", + val, + G_VARIANT_TYPE("(y)"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, + (GAsyncReadyCallback)__bluetooth_internal_activation_request_cb, + (gpointer)address); + + g_variant_builder_unref(builder); + + if (info == NULL) { + info = g_malloc0(sizeof(bt_tds_activation_info)); + info->remote_address = g_strdup(address); + info->sender = g_strdup(sender); + tds_activation_info_list = g_slist_append(tds_activation_info_list, info); + } + info->req_id = request_id; + info->activation_timeout_id = g_timeout_add(BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX, + (GSourceFunc)__bt_tds_indication_timeout_cb, (gpointer)info->remote_address); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address) +{ + GSList *l; + bt_tds_activation_info *info = NULL; + + for (l = tds_activation_info_list; l != NULL; l = g_slist_next(l)) { + info = (bt_tds_activation_info*)l->data; + if (info == NULL) + continue; + + if (!g_strcmp0(info->remote_address, address)) { + BT_INFO("Seeker found waiting for Ind from Provider addr[%s]", + info->remote_address); + return info; + } + } + return NULL; +} + +static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address) +{ + GSList *l; + bt_tds_data_read_req_info *info = NULL; + + for (l = tds_data_read_req_info_list; l != NULL; l = g_slist_next(l)) { + info = (bt_tds_data_read_req_info*)l->data; + if (info == NULL) + continue; + + if (!g_strcmp0(info->remote_address, address)) { + BT_INFO("Found waiting for Transport Data Read from Provider addr[%s]", + info->remote_address); + return info; + } + } + return NULL; +} + +static void __bt_tds_remove_indication_info(bt_tds_activation_info *info) +{ + BT_DBG("Removing Indication Info [%s]", info->remote_address); + + tds_activation_info_list = g_slist_remove(tds_activation_info_list, info); + if (info->remote_address) + g_free(info->remote_address); + if (info->sender) + g_free(info->sender); + if (info->activation_timeout_id > 0) { + g_source_remove(info->activation_timeout_id); + info->activation_timeout_id = 0; + } + g_free(info); +} + +static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info) +{ + BT_DBG("Removing Read Req Info [%s]", info->remote_address); + + tds_data_read_req_info_list = g_slist_remove(tds_data_read_req_info_list, info); + if (info->remote_address) + g_free(info->remote_address); + if (info->sender) + g_free(info->sender); + g_free(info); +} + +static void __bt_tds_send_indication_event(bt_tds_activation_info *info, + unsigned char *buffer, int len) +{ + GVariant *tds_data; + GVariant *param; + + tds_data = g_variant_new_from_data((const GVariantType *)"ay", + buffer, len, TRUE, NULL, NULL); + + BT_DBG("Send Indication event to sender"); + param = g_variant_new("(s@ay)", info->remote_address, tds_data); + _bt_send_event_to_dest(info->sender, BT_TDS_EVENT, + BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION, + param); + + /* Remove info from list */ + __bt_tds_remove_indication_info(info); +} + +void _bt_tds_check_indication(const char *path, GVariant *msg) +{ + char address[BT_ADDRESS_STRING_SIZE] = {0}; + bt_tds_activation_info *info = NULL; + unsigned char *buffer = NULL; + int len = 0; + int i; + GVariant *value = NULL; + BT_DBG("+"); + + _bt_convert_device_path_to_address(path, address); + info = __bt_tds_activation_info_by_address(address); + + if (info) { + g_variant_get(msg, "(is@ay)", NULL, NULL, &value); + len = g_variant_get_size(value); + BT_DBG("Indication data from Provider len[%d]", len); + if (len > 0) { + buffer = (unsigned char *)g_variant_get_data(value); + /* DEBUG */ + for (i = 0; i < len; i++) + BT_DBG("%.2x", buffer[i]); + } + + /* Reset Timer */ + if (info->activation_timeout_id > 0) + g_source_remove(info->activation_timeout_id); + + /* Send Indication & info removed internally */ + __bt_tds_send_indication_event(info, buffer, len); + + if (value) + g_variant_unref(value); + } + BT_DBG("-"); +} diff --git a/bt-service/include/bt-service-adapter-le.h b/bt-service/include/bt-service-adapter-le.h index 124a270..97763f8 100644 --- a/bt-service/include/bt-service-adapter-le.h +++ b/bt-service/include/bt-service-adapter-le.h @@ -133,20 +133,12 @@ int _bt_initialize_ipsp(void); int _bt_deinitialize_ipsp(void); -void _bt_init_gatt_client_senders(void); - -int _bt_insert_gatt_client_sender(char *sender); - -int _bt_delete_gatt_client_sender(char *sender); - -void _bt_clear_gatt_client_senders(void); - -void _bt_send_char_value_changed_event(void *param); - gboolean _bt_is_set_scan_parameter(void); void _bt_unregister_adv_slot_owner(int slot_id); +gboolean _bt_is_multi_adv_supported(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bt-service/include/bt-service-audio.h b/bt-service/include/bt-service-audio.h index 8bc9875..3659ad1 100644 --- a/bt-service/include/bt-service-audio.h +++ b/bt-service/include/bt-service-audio.h @@ -112,6 +112,9 @@ void _bt_add_headset_to_list(int type, int status, const char *address); void _bt_remove_headset_from_list(int type, const char *address); gboolean _bt_is_headset_type_connected(int type, char *address); +#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT +void _bt_check_already_connected_headset(int type, char *address); +#endif void _bt_remove_from_connected_list(const char *address); int _bt_get_device_state_from_list(int type, const char *address); diff --git a/bt-service/include/bt-service-common.h b/bt-service/include/bt-service-common.h index a85ef2a..feb43ef 100644 --- a/bt-service/include/bt-service-common.h +++ b/bt-service/include/bt-service-common.h @@ -126,6 +126,7 @@ extern "C" { #define BT_BLUEZ_NAME "org.bluez" +#define BT_IPSP_NAME "org.projectx.bt_ipsp" #define BT_BLUEZ_PATH "/org/bluez" #define BT_BLUEZ_HCI_PATH "/org/bluez/hci0" #define BT_AGENT_NAME "org.bluez.frwk_agent" @@ -137,6 +138,7 @@ extern "C" { #define BT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager" #define BT_ADAPTER_INTERFACE "org.bluez.Adapter1" +#define BT_IPSP_INTERFACE "org.projectx.bt_ipsp" #define BT_AGENT_INTERFACE "org.bluez.Agent1" #define BT_AGENT_MANAGER_INTERFACE "org.bluez.AgentManager1" #define BT_DEVICE_INTERFACE "org.bluez.Device1" @@ -165,6 +167,7 @@ extern "C" { #define BT_A2DP_SOURCE_INTERFACE "org.bluez.AudioSource" #define BT_PROXIMITY_MONITOR_INTERFACE "org.bluez.ProximityMonitor1" #define BT_PROXIMITY_REPORTER_INTERFACE "org.bluez.ProximityReporter1" +#define BT_TDS_PROVIDER_INTERFACE "org.bluez.TdsServiceProvider1" #define BT_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" @@ -172,7 +175,7 @@ extern "C" { #define BT_OBEX_CLIENT_PATH "/org/bluez/obex" #define BT_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1" - +#define BT_OBEX_MESSAGE_INTERFACE "org.bluez.obex.MessageAccess1" #define BT_OBEX_TRANSFER_INTERFACE "org.bluez.obex.Transfer1" #define BT_OBEX_AGENT_INTERFACE "org.bluez.obex.Agent1" @@ -232,6 +235,7 @@ extern "C" { #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb" #define OBEX_OPP_UUID "00001105-0000-1000-8000-00805f9b34fb" +#define OBEX_MAP_UUID "00001134-0000-1000-8000-00805f9b34fb" #define OBEX_PSE_UUID "0000112f-0000-1000-8000-00805f9b34fb" #define GATT_UUID "00001801-0000-1000-8000-00805f9b34fb" @@ -267,6 +271,7 @@ typedef enum { BT_SCAN_RSP_INFO = 0x01, } bt_le_device_info_type_t; +/* Profile type matched to bluetooth_service_type_t of bluetooth-api.h */ typedef enum { BT_PROFILE_CONN_RFCOMM = 0x01, BT_PROFILE_CONN_A2DP = 0x02, @@ -335,15 +340,21 @@ GDBusProxy *_bt_get_manager_proxy(void); GDBusProxy *_bt_get_adapter_proxy(void); +GDBusProxy *_bt_get_ipsp_proxy(void); + GDBusProxy *_bt_get_adapter_properties_proxy(void); char *_bt_get_device_object_path(char *address); char *_bt_get_profile_uuid128(bt_profile_type_t profile_type); -char *_bt_convert_error_to_string(int error); +const char *_bt_convert_uuid_to_string(const char *uuid); + +const char *_bt_convert_error_to_string(int error); + +const char *_bt_convert_disc_reason_to_string(int reason); -char * _bt_convert_disc_reason_to_string(int reason); +const char *_bt_convert_service_function_to_string(int function); void _bt_logging_connection(gboolean connect, int addr_type); diff --git a/bt-service/include/bt-service-event.h b/bt-service/include/bt-service-event.h index 1a4cd75..4312e8f 100644 --- a/bt-service/include/bt-service-event.h +++ b/bt-service/include/bt-service-event.h @@ -38,6 +38,9 @@ void _bt_deinit_service_event_receiver(void); int _bt_opp_client_event_init(void); void _bt_opp_client_event_deinit(void); +int _bt_map_client_event_init(void); +void _bt_map_client_event_deinit(void); + int _bt_send_hf_local_term_event(char *address); int _bt_init_hf_local_term_event_sender(void); void _bt_deinit_hf_local_term_event_sender(void); diff --git a/bt-service/include/bt-service-headset-connection.h b/bt-service/include/bt-service-headset-connection.h old mode 100755 new mode 100644 index 1cf4cd3..d7ebebf --- a/bt-service/include/bt-service-headset-connection.h +++ b/bt-service/include/bt-service-headset-connection.h @@ -23,7 +23,9 @@ #define ERR(fmt, args...) SLOGE(fmt, ##args) #define CONNECT_TIMEOUT (3 * 1000) - +#ifdef TIZEN_BT_DUAL_HEADSET_CONNECT +#define MAX_CONNECTED_HEADSET 2 +#endif void _bt_headset_set_local_connection(gboolean value); gboolean _bt_headset_get_local_connection(); void _bt_start_timer_for_connection(char *remote_address, int connection_type); diff --git a/bt-service/include/bt-service-map-client.h b/bt-service/include/bt-service-map-client.h new file mode 100644 index 0000000..4adde5d --- /dev/null +++ b/bt-service/include/bt-service-map-client.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#ifndef _BT_SERVICE_MAP_CLIENT_H_ +#define _BT_SERVICE_MAP_CLIENT_H_ + +#include +#include +#include +#include "bluetooth-api.h" +#include "bt-internal-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BT_OBEX_CLIENT_AGENT_PATH "/org/obex/client_agent" + +/* TODO: MAP */ + +typedef struct { + int request_id; + int result; + + char *session_path; + + char *address; + +/* int file_count; + int file_offset; + char **file_name_array; + gboolean is_canceled; */ + + /* TODO: MAP */ + +} bt_session_info_t; /* TODO: "session"? */ + +typedef struct { + char *address; + int request_id; + + /* char **file_path; + int file_count; */ + + /* TODO: MAP */ + +} bt_session_data_t; /* TODO: "session"? */ + +int _bt_create_session_sync( + const char* address, + char** session_id); +int _bt_destroy_session_sync( + const char* session_id); +int _bt_map_client_set_folder( + const char* session_id, + const char* name); +int _bt_map_client_list_folders( + int request_id, + GDBusMethodInvocation *context, + const char* session_id, + const char* filter_serialized); +int _bt_map_client_list_filter_fields( + int request_id, + GDBusMethodInvocation *context, + const char* session_id); +int _bt_map_client_list_messages( + int request_id, + GDBusMethodInvocation *context, + const char* session_id, + const char* folder, + const char* filter_serialized); +int _bt_map_client_update_inbox( + const char* session_id); +int _bt_map_client_push_message( + int request_id, + GDBusMethodInvocation *context, + const char* session_id, + const char* source_file, + const char* folder, + const char* args_serialized); +int _bt_map_client_get_message( + int request_id, + GDBusMethodInvocation *context, + const char* message_object, + const char* target_file, + bool attachment); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /*_BT_SERVICE_MAP_CLIENT_H_*/ diff --git a/bt-service/include/bt-service-tds.h b/bt-service/include/bt-service-tds.h new file mode 100644 index 0000000..edad85a --- /dev/null +++ b/bt-service/include/bt-service-tds.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _BT_SERVICE_TDS_H_ +#define _BT_SERVICE_TDS_H_ + +#include +#include +#include "bluetooth-api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int _bt_tds_provider_register(const char *sender); + +int _bt_tds_provider_unregister(const char *sender); + +int _bt_tds_provider_transport_create(const char *sender, int transport, unsigned int tds_handle); + +int _bt_tds_provider_transport_remove(const char *sender, unsigned int tds_handle); + +int _bt_tds_provider_set_transport_data(char *sender, int tds_handle, + int transport_state, unsigned char *data, unsigned int len); + +int _bt_tds_provider_set_manuf_data(char *sender, unsigned char *data, unsigned int len); + +int _bt_tds_provider_send_activation_response(char *sender, unsigned int tds_handle, + bluetooth_device_address_t *address, int response, unsigned char *data, unsigned int len); + +void _bt_tds_handle_activation_request(const char *path, unsigned char org_id, unsigned char *buf, int len); + +void _bt_tds_stop_by_terminated_process(char *name); + +void _bt_tds_handle_adv_disabled(const char *sender, int adv_handle); + +int _bt_tds_read_transport_data(int request_id, char *sender, + bluetooth_device_address_t *dev_addr, char *handle); + +int _bt_tds_enable_control_point(int request_id, char *sender, + bluetooth_device_address_t *dev_addr, char *handle); + +int _bt_tds_activate_control_point(int request_id, char *sender, + bluetooth_device_address_t *dev_addr, char *handle, + unsigned char *param, int length); + +void _bt_tds_check_indication(const char *path, GVariant *msg); + +void _bt_tds_insert_seeker(char *sender, char *address); + +void _bt_tds_delete_seeker(char *sender, char *address); + +void _bt_clear_tds_seekers(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /*_BT_SERVICE_TDS_H_*/ diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index 8129a1c..1dac034 100644 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -19,6 +19,7 @@ #define _BLUETOOTH_API_H_ #include +#include #include #include @@ -35,6 +36,7 @@ extern "C" { * @{ */ +#define BLUETOOTH_ADDRESS_STRING_LENGTH 17 /**< This specifies bluetooth device address length (AA:BB:CC:DD:EE:FF) */ #define BLUETOOTH_ADDRESS_LENGTH 6 /**< This specifies bluetooth device address length */ #define BLUETOOTH_VERSION_LENGTH_MAX 30 /**< This specifies bluetooth device version length */ #define BLUETOOTH_INTERFACE_NAME_LENGTH 16 @@ -76,6 +78,9 @@ extern "C" { #define BLUETOOTH_MAX_DPM_LIST 20 /**< This specifies maximum number of devices/uuids dpm shall store */ +#define BLUETOOTH_TDS_DATA_LENGTH_MAX 239 /**< This specifies maximum AD data length: 0xEF */ +#define BLUETOOTH_TDS_CONTROL_POINT_PARAM_LENGTH_MAX 500 /**< TDS Control Point parameter Max length */ + /** * This is Bluetooth error code */ @@ -186,6 +191,10 @@ extern "C" { #define BLUETOOTH_ERROR_LOCAL_HOST_TERM 0x16 #define BLUETOOTH_ERROR_REPEATED_ATTEMPTS 0x17 #define BLUETOOTH_ERROR_LMP_RESPONSE_TIMEOUT 0x22 +#define BLUETOOTH_ERROR_LMP_TRANSACTION_COLLISION 0x23 +#define BLUETOOTH_ERROR_INSTANT_PASSED 0x28 +#define BLUETOOTH_ERROR_INSUFFICIENT_SECURITY 0x2f +#define BLUETOOTH_ERROR_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE 0x3d #define BLUETOOTH_ERROR_CONNECTION_FAILED_TO_BE_ESTABLISHED 0x3e @@ -287,6 +296,7 @@ typedef enum { /** * Service type + * Service type matched to bt_profile_type_t of bt-service-common.h */ typedef enum { BLUETOOTH_RFCOMM_SERVICE = 0x01, @@ -412,6 +422,68 @@ typedef enum { } bluetooth_pxp_poperty_t; /** + * TDS transport Type + */ +typedef enum { + BLUETOOTH_TDS_TRANSPORT_BT = 0x01, /* Transport type BR-EDR */ + BLUETOOTH_TDS_TRANSPORT_CUSTOM, /* Transport type custom */ + /* ... */ + BLUETOOTH_TDS_TRANSPORT_INVALID +} bluetooth_tds_transport_t; + +/** + * TDS transport state + */ +typedef enum { + BLUETOOTH_TDS_TRANSPORT_STATE_OFF = 0, + BLUETOOTH_TDS_TRANSPORT_STATE_ON, + BLUETOOTH_TDS_TRANSPORT_STATE_UNAVAILABLE, + BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED +} bluetooth_tds_transport_state_t; + +/** +* TDS data +*/ +typedef struct { + int length; + guint8 data[BLUETOOTH_TDS_DATA_LENGTH_MAX]; +} bluetooth_tds_data_t; + +/** +* TDS activation request +*/ +typedef struct { + bluetooth_device_address_t rem_addr; + bluetooth_tds_transport_t transport; + bluetooth_tds_data_t tds_data; +} bluetooth_tds_activation_req_t; + +/** +* TDS Control Point data +*/ +typedef struct { + int length; /**< Control point data length */ + guint8 data[BLUETOOTH_TDS_CONTROL_POINT_PARAM_LENGTH_MAX]; /**< Control pint param data */ +} bluetooth_control_point_data_t; + +/** +* TDS Indication Response data +*/ +typedef struct { + bluetooth_device_address_t rem_addr; /**< Device address */ + bluetooth_control_point_data_t tds_data; /**< TDS Control Point Indication params */ +} bluetooth_tds_indication_res_t; + +/** +* Structure to hold the TDS Complete data information which is read from remote TDS provider +*/ +typedef struct { + bluetooth_device_address_t device_address; /**< Device address */ + int data_length; /**< Data length */ + char *data; /**< Complete Transport Specific data */ +} bluetooth_tds_transport_data_info_t; + +/** * Advertising parameters */ typedef struct { @@ -509,6 +581,8 @@ typedef struct { /**< Base ID for AVRCP events */ #define BLUETOOTH_EVENT_IPSP_BASE ((int)(BLUETOOTH_EVENT_AVRCP_CONTROL_BASE + 0x0020)) /**< Base ID for IPSP events */ +#define BLUETOOTH_EVENT_MAP_BASE ((int)(BLUETOOTH_EVENT_IPSP_BASE + 0x0020)) + /**< Base ID for MAP events */ /** * Bluetooth event type @@ -588,6 +662,29 @@ typedef enum { BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS, /* OPC Transfer progress event */ BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE, /* OPC Transfer Complete event */ + BLUETOOTH_EVENT_MAP_CONNECTED = BLUETOOTH_EVENT_MAP_BASE, + BLUETOOTH_EVENT_MAP_DISCONNECTED, + /* + BLUETOOTH_EVENT_MAP_SET_FOLDER_COMPLETE, + BLUETOOTH_EVENT_MAP_SET_FOLDER_INVALID_ARGUMENTS, + BLUETOOTH_EVENT_MAP_SET_FOLDER_FAILED, + BLUETOOTH_EVENT_MAP_UPDATE_INBOX_COMPLETE, + BLUETOOTH_EVENT_MAP_UPDATE_INBOX_FAILED, + */ + BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, + BLUETOOTH_EVENT_MAP_LIST_FOLDERS_INVALID_ARGUMENTS, + BLUETOOTH_EVENT_MAP_LIST_FOLDERS_FAILED, + BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, + BLUETOOTH_EVENT_MAP_LIST_MESSAGES_INVALID_ARGUMENTS, + BLUETOOTH_EVENT_MAP_LIST_MESSAGES_FAILED, + BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE, + BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_INVALID_ARGUMENTS, + BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_FAILED, + BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE, + BLUETOOTH_EVENT_MAP_GET_MESSAGE_INVALID_ARGUMENTS, + BLUETOOTH_EVENT_MAP_GET_MESSAGE_FAILED, + BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE, + BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE = BLUETOOTH_EVENT_OBEX_SERVER_BASE, /* Obex server authorize event*/ BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED, /* Obex Server transfer started event*/ @@ -696,6 +793,11 @@ typedef enum { BLUETOOTH_EVENT_IPSP_INTERFACE_INFO, /** IPSP BT Interface Info after connection */ BLUETOOTH_EVENT_LE_DATA_LENGTH_CHANGED, /** LE data length values changed */ BLUETOOTH_EVENT_PXP_PROPERTY_CHANGED, /** Proximity property changed */ + BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED, /** TDS activation requested */ + BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED, /** TDS Transport Data received */ + BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT, /** TDS Activation Result */ + BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED, /** TDS CCCD enabled event */ + BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION, /** TDS Activation Indication from Provider */ } bluetooth_event_type_t; /** @@ -709,6 +811,7 @@ typedef enum { BLUETOOTH_DUN_PROFILE_UUID = ((unsigned short)0x1103), /** ALL ARE COMMON. - profile = _PROFILE_COMMON; + case 'm': + case 'M': + profile = _PROFILE_MOBILE; + break; + case 'w': + case 'W': + profile = _PROFILE_WEARABLE; + break; + case 't': + case 'T': + profile = _PROFILE_TV; + break; + case 'i': + case 'I': + profile = _PROFILE_IVI; + break; + default: // common or unknown ==> ALL ARE COMMON. + profile = _PROFILE_COMMON; } free(profileName); diff --git a/packaging/bluetooth-frwk.spec b/packaging/bluetooth-frwk.spec index 66deb96..6ff27da 100644 --- a/packaging/bluetooth-frwk.spec +++ b/packaging/bluetooth-frwk.spec @@ -160,6 +160,9 @@ export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" %ifarch x86_64 export CFLAGS="$CFLAGS -Wall -g -fvisibility=hidden -fPIC" +export CFLAGS+=" -DARCH64" +export CXXFLAGS+=" -DARCH64" +export FFLAGS+=" -DARCH64" %else export CFLAGS="$CFLAGS -fpie" export LDFLAGS="$CFLAGS -pie" -- 2.7.4