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

[bluetooth-dev] BT library, kernel interface

Hi all

attached a propose an interface for a Bluetooth library, which should make
development of applications (e.g. OBEX integration) quite easy. Though it requires
some changes on the current stack, especially the interface from user level
through ioctl's to RFCOMM, SDP and HCI.

In my opinion there ought to be one device for SDP and one for HCI, separate
from RFCOMM (ie. the ttyBTx devices), to control SDP and HCI which exist exactly
once per stack (I haven't thought too much about interference of different
processes yet, but e.g. init stack, should be done once upon startup (loading) of the

I hope to get some feedback, and if there should be some acceptance for the
interface, I'll start implementing (ioctl's on kernel side and the corresponding
calls on user side).


/* -*- linux-c -*- */

/* Interface for Bluetooth library (c) 10/2000 Oliver Meili <omi@xxxxxxx.org> */
/* This is supposed to be a proposition, any comment is welcome            */
/* Please not the comments concerning stack integration in the             */
/* different sections */

/* The corresponding driver functions which could be used to perform the   */
/* task are noted in parentheses above the functions                       */

#ifndef BT_LIB_H

#define BT_LIB_H

#define BD_ADDR char*

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;

/*** HCI functions ************************************************************/
/* These may be invoked through one single device (for all processes the same */
/* and maybe not ttyBT0 (because this concerns HCI and not RFCOMM).           */

/* Data structure to keep the necessary information for HCI access */
struct bt_hci {
	int fd;

/* Structure to keep inquiry result information */
struct bt_inquiry_res {
	BD_ADDR bd_addr;
	uint8 rep_mode;
	uint8 per_mode;
	uint8 mode;
	uint32 dev_class;
	uint16 clock_off;

/* Structure to keep bluetooth device information */
struct bt_dev {
	BD_ADDR bd_addr;
	char *name;

/* Callback type for inquiry results */
typedef void (*bt_inq_cb)(struct bt_inquiry_res *, uint8);

/* Open the bt hci device (to get a reference to the driver) */
/* open() */
struct bt_hci *bt_open(char *name);

/* Close the bt hci device (to stop anything in a clean way) */
/* close */
uint8 bt_close(struct bt_hci *bt);

/* For the inquiry process there should in my opinion be two ways of operation   */
/* A blocking and a non-blocking one, there might be two different functions     */
/* required (with and without callback, and return structs and no return struct) */

/* Start inquiry */
/* ioctl() */
uint8 bt_inquiry(struct bt_hci *bt, uint8 duration, uint8 num_resp, bt_inq_cb callback);

/* Start periodic inquiry */
/* ioctl */
uint8 bt_inquiry_periodic(struct bt_hci *b, uint16 min_per, uint16 max_per, uint8 duration, 
			  uint8 num_resp, bt_inq_cb callback);

/* Cancel inquiry */
/* ioctl */
uint8 bt_inquiry_cancel(struct bt_hci *bt);

/* Request the name of a remote device */
/* ioctl */
char *bt_request_name(struct bt_hci *bt, BD_ADDR bd_addr);

/* Set the mode of the local device (e.g. discoverable, pairable, connectable) */
/* This function could be used to control the passive behavior of the device   */
/* ioctl */
uint8 bt_set_mode(struct bt_hci *bt, uint16 mode);

/*** SDP client functions ****************************************************/
/*   taken from service discovery profile                                    */
/*   Maybe some additional functions to manipulate the data elements would   */
/*   be nice as well, just for the users convenience                         */

/* Structure to keep information regarding a SDP connection */
struct bt_sdp_conn {
	int fd;
	BD_ADDR bd_addr;

/* Structure to keep an uuid for a service */
struct bt_uuid {
	uint8  size;
	uint32 uuid;

/* Structure to keep a service handle */
struct bt_serv_h {
	uint32 handle;

/* Structure for a data element */
struct bt_data_elt {
	uint32 size;
	uint8  type;
	char   *value;

/* Structure to keep a service attribute */
struct bt_serv_attr {
	uint16 id; /* this is always a 16 bit value => no size and type */
	struct bt_data_elt *value;

/* Open an SDP device to access SDP client or server functionality */
/* open() */
struct bt_sdp_conn *bt_sdp_open(char *name);

/* Close an SDP device */
/* close() */
uint8 bt_sdp_close(struct bt_sdp_conn *conn);

/* Connect to a remote SDP server */
/* ioctl() */
uint8 bt_sdp_connect(struct bt_sdp_conn *conn, struct bt_dev *dev);

/* Disconnect from a remote SDP server */
/* ioctl() */
uint8 bt_sdp_disconnect(struct bt_sdp_conn *conn);

/* Get a service handles for a type of service */
/* ioctl() */
uint8 bt_sdp_serv_search(struct bt_sdp_conn *conn, struct bt_uuid *pattern,
			 uint8 pattern_len, struct bt_serv_h *service_h, uint8 *service_h_num);

/* Search through a remote SDP database, i.e. attribute lookup */
/* ioctl() */
uint8 bt_sdp_attr_search(struct bt_sdp_conn *conn, struct bt_serv_h *handle, 
			 bt_serv_attr *attr, uint8 *attr_len);

/* Browse through a remote SDP database to find a certain service identified
   by a given uuid, start at group start */
/* ioctl */
uint8 bt_sdp_browse(struct bt_sdp_conn *conn, struct bt_uuid service, struct bt_uuid start);

/* Enumerate all bluetooth device (requires inquiry) */
/* ioctl */
uint8 bt_sdp_enum_devs(struct bt_dev **devs, uint8 size);

/* Cancel an SDP query */
/* ioctl */
uint8 bt_sdp_cancel(struct bt_sdp_conn *conn);

/*** SDP server functions ****************************************************/
/* These are required for maintenance of the local SDP database, the data    */
/* shoud represent a representation of the service records                   */

/* Structure to keep a protocol in a service record */
struct bt_serv_desc {
	struct bt_uuid type;
	uint8 num_attr;
	struct bt_serv_attr *attr;

/* Structure to keep a service record in the SDP database */
struct bt_serv_rec {
	uint8 num_serv_class;
	struct bt_uuid *serv_class;
	uint8 num_prot;
	struct bt_serv_desc *prot;
	uint8 num_profile;
	struct bt_serv_desc *profile;
	uint8 num_attr;
	struct bt_serv_attr *attr;
	char *service_name; /* \0 terminated */

/* The data had to be serialized in user space and the serialized version */
/* transferred to the kernel part of SDP                                  */

/* Add a new record to the local SDP database, e.g. new service registering itself */
/* write() */
uint8 bt_sdp_add_record(struct bt_uuid *service, void *data, uint8 size);

/* Delete a record in the local SDP database, e.g. service terminating */
/* write() */
uint8 bt_sdp_del_record(struct bt_uuid service);

/*** RFCOMM client functions *************************************************/

/* Structure to hold the information of a RFCOMM connection */
struct bt_rfcomm_conn {
	int fd;
	BD_ADDR bd_addr;
	int serv_chan;

/* Open a local RFCOMM device (/dev/ttyBTx) */
/* open() */
struct bt_rfcomm_conn *bt_rfcomm_open(char *device);

/* Close a local RFCOMM device */
/* open() */
uint8 bt_rfcomm_close(struct bt_rfcomm_conn *conn);

/* Connect a local RFCOMM device to a remote one */
/* ioctl() */
uint8 bt_rfcomm_connect(struct bt_rfcomm_conn *conn, struct bt_dev *dev, int serv_chan);

/* Disconnect RFCOMM */
/* ioctl() */
uint8 bt_rfcomm_disconnect(struct bt_rfcomm_conn *conn);

/* Read data from a RFCOMM connection */
/* read() */
uint8 bt_rfcomm_read(struct bt_rfcomm_conn *conn, char *buffer, uint32 len);

/* Write data to a RFCOMM connection */
/* write() */
uint8 bt_rfcomm_write(struct bt_rfcomm_conn *conn, char *buffer, uint32 len);

#endif /* BT_LIB_H */