示例#1
0
文件: gattrib.c 项目: 520lly/bluez
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 = g_try_new0(struct command, 1);
	if (c == NULL)
		return 0;

	c->opcode = opcode;
	c->expected = opcode2expected(opcode);
	c->pdu = g_malloc(len);
	memcpy(c->pdu, pdu, len);
	c->len = len;
	c->func = func;
	c->user_data = user_data;
	c->notify = notify;

	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);

	return c->id;
}
示例#2
0
guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len,
      GAttribResultFunc func, gpointer user_data,
      GDestroyNotify notify)
{
  struct command *c;
  GQueue *queue;
  uint8_t opcode;

  if (attrib->stale)
    return 0;

  c = g_try_new0(struct command, 1);
  if (c == NULL)
    return 0;

  opcode = pdu[0];

  c->opcode = opcode;
  c->expected = opcode2expected(opcode);
  c->pdu = g_malloc(len);
  memcpy(c->pdu, pdu, len);
  c->len = len;
  c->func = func;
  c->user_data = user_data;
  c->notify = notify;

  if (is_response(opcode))
    queue = attrib->responses;
  else
    queue = attrib->requests;

  if (id) {
    c->id = id;
    if (!is_response(opcode))
      g_queue_push_head(queue, c);
    else
      /* Don't re-order responses even if an ID is given */
      g_queue_push_tail(queue, c);
  } else {
    c->id = ++attrib->next_cmd_id;
    g_queue_push_tail(queue, c);
  }

  /*
   * If a command was added to the queue and it was empty before, wake up
   * the sender. If the sender was already woken up by the second queue,
   * wake_up_sender will just return.
   */
  if (g_queue_get_length(queue) == 1)
    wake_up_sender(attrib);

  return c->id;
}
示例#3
0
文件: gattrib.c 项目: 520lly/bluez
static gboolean received_data(GIOChannel *io, GIOCondition cond, gpointer data)
{
	struct _GAttrib *attrib = data;
	struct command *cmd = NULL;
	GSList *l;
	uint8_t buf[512], status;
	gsize len;
	GIOStatus iostat;
	gboolean qempty;

	if (attrib->timeout_watch > 0) {
		g_source_remove(attrib->timeout_watch);
		attrib->timeout_watch = 0;
	}

	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
		attrib->read_watch = 0;
		return FALSE;
	}

	memset(buf, 0, sizeof(buf));

	iostat = g_io_channel_read_chars(io, (gchar *) buf, sizeof(buf),
								&len, NULL);
	if (iostat != G_IO_STATUS_NORMAL) {
		status = ATT_ECODE_IO;
		goto done;
	}

	for (l = attrib->events; l; l = l->next) {
		struct event *evt = l->data;

		if (evt->expected == buf[0] ||
				evt->expected == GATTRIB_ALL_EVENTS ||
				(is_response(buf[0]) == FALSE &&
						evt->expected == GATTRIB_ALL_REQS))
			evt->func(buf, len, evt->user_data);
	}

	if (is_response(buf[0]) == FALSE)
		return TRUE;

	cmd = g_queue_pop_head(attrib->queue);
	if (cmd == NULL) {
		/* Keep the watch if we have events to report */
		return attrib->events != NULL;
	}

	if (buf[0] == ATT_OP_ERROR) {
		status = buf[4];
		goto done;
	}

	if (cmd->expected != buf[0]) {
		status = ATT_ECODE_IO;
		goto done;
	}

	status = 0;

done:
	qempty = attrib->queue == NULL || g_queue_is_empty(attrib->queue);

	if (cmd) {
		if (cmd->func)
			cmd->func(status, buf, len, cmd->user_data);

		command_destroy(cmd);
	}

	if (!qempty)
		wake_up_sender(attrib);

	return TRUE;
}
示例#4
0
static gboolean received_data(GIOChannel *io, GIOCondition cond, gpointer data)
{
	struct _GAttrib *attrib = data;
	struct command *cmd = NULL;
	GSList *l;
	uint8_t buf[512], status;
	gsize len;
	GIOStatus iostat;

	if (attrib->stale)
		return FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
		struct command *c;

		while ((c = g_queue_pop_head(attrib->requests))) {
			if (c->func)
				c->func(ATT_ECODE_IO, NULL, 0, c->user_data);
			command_destroy(c);
		}

		attrib->read_watch = 0;

		return FALSE;
	}

	memset(buf, 0, sizeof(buf));

	iostat = g_io_channel_read_chars(io, (char *) buf, sizeof(buf),
								&len, NULL);
	if (iostat != G_IO_STATUS_NORMAL) {
		status = ATT_ECODE_IO;
		goto done;
	}

	for (l = attrib->events; l; l = l->next) {
		struct event *evt = l->data;

		if (match_event(evt, buf, len))
			evt->func(buf, len, evt->user_data);
	}

	if (!is_response(buf[0]))
		return TRUE;

	if (attrib->timeout_watch > 0) {
		g_source_remove(attrib->timeout_watch);
		attrib->timeout_watch = 0;
	}

	cmd = g_queue_pop_head(attrib->requests);
	if (cmd == NULL) {
		/* Keep the watch if we have events to report */
		return attrib->events != NULL;
	}

	if (buf[0] == ATT_OP_ERROR) {
		status = buf[4];
		goto done;
	}

	if (cmd->expected != buf[0]) {
		status = ATT_ECODE_IO;
		goto done;
	}

	status = 0;

done:
	if (!g_queue_is_empty(attrib->requests) ||
					!g_queue_is_empty(attrib->responses))
		wake_up_sender(attrib);

	if (cmd) {
		if (cmd->func)
			cmd->func(status, buf, len, cmd->user_data);

		command_destroy(cmd);
	}

	return TRUE;
}