switch (pdu[0]) {
case ATT_OP_HANDLE_IND:
olen = enc_confirmation(opdu, sizeof(opdu));
- g_attrib_send(gatt->attrib, opdu[0], opdu, olen,
+ g_attrib_send(gatt->attrib, 0, opdu[0], opdu, olen,
NULL, NULL, NULL);
case ATT_OP_HANDLE_NOTIFY:
if (characteristic_set_value(chr, &pdu[3], len - 3) < 0)
if (plen == 0)
return 0;
- return g_attrib_send(attrib, op, pdu, plen, func, user_data, NULL);
+ return g_attrib_send(attrib, 0, op, pdu, plen, func, user_data, NULL);
}
guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
if (plen == 0)
return 0;
- return g_attrib_send(attrib, ATT_OP_READ_BY_TYPE_REQ,
+ return g_attrib_send(attrib, 0, ATT_OP_READ_BY_TYPE_REQ,
pdu, plen, func, user_data, NULL);
}
guint16 plen;
plen = enc_read_req(handle, pdu, sizeof(pdu));
- return g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen, func,
+ return g_attrib_send(attrib, 0, ATT_OP_READ_REQ, pdu, plen, func,
user_data, NULL);
}
guint16 plen;
plen = enc_write_req(handle, value, vlen, pdu, sizeof(pdu));
- return g_attrib_send(attrib, ATT_OP_WRITE_REQ, pdu, plen, func,
+ return g_attrib_send(attrib, 0, ATT_OP_WRITE_REQ, pdu, plen, func,
user_data, NULL);
}
if (plen == 0)
return 0;
- return g_attrib_send(attrib, ATT_OP_FIND_INFO_REQ, pdu, plen, func,
+ return g_attrib_send(attrib, 0, ATT_OP_FIND_INFO_REQ, pdu, plen, func,
user_data, NULL);
}
guint16 plen;
plen = enc_write_cmd(handle, value, vlen, pdu, sizeof(pdu));
- return g_attrib_send(attrib, ATT_OP_WRITE_CMD, pdu, plen, NULL,
+ return g_attrib_send(attrib, 0, ATT_OP_WRITE_CMD, pdu, plen, NULL,
user_data, notify);
}
uint8_t buf[512], status;
gsize len;
GIOStatus iostat;
+ gboolean qempty;
if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
attrib->read_watch = 0;
status = 0;
done:
- if (attrib->queue && g_queue_is_empty(attrib->queue) == FALSE)
- wake_up_sender(attrib);
+ qempty = attrib->queue == NULL || g_queue_is_empty(attrib->queue);
if (cmd) {
if (cmd->func)
command_destroy(cmd);
}
+ if (!qempty)
+ wake_up_sender(attrib);
+
return TRUE;
}
return g_attrib_ref(attrib);
}
-guint g_attrib_send(GAttrib *attrib, guint8 opcode, const guint8 *pdu,
- guint16 len, GAttribResultFunc func,
- gpointer user_data, GDestroyNotify notify)
+guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
+ const guint8 *pdu, guint16 len, GAttribResultFunc func,
+ gpointer user_data, GDestroyNotify notify)
{
struct command *c;
c->func = func;
c->user_data = user_data;
c->notify = notify;
- c->id = ++attrib->next_cmd_id;
- g_queue_push_tail(attrib->queue, c);
+ if (id) {
+ c->id = id;
+ g_queue_push_head(attrib->queue, c);
+ } else {
+ c->id = ++attrib->next_cmd_id;
+ g_queue_push_tail(attrib->queue, c);
+ }
if (g_queue_get_length(attrib->queue) == 1)
wake_up_sender(attrib);
gboolean g_attrib_set_destroy_function(GAttrib *attrib,
GDestroyNotify destroy, gpointer user_data);
-guint g_attrib_send(GAttrib *attrib, guint8 opcode, const guint8 *pdu,
- guint16 len, GAttribResultFunc func,
- gpointer user_data, GDestroyNotify notify);
+guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
+ const guint8 *pdu, guint16 len, GAttribResultFunc func,
+ gpointer user_data, GDestroyNotify notify);
+
gboolean g_attrib_cancel(GAttrib *attrib, guint id);
gboolean g_attrib_cancel_all(GAttrib *attrib);
olen = enc_confirmation(opdu, sizeof(opdu));
if (olen > 0)
- g_attrib_send(attrib, opdu[0], opdu, olen, NULL, NULL, NULL);
+ g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
}
static gboolean listen_start(gpointer user_data)
if (status)
length = enc_error_resp(ipdu[0], 0x0000, status, opdu, channel->mtu);
- g_attrib_send(channel->attrib, opdu[0], opdu, length,
+ g_attrib_send(channel->attrib, 0, opdu[0], opdu, length,
NULL, NULL, NULL);
}