Exemple #1
0
static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba)
{
	unsigned char key[16];
	char sa[18], da[18];
	int err;

	ba2str(sba, sa); ba2str(dba, da);
	syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)", sa, da);

	err = read_link_key(sba, dba, key);
	if (err < 0) {
		struct link_key *linkkey = get_link_key(sba, dba);
		if (linkkey) {
			memcpy(key, linkkey->key, 16);
			linkkey->time = time(0);
			err = 0;
		}
	}

	if (err < 0) {
		/* Link key not found */
		hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba);
	} else {
		/* Link key found */
		link_key_reply_cp lr;
		memcpy(lr.link_key, key, 16);
		bacpy(&lr.bdaddr, dba);
		hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY,
						LINK_KEY_REPLY_CP_SIZE, &lr);
	}
}
static void gap_run(){

    if (!hci_can_send_command_packet_now()) return;

    if (todos & SET_ADVERTISEMENT_DATA){
        printf("GAP_RUN: set advertisement data\n");
        todos &= ~SET_ADVERTISEMENT_DATA;
        hci_send_cmd(&hci_le_set_advertising_data, adv_data_len, adv_data);
        return;
    }    

    if (todos & SET_ADVERTISEMENT_PARAMS){
        todos &= ~SET_ADVERTISEMENT_PARAMS;
        uint8_t adv_type = 0;   // default
        bd_addr_t null_addr;
        memset(null_addr, 0, 6);
        uint16_t adv_int_min = 0x0030;
        uint16_t adv_int_max = 0x0030;
        hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, 0, 0, &null_addr, 0x07, 0x00);
        return;
    }    

    if (todos & ENABLE_ADVERTISEMENTS){
        printf("GAP_RUN: enable advertisements\n");
        todos &= ~ENABLE_ADVERTISEMENTS;
        hci_send_cmd(&hci_le_set_advertise_enable, 1);
        return;
    }
}
Exemple #3
0
static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_ev_auth_complete *ev = (void *) skb->data;
	struct hci_conn *conn;

	BT_DBG("%s status %d", hdev->name, ev->status);

	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
	if (conn) {
		if (!ev->status) {
			conn->link_mode |= HCI_LM_AUTH;
			conn->sec_level = conn->pending_sec_level;
		} else
			conn->sec_level = BT_SECURITY_LOW;

		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);

		if (conn->state == BT_CONFIG) {
			if (!ev->status && hdev->ssp_mode > 0 &&
							conn->ssp_mode > 0) {
				struct hci_cp_set_conn_encrypt cp;
				cp.handle  = ev->handle;
				cp.encrypt = 0x01;
				hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
							sizeof(cp), &cp);
			} else {
				conn->state = BT_CONNECTED;
				hci_proto_connect_cfm(conn, ev->status);
				hci_conn_put(conn);
			}
		} else {
			hci_auth_cfm(conn, ev->status);

			hci_conn_hold(conn);
			conn->disc_timeout = HCI_DISCONN_TIMEOUT;
			hci_conn_put(conn);
		}

		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
			if (!ev->status) {
				struct hci_cp_set_conn_encrypt cp;
				cp.handle  = ev->handle;
				cp.encrypt = 0x01;
				hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
							sizeof(cp), &cp);
			} else {
				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
				hci_encrypt_cfm(conn, ev->status, 0x00);
			}
		}
	}

	hci_dev_unlock(hdev);
}
Exemple #4
0
uint8_t test_codec(uint8_t ev, uint16_t lparam, void* rparam)
{
	switch(ev)
	{
		case EVENT_WINDOW_CREATED:
		codec_wakeup();
		hci_send_cmd(&hci_vs_set_pcm_loopback_enable, 1);
		break;

		case EVENT_WINDOW_PAINT:
		{
		  tContext *pContext = (tContext*)rparam;
		  GrContextForegroundSet(pContext, ClrBlack);
		  GrRectFill(pContext, &client_clip);

		  GrContextForegroundSet(pContext, ClrWhite);
      	  GrContextFontSet(pContext, (tFont*)&g_sFontGothic18);
 		  GrStringDraw(pContext, "Speaker is looping back to mic", -1, 0, 50, 0);

  		window_volume(pContext, 30, 125, 8, codec_getvolume());

 		  window_button(pContext, KEY_UP, "+");
 		  window_button(pContext, KEY_DOWN, "-");

 		  break;
 		}
 		case EVENT_KEY_PRESSED:
		  switch(lparam)
		      {
		      case KEY_UP:
		        {
		          codec_changevolume(+1);
		          break;
		        }
		      case KEY_DOWN:
		        {
		          // decrease voice
		          codec_changevolume(-1);
		          break;
		        }
					}
					window_invalid(NULL);
			break;
		case EVENT_EXIT_PRESSED:
		hci_send_cmd(&hci_vs_set_pcm_loopback_enable, 1);
		codec_suspend();
		return 0; // return 0 to close the window

		default:
		return 0;
	}

	return 1;
}
void
proc_scopcm()
{
	hci_send_cmd(hci_write_sco_pcm_int,
		sizeof(hci_write_sco_pcm_int));

	read_event(uart_fd, buffer);

	hci_send_cmd(hci_write_pcm_data_format,
		sizeof(hci_write_pcm_data_format));

	read_event(uart_fd, buffer);
}
Exemple #6
0
static void passkey_agent_free(struct passkey_agent *agent)
{
	GSList *l;

	if (!agent)
		return;

	for (l = agent->pending_requests; l != NULL; l = l->next) {
		struct pending_agent_request *req = l->data;

		hci_send_cmd(req->dev, OGF_LINK_CTL,
				OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);

		send_cancel_request(req);
	}

	if (agent->timeout)
		g_source_remove(agent->timeout);

	if (!agent->exited)
		release_agent(agent);

	g_free(agent->name);
	g_free(agent->path);
	g_free(agent->addr);

	if (agent->conn)
		dbus_connection_unref(agent->conn);

	g_slist_free(agent->pending_requests);

	g_free(agent);
}
Exemple #7
0
static int write_inquiry_mode(int dev_id, int sock)
{

       struct hci_filter flt;
       write_inquiry_mode_cp cp;

       hci_filter_clear(&flt);
       hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
       hci_filter_set_event(EVT_INQUIRY_RESULT, &flt);
       hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt);
       hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt);
       if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
               perror("Can't set HCI filter");
               return 1;
       }
       memset(&cp, 0, sizeof(cp));
       cp.mode = 0x01;
       //cp.mode = 0x00;
       
       if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE,WRITE_INQUIRY_MODE_RP_SIZE, &cp) < 0) 
       {
             perror("Can't set write inquiry mode");
             return 1;
       }
       return 0;
}
Exemple #8
0
static int hfp_ag_run_for_audio_connection(hfp_connection_t * context){
    if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED ||
        context->state > HFP_W2_DISCONNECT_SCO) return 0;


    if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED && context->release_audio_connection){
        context->state = HFP_W4_SCO_DISCONNECTED;
        context->release_audio_connection = 0;
        gap_disconnect(context->sco_handle);
        return 1;
    }

    if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0;
    
    // run codecs exchange
    int done = codecs_exchange_state_machine(context);
    if (done) return done;
    // printf(" -> State machine: Audio Connection\n");

    if (context->codecs_state != HFP_CODECS_EXCHANGED) return done;
    if (context->establish_audio_connection){
        context->state = HFP_W4_SCO_CONNECTED;
        context->establish_audio_connection = 0;
        hci_send_cmd(&hci_setup_synchronous_connection, context->con_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
        return 1;
    
    }
    return 0;
}
/* Authentication Complete */
static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data;
	struct hci_conn *conn;

	BT_DBG("%s status %d", hdev->name, ev->status);

	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
	if (conn) {
		if (!ev->status)
			conn->link_mode |= HCI_LM_AUTH;

		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);

		hci_auth_cfm(conn, ev->status);

		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
			if (!ev->status) {
				struct hci_cp_set_conn_encrypt cp;
				cp.handle  = __cpu_to_le16(conn->handle);
				cp.encrypt = 1;
				hci_send_cmd(conn->hdev, OGF_LINK_CTL,
					OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
			} else {
				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
				hci_encrypt_cfm(conn, ev->status, 0x00);
			}
		}
	}

	hci_dev_unlock(hdev);
}
Exemple #10
0
static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
{
	struct hci_cp_remote_name_req *cp;
	struct hci_conn *conn;

	BT_DBG("%s status 0x%x", hdev->name, status);

	/* If successful wait for the name req complete event before
	 * checking for the need to do authentication */
	if (!status)
		return;

	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
	if (!cp)
		return;

	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
	if (conn && hci_outgoing_auth_needed(hdev, conn)) {
		struct hci_cp_auth_requested cp;
		cp.handle = __cpu_to_le16(conn->handle);
		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
	}

	hci_dev_unlock(hdev);
}
void
proc_enable_lpm()
{
	hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode));

	read_event(uart_fd, buffer);
}
Exemple #12
0
static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_ev_remote_features *ev = (void *) skb->data;
	struct hci_conn *conn;

	BT_DBG("%s status %d", hdev->name, ev->status);

	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
	if (conn) {
		if (!ev->status)
			memcpy(conn->features, ev->features, 8);

		if (conn->state == BT_CONFIG) {
			if (!ev->status && lmp_ssp_capable(hdev) &&
						lmp_ssp_capable(conn)) {
				struct hci_cp_read_remote_ext_features cp;
				cp.handle = ev->handle;
				cp.page = 0x01;
				hci_send_cmd(hdev,
					HCI_OP_READ_REMOTE_EXT_FEATURES,
							sizeof(cp), &cp);
			} else {
				conn->state = BT_CONNECTED;
				hci_proto_connect_cfm(conn, ev->status);
				hci_conn_put(conn);
			}
		}
	}

	hci_dev_unlock(hdev);
}
void
proc_bdaddr()
{
	hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr));

	read_event(uart_fd, buffer);
}
Exemple #14
0
/*
 * sco_connect(pcb, sockaddr)
 *
 *	Initiate a SCO connection to the destination address.
 */
int
sco_connect(struct sco_pcb *pcb, struct sockaddr_bt *dest)
{
	hci_add_sco_con_cp cp;
	struct hci_unit *unit;
	struct hci_link *acl, *sco;
	int err;

	if (pcb->sp_flags & SP_LISTENING)
		return EINVAL;

	bdaddr_copy(&pcb->sp_raddr, &dest->bt_bdaddr);

	if (bdaddr_any(&pcb->sp_raddr))
		return EDESTADDRREQ;

	if (bdaddr_any(&pcb->sp_laddr)) {
		err = hci_route_lookup(&pcb->sp_laddr, &pcb->sp_raddr);
		if (err)
			return err;
	}

	unit = hci_unit_lookup(&pcb->sp_laddr);
	if (unit == NULL)
		return ENETDOWN;

	/*
	 * We must have an already open ACL connection before we open the SCO
	 * connection, and since SCO connections dont happen on their own we
	 * will not open one, the application wanting this should have opened
	 * it previously.
	 */
	acl = hci_link_lookup_bdaddr(unit, &pcb->sp_raddr, HCI_LINK_ACL);
	if (acl == NULL || acl->hl_state != HCI_LINK_OPEN)
		return EHOSTUNREACH;

	sco = hci_link_alloc(unit);
	if (sco == NULL)
		return ENOMEM;

	sco->hl_type = HCI_LINK_SCO;
	bdaddr_copy(&sco->hl_bdaddr, &pcb->sp_raddr);

	sco->hl_link = hci_acl_open(unit, &pcb->sp_raddr);
	KKASSERT(sco->hl_link == acl);

	cp.con_handle = htole16(acl->hl_handle);
	cp.pkt_type = htole16(0x00e0);		/* HV1, HV2, HV3 */
	err = hci_send_cmd(unit, HCI_CMD_ADD_SCO_CON, &cp, sizeof(cp));
	if (err) {
		hci_link_free(sco, err);
		return err;
	}

	sco->hl_sco = pcb;
	pcb->sp_link = sco;

	pcb->sp_mtu = unit->hci_max_sco_size;
	return 0;
}
irqreturn_t mt_bt_eirq_handler(int i, void *arg)
{
    struct hci_dev *hdev = NULL;

    //printk(KERN_ALERT "mt_bt_eirq_handler\n");
    mt_bt_disable_irq();

if(eint_handle_method == 0) {
//#ifdef CONFIG_BT_HCIUART
    /* BlueZ stack, hci_uart driver */
    hdev = hci_dev_get(0);
    if(hdev == NULL){
        /* Avoid the early interrupt before hci0 registered */
        //BT_HWCTL_ALERT("hdev is NULL\n");
    }else{
        //BT_HWCTL_ALERT("EINT arrives! notify host wakeup\n");
        printk("Send host wakeup command\n");
        hci_send_cmd(hdev, 0xFCC1, 0, NULL);
        /* enable irq after receiving host wakeup command's event */
    }
	mt_bt_enable_irq();
} else {
//#else
    /* Maybe handle the interrupt in user space? */
    eint_gen = 1;
    wake_up_interruptible(&eint_wait);
    /* Send host wakeup command in user space, enable irq then */
//#endif
}

    return IRQ_HANDLED;
}
int hci_disable_device_under_test_mode()
{
	int ret = -1;
    int dev_id = -1;

	dev_id = init_smd("/dev/smd3");
    if (dev_id < 0) {
		ALOGE("Can not open file /dev/smd3,maybe file is not exist or no permission to access \n");
        return ret;
    }

	ret = hci_send_cmd(dev_id, 0x03, 0x0003, 0, NULL);
	if (ret < 0)
	{
		ALOGE("Disable Device Under Test Mode Command failure");
		fprintf(stderr, "Disable Device Under Test Mode Command failure hci%d: %s (%d)\n",
						dev_id, strerror(errno), errno);
		goto failed;
	}

	goto done;

failed:
    close(dev_id);
	ALOGE("hci_Disable_device_under_test_mode Failed\n");
    return ret ;

done:
    close(dev_id);
	ALOGV("hci_Disable_device_under_test_mode OUT\n");
    return ret ;
}
Exemple #17
0
/* Authentication Complete */
static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	evt_auth_complete *ac = (evt_auth_complete *) skb->data;
	struct hci_conn *conn = NULL;
	__u16 handle = __le16_to_cpu(ac->handle);

	BT_DBG("%s status %d", hdev->name, ac->status);

	hci_dev_lock(hdev);
	
	conn = conn_hash_lookup_handle(hdev, handle);
	if (conn) {
		if (!ac->status)
			conn->link_mode |= HCI_LM_AUTH;
		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);

		hci_proto_auth_cfm(conn, ac->status);
		
		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
			if (!ac->status) {
				set_conn_encrypt_cp ce;
				ce.handle  = __cpu_to_le16(conn->handle);
				ce.encrypt = 1;
				hci_send_cmd(conn->hdev, OGF_LINK_CTL,
						OCF_SET_CONN_ENCRYPT,
						SET_CONN_ENCRYPT_CP_SIZE, &ce);
			} else {
				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
				hci_proto_encrypt_cfm(conn, ac->status);
			}
		}
	}

	hci_dev_unlock(hdev);
}
/* Connect Request */
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data;
	int mask = hdev->link_mode;

	BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
			batostr(&ev->bdaddr), ev->link_type);

	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);

	if (mask & HCI_LM_ACCEPT) {
		/* Connection accepted */
		struct hci_conn *conn;
		struct hci_cp_accept_conn_req cp;

		hci_dev_lock(hdev);
		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
		if (!conn) {
			if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
				BT_ERR("No memmory for new connection");
				hci_dev_unlock(hdev);
				return;
			}
		}
		memcpy(conn->dev_class, ev->dev_class, 3);
		conn->state = BT_CONNECT;
		hci_dev_unlock(hdev);

		bacpy(&cp.bdaddr, &ev->bdaddr);

		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
			cp.role = 0x00; /* Become master */
		else
			cp.role = 0x01; /* Remain slave */

		hci_send_cmd(hdev, OGF_LINK_CTL,
				OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
	} else {
		/* Connection rejected */
		struct hci_cp_reject_conn_req cp;

		bacpy(&cp.bdaddr, &ev->bdaddr);
		cp.reason = 0x0f;
		hci_send_cmd(hdev, OGF_LINK_CTL,
				OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
	}
}
Exemple #19
0
static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length)
{
	unsigned char cp[254], rp[254];
	struct hci_request rq;
	uint8_t cmd[10];
	uint16_t size;

	size = (length < 8) ? 9 : ((length + 1) / 2) + 5;

	cmd[0] = command & 0xff;
	cmd[1] = command >> 8;
	cmd[2] = size & 0xff;
	cmd[3] = size >> 8;
	cmd[4] = seqnum & 0xff;
	cmd[5] = seqnum >> 8;
	cmd[6] = varid & 0xff;
	cmd[7] = varid >> 8;
	cmd[8] = 0x00;
	cmd[9] = 0x00;

	memset(cp, 0, sizeof(cp));
	cp[0] = 0xc2;
	memcpy(cp + 1, cmd, sizeof(cmd));
	memcpy(cp + 11, value, length);

	switch (varid) {
	case CSR_VARID_COLD_RESET:
	case CSR_VARID_WARM_RESET:
	case CSR_VARID_COLD_HALT:
	case CSR_VARID_WARM_HALT:
		return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, (size * 2) + 1, cp);
	}

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_VENDOR_CMD;
	rq.ocf    = 0x00;
	rq.event  = EVT_VENDOR;
	rq.cparam = cp;
	rq.clen   = (size * 2) + 1;
	rq.rparam = rp;
	rq.rlen   = sizeof(rp);

	if (hci_send_req(dd, &rq, 2000) < 0)
		return -1;

	if (rp[0] != 0xc2) {
		errno = EIO;
		return -1;
	}

	if ((rp[9] + (rp[10] << 8)) != 0) {
		errno = ENXIO;
		return -1;
	}

	memcpy(value, rp + 11, length);

	return 0;
}
Exemple #20
0
/* Connect Request */
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	evt_conn_request *cr = (evt_conn_request *) skb->data;
	int mask = hdev->link_mode;

	BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
			batostr(&cr->bdaddr), cr->link_type);

	mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);

	if (mask & HCI_LM_ACCEPT) {
		/* Connection accepted */
		struct hci_conn *conn;
		accept_conn_req_cp ac;

		hci_dev_lock(hdev);
		conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
		if (!conn) {
			if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
				BT_ERR("No memmory for new connection");
				hci_dev_unlock(hdev);
				return;
			}
		}
		conn->state = BT_CONNECT;
		hci_dev_unlock(hdev);

		bacpy(&ac.bdaddr, &cr->bdaddr);
	
		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
			ac.role = 0x00; /* Become master */
		else
			ac.role = 0x01; /* Remain slave */

		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, 
				ACCEPT_CONN_REQ_CP_SIZE, &ac);
	} else {
		/* Connection rejected */
		reject_conn_req_cp rc;

		bacpy(&rc.bdaddr, &cr->bdaddr);
		rc.reason = 0x0f;
		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
				REJECT_CONN_REQ_CP_SIZE, &rc);
	}
}
void
proc_i2s()
{
	hci_send_cmd(hci_write_i2spcm_interface_param,
		sizeof(hci_write_i2spcm_interface_param));

	read_event(uart_fd, buffer);
}
Exemple #22
0
// enable LE, setup ADV data
static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    if (packet_type != HCI_EVENT_PACKET) return;
    bd_addr_t addr;
    uint8_t adv_data[] = { 02, 01, 05,   03, 02, 0xf0, 0xff }; 
    
    switch (packet[0]) {
        case BTSTACK_EVENT_STATE:
            // bt stack activated, get started - set local name
            if (packet[2] == HCI_STATE_WORKING) {
                printf("Working!\n");
                hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
            }
            break;
            
        case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED:
            if (packet[2]) {
                printf("CONNECTED");
            } else {
                printf("DISCONNECTED");
            }
            break;
            
        case HCI_EVENT_DISCONNECTION_COMPLETE:
            // restart advertising
            hci_send_cmd(&hci_le_set_advertise_enable, 1);
            break;
            
        case HCI_EVENT_COMMAND_COMPLETE:
            if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){
                bt_flip_addr(addr, &packet[6]);
                printf("BD ADDR: %s\n", bd_addr_to_str(addr));
                break;
            }
            if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)){
               hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
               break;
            }
            if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)){
               hci_send_cmd(&hci_le_set_advertise_enable, 1);
               break;
            }
        default:
            break;
    }
	
}
Exemple #23
0
static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_ev_remote_features *ev = (void *) skb->data;
	struct hci_conn *conn;

	BT_DBG("%s status %d", hdev->name, ev->status);

	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
	if (!conn)
		goto unlock;

	if (!ev->status)
		memcpy(conn->features, ev->features, 8);

	if (conn->state != BT_CONFIG)
		goto unlock;

	if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
		struct hci_cp_read_remote_ext_features cp;
		cp.handle = ev->handle;
		cp.page = 0x01;
		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
							sizeof(cp), &cp);
		goto unlock;
	}

	if (!ev->status) {
		struct hci_cp_remote_name_req cp;
		memset(&cp, 0, sizeof(cp));
		bacpy(&cp.bdaddr, &conn->dst);
		cp.pscan_rep_mode = 0x02;
		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
	}

	if (!hci_outgoing_auth_needed(hdev, conn)) {
		conn->state = BT_CONNECTED;
		hci_proto_connect_cfm(conn, ev->status);
		hci_conn_put(conn);
	}

unlock:
	hci_dev_unlock(hdev);
}
Exemple #24
0
static void device_devup_setup(int index)
{
	struct hci_dev_info di;
	uint16_t policy;
	int dd, err;

	if (hci_devinfo(index, &di) < 0)
		return;

	if (hci_test_bit(HCI_RAW, &di.flags))
		return;

	dd = hci_open_dev(index);
	if (dd < 0) {
		err = errno;
		error("Can't open device hci%d: %s (%d)",
						index, strerror(err), err);
		return;
	}

	/* Set page timeout */
	if ((main_opts.flags & (1 << HCID_SET_PAGETO))) {
		write_page_timeout_cp cp;

		cp.timeout = htobs(main_opts.pageto);
		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT,
					WRITE_PAGE_TIMEOUT_CP_SIZE, &cp);
	}

	/* Set default link policy */
	policy = htobs(main_opts.link_policy);
	hci_send_cmd(dd, OGF_LINK_POLICY,
				OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);

	hci_close_dev(dd);

	start_security_manager(index);

	/* Return value 1 means ioctl(DEVDOWN) was performed */
	if (manager_start_adapter(index) == 1)
		stop_security_manager(index);
}
Exemple #25
0
static int generic_reset_device(int dd)
{
	bdaddr_t bdaddr;
	int err;

	err = hci_send_cmd(dd, 0x03, 0x0003, 0, NULL);
	if (err < 0)
		return err;

	return hci_read_bd_addr(dd, &bdaddr, 10000);
}
Exemple #26
0
/** send_hciCmd Function
 *  This function takes the hci commands for the BT chip configurations, creates 
 *  a hci channel to send the commadns through UART to configure BT chip
 *
 *  Parameters :
 *  @ dev_id            : HCI device ID
 *  @ command_length    : Number of arguments of the command
 *  @ command           : Pointer to command list
 *  Returns 0 upon success
 *        , different error messages depending upon the error.
 */
static void send_hciCmd(int dev_id, int command_length, char **command)
{
        unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf;
        struct hci_filter flt;
        hci_event_hdr *hdr;
        int i, opt, len, dd;
        uint16_t ocf;
        uint8_t ogf;
        
        if (dev_id < 0)
                dev_id = hci_get_route(NULL);

        errno = 0;
        ogf = strtol(command[0], NULL, 16);
        ocf = strtol(command[1], NULL, 16);

        for (i = 2, len = 0; i < command_length && len < sizeof(buf); i++, len++)
                *ptr++ = (uint8_t) strtol(command[i], NULL, 16);

        dd = hci_open_dev(dev_id);
        if (dd < 0) {
                perror("Device open failed");
                return;
        }

        /* Setup filter */
        hci_filter_clear(&flt);
        hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
        hci_filter_all_events(&flt);
        if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
                perror("HCI filter setup failed");
                return;
        }

	    /* Send the BT chip configuration commands */
        if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) {
                perror("Send failed");
                return;
        }

	    /* Wait for the command completion event */
        len = read(dd, buf, sizeof(buf));
        if (len < 0) {
                perror("Read failed");
                return;
        }

        hdr = (void *)(buf + 1);
        ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
        len -= (1 + HCI_EVENT_HDR_SIZE);

        hci_close_dev(dd);
}
Exemple #27
0
static void do_next_remote_name_request(void){
    int i;
    for (i=0;i<deviceCount;i++) {
        // remote name request
        if (devices[i].state == REMOTE_NAME_REQUEST){
            devices[i].state = REMOTE_NAME_INQUIRED;
            printf("Get remote name of %s...\n", bd_addr_to_str(devices[i].address));
            hci_send_cmd(&hci_remote_name_request, devices[i].address,
                        devices[i].pageScanRepetitionMode, 0, devices[i].clockOffset | 0x8000);
            return;
        }
    }
}
Exemple #28
0
void proc_reset()
{
	signal(SIGALRM, expired);


	hci_send_cmd(hci_reset, sizeof(hci_reset));

	alarm(4);

	read_event(uart_fd, buffer);

	alarm(0);
}
void
proc_baudrate()
{

	if (baudrate > 3000000) {
		hci_send_cmd(hci_write_uart_clock_setting_48Mhz,
			sizeof(hci_write_uart_clock_setting_48Mhz));

		read_event(uart_fd, buffer);
	}

	hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate));

	read_event(uart_fd, buffer);

	cfsetospeed(&termios, termios_baudrate);
	cfsetispeed(&termios, termios_baudrate);
	tcsetattr(uart_fd, TCSANOW, &termios);

	if (debug) {
		fprintf(stderr, "Done setting baudrate\n");
	}
}
Exemple #30
0
static void gap_run(){
    if (!hci_can_send_command_packet_now()) return;

    if (todos & DISABLE_ADVERTISEMENTS){
        todos &= ~DISABLE_ADVERTISEMENTS;
        printf("GAP_RUN: disable advertisements\n");
        advertisements_enabled = 0;
        hci_send_cmd(&hci_le_set_advertise_enable, 0);
        return;
    }    

    if (todos & SET_ADVERTISEMENT_DATA){
        printf("GAP_RUN: set advertisement data\n");
        todos &= ~SET_ADVERTISEMENT_DATA;
        hci_send_cmd(&hci_le_set_advertising_data, adv_data_len, adv_data);
        return;
    }    

    if (todos & SET_ADVERTISEMENT_PARAMS){
        todos &= ~SET_ADVERTISEMENT_PARAMS;
        uint8_t adv_type = gap_adv_type();
        bd_addr_t null_addr;
        memset(null_addr, 0, 6);
        uint16_t adv_int_min = 0x800;
        uint16_t adv_int_max = 0x800;
        switch (adv_type){
            case 0:
            case 2:
            case 3:
                hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, gap_random, 0, &null_addr, 0x07, 0x00);
                break;
            case 1:
            case 4:
                hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, gap_random, tester_address_type, &tester_address, 0x07, 0x00);
                break;
        }
        return;
    }    

    if (todos & SET_SCAN_RESPONSE_DATA){
        printf("GAP_RUN: set scan response data\n");
        todos &= ~SET_SCAN_RESPONSE_DATA;
        hci_send_cmd(&hci_le_set_scan_response_data, adv_data_len, adv_data);
        // hack for menu
        if ((todos & ENABLE_ADVERTISEMENTS) == 0) show_usage();
        return;
    }    

    if (todos & ENABLE_ADVERTISEMENTS){
        printf("GAP_RUN: enable advertisements\n");
        todos &= ~ENABLE_ADVERTISEMENTS;
        advertisements_enabled = 1;
        hci_send_cmd(&hci_le_set_advertise_enable, 1);
        show_usage();
        return;
    }
}