remote_name_request, using libbluetooth

View: New views
3 Messages — Rating Filter:   Alert me  

remote_name_request, using libbluetooth

by Masoom Shaikh-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 ;-(
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)
            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);

    /* 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);
        }
        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;
}
_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."

Parent Message unknown Re: remote_name_request, using libbluetooth

by Masoom Shaikh-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Oct 3, 2009 at 8:13 PM, Iain Hibbert <plunky@...> 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
_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."

Parent Message unknown Re: remote_name_request, using libbluetooth

by Masoom Shaikh-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Oct 4, 2009 at 7:57 AM, Iain Hibbert <plunky@...> wrote:

> On Sun, 4 Oct 2009, Masoom Shaikh wrote:
>
> > > On Sat, 3 Oct 2009, Masoom Shaikh wrote:
> > >
> > > >         int status = bt_devreq( s, &request, 0);
> >
> > yes, i did forgot to say where it failed, devices are inquired properly
> no
> > issues there
> > but bt_devreq() fails with status == -1
>
> ah, I see.. you should put a non-zero timeout value there (waiting for 0
> seconds will not leave enough time for the response :)
>
> if you use eg
>
>        if (status == -1)
>                err(1, "bt_devreq (RemoteNameRequest)")
>
> then you would see an "Operation timed out" message.. I should think 5
> seconds would be reasonable..
>
> regards,
> iain
>
>
> u got the bug by neck, and i would have slit its neck by the time this mail
is in your inbox ;-)
that was the exact error, timeout value of 5 didn't work for me, thus am
using 60, and it works
thanks Iain
_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."