Example #1
0
static void send_packet(void){
    rfcomm_send(rfcomm_cid, (uint8_t*) test_data, test_data_len);

    test_track_sent(test_data_len);
    if (data_to_send <= test_data_len){
        state = DONE;
        printf("SPP Streamer: enough data send, closing channel\n");
        rfcomm_disconnect(rfcomm_cid);
        rfcomm_cid = 0;
        return;
    }
    data_to_send -= test_data_len;
    rfcomm_request_can_send_now_event(rfcomm_cid);
}
Example #2
0
static void hsp_run(void){

    if (wait_ok) return;

    if (hsp_release_audio_connection){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        hsp_release_audio_connection = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }

    if (hsp_disconnect_rfcomm){
        hsp_disconnect_rfcomm = 0;
        hsp_establish_audio_connection = 0;
        rfcomm_disconnect(rfcomm_cid);
        return;
    }

    if (hsp_establish_audio_connection){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        hsp_establish_audio_connection = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }
    
    if (hs_send_button_press){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        hs_send_button_press = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }

    switch (hsp_state){
        case HSP_SDP_QUERY_RFCOMM_CHANNEL:
            hsp_state = HSP_W4_SDP_QUERY_COMPLETE;
            sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_Headset_AG);
            break;
        
        case HSP_AUDIO_CONNECTION_ESTABLISHED:
        case HSP_RFCOMM_CONNECTION_ESTABLISHED:

            if (hs_microphone_gain >= 0){
                if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
                    rfcomm_request_can_send_now_event(rfcomm_cid);
                    return;
                }
                char buffer[20];
                sprintf(buffer, "%s=%d\r\n", HSP_HS_MICROPHONE_GAIN, hs_microphone_gain);
                hsp_hs_send_str_over_rfcomm(rfcomm_cid, buffer);
                hs_microphone_gain = -1;
                break;
            }

            if (hs_speaker_gain >= 0){
                if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
                    rfcomm_request_can_send_now_event(rfcomm_cid);
                    return;
                }
                char buffer[20];
                sprintf(buffer, "%s=%d\r\n", HSP_HS_SPEAKER_GAIN, hs_speaker_gain);
                hsp_hs_send_str_over_rfcomm(rfcomm_cid, buffer);
                hs_speaker_gain = -1;
                break;
            }
            break;
        case HSP_W4_RFCOMM_DISCONNECTED:
            rfcomm_disconnect(rfcomm_cid);
            break;
        default:
            break;
    }
}
Example #3
0
/*
 * User Request.
 * up is socket
 * m is either
 *	optional mbuf chain containing message
 *	ioctl command (PRU_CONTROL)
 * nam is either
 *	optional mbuf chain containing an address
 *	ioctl data (PRU_CONTROL)
 *	optionally protocol number (PRU_ATTACH)
 *	message flags (PRU_RCVD)
 * ctl is either
 *	optional mbuf chain containing socket options
 *	optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
 * l is pointer to process requesting action (if any)
 *
 * we are responsible for disposing of m and ctl if
 * they are mbuf chains
 */
int
rfcomm_usrreq(struct socket *up, int req, struct mbuf *m,
		struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
{
	struct rfcomm_dlc *pcb = up->so_pcb;
	struct sockaddr_bt *sa;
	struct mbuf *m0;
	int err = 0;

	DPRINTFN(2, "%s\n", prurequests[req]);

	switch (req) {
	case PRU_CONTROL:
		return EPASSTHROUGH;

	case PRU_PURGEIF:
		return EOPNOTSUPP;

	case PRU_ATTACH:
		if (up->so_lock == NULL) {
			mutex_obj_hold(bt_lock);
			up->so_lock = bt_lock;
			solock(up);
		}
		KASSERT(solocked(up));
		if (pcb != NULL)
			return EINVAL;
		/*
		 * Since we have nothing to add, we attach the DLC
		 * structure directly to our PCB pointer.
		 */
		err = soreserve(up, rfcomm_sendspace, rfcomm_recvspace);
		if (err)
			return err;

		err = rfcomm_attach((struct rfcomm_dlc **)&up->so_pcb,
					&rfcomm_proto, up);
		if (err)
			return err;

		err = rfcomm_rcvd(up->so_pcb, sbspace(&up->so_rcv));
		if (err) {
			rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);
			return err;
		}

		return 0;
	}

	if (pcb == NULL) {
		err = EINVAL;
		goto release;
	}

	switch(req) {
	case PRU_DISCONNECT:
		soisdisconnecting(up);
		return rfcomm_disconnect(pcb, up->so_linger);

	case PRU_ABORT:
		rfcomm_disconnect(pcb, 0);
		soisdisconnected(up);
		/* fall through to */
	case PRU_DETACH:
		return rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);

	case PRU_BIND:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		return rfcomm_bind(pcb, sa);

	case PRU_CONNECT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		soisconnecting(up);
		return rfcomm_connect(pcb, sa);

	case PRU_PEERADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return rfcomm_peeraddr(pcb, sa);

	case PRU_SOCKADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return rfcomm_sockaddr(pcb, sa);

	case PRU_SHUTDOWN:
		socantsendmore(up);
		break;

	case PRU_SEND:
		KASSERT(m != NULL);

		if (ctl)	/* no use for that */
			m_freem(ctl);

		m0 = m_copypacket(m, M_DONTWAIT);
		if (m0 == NULL)
			return ENOMEM;

		sbappendstream(&up->so_snd, m);

		return rfcomm_send(pcb, m0);

	case PRU_SENSE:
		return 0;		/* (no release) */

	case PRU_RCVD:
		return rfcomm_rcvd(pcb, sbspace(&up->so_rcv));

	case PRU_RCVOOB:
		return EOPNOTSUPP;	/* (no release) */

	case PRU_LISTEN:
		return rfcomm_listen(pcb);

	case PRU_ACCEPT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return rfcomm_peeraddr(pcb, sa);

	case PRU_CONNECT2:
	case PRU_SENDOOB:
	case PRU_FASTTIMO:
	case PRU_SLOWTIMO:
	case PRU_PROTORCV:
	case PRU_PROTOSEND:
		err = EOPNOTSUPP;
		break;

	default:
		UNKNOWN(req);
		err = EOPNOTSUPP;
		break;
	}

release:
	if (m) m_freem(m);
	if (ctl) m_freem(ctl);
	return err;
}
Example #4
0
static void hsp_run(void){

    if (wait_ok) return;

    if (hs_accept_sco_connection && hci_can_send_command_packet_now()){
        hs_accept_sco_connection = 0;
        
        log_info("HSP: sending hci_accept_connection_request.");
        // remote supported feature eSCO is set if link type is eSCO
        // eSCO: S4 - max latency == transmission interval = 0x000c == 12 ms, 
        uint16_t max_latency;
        uint8_t  retransmission_effort;
        uint16_t packet_types;
        
        if (hci_remote_esco_supported(rfcomm_handle)){
            max_latency = 0x000c;
            retransmission_effort = 0x02;
            packet_types = 0x388;
        } else {
            max_latency = 0xffff;
            retransmission_effort = 0xff;
            packet_types = 0x003f;
        }
        
        uint16_t sco_voice_setting = hci_get_sco_voice_setting();
        
        log_info("HFP: sending hci_accept_connection_request, sco_voice_setting %02x", sco_voice_setting);
        hci_send_cmd(&hci_accept_synchronous_connection, remote, 8000, 8000, max_latency, 
                        sco_voice_setting, retransmission_effort, packet_types);
        return;
    }

    if (hsp_release_audio_connection){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        hsp_release_audio_connection = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }

    if (hsp_disconnect_rfcomm){
        hsp_disconnect_rfcomm = 0;
        hsp_establish_audio_connection = 0;
        rfcomm_disconnect(rfcomm_cid);
        return;
    }

    if (hsp_establish_audio_connection){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        hsp_establish_audio_connection = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }
    
    if (hs_send_button_press){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        hs_send_button_press = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }

    switch (hsp_state){
        case HSP_SDP_QUERY_RFCOMM_CHANNEL:
            hsp_state = HSP_W4_SDP_QUERY_COMPLETE;
            sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, BLUETOOTH_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY_AG);
            break;
        
        case HSP_AUDIO_CONNECTION_ESTABLISHED:
        case HSP_RFCOMM_CONNECTION_ESTABLISHED:

            if (hs_microphone_gain >= 0){
                if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
                    rfcomm_request_can_send_now_event(rfcomm_cid);
                    return;
                }
                char buffer[20];
                sprintf(buffer, "%s=%d\r\n", HSP_HS_MICROPHONE_GAIN, hs_microphone_gain);
                hsp_hs_send_str_over_rfcomm(rfcomm_cid, buffer);
                hs_microphone_gain = -1;
                break;
            }

            if (hs_speaker_gain >= 0){
                if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
                    rfcomm_request_can_send_now_event(rfcomm_cid);
                    return;
                }
                char buffer[20];
                sprintf(buffer, "%s=%d\r\n", HSP_HS_SPEAKER_GAIN, hs_speaker_gain);
                hsp_hs_send_str_over_rfcomm(rfcomm_cid, buffer);
                hs_speaker_gain = -1;
                break;
            }
            break;
        case HSP_W4_RFCOMM_DISCONNECTED:
            rfcomm_disconnect(rfcomm_cid);
            break;
        default:
            break;
    }
}