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