static gboolean io_conn_ind(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct vhci_link_info info;
	struct vhci_conn *conn;
	struct sockaddr_in sa;
	socklen_t len;
	int sk, nsk, h;

	if (cond & G_IO_NVAL)
		return FALSE;

	sk = g_io_channel_unix_get_fd(chan);

	len = sizeof(sa);
	if ((nsk = accept(sk, (struct sockaddr *) &sa, &len)) < 0)
		return TRUE;

	if (read_n(nsk, &info, sizeof(info)) < 0) {
		syslog(LOG_ERR, "Can't read link info");
		return TRUE;
	}

	if (!(conn = malloc(sizeof(*conn)))) {
		syslog(LOG_ERR, "Can't alloc new connection");
		close(nsk);
		return TRUE;
	}

	bacpy(&conn->dest, &info.bdaddr);

	for (h = 0; h < VHCI_MAX_CONN; h++)
		if (!vconn[h])
			goto accepted;

	syslog(LOG_ERR, "Too many connections");
	free(conn);
	close(nsk);
	return TRUE;

accepted:
	vconn[h] = conn;
	conn->handle = h + 1;
	conn->chan = g_io_channel_unix_new(nsk);
	connect_request(conn);

	return TRUE;
}
Beispiel #2
0
int sco_connect(struct sock *sk)
{
    bdaddr_t *src = &bluez_pi(sk)->src;
    bdaddr_t *dst = &bluez_pi(sk)->dst;
    struct sco_conn *conn;
    struct hci_conn *hcon;
    struct hci_dev  *hdev;
    int err = 0;

    BT_DBG("%s -> %s", batostr(src), batostr(dst));

    if (!(hdev = hci_get_route(dst, src)))
        return -EHOSTUNREACH;

    hci_dev_lock_bh(hdev);

    err = -ENOMEM;

    hcon = hci_connect(hdev, SCO_LINK, dst);
    if (!hcon)
        goto done;

    conn = sco_conn_add(hcon, 0);
    if (!conn) {
        hci_conn_put(hcon);
        goto done;
    }

    /* Update source addr of the socket */
    bacpy(src, conn->src);

    err = sco_chan_add(conn, sk, NULL);
    if (err)
        goto done;

    if (hcon->state == BT_CONNECTED) {
        sco_sock_clear_timer(sk);
        sk->state = BT_CONNECTED;
    } else {
        sk->state = BT_CONNECT;
        sco_sock_set_timer(sk, sk->sndtimeo);
    }
done:
    hci_dev_unlock_bh(hdev);
    hci_dev_put(hdev);
    return err;
}
Beispiel #3
0
int connection_init(int dev_id, char *addr, struct conn_info_handles *ci)
{
	struct hci_conn_info_req *cr = NULL;
	bdaddr_t bdaddr;
	
	int dd;
	int ret = 1;

	str2ba(addr, &bdaddr);

	if (dev_id < 0) {
		dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
		if (dev_id < 0) {
			ret = ERR_NOT_CONNECTED;
			goto out;
		}
	}

	dd = hci_open_dev(dev_id);
	if (dd < 0) {
		ret = ERR_HCI_DEV_OPEN_FAILED;
		goto out;
	}

	cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
	if (!cr) {
		ret = ERR_CANNOT_ALLOCATE;
		goto out;
	}

	bacpy(&cr->bdaddr, &bdaddr);
	cr->type = ACL_LINK;
	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
		ret = ERR_GET_CONN_INFO_FAILED;
		goto out;
	}
	
	ci->dd = dd;
	ci->handle = cr->conn_info->handle;

out:
	if (cr)
		free(cr);
	
	return ret;
}
Beispiel #4
0
static int l2cap_accept(int sk, bdaddr_t *bdaddr)
{
    struct sockaddr_l2 addr;
    socklen_t addrlen;
    int nsk;

    memset(&addr, 0, sizeof(addr));
    addrlen = sizeof(addr);

    if ((nsk = accept(sk, (struct sockaddr *) &addr, &addrlen)) < 0)
        return -1;

    if (bdaddr)
        bacpy(bdaddr, &addr.l2_bdaddr);

    return nsk;
}
Beispiel #5
0
bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	GError *err = NULL;
	sdp_record_t *rec;

	DBG("");

	bacpy(&adapter_addr, addr);

	server = bt_io_listen(NULL, confirm_cb, NULL, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_PSM, L2CAP_PSM_AVCTP,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_INVALID);
	if (!server) {
		error("Failed to listen on AVDTP channel: %s", err->message);
		g_error_free(err);
		return false;
	}

	rec = avrcp_record();
	if (!rec) {
		error("Failed to allocate AVRCP record");
		goto fail;
	}

	if (bt_adapter_add_record(rec, 0) < 0) {
		error("Failed to register AVRCP record");
		sdp_record_free(rec);
		goto fail;
	}
	record_id = rec->handle;

	hal_ipc = ipc;

	ipc_register(hal_ipc, HAL_SERVICE_ID_AVRCP, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	return true;
fail:
	g_io_channel_shutdown(server, TRUE, NULL);
	g_io_channel_unref(server);
	server = NULL;

	return false;
}
Beispiel #6
0
static void confirm_event(GIOChannel *chan, gpointer user_data)
{
	struct network_adapter *na = user_data;
	bdaddr_t src, dst;
	char address[18];
	GError *err = NULL;
	guint ret;

	bt_io_get(chan, &err,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST, address,
			BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		goto drop;
	}

	DBG("BNEP: incoming connect from %s", address);

	if (na->setup) {
		error("Refusing connect from %s: setup in progress", address);
		goto drop;
	}

	if (!na->servers)
		goto drop;

	na->setup = g_new0(struct network_session, 1);
	bacpy(&na->setup->dst, &dst);
	na->setup->io = g_io_channel_ref(chan);

	ret = btd_request_authorization(&src, &dst, BNEP_SVC_UUID,
					auth_cb, na);
	if (ret == 0) {
		error("Refusing connect from %s", address);
		setup_destroy(na);
		goto drop;
	}

	return;

drop:
	g_io_channel_shutdown(chan, TRUE, NULL);
}
Beispiel #7
0
/**
 * Called by run_scan when we receive a complete EVT_INQUIRY_RESULT_WITH_RSSI
 * message.
 *
 * Writes a byte with value EVT_INQUIRY_RESULT_WITH_RSSI and then a
 * bluetrax_inquiry_result_with_rssi_t structure (in binary format) to out_file.
 *
 * Reference: [BTSPEC, volume 2, section 7.7.33, page 756]
 *
 * @param out_file to write record to
 *
 * @param time that the message was received
 *
 * @param hdr the event header
 *
 * @param data all data after the header; length is at least hdr->plen 
 *
 * @return EXIT_SUCCESS if no errors
 */
static int handle_inquiry_result_with_rssi(FILE *out_file,
    struct timeval time, hci_event_hdr *hdr, unsigned char *data)
{
  int num_rsp, i;
  inquiry_info_with_rssi *info;
  bluetrax_inquiry_result_with_rssi_t record;

  if (hdr->plen <= 0) {
    syslog(LOG_ERR, "handle_inquiry_result_with_rssi: bad plen: plen=%hhd",
        hdr->plen);
    return EXIT_FAILURE;
  }

  /* note: we never seem to get num_rsp > 1 here, but handle it anyway */
  num_rsp = data[0];
  syslog(LOG_DEBUG, "handle_inquiry_result_with_rssi: num_rsp=%d", num_rsp);

  /* sanity check */
  if (hdr->plen != num_rsp * sizeof(inquiry_info_with_rssi) + 1) {
    syslog(LOG_ERR,
        "handle_inquiry_result_with_rssi: bad plen: num_rsp=%d, plen=%hhd",
        num_rsp, hdr->plen);
    return EXIT_FAILURE;
  }

  record.time = time;
  info = (inquiry_info_with_rssi *)(data + 1);
  for (i = 0; i < num_rsp; ++i) {
    bacpy(&record.bdaddr, &info[i].bdaddr);
    memcpy(&record.dev_class, info[i].dev_class, sizeof(record.dev_class));
    record.rssi = info[i].rssi;

    /* write the event type and then the event record */
    if (EVT_INQUIRY_RESULT_WITH_RSSI !=
        fputc(EVT_INQUIRY_RESULT_WITH_RSSI, out_file)) {
      syslog(LOG_ERR, "handle_inquiry_result_with_rssi: fputc: %m");
      return EXIT_FAILURE;
    }
    if (1 != fwrite(&record, sizeof(record), 1, out_file)) {
      syslog(LOG_ERR, "handle_inquiry_result_with_rssi: fwrite: %m");
      return EXIT_FAILURE;
    }
  }

  return EXIT_SUCCESS;
}
Beispiel #8
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);
}
Beispiel #9
0
static int sco_listen(pa_bluetooth_transport *t) {
    struct transport_data *trd = t->userdata;
    struct sockaddr_sco addr;
    int sock, i;
    bdaddr_t src;
    const char *src_addr;

    sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
    if (sock < 0) {
        pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno));
        return -1;
    }

    src_addr = t->device->adapter->address;

    /* don't use ba2str to avoid -lbluetooth */
    for (i = 5; i >= 0; i--, src_addr += 3)
        src.b[i] = strtol(src_addr, NULL, 16);

    /* Bind to local address */
    memset(&addr, 0, sizeof(addr));
    addr.sco_family = AF_BLUETOOTH;
    bacpy(&addr.sco_bdaddr, &src);

    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        pa_log_error("bind(): %s", pa_cstrerror(errno));
        goto fail_close;
    }

    pa_log_info ("doing listen");
    if (listen(sock, 1) < 0) {
        pa_log_error("listen(): %s", pa_cstrerror(errno));
        goto fail_close;
    }

    trd->sco_fd = sock;
    trd->sco_io = trd->mainloop->io_new(trd->mainloop, sock, PA_IO_EVENT_INPUT,
        sco_io_callback, t);

    return sock;

fail_close:
    close(sock);
    return -1;
}
Beispiel #10
0
static void bt_hid_connect(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_connect *cmd = buf;
	struct hid_device *dev;
	uint8_t status;
	char addr[18];
	bdaddr_t dst;
	GSList *l;
	uuid_t uuid;

	DBG("");

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = g_new0(struct hid_device, 1);
	bacpy(&dev->dst, &dst);
	dev->uhid_fd = -1;

	ba2str(&dev->dst, addr);
	DBG("connecting to %s", addr);

	sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID);
	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
				hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
		error("Failed to search DeviceID SDP details");
		hid_device_remove(dev);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	devices = g_slist_append(devices, dev);
	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT,
									status);
}
Beispiel #11
0
int main(int argc, char **argv)
{
	struct sockaddr_rc loc_addr = { 0 };	/* local bluetooth adapter's info */
	struct sockaddr_rc client_addr = { 0 };	/* filled in with remote (client) bluetooth device's info */
	char buf[1024] = { 0 };
	int server_sock, client_sock, bytes_read;
	unsigned int opt = sizeof(client_addr);

	printf("Start Bluetooth RFCOMM server...\n");

	/* allocate socket */
	server_sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

	loc_addr.rc_family = AF_BLUETOOTH;		/* Addressing family, always AF_BLUETOOTH */
	bacpy(&loc_addr.rc_bdaddr, BDADDR_ANY);		/* Bluetooth address of local bluetooth adapter */
	loc_addr.rc_channel = RFCOMM_SERVER_PORT_NUM;	/* port number of local bluetooth adapter */

	printf("binding\n");
	if(bind(server_sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) {
		perror("failed to bind");
		exit(1);
	}

	printf("listening\n");
	/* put socket into listening mode */
	listen(server_sock, 1);		/* backlog is one */

	/* accept one connection */
	client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &opt);	/* return new socket for connection with a client */

	ba2str( &client_addr.rc_bdaddr, buf );
	printf("connected from %s\n", buf);

	/* read data from the client */
	memset(buf, 0, sizeof(buf));
	bytes_read = recv(client_sock, buf, sizeof(buf), 0);
	if( bytes_read > 0 ) {
		printf("received [%s]\n", buf);
	}

	/* close connection */
	close(client_sock);
	close(server_sock);
	return 0;
}
Beispiel #12
0
static uint8_t get_serial_channel(bdaddr_t *device, int only_gnapplet)
{
	bdaddr_t src;
	int channel;
	uint8_t retval;

	bacpy(&src, BDADDR_ANY);

	channel = find_service_channel(&src, device, only_gnapplet, GNOKII_SERIAL_PORT_CLASS);
	if (channel < 0)
		channel = find_service_channel(&src, device, only_gnapplet, GNOKII_DIALUP_NETWORK_CLASS);

	if (channel < 0)
		retval = 0;
	else
		retval = channel;
	return retval;
}
Beispiel #13
0
/*
 * Add a service record to the repository
 */
void sdp_record_add(const bdaddr_t *device, sdp_record_t *rec)
{
	sdp_access_t *dev;

	SDPDBG("Adding rec : 0x%lx", (long) rec);
	SDPDBG("with handle : 0x%x", rec->handle);

	service_db = sdp_list_insert_sorted(service_db, rec, record_sort);

	dev = malloc(sizeof(*dev));
	if (!dev)
		return;

	bacpy(&dev->device, device);
	dev->handle = rec->handle;

	access_db = sdp_list_insert_sorted(access_db, dev, access_sort);
}
Beispiel #14
0
static void adapter_ready(int err, const bdaddr_t *addr)
{
	if (err < 0) {
		error("Adapter initialization failed: %s", strerror(-err));
		exit(EXIT_FAILURE);
	}

	bacpy(&adapter_bdaddr, addr);

	if (bluetooth_start_timeout > 0) {
		g_source_remove(bluetooth_start_timeout);
		bluetooth_start_timeout = 0;
	}

	info("Adapter initialized");

	ipc_init();
}
Beispiel #15
0
void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci)
{
	DBusMessage *message;
	DBusMessageIter iter;
	DBusPendingCall *pending = NULL;
	struct pin_request *req;

	message = dbus_message_new_method_call(SERVICE_NAME, PATH_NAME,
						INTERFACE_NAME, REQUEST_NAME);
	if (message == NULL) {
		syslog(LOG_ERR, "Couldn't allocate D-BUS message");
		goto failed;
	}

	req = malloc(sizeof(*req));
	req->dev = dev;
	bacpy(&req->bda, &ci->bdaddr);

	dbus_message_append_iter_init(message, &iter);

	dbus_message_iter_append_boolean(&iter, ci->out);
	dbus_message_iter_append_byte_array(&iter,
			(unsigned char *) &ci->bdaddr, sizeof(ci->bdaddr));

	if (dbus_connection_send_with_reply(connection, message,
						&pending, TIMEOUT) == FALSE) {
		syslog(LOG_ERR, "D-BUS send failed");
		goto failed;
	}

	dbus_pending_call_set_notify(pending, reply_handler_function,
							req, free_pin_req);

	dbus_connection_flush (connection);

	dbus_message_unref (message);

	return;

failed:
	dbus_message_unref (message);
	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY,
							6, &ci->bdaddr);
}
static int cmd_connect(const char *dst, gpointer user_data)
{
  bdaddr_t sba, dba;
  uint8_t dest_type;
  BtIOSecLevel sec;

  if (get_state() != STATE_DISCONNECTED) {
    return -1;
  }

  set_state(STATE_CONNECTING);

  str2ba(dst, &dba);
  bacpy(&sba, BDADDR_ANY);            /* {0, 0, 0, 0, 0, 0} */
  dest_type = BDADDR_LE_PUBLIC;       /* 0x01 */
  sec = BT_IO_SEC_LOW;                /* Connection happens at low security. Change later */

  GError *gerr = NULL;

  /* iochannel is declared global for now
   * source: src/device.c in bluez tree for more details
   */
  iochannel = bt_io_connect(connect_cb, user_data, NULL, &gerr,
              BT_IO_OPT_SOURCE_BDADDR, &sba,
              BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
              BT_IO_OPT_DEST_BDADDR, &dba,
              BT_IO_OPT_DEST_TYPE, dest_type,
              BT_IO_OPT_CID, ATT_CID,
              BT_IO_OPT_SEC_LEVEL, sec,
              BT_IO_OPT_INVALID);

  if (gerr) {
    set_state(STATE_DISCONNECTED);
    set_error(ERR_CONNECT_FAILED, gerr->message, user_data);
    printf("Error: %d  %s\n", gerr->code, gerr->message);
    g_error_free(gerr);
    return -2;
  } else {
    g_io_add_watch(iochannel, G_IO_HUP, channel_hangup_watcher, user_data);
    g_main_loop_run(event_loop);
  }

  return 0;
}
static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf,
								size_t len)
{
	struct mgmt_ev_user_confirm_request *ev = buf;
	struct controller_info *info;
	char addr[18];
	int err;

	if (len < sizeof(*ev)) {
		error("Too small user_confirm_request event");
		return;
	}

	ba2str(&ev->bdaddr, addr);

	DBG("hci%u %s confirm_hint %u", index, addr, ev->confirm_hint);

	if (index > max_index) {
		error("Unexpected index %u in user_confirm_request event",
									index);
		return;
	}

	if (ev->confirm_hint) {
		struct confirm_data *data;

		data = g_new0(struct confirm_data, 1);
		data->index = index;
		bacpy(&data->bdaddr, &ev->bdaddr);

		g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1,
						confirm_accept, data, g_free);
		return;
	}

	info = &controllers[index];

	err = btd_event_user_confirm(&info->bdaddr, &ev->bdaddr,
							btohl(ev->value));
	if (err < 0) {
		error("btd_event_user_confirm: %s", strerror(-err));
		mgmt_confirm_reply(index, &ev->bdaddr, FALSE);
	}
}
Beispiel #18
0
static void auth_cb(DBusError *derr, void *user_data)
{
	struct service_adapter *serv_adapter = user_data;
	DBusMessage *reply;
	struct pending_auth *auth;
	bdaddr_t src;

	auth = next_pending(serv_adapter);
	if (auth == NULL) {
		info("Authorization cancelled: Client exited");
		return;
	}

	if (derr) {
		error("Access denied: %s", derr->message);

		reply = btd_error_not_authorized(auth->msg);
		dbus_message_unref(auth->msg);
		g_dbus_send_message(auth->conn, reply);
		goto done;
	}

	g_dbus_send_reply(auth->conn, auth->msg,
			DBUS_TYPE_INVALID);

done:
	dbus_connection_unref(auth->conn);

	serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
									auth);
	g_free(auth);

	auth = next_pending(serv_adapter);
	if (auth == NULL)
		return;

	if (serv_adapter->adapter)
		adapter_get_address(serv_adapter->adapter, &src);
	else
		bacpy(&src, BDADDR_ANY);

	btd_request_authorization(&src, &auth->dst,
					auth->uuid, auth_cb, serv_adapter);
}
Beispiel #19
0
static int mgmt_load_link_keys(int sk, uint16_t index, uint16_t nb_keys, bdaddr_t bdaddrs[nb_keys], unsigned char keys[nb_keys][16])
{
  char *buf;
  struct mgmt_hdr *hdr;
  struct mgmt_cp_load_link_keys *cp;
  struct mgmt_link_key_info *key;
  size_t cp_size;
  int err = 0;

  cp_size = sizeof(*cp) + (nb_keys * sizeof(*key));

  buf = calloc(sizeof(*hdr) + cp_size, 1);
  if (buf == NULL)
    return -ENOMEM;

  hdr = (void *) buf;
  hdr->opcode = htobs(MGMT_OP_LOAD_LINK_KEYS);
  hdr->len = htobs(cp_size);
  hdr->index = htobs(index);

  cp = (void *) (buf + sizeof(*hdr));
  cp->debug_keys = 0x00;
  cp->key_count = htobs(nb_keys);

  unsigned int i;
  for (i=0, key=cp->keys; i<nb_keys; ++i, ++key) {

    bacpy(&key->addr.bdaddr, bdaddrs+i);
    key->addr.type = BDADDR_BREDR;
    key->type = HCI_LK_UNAUTH_COMBINATION;
    memcpy(key->val, keys[i], 16);
    key->pin_len = 0x00;
  }

  if (write(sk, buf, sizeof(*hdr) + cp_size) < 0)
  {
    perror("write");
    err = -1;
  }

  free(buf);

  return err;
}
Beispiel #20
0
bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	GError *err = NULL;

	DBG("");

	bacpy(&adapter_addr, addr);

	ctrl_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	if (!ctrl_io) {
		error("hidhost: Failed to listen on control channel: %s",
								err->message);
		g_error_free(err);
		return false;
	}

	intr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	if (!intr_io) {
		error("hidhost: Failed to listen on interrupt channel: %s",
								err->message);
		g_error_free(err);

		g_io_channel_shutdown(ctrl_io, TRUE, NULL);
		g_io_channel_unref(ctrl_io);
		ctrl_io = NULL;

		return false;
	}

	hal_ipc = ipc;

	ipc_register(hal_ipc, HAL_SERVICE_ID_HIDHOST, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	return true;
}
Beispiel #21
0
static void nap_confirm_cb(GIOChannel *chan, gpointer data)
{
    struct pan_device *dev;
    bdaddr_t dst;
    char address[18];
    GError *err = NULL;

    DBG("");

    bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst,
              BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID);
    if (err) {
        error("%s", err->message);
        g_error_free(err);
        return;
    }

    DBG("incoming connect request from %s", address);
    dev = g_new0(struct pan_device, 1);
    bacpy(&dev->dst, &dst);
    local_role = HAL_PAN_ROLE_NAP;
    dev->role = HAL_PAN_ROLE_PANU;

    strncpy(dev->iface, BNEP_NAP_INTERFACE, 16);
    dev->iface[15] = '\0';

    dev->io = g_io_channel_ref(chan);
    g_io_channel_set_close_on_unref(dev->io, TRUE);

    if (!bt_io_accept(dev->io, nap_connect_cb, dev, NULL, &err)) {
        error("bt_io_accept: %s", err->message);
        g_error_free(err);
        goto failed;
    }

    devices = g_slist_append(devices, dev);
    bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING);

    return;

failed:
    bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
}
static int create_rfcomm_sock(bdaddr_t *address, uint8_t channel)
{
	int sk;
	struct sockaddr_rc addr;

	sk = socket(PF_BLUETOOTH, SOCK_STREAM | SOCK_NONBLOCK, BTPROTO_RFCOMM);

	memset(&addr, 0, sizeof(addr));
	addr.rc_family = AF_BLUETOOTH;
	addr.rc_channel = channel;
	bacpy(&addr.rc_bdaddr, address);

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		close(sk);
		return -1;
	}

	return sk;
}
Beispiel #23
0
static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_ev_remote_ext_features *ev = (void *) skb->data;
	struct hci_conn *conn;

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

	hci_dev_lock(hdev);

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

	if (!ev->status && ev->page == 0x01) {
		struct inquiry_entry *ie;

		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
		if (ie)
			ie->data.ssp_mode = (ev->features[0] & 0x01);

		conn->ssp_mode = (ev->features[0] & 0x01);
	}

	if (conn->state != BT_CONFIG)
		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);
}
static void device_info(int fd, uint16_t index, uint8_t *type, uint8_t *bus,
						bdaddr_t *bdaddr, char *name)
{
	struct hci_dev_info di;

	memset(&di, 0, sizeof(di));
	di.dev_id = index;

	if (ioctl(fd, HCIGETDEVINFO, (void *) &di) < 0) {
		perror("Failed to get device information");
		return;
	}

	*type = di.type >> 4;
	*bus = di.type & 0x0f;

	bacpy(bdaddr, &di.bdaddr);
	memcpy(name, di.name, 8);
}
static void device_list(int fd, int max_dev)
{
	struct hci_dev_list_req *dl;
	struct hci_dev_req *dr;
	int i;

	dl = malloc(max_dev * sizeof(*dr) + sizeof(*dl));
	if (!dl) {
		perror("Failed to allocate device list memory");
		return;
	}

	memset(dl, 0, max_dev * sizeof(*dr) + sizeof(*dl));
	dl->dev_num = max_dev;

	dr = dl->dev_req;

	if (ioctl(fd, HCIGETDEVLIST, (void *) dl) < 0) {
		perror("Failed to get device list");
		goto done;
	}

	for (i = 0; i < dl->dev_num; i++, dr++) {
		struct timeval tmp_tv, *tv = NULL;
		uint8_t type = 0xff, bus = 0xff;
		char str[18], name[8] = "";
		bdaddr_t bdaddr;

		bacpy(&bdaddr, BDADDR_ANY);

		if (!gettimeofday(&tmp_tv, NULL))
			tv = &tmp_tv;

		device_info(fd, dr->dev_id, &type, &bus, &bdaddr, name);
		ba2str(&bdaddr, str);
		packet_new_index(tv, dr->dev_id, str, type, bus, name);
		open_device(dr->dev_id);
	}

done:
	free(dl);
}
Beispiel #26
0
int avdtp_connect(avdtp_t *avdtp, bdaddr_t *bdaddr, uint8_t seid)
{
	struct avdtp_session *session;
	int sk;

	if (!avdtp)
		return -EIO;

	session = avdtp;

	bacpy(&session->dst, bdaddr);

	sk = l2cap_connect(&session->src, &session->dst, AVDTP_PSM, NULL);
	if (sk < 0)
		return -EIO;

	session->ssk = sk;

	return 0;
}
Beispiel #27
0
static int add_xml_record(DBusConnection *conn, const char *sender,
			struct service_adapter *serv_adapter,
			const char *record, dbus_uint32_t *handle)
{
	struct record_data *user_record;
	sdp_record_t *sdp_record;
	bdaddr_t src;

	sdp_record = sdp_xml_parse_record(record, strlen(record));
	if (!sdp_record) {
		error("Parsing of XML service record failed");
		return -EIO;
	}

	if (serv_adapter->adapter)
		adapter_get_address(serv_adapter->adapter, &src);
	else
		bacpy(&src, BDADDR_ANY);

	if (add_record_to_server(&src, sdp_record) < 0) {
		error("Failed to register service record");
		sdp_record_free(sdp_record);
		return -EIO;
	}

	user_record = g_new0(struct record_data, 1);
	user_record->handle = sdp_record->handle;
	user_record->sender = g_strdup(sender);
	user_record->serv_adapter = serv_adapter;
	user_record->listener_id = g_dbus_add_disconnect_watch(conn, sender,
					exit_callback, user_record, NULL);

	serv_adapter->records = g_slist_append(serv_adapter->records,
								user_record);

	DBG("listener_id %d", user_record->listener_id);

	*handle = user_record->handle;

	return 0;
}
Beispiel #28
0
/* Inquiry Result With RSSI */
static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	inquiry_info_with_rssi *info = (inquiry_info_with_rssi *) (skb->data + 1);
	int num_rsp = *((__u8 *) skb->data);

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

	hci_dev_lock(hdev);
	for (; num_rsp; num_rsp--) {
		inquiry_info tmp;
		bacpy(&tmp.bdaddr, &info->bdaddr);
		tmp.pscan_rep_mode    = info->pscan_rep_mode;
		tmp.pscan_period_mode = info->pscan_period_mode;
		tmp.pscan_mode        = 0x00;
		memcpy(tmp.dev_class, &info->dev_class, 3);
		tmp.clock_offset      = info->clock_offset;
		info++;
		inquiry_cache_update(hdev, &tmp);
	}
	hci_dev_unlock(hdev);
}
Beispiel #29
0
static void return_link_keys(int dev, bdaddr_t *sba, void *ptr)
{
	evt_return_link_keys *evt = ptr;
	uint8_t num = evt->num_keys;
	unsigned char key[16];
	char sa[18], da[18];
	bdaddr_t dba;
	int i;

	ba2str(sba, sa);
	ptr++;

	for (i = 0; i < num; i++) {
		bacpy(&dba, ptr); ba2str(&dba, da);
		memcpy(key, ptr + 6, 16);

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

		ptr += 22;
	}
}
Beispiel #30
0
static void cmd_unpair(int argcp, char **argvp)
{
    struct mgmt_cp_unpair_device cp;
    bdaddr_t bdaddr;
    uint8_t addr_type = BDADDR_LE_RANDOM;

    if (argcp != 3) {
        resp_mgmt(err_BAD_PARAM);
        return;
    }

    if (str2ba(argvp[1], &bdaddr)) {
        DBG("str2ba failed");
        resp_mgmt(err_NOT_FOUND);
        return;
    }

    if (!memcmp(argvp[2], "public", 6)) {
            addr_type = BDADDR_LE_PUBLIC;
    }

    memset(&cp, 0, sizeof(cp));
    bacpy(&cp.addr.bdaddr, &bdaddr);
    cp.addr.type = addr_type;
    cp.disconnect = 1;

    if (!mgmt_master) {
        resp_error(err_NO_MGMT);
        return;
    }

    if (mgmt_send(mgmt_master, MGMT_OP_UNPAIR_DEVICE,
                opt_src_idx, sizeof(cp), &cp,
                unpair_device_complete, NULL,
                NULL) == 0) {
        DBG("mgmt_send(MGMT_OP_UNPAIR_DEVICE) failed for %s for hci%u", opt_dst, MGMT_INDEX_NONE);
        resp_mgmt(err_PROTO_ERR);
        return;
    }
}