ATT_OP_TYPE_RSP,
ATT_OP_TYPE_CMD,
ATT_OP_TYPE_IND,
- ATT_OP_TYPE_NOT,
+ ATT_OP_TYPE_NFY,
ATT_OP_TYPE_CONF,
ATT_OP_TYPE_UNKNOWN,
};
{ BT_ATT_OP_PREP_WRITE_RSP, ATT_OP_TYPE_RSP },
{ BT_ATT_OP_EXEC_WRITE_REQ, ATT_OP_TYPE_REQ },
{ BT_ATT_OP_EXEC_WRITE_RSP, ATT_OP_TYPE_RSP },
- { BT_ATT_OP_HANDLE_VAL_NOT, ATT_OP_TYPE_NOT },
- { BT_ATT_OP_HANDLE_VAL_IND, ATT_OP_TYPE_IND },
- { BT_ATT_OP_HANDLE_VAL_CONF, ATT_OP_TYPE_CONF },
+ { BT_ATT_OP_HANDLE_NFY, ATT_OP_TYPE_NFY },
+ { BT_ATT_OP_HANDLE_IND, ATT_OP_TYPE_IND },
+ { BT_ATT_OP_HANDLE_CONF, ATT_OP_TYPE_CONF },
{ }
};
#ifndef TIZEN_FEATURE_BLUEZ_MODIFY
case ATT_OP_TYPE_CMD:
#endif
- case ATT_OP_TYPE_NOT:
+ case ATT_OP_TYPE_NFY:
case ATT_OP_TYPE_CONF:
case ATT_OP_TYPE_UNKNOWN:
default:
}
if (op->callback)
- op->callback(BT_ATT_OP_HANDLE_VAL_CONF, NULL, 0, op->user_data);
+ op->callback(BT_ATT_OP_HANDLE_NFY, NULL, 0, op->user_data);
destroy_att_send_op(op);
chan->pending_ind = NULL;
chan->in_req = true;
/* fall through */
case ATT_OP_TYPE_CMD:
- case ATT_OP_TYPE_NOT:
+ case ATT_OP_TYPE_NFY:
case ATT_OP_TYPE_UNKNOWN:
case ATT_OP_TYPE_IND:
/* fall through */
result = queue_push_tail(att->ind_queue, op);
break;
case ATT_OP_TYPE_CMD:
- case ATT_OP_TYPE_NOT:
+ case ATT_OP_TYPE_NFY:
case ATT_OP_TYPE_UNKNOWN:
case ATT_OP_TYPE_RSP:
case ATT_OP_TYPE_CONF:
struct queue *notify_list;
struct queue *notify_chrcs;
int next_reg_id;
- unsigned int disc_id, notify_id, ind_id;
+ unsigned int disc_id, nfy_id, nfy_mult_id, ind_id;
/*
* Handles of the GATT Service and the Service Changed characteristic
return true;
}
-struct pdu_data {
- const void *pdu;
- uint16_t length;
+struct value_data {
+ uint16_t handle;
+ uint16_t len;
+ const void *data;
};
static void disable_ccc_callback(uint8_t opcode, const void *pdu,
static void notify_handler(void *data, void *user_data)
{
struct notify_data *notify_data = data;
- struct pdu_data *pdu_data = user_data;
- uint16_t value_handle;
- const uint8_t *value = NULL;
-
- value_handle = get_le16(pdu_data->pdu);
+ struct value_data *value_data = user_data;
- if (notify_data->chrc->value_handle != value_handle)
+ if (notify_data->chrc->value_handle != value_data->handle)
return;
- if (pdu_data->length > 2)
- value = pdu_data->pdu + 2;
-
/*
* Even if the notify data has a pending ATT request to write to the
* CCC, there is really no reason not to notify the handlers.
*/
if (notify_data->notify)
- notify_data->notify(value_handle, value, pdu_data->length - 2,
- notify_data->user_data);
+ notify_data->notify(value_data->handle, value_data->data,
+ value_data->len, notify_data->user_data);
}
static void notify_cb(struct bt_att_chan *chan, uint8_t opcode,
void *user_data)
{
struct bt_gatt_client *client = user_data;
- struct pdu_data pdu_data;
+ struct value_data data;
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
if (client->ready == false) {
/* GATT caching is not supported yet.
Once it supported, need to handle svc changed indication */
- if (opcode == BT_ATT_OP_HANDLE_VAL_IND && !client->parent
+ if (opcode == BT_ATT_OP_HANDLE_IND && !client->parent
&& !client->discovery_req) {
util_debug(client->debug_callback, client->debug_data,
"Service browsing is not started. No need handling svc changed indication before starting full scan");
- bt_att_send(client->att, BT_ATT_OP_HANDLE_VAL_CONF, NULL, 0,
+ bt_att_send(client->att, BT_ATT_OP_HANDLE_CONF, NULL, 0,
NULL, NULL, NULL);
return;
}
bt_gatt_client_ref(client);
- memset(&pdu_data, 0, sizeof(pdu_data));
- pdu_data.pdu = pdu;
- pdu_data.length = length;
+ memset(&data, 0, sizeof(data));
+
+ if (opcode == BT_ATT_OP_HANDLE_NFY_MULT) {
+ while (length >= 4) {
+ data.handle = get_le16(pdu);
+ length -= 2;
+ pdu += 2;
+
+ data.len = get_le16(pdu);
+ length -= 2;
+ pdu += 2;
- queue_foreach(client->notify_list, notify_handler, &pdu_data);
+ data.data = pdu;
- if (opcode == BT_ATT_OP_HANDLE_VAL_IND && !client->parent){
+ queue_foreach(client->notify_list, notify_handler,
+ &data);
+
+ length -= data.len;
+ }
+ } else {
+ data.handle = get_le16(pdu);
+ length -= 2;
+ pdu += 2;
+
+ data.len = length;
+ data.data = pdu;
+ queue_foreach(client->notify_list, notify_handler, &data);
+ }
+
+ if (opcode == BT_ATT_OP_HANDLE_IND && !client->parent){
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
if (!chan)
- bt_att_send(client->att, BT_ATT_OP_HANDLE_VAL_CONF, NULL, 0,
+ bt_att_send(client->att, BT_ATT_OP_HANDLE_CONF, NULL, 0,
NULL, NULL, NULL);
else
- bt_att_chan_send(chan, BT_ATT_OP_HANDLE_VAL_CONF, NULL, 0,
+ bt_att_chan_send(chan, BT_ATT_OP_HANDLE_CONF, NULL, 0,
NULL, NULL, NULL);
}
#else
- bt_att_chan_send(chan, BT_ATT_OP_HANDLE_VAL_CONF, NULL, 0,
+ bt_att_chan_send(chan, BT_ATT_OP_HANDLE_CONF, NULL, 0,
NULL, NULL, NULL);
}
#endif
if (client->att) {
bt_att_unregister_disconnect(client->att, client->disc_id);
- bt_att_unregister(client->att, client->notify_id);
+ bt_att_unregister(client->att, client->nfy_id);
+ bt_att_unregister(client->att, client->nfy_mult_id);
bt_att_unregister(client->att, client->ind_id);
bt_att_unref(client->att);
}
client->pending_noti = queue_new();
#endif
- client->notify_id = bt_att_register(att, BT_ATT_OP_HANDLE_VAL_NOT,
+ client->nfy_id = bt_att_register(att, BT_ATT_OP_HANDLE_NFY,
+ notify_cb, client, NULL);
+ if (!client->nfy_id)
+ goto fail;
+
+ client->nfy_mult_id = bt_att_register(att, BT_ATT_OP_HANDLE_NFY_MULT,
notify_cb, client, NULL);
- if (!client->notify_id)
+ if (!client->nfy_mult_id)
goto fail;
- client->ind_id = bt_att_register(att, BT_ATT_OP_HANDLE_VAL_IND,
+ client->ind_id = bt_att_register(att, BT_ATT_OP_HANDLE_IND,
notify_cb, client, NULL);
if (!client->ind_id)
goto fail;