summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/device/bluetoth/bluez.c
authorzautrix <zautrix>2004-08-07 17:24:40 (UTC)
committer zautrix <zautrix>2004-08-07 17:24:40 (UTC)
commit88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (unidiff)
tree6331418973714243beb674abc87692277b83869d /gammu/emb/common/device/bluetoth/bluez.c
parentef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff)
downloadkdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.zip
kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.gz
kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.bz2
Initial revision
Diffstat (limited to 'gammu/emb/common/device/bluetoth/bluez.c') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/device/bluetoth/bluez.c207
1 files changed, 207 insertions, 0 deletions
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 @@
1/* Based on work by Marcel Holtmann and other authors of Bluez */
2
3#include "../../gsmstate.h"
4
5#ifdef GSM_ENABLE_BLUETOOTHDEVICE
6#ifdef GSM_ENABLE_BLUEZ
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <fcntl.h>
11#include <errno.h>
12#include <string.h>
13#include <sys/socket.h>
14#include <sys/time.h>
15#include <unistd.h>
16#include <bluetooth/bluetooth.h>
17#include <bluetooth/rfcomm.h>
18#include <bluetooth/sdp.h>
19#include <bluetooth/sdp_lib.h>
20
21#include "../../gsmcomon.h"
22#include "../devfunc.h"
23#include "bluetoth.h"
24
25GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device)
26{
27 GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth;
28 struct sockaddr_rc laddr, raddr;
29 bdaddr_t bdaddr;
30 int fd;
31
32 smprintf(s, "Connecting to RF channel %i\n",port);
33
34 fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
35 if (fd < 0) {
36 dbgprintf("Can't create socket\n");
37 return ERR_DEVICENODRIVER;
38 }
39
40 bacpy(&laddr.rc_bdaddr, BDADDR_ANY);
41 laddr.rc_family = AF_BLUETOOTH;
42 laddr.rc_channel = 0;
43
44 if (bind(fd, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
45 dbgprintf("Can't bind socket\n");
46 close(fd);
47 return ERR_DEVICEOPENERROR;
48 }
49
50 str2ba(device, &bdaddr);
51 bacpy(&raddr.rc_bdaddr, &bdaddr);
52 raddr.rc_family = AF_BLUETOOTH;
53 raddr.rc_channel = port;
54
55 if (connect(fd, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) {
56 dbgprintf("Can't connect\n");
57 close(fd);
58 return ERR_DEVICEOPENERROR;
59 }
60
61 d->hPhone = fd;
62 return ERR_NONE;
63}
64
65#ifdef BLUETOOTH_RF_SEARCHING
66
67struct search_context {
68 char *svc;
69 uuid_t group;
70 int tree;
71 uint32_t handle;
72};
73
74static void print_service_desc(void *value, void *user)
75{
76 sdp_data_t *p = (sdp_data_t *)value;
77 int i = 0, proto = 0, *channel = (int *)user;
78
79 for (; p; p = p->next, i++) {
80 switch (p->dtd) {
81 case SDP_UUID16:
82 case SDP_UUID32:
83 case SDP_UUID128:
84 proto = 1;//sdp_uuid_to_proto(&p->val.uuid);
85 break;
86 case SDP_UINT8:
87 if (proto == RFCOMM_UUID) {
88 (*channel) = p->val.uint8;
89 return;
90 }
91 break;
92 }
93 }
94}
95
96void print_access_protos(value, user)
97{
98 sdp_list_t *protDescSeq = (sdp_list_t *)value;
99 int *channel = (int *)user;
100
101 sdp_list_foreach(protDescSeq,print_service_desc,channel);
102}
103
104static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, struct search_context *context)
105{
106 sdp_session_t *sess;
107 sdp_list_t *attrid, *search, *seq, *next, *proto = 0;
108 uint32_t range = 0x0000ffff;
109 char str[20];
110 sdp_record_t *rec;
111 sdp_data_t *d;
112 bdaddr_t interface;
113 struct search_context subcontext;
114 int channel,channel2;
115
116 bacpy(&interface,BDADDR_ANY);
117
118 ba2str(bdaddr, str);
119 smprintf(s,"%s\n", str);
120
121 sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY);
122 if (!sess) {
123 dbgprintf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno));
124 return ERR_UNKNOWN;
125 }
126
127 attrid = sdp_list_append(0, &range);
128 search = sdp_list_append(0, &context->group);
129 if (sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_RANGE, attrid, &seq)) {
130 dbgprintf("Service Search failed: %s\n", strerror(errno));
131 sdp_close(sess);
132 return ERR_UNKNOWN;
133 }
134 sdp_list_free(attrid, 0);
135 sdp_list_free(search, 0);
136
137 channel2 = -1;
138 for (; seq; seq = next) {
139 rec = (sdp_record_t *) seq->data;
140
141 if (channel2 == -1) {
142 if (!context->tree) {
143 d = sdp_data_get(rec,SDP_ATTR_SVCNAME_PRIMARY);
144
145 if (false) {
146 channel = -1;
147 sdp_list_foreach(proto,print_access_protos,&channel);
148 //sdp_list_free(proto,(sdp_free_func_t)sdp_data_free);
149 }
150 smprintf(s,"Channel %i",channel);
151 if (d) smprintf(s," - \"%s\"",d->val.str);
152 smprintf(s,"\n");
153 if (channel2 == -1 && bluetooth_checkservicename(s, d->val.str) == ERR_NONE) {
154 channel2 = channel;
155 }
156 }
157 if (sdp_get_group_id(rec,&subcontext.group) != -1) {
158 memcpy(&subcontext, context, sizeof(struct search_context));
159 if (subcontext.group.value.uuid16 != context->group.value.uuid16) bluetooth_checkdevice(s,bdaddr,&subcontext);
160 }
161 }
162
163 next = seq->next;
164 free(seq);
165 //sdp_record_free(rec);
166 }
167 sdp_close(sess);
168
169 if (channel2 != -1) return bluetooth_connect(s, channel2, str);
170
171 return ERR_UNKNOWN;
172}
173
174GSM_Error bluetooth_findchannel(GSM_StateMachine *s)
175{
176 inquiry_info ii[20];
177 uint8_t count = 0;
178 int i;
179 struct search_context context;
180 GSM_Error error = ERR_NOTSUPPORTED;
181
182 memset(&context, '\0', sizeof(struct search_context));
183 //sdp_uuid16_create(&(context.group),PUBLIC_BROWSE_GROUP);
184
185 if (!strcmp(s->CurrentConfig->Device,"/dev/ttyS1")) {
186 dbgprintf("Searching for devices\n");
187 if (sdp_general_inquiry(ii, 20, 8, &count) < 0) {
188 return ERR_UNKNOWN;
189 }
190 } else {
191 count = 1;
192 str2ba(s->CurrentConfig->Device,&ii[0].bdaddr);
193 }
194 for (i=0;i<count;i++) {
195 error = bluetooth_checkdevice(s,&ii[i].bdaddr,&context);
196 if (error == ERR_NONE) return error;
197 }
198 return error;
199}
200
201#endif
202#endif
203#endif
204
205/* How should editor hadle tabs in this file? Add editor commands here.
206 * vim: noexpandtab sw=8 ts=8 sts=8:
207 */