Chinaunix首页 | 论坛 | 博客
  • 博客访问: 310022
  • 博文数量: 92
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 960
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-21 19:38






分类: 嵌入式

2009-09-19 20:32:08

1 inquiry Remote Bluetooth Device:
int hci_inquiry (int dev_id, int len, int nrsp, const uint8_t * lap, inquiry_info ** ii, long flags)
hci_inquiry () is used to ask certain Dongle to search all around bluetooth device. and to search for Bluetooth Device bdaddr.
Parameter 1: dev_id: specify Dongle Device ID. If this value is less than 0, it will use the first available Dongle.
Parameter 2: len: the length of time of this inquiry (each increase of 1 and an increase of 1.25 seconds time)
Parameter 3: nrsp: The Search for the largest number of searches, if given 0. Then this value will take 255.
Parameter 4: lap: BDADDR in the LAP part, Inquiry, when the value of the default is 0X9E8B33. Normally use NULL. Is automatically set.
Parameter 5: ii: store search for Bluetooth Device place. Inquiry_info pointer to a storage address, it will automatically allocate space. And to put that space in which the first address.
Parameter 6: flags: search flags. using IREQ_CACHE_FLUSH, will be a real re-inquiry. Otherwise it will return the last result.
The return value is the number of Inquiry to the Bluetooth Device.  
Note: If * ii is not to allocate by itself, hci_inquiry() to allocate it, then you need to call bt_free () to free up space.
2: get the specified BDAddr the reomte device Name:
int hci_read_remote_name (int dd, const bdaddr_t * bdaddr, int len, char * name, int to)
Parameter 1:dd: Use hci_open_dev () to open a Socket.
Parameter 2:bdaddr: the other side BDAddr.
Parameter 3:len: name length.
Parameter 4:name: (out) to place the location name.
Parameter 5:to:  wait time.
3: Read the connection signal strength:
int hci_read_rssi (int dd, uint16_t handle, int8_t * rssi, int to)
Note that for all pairs of connect operations, there will be a parameter, handle. This parameter is the connection Handle. Talked about how to get connected in front of the Handle.

A simple program that detects nearby Bluetooth devices is shown in . The program reserves system Bluetooth resources, scans for nearby Bluetooth devices, and then looks up the user friendly name for each detected device. A more detailed explanation of the data structures and functions used follows.

Example simplescan.c









int main(int argc, char **argv)


    inquiry_info *ii = NULL;

    int max_rsp, num_rsp;

    int dev_id, sock, len, flags;

    int i;

    char addr[19] = { 0 };

    char name[248] = { 0 };


    dev_id = hci_get_route(NULL);

    sock = hci_open_dev( dev_id );

    if (dev_id < 0 || sock < 0) {

        perror("opening socket");




    len  = 8;

    max_rsp = 255;

    flags = IREQ_CACHE_FLUSH;

    ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));


    num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);

    if( num_rsp < 0 ) perror("hci_inquiry");


    for (i = 0; i < num_rsp; i++) {

        ba2str(&(ii+i)->bdaddr, addr);

        memset(name, 0, sizeof(name));

        if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name),

            name, 0) < 0)

        strcpy(name, "[unknown]");

        printf("%s  %s\n", addr, name);



    free( ii );

    close( sock );

    return 0;



To compile our program, invoke gcc and link against libbluetooth

# arm-softfloat-linux-gnu-gcc simplescan.c -L /usr/local/lib -lbluetooth -o simplescan



typedef struct {

        uint8_t b[6];

} __attribute__((packed)) bdaddr_t;

The basic data structure used to specify a Bluetooth device address is the bdaddr_t. All Bluetooth addresses in BlueZ will be stored and manipulated as bdaddr_t structures. BlueZ provides two convenience functions to convert between strings and bdaddr_t structures.

int str2ba( const char *str, bdaddr_t *ba );

int ba2str( const bdaddr_t *ba, char *str );

str2ba takes an string of the form ``XX:XX:XX:XX:XX:XX", where each XX is a hexadecimal number specifying an octet of the 48-bit address, and packs it into a 6-byte bdaddr_t. ba2str does exactly the opposite.

Local Bluetooth adapters are assigned identifying numbers starting with 0, and a program must specify which adapter to use when allocating system resources. Usually, there is only one adapter or it doesn't matter which one is used, so passing NULL to hci_get_route will retrieve the resource number of the first available Bluetooth adapter.

int hci_get_route( bdaddr_t *bdaddr );

int hci_open_dev( int dev_id );

If there are multiple Bluetooth adapters present, then to choose the adapter with address ``01:23:45:67:89:AB", pass the char * representation of the address to hci_devid and use that in place of hci_get_route.

int dev_id = hci_devid( "01:23:45:67:89:AB" );

Most Bluetooth operations require the use of an open socket. hci_open_dev is a convenience function that opens a Bluetooth socket with the specified resource number. To be clear, the socket opened by hci_open_dev represents a connection to the microcontroller on the specified local Bluetooth adapter, and not a connection to a remote Bluetooth device. Performing low level Bluetooth operations involves sending commands directly to the microcontroller with this socket.

After choosing the local Bluetooth adapter to use and allocating system resources, the program is ready to scan for nearby Bluetooth devices. In the example, hci_inquiry performs a Bluetooth device discovery and returns a list of detected devices and some basic information about them in the variable ii. On error, it returns -1 and sets errno accordingly.

int hci_inquiry(int dev_id, int len, int max_rsp, const uint8_t *lap,

                inquiry_info **ii, long flags);

hci_inquiry is one of the few functions that requires the use of a resource number instead of an open socket, so we use the dev_id returned by hci_get_route. The inquiry lasts for at most 1.28 * len seconds, and at most max_rsp devices will be returned in the output parameter ii, which must be large enough to accommodate max_rsp results. We suggest using a max_rsp of 255 for a standard 10.24 second inquiry.

If flags is set to IREQ_CACHE_FLUSH, then the cache of previously detected devices is flushed before performing the current inquiry. Otherwise, if flags is set to 0, then the results of previous inquiries may be returned, even if the devices aren't in range anymore.

The inquiry_info structure is defined as

typedef struct {

    bdaddr_t    bdaddr;

    uint8_t     pscan_rep_mode;

    uint8_t     pscan_period_mode;

    uint8_t     pscan_mode;

    uint8_t     dev_class[3];

    uint16_t    clock_offset;

} __attribute__ ((packed)) inquiry_info;

For the most part, only the first entry - the bdaddr field, which gives the address of the detected device - is of any use. Occasionally, there may be a use for the dev_class field, which gives information about the type of device detected (i.e. if it's a printer, phone, desktop computer, etc.) and is described in the Bluetooth Assigned Numbers. The rest of the fields are used for low level communication, and are not useful for most purposes. The interested reader can see the Bluetooth Core Specification  for more details.

Once a list of nearby Bluetooth devices and their addresses has been found, the program determines the user-friendly names associated with those addresses and presents them to the user. The hci_read_remote_name function is used for this purpose.

int hci_read_remote_name(int sock, const bdaddr_t *ba, int len,

                         char *name, int timeout)

hci_read_remote_name tries for at most timeout milliseconds to use the socket sock to query the user-friendly name of the device with Bluetooth address ba. On success, hci_read_remote_name returns 0 and copies at most the first len bytes of the device's user-friendly name into name. On failure, it returns -1 and sets errno accordingly.


阅读(1940) | 评论(0) | 转发(0) |