Re: Problem with inquiry result with rssi

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ulrich,

On Thu, Jan 20, 2011 at 12:44 PM, Ulrich BÃrgi <buergi@xxxxxxxxxxxx> wrote:
> Hello everyone,
>
> I'm encountering a strange behavior regarding inquiry results. I'm working
> on a C program, which has a method called 'scanner_start'. This method
> performs an inquiry and reports the corresponding addresses and RSSI values
> of all results.
> When I just call this method and do nothing else, it works as intended.
> However, if I do anything prior to that, I only get 'normal' inquiry results
> without RSSI.
>
> As example, this works:
> /* do nothing here */
> scanner_start();
> /* do something here */
>
> whereas this fails:
> /* do nothing here */
> int i;
> scanner_start();
> /* do something here */
>
> Below is the complete source code needed to reproduce this behavior.
>
> I cannot really imagine, how an unused declaration can have an impact on the
> inquiry results. Does anybody have a clue, how this could be?
>
> Thank you,
> Ulrich
>
> --
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <sys/socket.h>
> #include <sys/poll.h>
> #include <sys/ioctl.h>
> #include <bluetooth/bluetooth.h>
> #include <bluetooth/hci.h>
> #include <bluetooth/hci_lib.h>
>
> static void print_result(bdaddr_t *bdaddr, char has_rssi, int rssi)
> {
> Â Â Â Âchar addr[18];
>
> Â Â Â Âba2str(bdaddr, addr);
>
> Â Â Â Âprintf("%17s", addr);
> Â Â Â Âif(has_rssi)
> Â Â Â Â Â Â Â Âprintf(" RSSI:%d", rssi);
> Â Â Â Âelse
> Â Â Â Â Â Â Â Âprintf(" RSSI:n/a");
> Â Â Â Âprintf("\n");
> Â Â Â Âfflush(NULL);
> }
>
>
> static void scanner_start()
> {
> Â Â Â Âint dev_id, sock = 0;
> Â Â Â Âstruct hci_filter flt;
> Â Â Â Âinquiry_cp cp;
> Â Â Â Âunsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
> Â Â Â Âhci_event_hdr *hdr;
> Â Â Â Âchar canceled = 0;
> Â Â Â Âinquiry_info_with_rssi *info_rssi;
> Â Â Â Âinquiry_info *info;
> Â Â Â Âint results, i, len;
> Â Â Â Âstruct pollfd p;
>
> Â Â Â Âdev_id = hci_get_route(NULL);
> Â Â Â Âsock = hci_open_dev( dev_id );
> Â Â Â Âif (dev_id < 0 || sock < 0) {
> Â Â Â Â Â Â Â Âperror("Can't open socket");
> Â Â Â Â Â Â Â Âreturn;
> Â Â Â Â}
>
> Â Â Â Â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;
> Â Â Â Â}
>
> Â Â Â Âif (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE,
> WRITE_INQUIRY_MODE_RP_SIZE, &cp) < 0) {

Taking a look at your code, a few things look out of place: you are
using cp uninitialized, it is expecting a write_inquiry_mode_cp, not a
inquiry_cp and the plen parameter seems wrong.

Declaring (or not) the variable i is messing with the stack state and
affecting the value that goes into cp.

> Â Â Â Â Â Â Â Âperror("Can't set inquiry mode");
> Â Â Â Â Â Â Â Âreturn;
> Â Â Â Â}
>
> Â Â Â Âmemset (&cp, 0, sizeof(cp));
> Â Â Â Âcp.lap[2] = 0x9e;
> Â Â Â Âcp.lap[1] = 0x8b;
> Â Â Â Âcp.lap[0] = 0x33;
> Â Â Â Âcp.num_rsp = 0;
> Â Â Â Âcp.length = 0x30;
>
> Â Â Â Âprintf("Starting inquiry with RSSI...\n");
>
> Â Â Â Âif (hci_send_cmd (sock, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE,
> &cp) < 0) {
> Â Â Â Â Â Â Â Âperror("Can't start inquiry");
> Â Â Â Â Â Â Â Âreturn;
> Â Â Â Â}
>
> Â Â Â Âp.fd = sock;
> Â Â Â Âp.events = POLLIN | POLLERR | POLLHUP;
>
> Â Â Â Âwhile(!canceled) {
> Â Â Â Â Â Â Â Âp.revents = 0;
>
> Â Â Â Â Â Â Â Â/* poll the BT device for an event */
> Â Â Â Â Â Â Â Âif (poll(&p, 1, -1) > 0) {
> Â Â Â Â Â Â Â Â Â Â Â Âlen = read(sock, buf, sizeof(buf));
>
> Â Â Â Â Â Â Â Â Â Â Â Âif (len < 0)
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âcontinue;
> Â Â Â Â Â Â Â Â Â Â Â Âelse if (len == 0)
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âbreak;
>
> Â Â Â Â Â Â Â Â Â Â Â Âhdr = (void *) (buf + 1);
> Â Â Â Â Â Â Â Â Â Â Â Âptr = buf + (1 + HCI_EVENT_HDR_SIZE);
>
> Â Â Â Â Â Â Â Â Â Â Â Âresults = ptr[0];
>
> Â Â Â Â Â Â Â Â Â Â Â Âswitch (hdr->evt) {
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âcase EVT_INQUIRY_RESULT:
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âfor (i = 0; i < results; i++) {
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âinfo = (void *)ptr +
> (sizeof(*info) * i) + 1;
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âprint_result(&info->bdaddr,
> 0, 0);
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â}
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âbreak;
>
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âcase EVT_INQUIRY_RESULT_WITH_RSSI:
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âfor (i = 0; i < results; i++) {
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âinfo_rssi = (void *)ptr +
> (sizeof(*info_rssi) * i) + 1;
>
> Âprint_result(&info_rssi->bdaddr, 1, info_rssi->rssi);
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â}
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âbreak;
>
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âcase EVT_INQUIRY_COMPLETE:
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âcanceled = 1;
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âbreak;
> Â Â Â Â Â Â Â Â Â Â Â Â}
> Â Â Â Â Â Â Â Â}
> Â Â Â Â}
> Â Â Â Âclose(sock);
> }
>
> int main(int argc, char **argv)
> {
> Â Â Â Â//int i; /* causes inq. result to have no rssi value */
> Â Â Â Âscanner_start();
> Â Â Â Âreturn 0;
> }
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth"
> in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at Âhttp://vger.kernel.org/majordomo-info.html
>


Cheers,
-- 
Vinicius
ÿô.nlj·Ÿ®‰­†+%ŠË±é¥Šwÿº{.nlj·¥Š{±ý¶â^n‡r¡öë¨è&£ûz¹Þúzf£¢·hšˆ§~†­†Ûÿÿïÿ‘ê_èæ+v‰¨þ)ßø

[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux