From 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 Mon Sep 17 00:00:00 2001 From: zautrix Date: Sat, 07 Aug 2004 17:24:40 +0000 Subject: Initial revision --- (limited to 'gammu/emb/common/device/bluetoth/bluez.c') diff --git a/gammu/emb/common/device/bluetoth/bluez.c b/gammu/emb/common/device/bluetoth/bluez.c new file mode 100644 index 0000000..8a4807e --- a/dev/null +++ b/gammu/emb/common/device/bluetoth/bluez.c @@ -0,0 +1,207 @@ +/* Based on work by Marcel Holtmann and other authors of Bluez */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_BLUETOOTHDEVICE +#ifdef GSM_ENABLE_BLUEZ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../gsmcomon.h" +#include "../devfunc.h" +#include "bluetoth.h" + +GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device) +{ + GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth; + struct sockaddr_rc laddr, raddr; + bdaddr_t bdaddr; + int fd; + + smprintf(s, "Connecting to RF channel %i\n",port); + + fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (fd < 0) { + dbgprintf("Can't create socket\n"); + return ERR_DEVICENODRIVER; + } + + bacpy(&laddr.rc_bdaddr, BDADDR_ANY); + laddr.rc_family = AF_BLUETOOTH; + laddr.rc_channel = 0; + + if (bind(fd, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { + dbgprintf("Can't bind socket\n"); + close(fd); + return ERR_DEVICEOPENERROR; + } + + str2ba(device, &bdaddr); + bacpy(&raddr.rc_bdaddr, &bdaddr); + raddr.rc_family = AF_BLUETOOTH; + raddr.rc_channel = port; + + if (connect(fd, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) { + dbgprintf("Can't connect\n"); + close(fd); + return ERR_DEVICEOPENERROR; + } + + d->hPhone = fd; + return ERR_NONE; +} + +#ifdef BLUETOOTH_RF_SEARCHING + +struct search_context { + char *svc; + uuid_t group; + int tree; + uint32_t handle; +}; + +static void print_service_desc(void *value, void *user) +{ + sdp_data_t *p = (sdp_data_t *)value; + int i = 0, proto = 0, *channel = (int *)user; + + for (; p; p = p->next, i++) { + switch (p->dtd) { + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + proto = 1;//sdp_uuid_to_proto(&p->val.uuid); + break; + case SDP_UINT8: + if (proto == RFCOMM_UUID) { + (*channel) = p->val.uint8; + return; + } + break; + } + } +} + +void print_access_protos(value, user) +{ + sdp_list_t *protDescSeq = (sdp_list_t *)value; + int *channel = (int *)user; + + sdp_list_foreach(protDescSeq,print_service_desc,channel); +} + +static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, struct search_context *context) +{ + sdp_session_t *sess; + sdp_list_t *attrid, *search, *seq, *next, *proto = 0; + uint32_t range = 0x0000ffff; + char str[20]; + sdp_record_t *rec; + sdp_data_t *d; + bdaddr_t interface; + struct search_context subcontext; + int channel,channel2; + + bacpy(&interface,BDADDR_ANY); + + ba2str(bdaddr, str); + smprintf(s,"%s\n", str); + + sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY); + if (!sess) { + dbgprintf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); + return ERR_UNKNOWN; + } + + attrid = sdp_list_append(0, &range); + search = sdp_list_append(0, &context->group); + if (sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_RANGE, attrid, &seq)) { + dbgprintf("Service Search failed: %s\n", strerror(errno)); + sdp_close(sess); + return ERR_UNKNOWN; + } + sdp_list_free(attrid, 0); + sdp_list_free(search, 0); + + channel2 = -1; + for (; seq; seq = next) { + rec = (sdp_record_t *) seq->data; + + if (channel2 == -1) { + if (!context->tree) { + d = sdp_data_get(rec,SDP_ATTR_SVCNAME_PRIMARY); + + if (false) { + channel = -1; + sdp_list_foreach(proto,print_access_protos,&channel); + //sdp_list_free(proto,(sdp_free_func_t)sdp_data_free); + } + smprintf(s,"Channel %i",channel); + if (d) smprintf(s," - \"%s\"",d->val.str); + smprintf(s,"\n"); + if (channel2 == -1 && bluetooth_checkservicename(s, d->val.str) == ERR_NONE) { + channel2 = channel; + } + } + if (sdp_get_group_id(rec,&subcontext.group) != -1) { + memcpy(&subcontext, context, sizeof(struct search_context)); + if (subcontext.group.value.uuid16 != context->group.value.uuid16) bluetooth_checkdevice(s,bdaddr,&subcontext); + } + } + + next = seq->next; + free(seq); + //sdp_record_free(rec); + } + sdp_close(sess); + + if (channel2 != -1) return bluetooth_connect(s, channel2, str); + + return ERR_UNKNOWN; +} + +GSM_Error bluetooth_findchannel(GSM_StateMachine *s) +{ + inquiry_info ii[20]; + uint8_t count = 0; + int i; + struct search_context context; + GSM_Error error = ERR_NOTSUPPORTED; + + memset(&context, '\0', sizeof(struct search_context)); + //sdp_uuid16_create(&(context.group),PUBLIC_BROWSE_GROUP); + + if (!strcmp(s->CurrentConfig->Device,"/dev/ttyS1")) { + dbgprintf("Searching for devices\n"); + if (sdp_general_inquiry(ii, 20, 8, &count) < 0) { + return ERR_UNKNOWN; + } + } else { + count = 1; + str2ba(s->CurrentConfig->Device,&ii[0].bdaddr); + } + for (i=0;i