remote_name_request, using libbluetooth

Masoom Shaikh masoom.shaikh at gmail.com
Sun Oct 4 04:57:00 UTC 2009


On Sat, Oct 3, 2009 at 8:13 PM, Iain Hibbert <plunky at rya-online.net> wrote:

> On Sat, 3 Oct 2009, Masoom Shaikh wrote:
>
> > Hi,
> >
> > today i spent ages hacking hccontrol to do something similar it does when
> > invoked as below
> >
> > hccontrol remote_name_request <BD_ADDR>
> >
> > somehow i couldn't succeed ;-(
>
> you didn't say exactly the failure you have reached, did you use hcidump
> to check the actions?
>
> > what really i want is to search for devices and request their names
> > i have a ruby script which does the same by using hccontrol and
> manipulating
> > it console output
> > but am interested in C version.
> >
> > pasted below is full source.
> >
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <errno.h>
> > #include <string.h>
> > #include <bluetooth.h>
> >
> > /*
> >  * removes duplicate entries from result and returns the new size
> >  * free()'s the original array, result is calloc()ed
> >  * TODO: implement in a better way
> >  */
> > int do_uniq( const int size, struct bt_devinquiry** result)
> > {
> >     struct bt_devinquiry* newResult = (struct bt_devinquiry*)calloc(
> size,
> > sizeof(struct bt_devinquiry));
> >
> >     struct bt_devinquiry* srcCurr = *result;
> >     struct bt_devinquiry* dstCurr = newResult;
> >
> >     int count = 0;
> >     int index = 0;
> >     for ( ; index < size; ++index)
> >     {
> >         int j = 0;
> >         int found = 0;
> >         while ( j < count)
> >         {
> >             if ( bdaddr_same( &( newResult[j++].bdaddr), &(
> > srcCurr->bdaddr)))
> >             {
> >                 found = 1;
> >                 break;
> >             }
> >         }
> >
> >         if ( !found)
> >         {
> >             *dstCurr = *srcCurr;
> >             ++dstCurr;
> >             ++count;
> >         }
> >         ++srcCurr;
> >     }
> >     free(*result);
> >     *result = newResult;
> >     return count;
> > }
> >
> > int main( int argc, char* argv[])
> > {
> >     /* search devices */
> >     struct bt_devinquiry* result = 0;
> >     int num = bt_devinquiry( 0, 0, 0, &result);
> >     if ( num <= 0)
> >     {
> >         if ( h_errno)
>
> what is h_errno?  I think these checks are uninvolved with the code at
> hand..
>
> >             herror( "no devices found");
> >         else
> >             printf( "no devices found\n");
> >         return num;
> >     }
> >     /* remove duplicate entries */
> >     num = do_uniq( num, &result);
> >     printf( "%d device(s) found\n", num);
>
> also, I don't think the do_uniq() step should be necessary -- we did
> discuss it at least and in the version i wrote for NetBSD it doesn't
> return duplicate results
>
> >     /* try to query device's name */
> >     int s = bt_devopen( "ubt0hci");
> >     if ( s == -1)
> >     {
> >         if ( h_errno)
> >             herror( "bt_devopen error\n");
> >         else
> >             printf( "bt_devopen error\n");
> >         return -1;
> >     }
> >     int i = 0;
> >     for ( ; i < num; ++i)
> >     {
> >         struct bt_devreq request;
> >         memset( &request, 0, sizeof(request));
> >         request.opcode = NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
> > NG_HCI_OCF_REMOTE_NAME_REQ);
> >         request.event = NG_HCI_EVENT_REMOTE_NAME_REQ_COMPL;
> >
> >         ng_hci_remote_name_req_cp cp;
> >         memset(&cp, 0, sizeof(cp));
> >         bdaddr_copy( &cp.bdaddr, &result->bdaddr);
> >         cp.page_scan_rep_mode = NG_HCI_SCAN_REP_MODE0;
> >         cp.page_scan_mode = NG_HCI_MANDATORY_PAGE_SCAN_MODE;
> >         request.cparam = (void*)&cp;
> >         request.clen = sizeof(cp);
> >
> >         char buffer[512];
> >         memset( buffer, 0, 512);
> >         request.rparam = (void*)buffer;
> >         request.rlen = 512;
> >
> >         int status = bt_devreq( s, &request, 0);
> >         if ( status == 0)
> >         {
> >             ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t*)buffer;
> >             ng_hci_remote_name_req_compl_ep *ep =
> > (ng_hci_remote_name_req_compl_ep*)(e + 1);
> >             printf( "status: %d\n", ep->status);
> >             printf( "name: %s\n", ep->name);
> >         }
>
> I think your problem might be here. The event header is not returned, only
> the remote_name_req_compl_ep event packet..  (I would have used that
> directly in the rparam field rather than a separate buffer -- bt_devreq
> will not overflow the given space)
>
> >         else if (status == -1)
> >         {
> >             if ( h_errno)
> >                 herror( "bt_devreq error\n");
> >             else
> >                 printf( "bt_devreq error\n");
> >         }
> >         else
> >         {
> >             printf("bt_devreq unknown return value\n");
> >         }
> >     }
> >     bt_devclose(s);
> >     return 0;
> > }
>
> iain
>
>
> thanks for replying
yes, i did forgot to say where it failed, devices are inquired properly no
issues there
but bt_devreq() fails with status == -1

comment taken
i will remove the separate buffer, thank you again

here is the hcidump output

HCIDump - HCI packet analyzer ver 1.5
device: any snap_len: 65535 filter: 0xffffffffffffffff
< HCI Command: Inquiry(0x01|0x0001) plen 5
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Inquiry Result(0x02) plen 15
> HCI Event: Inquiry Result(0x02) plen 15
> HCI Event: Inquiry Complete(0x01) plen 1
< HCI Command: Remote Name Request(0x01|0x0019) plen 10
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Remote Name Req Complete(0x07) plen 255

i guess the last line indicates that we does receive device name but some
how bt_devreq() returns fails
i will poke around bt_devreq() for clues


More information about the freebsd-bluetooth mailing list