X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-oal%2Fbluez_hal%2Fsrc%2Fbt-hal-gatt-server.c;h=b90ed57b446555e993ef13a5dbd745caf1e4a4cb;hb=e8132a5b1e7fc5a1e8feab203393d3f772fbebd2;hp=fa29c69f6ef19f649d4996f146a5ca86a8c45423;hpb=243fc81f3bf1ed11a17cddd17bf95ff0394ca526;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-server.c b/bt-oal/bluez_hal/src/bt-hal-gatt-server.c index fa29c69..b90ed57 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-server.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-server.c @@ -111,6 +111,8 @@ typedef enum { BT_HAL_GATT_REQUEST_TYPE_READ = 0x00, /* Read Requested */ BT_HAL_GATT_REQUEST_TYPE_WRITE = 0x01, /* Write Requested */ BT_HAL_GATT_REQUEST_TYPE_EXEC_WRITE = 0x02, /* Exec Write Requested */ + BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE = 0x03, /* Exec Write Requested */ + BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY = 0x04, /* Exec Write Requested */ } bt_gatt_request_type_e; struct gatt_req_info { @@ -239,6 +241,16 @@ static const gchar characteristics_introspection_xml[] = " " " " " " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " " " @@ -263,6 +275,10 @@ static const gchar characteristics_introspection_xml[] = " " " " " " +" " +" " +" " +" " " " ""; @@ -599,6 +615,8 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, GSList *gatt_services = NULL; int *instance; instance = (int*)user_data; + gboolean writeAcquired = FALSE; + gboolean notifyAcquired = FALSE; DBG("Getting values for service, chars and descriptors"); DBG("GATT Server App for which services are requested [%d]", *instance); @@ -719,6 +737,11 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, for (i = 0; i < char_info->flags_length; i++) { g_variant_builder_add(builder2, "s", char_info->char_flags[i]); + if (strncmp(char_info->char_flags[i], "write-without-response", 16) == 0) + writeAcquired = TRUE; + + if (strncmp(char_info->char_flags[i], "notify", 4) == 0) + notifyAcquired = TRUE; } flags_val = g_variant_new("as", builder2); @@ -730,6 +753,14 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, g_variant_new("b", notify)); /* Unicast */ + g_variant_builder_add(inner_builder, "{sv}", "WriteAcquired", + g_variant_new("b", writeAcquired)); + + /* NotifyAcquired */ + g_variant_builder_add(inner_builder, "{sv}", "NotifyAcquired", + g_variant_new("b", notifyAcquired)); + + /* Unicast */ unicast = g_strdup("00:00:00:00:00:00"); g_variant_builder_add(inner_builder, "{sv}", "Unicast", g_variant_new("s", unicast)); @@ -1250,8 +1281,149 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection, _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr); event_cb(HAL_EV_GATT_INDICATE_CFM, (void *)&ev, sizeof(ev)); + } else if (g_strcmp0(method_name, "AcquireWrite") == 0) { + + uint16_t mtu = 512; + int char_hdl = -1; + struct hal_ev_gatt_server_acquire_write_res ev; + struct gatt_service_info *svc_info = NULL; + struct gatt_req_info *req_info = NULL; + struct gatt_client_info_t *conn_info = NULL; + char * dev_path = NULL; + char * link = 0; + char addr[BT_HAL_ADDRESS_STRING_SIZE]; + + DBG("AcquireWrite"); + DBG("Application path = %s", object_path); + DBG("Sender = %s", sender); + + GVariantIter* iter; + g_variant_get(parameters, "(a{sv})", &iter); + char* key = NULL; + GVariant* value = NULL; + while (g_variant_iter_loop(iter, "{sv}", &key, &value)) { + if (g_strcmp0(key, "MTU") == 0) + g_variant_get(value, "i", &mtu); + else if (g_strcmp0(key, "link") == 0) + g_variant_get(value, "s", &link); + else if (g_strcmp0(key, "device") == 0) + g_variant_get(value, "o", &dev_path); + } + + DBG("AcquireWrite values retived"); + DBG(" path %s LINK = %s, MTU = %u", addr, link, mtu); + + svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl); + + _bt_hal_convert_device_path_to_address(dev_path, addr); + + DBG("remote adress %s", addr); + + /* Check if device is already in connected list */ + conn_info = __bt_find_remote_gatt_client_info(addr); + + if (conn_info == NULL) { + ERR("Cleint info not found\n"); + goto done; + } + + if (svc_info == NULL) { + ERR("svc_info info not found\n"); + goto done; + } + + /* 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(svc_info->serv_path); + req_info->request_id = conn_info->connection_id; + req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE; + req_info->offset = mtu; + req_info->context = invocation; + + /* Append request info in list of requests for the particular connection */ + conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info); + + /* Send HAL event */ + memset(&ev, 0, sizeof(ev)); + ev.conn_id = conn_info->connection_id; + ev.char_handl = char_hdl; + ev.mtu = mtu; + ev.trans_id = conn_info->connection_id; + _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr); + event_cb(HAL_EV_GATT_SERVER_ACQUIRE_WRITE_RES, (void *)&ev, sizeof(ev)); + + DBG("HAL_EV_GATT_ACQUIRE_WRITE_RES called"); + + + return; + } else if (g_strcmp0(method_name, "AcquireNotify") == 0) { + + uint16_t mtu = 512; + int char_hdl = -1; + struct hal_ev_gatt_server_acquire_notify ev; + struct gatt_service_info *svc_info = NULL; + struct gatt_client_info_t *conn_info = NULL; + struct gatt_req_info *req_info = NULL; + char * link = 0; + int len = 0; + + DBG("AcquireNotify"); + DBG("Application path = %s", object_path); + DBG("Sender = %s", sender); + + GVariantIter* iter; + g_variant_get(parameters, "(a{sv})", &iter); + char* key = NULL; + GVariant* value = NULL; + while (g_variant_iter_loop(iter, "{sv}", &key, &value)) { + if (g_strcmp0(key, "MTU") == 0) + g_variant_get(value, "q", &mtu); + } + + DBG("AcquireNotify values retived"); + DBG(" MTU = %u", mtu); + + svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl); + + if (svc_info == NULL) { + ERR("svc_info info not found\n"); + goto done; + } + + /* 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(svc_info->serv_path); + req_info->request_id = 33; + req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY; + req_info->offset = mtu; + req_info->context = invocation; + + conn_info = g_new0(struct gatt_client_info_t, 1); + conn_info->addr = g_strdup(object_path); + INFO("Added GATT client path[%s]", conn_info->addr); + conn_info->connection_id = 33; + conn_info->instance_id = 33; + /* Append request info in list of requests for the particular connection */ + conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info); + gatt_client_info_list = g_slist_append(gatt_client_info_list, conn_info); + + /* Send HAL event */ + memset(&ev, 0, sizeof(ev)); + ev.conn_id = 33; + ev.char_handl = char_hdl; + ev.mtu = mtu; + ev.trans_id = 33; + + event_cb(HAL_EV_GATT_SERVER_ACQUIRE_NOTIFY_RES, (void *)&ev, sizeof(ev)); + + DBG("HAL_EV_GATT_ACQUIRE_NOTIFY_RES called"); + + return; } +done: g_dbus_method_invocation_return_value(invocation, NULL); } @@ -2638,11 +2810,12 @@ static gboolean __bt_gatt_get_service_state(const char *service_path) { struct gatt_service_info *svc_info = NULL; GSList *l = NULL; - for (l = gatt_services; l; l = g_slist_next(l)) { svc_info = (struct gatt_service_info *)l->data; - if (svc_info->serv_path == service_path) { + + + if (!g_strcmp0(svc_info->serv_path, service_path)) { DBG("Return the state of the gatt service %d", svc_info->is_svc_registered); return svc_info->is_svc_registered; @@ -2878,6 +3051,77 @@ static bt_status_t gatt_server_send_response(int conn_id, int trans_id, return BT_STATUS_SUCCESS; } + +static bt_status_t gatt_server_send_acquire_response(int conn_id, int trans_id, + int status, int fd, int mtu, void *fdlist) +{ + CHECK_BTGATT_INIT(); + + struct gatt_req_info *req_info = NULL; + struct gatt_client_info_t *conn_info = NULL; + int i; + + DBG("GATT Server Send Response Conn ID [%d]", conn_id); + + conn_info = __bt_find_remote_gatt_client_info_from_conn(conn_id); + if (conn_info == NULL) { + ERR("No Connection Inforamtion!!!"); + return BT_STATUS_FAIL; + } + + req_info = __bt_find_remote_gatt_client_request_info(conn_id, trans_id); + if (req_info == NULL) { + ERR("No Request Inforamtion!!!"); + return BT_STATUS_FAIL; + } + + if (status != BT_STATUS_SUCCESS) { + ERR("resp_state is 0x%X", status); + + g_dbus_method_invocation_return_dbus_error(req_info->context, + "org.bluez.Error.Failed", "Application Error"); + + conn_info->gatt_req_info_list = g_slist_remove(conn_info->gatt_req_info_list, 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 BT_STATUS_SUCCESS; + } + + + if (req_info->request_type == BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE) { + + INFO("GATT Server Send Response BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE to bluez %d\n", fd); + g_dbus_method_invocation_return_value_with_unix_fd_list( + req_info->context, g_variant_new("(hq)", 0, mtu), (GUnixFDList*)fdlist); + + } else if (req_info->request_type == BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY) { + + INFO("GATT Server Send Response BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY to bluez %d\n", fd); + g_dbus_method_invocation_return_value_with_unix_fd_list( + req_info->context, g_variant_new("(hq)", 0, mtu), (GUnixFDList*)fdlist); + + } else { + g_dbus_method_invocation_return_value(req_info->context, NULL); + } + conn_info->gatt_req_info_list = g_slist_remove(conn_info->gatt_req_info_list, 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 BT_STATUS_SUCCESS; +} + + static bt_status_t gatt_server_update_att_value(int server_if, int attribute_handle, int value_length, char* att_value) { @@ -3138,5 +3382,6 @@ const btgatt_server_interface_t btgatt_server_interface = { gatt_server_multi_adv_update, gatt_server_multi_adv_set_inst_data, gatt_server_multi_adv_disable, - gatt_server_get_mtu_size + gatt_server_get_mtu_size, + gatt_server_send_acquire_response };