author | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
commit | 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (unidiff) | |
tree | 6331418973714243beb674abc87692277b83869d /gammu/emb/common/device/bluetoth/bluez.c | |
parent | ef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff) | |
download | kdepimpi-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) (show whitespace changes)
-rw-r--r-- | gammu/emb/common/device/bluetoth/bluez.c | 207 |
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 | |||
25 | GSM_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 | |||
67 | struct search_context { | ||
68 | char *svc; | ||
69 | uuid_t group; | ||
70 | int tree; | ||
71 | uint32_t handle; | ||
72 | }; | ||
73 | |||
74 | static 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 | |||
96 | void 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 | |||
104 | static 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 | |||
174 | GSM_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 | */ | ||