Exemple #1
0
int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_att_func_t func,
		void *user_data, bt_att_destroy_t destroy)
{
	struct bt_att *att;
	struct bt_att_hdr *hdr = (void *)buf->data;

	if (!conn) {
		return -EINVAL;
	}

	att = att_chan_get(conn);
	if (!att) {
		return -ENOTCONN;
	}

	if (func) {
		/* Check if there is a request pending */
		if (att->req.func) {
			 /* TODO: Allow more than one pending request */
			return -EBUSY;
		}

		att->req.buf = net_buf_clone(buf);
#if defined(CONFIG_BLUETOOTH_SMP)
		att->req.retrying = false;
#endif /* CONFIG_BLUETOOTH_SMP */
		att->req.func = func;
		att->req.user_data = user_data;
		att->req.destroy = destroy;
	}

	if (hdr->code == BT_ATT_OP_SIGNED_WRITE_CMD) {
		int err;

		err = bt_smp_sign(conn, buf);
		if (err) {
			BT_ERR("Error signing data");
			return err;
		}
	}

	bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf);

	return 0;
}
Exemple #2
0
/* This is called by contiki/ip/tcpip.c:tcpip_uipcall() when packet
 * is processed.
 */
PROCESS_THREAD(tcp, ev, data, buf, user_data)
{
	PROCESS_BEGIN();

	while(1) {
		PROCESS_YIELD_UNTIL(ev == tcpip_event);

		if (POINTER_TO_INT(data) == TCP_WRITE_EVENT) {
			/* We want to send data to peer. */
			struct net_context *context = user_data;

			if (!context) {
				continue;
			}

			do {
				context = user_data;
				if (!context || !buf) {
					break;
				}

				if (!context->ps.net_buf ||
				    context->ps.net_buf != buf) {
					NET_DBG("psock init %p buf %p\n",
						&context->ps, buf);
					PSOCK_INIT(&context->ps, buf);
				}

				handle_tcp_connection(&context->ps,
						      POINTER_TO_INT(data),
						      buf);

				PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);

				if (POINTER_TO_INT(data) != TCP_WRITE_EVENT) {
					goto read_data;
				}
			} while(!(uip_closed(buf)  ||
				  uip_aborted(buf) ||
				  uip_timedout(buf)));

			context = user_data;

			if (context &&
			    context->tcp_type == NET_TCP_TYPE_CLIENT) {
				NET_DBG("\nConnection closed.\n");
				ip_buf_sent_status(buf) = -ECONNRESET;
			}

			continue;
		}

	read_data:
		/* We are receiving data from peer. */
		if (buf && uip_newdata(buf)) {
			struct net_buf *clone;

			if (!uip_len(buf)) {
				continue;
			}

			/* Note that uIP stack will reuse the buffer when
			 * sending ACK to peer host. The sending will happen
			 * right after this function returns. Because of this
			 * we cannot use the same buffer to pass data to
			 * application.
			 */
			clone = net_buf_clone(buf);
			if (!clone) {
				NET_ERR("No enough RX buffers, "
					"packet %p discarded\n", buf);
				continue;
			}

			ip_buf_appdata(clone) = uip_buf(clone) +
				(ip_buf_appdata(buf) - (void *)uip_buf(buf));
			ip_buf_appdatalen(clone) = uip_len(buf);
			ip_buf_len(clone) = ip_buf_len(buf);
			ip_buf_context(clone) = user_data;
			uip_set_conn(clone) = uip_conn(buf);
			uip_flags(clone) = uip_flags(buf);
			uip_flags(clone) |= UIP_CONNECTED;

			NET_DBG("packet received context %p buf %p len %d "
				"appdata %p appdatalen %d\n",
				ip_buf_context(clone),
				clone,
				ip_buf_len(clone),
				ip_buf_appdata(clone),
				ip_buf_appdatalen(clone));

			nano_fifo_put(net_context_get_queue(user_data), clone);

			/* We let the application to read the data now */
			fiber_yield();
		}
	}

	PROCESS_END();
}