/*
 * l2cap_connected():
 *
 * Called by L2CAP when a connection response was received.
 * Sends a L2CAP configuration request.
 * Initializes a search for other devices if the connection attempt failed.
 */
err_t l2cap_connected(void *arg, struct l2cap_pcb *l2cappcb, u16_t result, u16_t status)
{
	struct sdp_pcb *sdppcb;
	struct rfcomm_pcb *rfcommpcb;

	u8_t ssp[] = {0x35, 0x03, 0x19, 0x11, 0x02}; /* Service search pattern with LAP UUID is default */ 
	err_t ret;

	u8_t attrids[] = {0x35, 0x03, 0x09, 0x00, 0x04}; /* Attribute IDs to search for in data element 
														sequence form */

	if(result == L2CAP_CONN_SUCCESS) {
		LWIP_DEBUGF(BT_SPP_DEBUG, ("l2cap_connected: L2CAP connected pcb->state = %d\n", l2cappcb->state));
		/* Tell L2CAP that we wish to be informed of a disconnection request */
		l2cap_disconnect_ind(l2cappcb, l2cap_disconnected_ind);
		switch(l2cap_psm(l2cappcb)) {
			case SDP_PSM:
				LWIP_DEBUGF(BT_SPP_DEBUG, ("l2cap_connected: SDP L2CAP configured. Result = %d\n", result));
				if((sdppcb = sdp_new(l2cappcb)) == NULL) {
					LWIP_DEBUGF(BT_SPP_DEBUG, ("l2cap_connected: Failed to create a SDP PCB\n"));
					return ERR_MEM;
				}

				l2cap_recv(l2cappcb, sdp_recv);

				ret = sdp_service_search_attrib_req(sdppcb, 0xFFFF, ssp, sizeof(ssp),
						attrids, sizeof(attrids), sdp_attributes_recv);
				return ret;

			case RFCOMM_PSM:
				LWIP_DEBUGF(BT_SPP_DEBUG, ("l2cap_connected: RFCOMM L2CAP configured. Result = %d CN = %d\n", result, bt_spp_state.cn));
				l2cap_recv(l2cappcb, rfcomm_input);

				if((rfcommpcb = rfcomm_new(l2cappcb)) == NULL) {
					LWIP_DEBUGF(BT_SPP_DEBUG, ("l2cap_connected: Failed to create a RFCOMM PCB\n"));
					return ERR_MEM;
				}

				hci_link_key_not(link_key_not); /* Set function to be called if a new link key is created */

				return rfcomm_connect(rfcommpcb, bt_spp_state.cn, rfcomm_connected); /* Connect with DLCI 0 */
			default:
				return ERR_VAL;
		}
	} else {
		LWIP_DEBUGF(BT_SPP_DEBUG, ("l2cap_connected: L2CAP not connected. Redo inquiry\n"));
		l2cap_close(l2cappcb);
		bt_spp_start();
	}

	return ERR_OK;
}
err_t bt_connect_ind(void *arg, struct l2cap_pcb *pcb, err_t err)
{
	LWIP_DEBUGF(BT_SPP_DEBUG, ("bt_connect_ind\n"));

	/* Tell L2CAP that we wish to be informed of a disconnection request */
	l2cap_disconnect_ind(pcb, bt_disconnect_ind);

	/* Tell L2CAP that we wish to be informed of incoming data */
	if(pcb->psm == SDP_PSM) {
		LWIP_DEBUGF(BT_SPP_DEBUG, ("bt_connect_ind SDP\n"));
		l2cap_recv(pcb, sdp_recv);
	} else if (pcb->psm == RFCOMM_PSM) {
		LWIP_DEBUGF(BT_SPP_DEBUG, ("bt_connect_ind RFCOMM\n"));
		l2cap_recv(pcb, rfcomm_input);
	}
	return ERR_OK;  
}
Beispiel #3
0
static err_t l2ca_connect_ind_cb(void *arg, struct l2cap_pcb *pcb, err_t err)
{
	struct ds3wiibt_context *ctx = (struct ds3wiibt_context *)arg;
	if (ctx == NULL || pcb == NULL) return -1;
	
	//LOG("l2ca_connect_ind_cb, PSM: 0x%02X\n", l2cap_psm(pcb));
	
	if (l2cap_psm(pcb) == HIDP_PSM) {
		/* Control PSM is connected */
		l2cap_disconnect_ind(ctx->ctrl_pcb, l2ca_disconnect_ind_cb);
		l2cap_timeout_ind(ctx->ctrl_pcb, l2ca_timeout_ind_cb);
		l2cap_recv(ctx->ctrl_pcb, l2ca_recv_cb);
	} else if (l2cap_psm(pcb) == INTR_PSM) {
		/* Both Control PSM and Data PSM are connected */
		l2cap_disconnect_ind(ctx->data_pcb, l2ca_disconnect_ind_cb);
		l2cap_timeout_ind(ctx->data_pcb, l2ca_timeout_ind_cb);
		l2cap_recv(ctx->data_pcb, l2ca_recv_cb);
		set_operational(ctx);
	}
	return ERR_OK;
}