Ejemplo n.º 1
0
void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
    app_gap_cb_t *p_dev = &m_dev_info;
    char bda_str[18];
    char uuid_str[37];

    switch (event) {
    case ESP_BT_GAP_DISC_RES_EVT: {
        update_device_info(param);
        break;
    }
    case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
        if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
            ESP_LOGI(GAP_TAG, "Device discovery stopped.");
            if ( (p_dev->state == APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE ||
                    p_dev->state == APP_GAP_STATE_DEVICE_DISCOVERING)
                    && p_dev->dev_found) {
                p_dev->state = APP_GAP_STATE_SERVICE_DISCOVERING;
                ESP_LOGI(GAP_TAG, "Discover services ...");
                esp_bt_gap_get_remote_services(p_dev->bda);
            }
        } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
            ESP_LOGI(GAP_TAG, "Discovery started.");
        }
        break;
    }
    case ESP_BT_GAP_RMT_SRVCS_EVT: {
        if (memcmp(param->rmt_srvcs.bda, p_dev->bda, ESP_BD_ADDR_LEN) == 0 &&
                p_dev->state == APP_GAP_STATE_SERVICE_DISCOVERING) {
            p_dev->state = APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE;
            if (param->rmt_srvcs.stat == ESP_BT_STATUS_SUCCESS) {
                ESP_LOGI(GAP_TAG, "Services for device %s found",  bda2str(p_dev->bda, bda_str, 18));
                for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) {
                    esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i;
                    ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37));
                    // ESP_LOGI(GAP_TAG, "--%d", u->len);
                }
            } else {
                ESP_LOGI(GAP_TAG, "Services for device %s not found",  bda2str(p_dev->bda, bda_str, 18));
            }
        }
        break;
    }
    case ESP_BT_GAP_RMT_SRVC_REC_EVT:
    default: {
        ESP_LOGI(GAP_TAG, "event: %d", event);
        break;
    }
    }
    return;
}
Ejemplo n.º 2
0
void btdev_cache_print(int state)
{
	btdev_struct	*entry;
	char		buf[256], *name;
	int		i;
	char		ch;

	for (i = 0; (entry = s_list_nth_data(devcache.head, i)); i++) {
		if (!(entry->state & state))
			continue;
		parse_cod(buf, entry->cod);
		if (entry->name[0] != '\0')
			name = entry->name;
		else
			name = "(none)";
		switch (entry->state) {
			case DEVSTATE_RANGE:
				ch = '+';
				break;
			case DEVSTATE_GONE:
				ch = '-';
				break;
			case DEVSTATE_UNKNOWN:
			default:
				ch = ' ';
		}
		printf("%c%d: Address: %s, Class: 0x%06X, Key: \"%s\"", 
				ch, i+1, bda2str(&entry->bda), entry->cod, (entry->flags & BTDEV_KEY)?"yes":"no");
		printf(", Name: \"%s\"\n", name);
		printf("    %s\n", buf);
	}
}
Ejemplo n.º 3
0
int __sdp_connect(char *target)
{
	int 			status;
	struct sockaddr_affix	sa;

	status = sdp_init(0);
	if (status < 0)
		return status;
	sa.family = PF_AFFIX;
	sa.devnum = hci_devnum(btdev);//HCIDEV_ANY;
	if (strcmp(target, "local") == 0) {
		printf("Opening local connection\n");
		srvHandle = sdp_connect_local();
	} else {
		status = btdev_get_bda(&sa.bda, target);
		if (status) {
			printf("Incorrect address given\n");
			return -1;
		}
		printf("Connecting to host %s ...\n", bda2str(&sa.bda));
		srvHandle = sdp_connect(&sa);
	}
	if (srvHandle < 0)
		return -1;
	return 0;
}
Ejemplo n.º 4
0
int btdev_cache_save(void)
{
	btdev_struct	*entry;
	FILE		*cfd;
	int		i, k;

	if (devcache.lock == -1 && btdev_cache_lock() < 0)
		return -1;

	cfd = fopen(devcache.file, "w");
	if (!cfd) {
		fprintf(stderr, "Unable to fopen cache file: %s\n", devcache.file);
		btdev_cache_unlock();
		return -1;
	}
	fprintf(cfd, "<device-listing>\n");
	for (i = 0; (entry = s_list_nth_data(devcache.head, i)); i++) {
		fprintf(cfd, "<device bda=\"%s\"", bda2str(&entry->bda));
		if (entry->cod)
			fprintf(cfd, " class=\"%x\"", entry->cod);
		if (entry->name[0] != '\0')
			fprintf(cfd, " name=\"%s\"", entry->name);
		if (entry->flags & BTDEV_KEY) {
			fprintf(cfd, " key=\"");
			for (k = 0; k < 16; k++)
				fprintf(cfd, "%02x", entry->link_key[k]);
			fprintf(cfd, "\"");
		}

		fprintf(cfd, "/>\n");
	}
	fprintf(cfd, "</device-listing>\n");
	fclose(cfd);
	btdev_cache_unlock();
	return 0;
}
Ejemplo n.º 5
0
int cmd_pan_connect(struct command *cmd)
{
	int		err, role = AFFIX_PAN_NAP;
	BD_ADDR		bda;
	struct sockaddr_affix	saddr;

	__argv = &__argv[optind];

	if (!*__argv) {
		printf("Address missing\n");
		print_usage(cmd);
		return 1;
	}
	err = btdev_get_bda(&bda, *__argv);
	if (err) {
		printf("Incorrect address given\n");
		return 1;
	}
	if (*(++__argv)) {
		/* role */
		role = str2role(*__argv);
		if (!role) {
			fprintf(stderr, "invalid role: %s\n", *__argv);
			return 1;
		}
	}

	saddr.family = PF_AFFIX;
	saddr.bda = bda;
	saddr.devnum = HCIDEV_ANY;

#if defined(CONFIG_AFFIX_SDP)
	if (sdpmode) {
		uint16_t	ServiceID;
		uint16_t	count;
		slist_t		*searchList = NULL;
		slist_t		*attrList = NULL;
		slist_t		*svcList = NULL;
		sdpsvc_t	*svcRec;

		if (role == AFFIX_PAN_NAP)
			ServiceID = SDP_UUID_NAP;
		else if (role == AFFIX_PAN_GN)
			ServiceID = SDP_UUID_GN;
		else
			ServiceID = SDP_UUID_PANU;

		printf("Connecting to host %s ...\n", bda2str(&bda));

		/* search for service ServiceID */
		s_list_append_uuid16(&searchList, ServiceID);
		/* set attributes to find */
		s_list_append_uint(&attrList, SDP_ATTR_SERVICE_RECORD_HANDLE);
		s_list_append_uint(&attrList, SDP_ATTR_PROTO_DESC_LIST);
		err = __sdp_search_attr_req(&saddr, searchList, IndividualAttributes, attrList, 0xffff, &svcList, &count);
		s_list_destroy(&searchList);
		s_list_free(&attrList);
		if (err) {
			fprintf(stderr, "%s\n", sdp_error(err));
			return -1;
		}
		if (count == 0) {
			printf("services [%s] not found\n", val2str(sdp_service_map, ServiceID));
			return -1;
		}
		printf("Service found\n");
		svcRec = s_list_dequeue(&svcList);
		sdp_free_svc(svcRec);
		sdp_free_svclist(&svcList);
	}
#endif
	saddr.devnum = hci_devnum(btdev);
	err = affix_pan_connect(&saddr, role);
	if (err) {
		if (errno == EINVAL)
			fprintf(stderr, "Connection not allowed in this role.\n");
		else
			fprintf(stderr, "failed.\n");
	} else 
		fprintf(stderr, "connected.\n");
	return 0;
}
Ejemplo n.º 6
0
int cmd_pan_discovery(struct command *cmd)
{
	int		role = AFFIX_PAN_NAP;
	int		fd, i, found = 0;
	__u32		length = 8;
	int		err;
	INQUIRY_ITEM	devs[20];
	char		*devnames[20];
	char		name[248];
	__u8		num;
	uint16_t	ServiceID;
	uint16_t	count;
	slist_t		*searchList = NULL;
	slist_t		*attrList = NULL;
	slist_t		*svcList = NULL;
	sdpsvc_t	*svcRec;
	struct sockaddr_affix	saddr;

	__argv = &__argv[optind];

	if (*__argv) {
		role = str2role(*__argv);
		if (!role) {
			fprintf(stderr, "invalid role: %s\n", *__argv);
			return 1;
		}
		if (*(++__argv))
			sscanf(*__argv, "%x", &length);
	}

	fd = hci_open(btdev);
	if (fd < 0) {
		printf("Unable to open device %s: %s\n", btdev, strerror(errno));
		return -1;
	}
	printf("Searching %d sec ...\n", length);
	err = HCI_Inquiry(fd, length, 20, devs, &num);
	if (err) {
		fprintf(stderr, "%s\n", hci_error(err));
		exit(1);
	}
	if (num == 0) {
		printf("done.\nNo devices found.\n");
	} else {
		printf("Searching done. Checking for service %s ...\n", role2str(role));
		btdev_cache_reload();
		btdev_cache_retire();
		for (i = 0; i < num; i++) {
			if (!(devs[i].Class_of_Device & HCI_COD_NETWORKING))
				continue;
			saddr.family = PF_AFFIX;
			saddr.bda = devs[i].bda;
			saddr.devnum = HCIDEV_ANY;
			printf("% 2d: %s ", ++found, bda2str(&saddr.bda));
			devs[i].Clock_Offset |= 0x8000;
			err = HCI_RemoteNameRequest(fd, &devs[i], name);
			if (!err)
				devnames[i] = strdup(name);
			else 
				devnames[i] = NULL;
			printf("(%s)... ", name);
#if defined(CONFIG_AFFIX_SDP)
			if (role == AFFIX_PAN_NAP)
				ServiceID = SDP_UUID_NAP;
			else if (role == AFFIX_PAN_GN)
				ServiceID = SDP_UUID_GN;
			else
				ServiceID = SDP_UUID_PANU;

			/* search for service ServiceID */
			s_list_append_uuid16(&searchList, ServiceID);
			/* set attributes to find */
			s_list_append_uint(&attrList, SDP_ATTR_SERVICE_RECORD_HANDLE);
			s_list_append_uint(&attrList, SDP_ATTR_PROTO_DESC_LIST);
			err = __sdp_search_attr_req(&saddr, searchList, IndividualAttributes, attrList, 0xffff, &svcList, &count);
			s_list_destroy(&searchList);
			s_list_free(&attrList);
			hci_disconnect(&saddr);
			if (err) {
				//fprintf(stderr, "%s\n", sdp_error(err));
				printf("no\n");
				continue;
			}
			if (count == 0) {
				printf("no\n");
				continue;
			}
			printf("yes\n");
			svcRec = s_list_dequeue(&svcList);
			sdp_free_svc(svcRec);
			sdp_free_svclist(&svcList);
			//hci_get_conn();
#else
			fprintf(stderr, "Affix SDP support disabled at compile time!\n");
			break;
#endif
			__btdev_cache_add(devs[i].bda, devs[i].Class_of_Device, devnames[i]);
			if (devnames[i])
				free(devnames[i]);
		}
		btdev_cache_save();
	}
	close(fd);
	return 0;
}
Ejemplo n.º 7
0
static void update_device_info(esp_bt_gap_cb_param_t *param)
{
    char bda_str[18];
    uint32_t cod = 0;
    int32_t rssi = -129; /* invalid value */
    esp_bt_gap_dev_prop_t *p;

    ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, 18));
    for (int i = 0; i < param->disc_res.num_prop; i++) {
        p = param->disc_res.prop + i;
        switch (p->type) {
        case ESP_BT_GAP_DEV_PROP_COD:
            cod = *(uint32_t *)(p->val);
            ESP_LOGI(GAP_TAG, "--Class of Device: 0x%x", cod);
            break;
        case ESP_BT_GAP_DEV_PROP_RSSI:
            rssi = *(int8_t *)(p->val);
            ESP_LOGI(GAP_TAG, "--RSSI: %d", rssi);
            break;
        case ESP_BT_GAP_DEV_PROP_BDNAME:
        default:
            break;
        }
    }

    /* search for device with MAJOR service class as "rendering" in COD */
    app_gap_cb_t *p_dev = &m_dev_info;
    if (p_dev->dev_found && 0 != memcmp(param->disc_res.bda, p_dev->bda, ESP_BD_ADDR_LEN)) {
        return;
    }

    if (!esp_bt_gap_is_valid_cod(cod) ||
            !(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_PHONE)) {
        return;
    }

    memcpy(p_dev->bda, param->disc_res.bda, ESP_BD_ADDR_LEN);
    p_dev->dev_found = true;
    for (int i = 0; i < param->disc_res.num_prop; i++) {
        p = param->disc_res.prop + i;
        switch (p->type) {
        case ESP_BT_GAP_DEV_PROP_COD:
            p_dev->cod = *(uint32_t *)(p->val);
            break;
        case ESP_BT_GAP_DEV_PROP_RSSI:
            p_dev->rssi = *(int8_t *)(p->val);
            break;
        case ESP_BT_GAP_DEV_PROP_BDNAME: {
            uint8_t len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN :
                          (uint8_t)p->len;
            memcpy(p_dev->bdname, (uint8_t *)(p->val), len);
            p_dev->bdname[len] = '\0';
            p_dev->bdname_len = len;
            break;
        }
        case ESP_BT_GAP_DEV_PROP_EIR: {
            memcpy(p_dev->eir, (uint8_t *)(p->val), p->len);
            p_dev->eir_len = p->len;
            break;
        }
        default:
            break;
        }
    }

    if (p_dev->eir && p_dev->bdname_len == 0) {
        get_name_from_eir(p_dev->eir, p_dev->bdname, &p_dev->bdname_len);
        ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname);
        p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE;
        ESP_LOGI(GAP_TAG, "Cancel device discovery ...");
        esp_bt_gap_cancel_discovery();
    }
}