summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/device/bluetoth
Unidiff
Diffstat (limited to 'gammu/emb/common/device/bluetoth') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/device/bluetoth/affix.c44
-rw-r--r--gammu/emb/common/device/bluetoth/affix.h3
-rw-r--r--gammu/emb/common/device/bluetoth/blue_w32.c216
-rw-r--r--gammu/emb/common/device/bluetoth/blue_w32.h188
-rw-r--r--gammu/emb/common/device/bluetoth/bluetoth.c85
-rw-r--r--gammu/emb/common/device/bluetoth/bluetoth.h15
-rw-r--r--gammu/emb/common/device/bluetoth/bluez.c207
-rw-r--r--gammu/emb/common/device/bluetoth/bluez.h3
8 files changed, 761 insertions, 0 deletions
diff --git a/gammu/emb/common/device/bluetoth/affix.c b/gammu/emb/common/device/bluetoth/affix.c
new file mode 100644
index 0000000..30a917b
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/affix.c
@@ -0,0 +1,44 @@
1/* (c) 2004 by Marcin Wiacek */
2
3#include "../../gsmstate.h"
4
5#ifdef GSM_ENABLE_BLUETOOTHDEVICE
6#ifdef GSM_ENABLE_AFFIX
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
17#include "../../gsmcomon.h"
18#include "../devfunc.h"
19#include "bluetoth.h"
20
21GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device)
22{
23 d->hPhone = fd;
24 return ERR_NONE;
25}
26
27#ifdef BLUETOOTH_RF_SEARCHING
28
29static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, struct search_context *context)
30{
31}
32
33GSM_Error bluetooth_findchannel(GSM_StateMachine *s)
34{
35 return error;
36}
37
38#endif
39#endif
40#endif
41
42/* How should editor hadle tabs in this file? Add editor commands here.
43 * vim: noexpandtab sw=8 ts=8 sts=8:
44 */
diff --git a/gammu/emb/common/device/bluetoth/affix.h b/gammu/emb/common/device/bluetoth/affix.h
new file mode 100644
index 0000000..896ecbe
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/affix.h
@@ -0,0 +1,3 @@
1
2GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device);
3GSM_Error bluetooth_findchannel(GSM_StateMachine *s);
diff --git a/gammu/emb/common/device/bluetoth/blue_w32.c b/gammu/emb/common/device/bluetoth/blue_w32.c
new file mode 100644
index 0000000..a631c9f
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/blue_w32.c
@@ -0,0 +1,216 @@
1/* (c) 2003-2004 by Marcin Wiacek and Intra */
2
3#include "../../gsmstate.h"
4
5#ifdef GSM_ENABLE_BLUETOOTHDEVICE
6#ifdef WIN32
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <fcntl.h>
11#include <errno.h>
12#include <string.h>
13#include <windows.h>
14#include <io.h>
15
16#include "../../misc/coding/coding.h"
17#include "../../gsmcomon.h"
18#include "../devfunc.h"
19#include "bluetoth.h"
20#include "blue_w32.h"
21
22GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device)
23{
24 GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth;
25 WSADATA wsaData;
26 SOCKADDR_BTH sab;
27 int i;
28
29 smprintf(s, "Connecting to RF channel %i\n",port);
30
31 WSAStartup(MAKEWORD(1,1), &wsaData);
32
33 d->hPhone = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
34 if (d->hPhone == INVALID_SOCKET) {
35 i = GetLastError();
36 GSM_OSErrorInfo(s, "Socket in bluetooth_open");
37 if (i == 10041) return ERR_DEVICENODRIVER;//unknown socket type
38 return ERR_UNKNOWN;
39 }
40
41 memset (&sab, 0, sizeof(sab));
42 sab.port = port;
43 sab.addressFamily = AF_BTH;
44 sab.btAddr = 0;
45 for (i=0;i<(int)strlen(device);i++) {
46 if (device[i] >='0' && device[i] <='9') {
47 sab.btAddr = sab.btAddr * 16;
48 sab.btAddr = sab.btAddr + (device[i]-'0');
49 }
50 if (device[i] >='a' && device[i] <='f') {
51 sab.btAddr = sab.btAddr * 16;
52 sab.btAddr = sab.btAddr + (device[i]-'a'+10);
53 }
54 if (device[i] >='A' && device[i] <='F') {
55 sab.btAddr = sab.btAddr * 16;
56 sab.btAddr = sab.btAddr + (device[i]-'A'+10);
57 }
58 }
59 dbgprintf("Remote Bluetooth device is %04x%08x\n",
60 GET_NAP(sab.btAddr), GET_SAP(sab.btAddr));
61
62 if (connect (d->hPhone, (struct sockaddr *)&sab, sizeof(sab)) != 0) {
63 i = GetLastError();
64 GSM_OSErrorInfo(s, "Connect in bluetooth_open");
65 if (i == 10060) return ERR_TIMEOUT; //remote device failed to respond
66 if (i == 10050) return ERR_DEVICENOTWORK; //socket operation connected with dead network
67 //noauth
68 close(d->hPhone);
69 return ERR_UNKNOWN;
70 }
71
72 return ERR_NONE;
73}
74
75#ifdef BLUETOOTH_RF_SEARCHING
76
77#pragma comment(lib, "irprops.lib")
78#pragma comment(lib, "ws2_32.lib")
79
80static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, char *address, WSAPROTOCOL_INFO *protocolInfo)
81{
82 GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth;
83 WSAQUERYSET querySet;
84 DWORD flags;
85 GUID protocol;
86 int i, result;
87 BYTE buffer[2000];
88 char addressAsString[1000];
89 DWORD bufferLength, addressSize;
90 WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
91 HANDLE handle;
92 GSM_Error error;
93
94 memset(&querySet, 0, sizeof(querySet));
95 querySet.dwSize = sizeof(querySet);
96 protocol = L2CAP_PROTOCOL_UUID;
97 querySet.lpServiceClassId = &protocol;
98 querySet.dwNameSpace = NS_BTH;
99 querySet.lpszContext = address;
100
101 flags = LUP_FLUSHCACHE | LUP_RETURN_NAME |
102 LUP_RETURN_TYPE | LUP_RETURN_ADDR |
103 LUP_RETURN_BLOB | LUP_RETURN_COMMENT;
104
105 result = WSALookupServiceBegin(&querySet, flags, &handle);
106 if (result != 0) return ERR_UNKNOWN;
107
108 bufferLength = sizeof(buffer);
109 while (1) {
110 result = WSALookupServiceNext(handle, flags, &bufferLength, pResults);
111 if (result != 0) break;
112 addressSize = sizeof(addressAsString);
113 addressAsString[0] = 0;
114 if (WSAAddressToString(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr,
115 pResults->lpcsaBuffer->RemoteAddr.iSockaddrLength, protocolInfo,
116 addressAsString,&addressSize)==0) {
117 smprintf(s, "%s - ", addressAsString);
118 }
119 smprintf(s, "\"%s\"\n", pResults->lpszServiceInstanceName);
120 if (addressAsString[0] != 0) {
121 for (i=strlen(addressAsString)-1;i>0;i--) {
122 if (addressAsString[i] == ':') break;
123 }
124 if (bluetooth_checkservicename(s, pResults->lpszServiceInstanceName) == ERR_NONE) {
125 error = bluetooth_connect(s,atoi(addressAsString+i+1),address+1);
126 result = WSALookupServiceEnd(handle);
127 return error;
128 }
129 }
130 }
131 result = WSALookupServiceEnd(handle);
132 return ERR_NOTSUPPORTED;
133}
134
135GSM_Error bluetooth_findchannel(GSM_StateMachine *s)
136{
137 GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth;
138 WSADATA wsaData;
139 int i, protocolInfoSize, result;
140 WSAPROTOCOL_INFO protocolInfo;
141 HANDLE handle;
142 DWORD flags;
143 WSAQUERYSET querySet;
144 BYTE buffer[2000];
145 char addressAsString[1000];
146 DWORD bufferLength, addressSize;
147 WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
148 GSM_Error error;
149
150 if (WSAStartup(MAKEWORD(2,2), &wsaData)!=0x00) return ERR_DEVICENODRIVER;
151
152 d->hPhone = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
153 if (d->hPhone == INVALID_SOCKET) {
154 i = GetLastError();
155 GSM_OSErrorInfo(s, "Socket in bluetooth_open");
156 if (i == 10041) return ERR_DEVICENODRIVER;//unknown socket type
157 return ERR_UNKNOWN;
158 }
159
160 protocolInfoSize = sizeof(protocolInfo);
161 if (getsockopt(d->hPhone, SOL_SOCKET, SO_PROTOCOL_INFO,
162 (char*)&protocolInfo, &protocolInfoSize) != 0)
163 {
164 close(d->hPhone);
165 return ERR_UNKNOWN;
166 }
167 close(d->hPhone);
168
169 if (!strcmp(s->CurrentConfig->Device,"com2:")) {
170 bufferLength = sizeof(buffer);
171
172 flags = LUP_RETURN_NAME | LUP_CONTAINERS |
173 LUP_RETURN_ADDR | LUP_FLUSHCACHE |
174 LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE;
175
176 memset(&querySet, 0, sizeof(querySet));
177 querySet.dwSize = sizeof(querySet);
178 querySet.dwNameSpace = NS_BTH;
179
180 result = WSALookupServiceBegin(&querySet, flags, &handle);
181 if (result != 0) return ERR_UNKNOWN;
182
183 while (1) {
184 result = WSALookupServiceNext(handle, flags, &bufferLength, pResults);
185 if (result != 0) break;
186
187 smprintf(s, "\"%s\"", pResults->lpszServiceInstanceName);
188
189 addressSize = sizeof(addressAsString);
190 addressAsString[0] = 0;
191 if (WSAAddressToString(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr,
192 pResults->lpcsaBuffer->RemoteAddr.iSockaddrLength, &protocolInfo,
193 addressAsString,&addressSize)==0) {
194 smprintf(s, " - %s\n", addressAsString);
195 error = bluetooth_checkdevice(s, addressAsString,&protocolInfo);
196 if (error == ERR_NONE) {
197 result = WSALookupServiceEnd(handle);
198 return error;
199 }
200 } else smprintf(s, "\n");
201 }
202
203 result = WSALookupServiceEnd(handle);
204 return ERR_NOTSUPPORTED;
205 } else {
206 return bluetooth_checkdevice(s, s->CurrentConfig->Device,&protocolInfo);
207 }
208}
209
210#endif
211#endif
212#endif
213
214/* How should editor hadle tabs in this file? Add editor commands here.
215 * vim: noexpandtab sw=8 ts=8 sts=8:
216 */
diff --git a/gammu/emb/common/device/bluetoth/blue_w32.h b/gammu/emb/common/device/bluetoth/blue_w32.h
new file mode 100644
index 0000000..e457c92
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/blue_w32.h
@@ -0,0 +1,188 @@
1
2GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device);
3GSM_Error bluetooth_findchannel(GSM_StateMachine *s);
4
5/* MS Platform SDK */
6
7#ifndef __blue_w32_h
8#define __blue_w32_h
9
10 #include <pshpack1.h> // Without it compiled code hangs up BT stack
11
12 typedef ULONGLONG BTH_ADDR, *PBTH_ADDR;
13
14#define NAP_MASK ((ULONGLONG) 0xFFFF00000000)
15#define SAP_MASK ((ULONGLONG) 0x0000FFFFFFFF)
16
17#define NAP_BIT_OFFSET (8 * 4)
18#define SAP_BIT_OFFSET (0)
19
20 #define GET_NAP(_bth_addr) ((USHORT) (((_bth_addr) & NAP_MASK) >> NAP_BIT_OFFSET))
21 #define GET_SAP(_bth_addr) ((ULONG) (((_bth_addr) & SAP_MASK) >> SAP_BIT_OFFSET))
22
23#ifndef AF_BTH
24 #define AF_BTH 32
25#endif
26
27typedef struct _SOCKADDR_BTH {
28 USHORT addressFamily; // Always AF_BTH
29 BTH_ADDR btAddr; // Bluetooth device address
30 GUID serviceClassId; // [OPTIONAL] system will query SDP for port
31 ULONG port; // RFCOMM channel or L2CAP PSM
32} SOCKADDR_BTH, *PSOCKADDR_BTH;
33
34 #define BTHPROTO_RFCOMM 0x0003
35
36#ifdef BLUETOOTH_RF_SEARCHING
37
38typedef struct _SOCKET_ADDRESS {
39 LPSOCKADDR lpSockaddr ;
40 INT iSockaddrLength ;
41} SOCKET_ADDRESS, *PSOCKET_ADDRESS, FAR * LPSOCKET_ADDRESS ;
42
43typedef struct _CSADDR_INFO {
44 SOCKET_ADDRESS LocalAddr ;
45 SOCKET_ADDRESS RemoteAddr ;
46 INT iSocketType ;
47 INT iProtocol ;
48} CSADDR_INFO, *PCSADDR_INFO, FAR * LPCSADDR_INFO ;
49
50typedef struct _AFPROTOCOLS {
51 INT iAddressFamily;
52 INT iProtocol;
53} AFPROTOCOLS, *PAFPROTOCOLS, *LPAFPROTOCOLS;
54
55typedef enum _WSAEcomparator
56{
57 COMP_EQUAL = 0,
58 COMP_NOTLESS
59} WSAECOMPARATOR, *PWSAECOMPARATOR, *LPWSAECOMPARATOR;
60
61typedef struct _WSAVersion
62{
63 DWORD dwVersion;
64 WSAECOMPARATOR ecHow;
65}WSAVERSION, *PWSAVERSION, *LPWSAVERSION;
66
67typedef struct _WSAQuerySetA
68{
69 DWORD dwSize;
70 LPSTR lpszServiceInstanceName;
71 LPGUID lpServiceClassId;
72 LPWSAVERSION lpVersion;
73 LPSTR lpszComment;
74 DWORD dwNameSpace;
75 LPGUID lpNSProviderId;
76 LPSTR lpszContext;
77 DWORD dwNumberOfProtocols;
78 LPAFPROTOCOLS lpafpProtocols;
79 LPSTR lpszQueryString;
80 DWORD dwNumberOfCsAddrs;
81 LPCSADDR_INFO lpcsaBuffer;
82 DWORD dwOutputFlags;
83 LPBLOB lpBlob;
84} WSAQUERYSET, WSAQUERYSETA, *PWSAQUERYSETA, *LPWSAQUERYSETA;
85
86DEFINE_GUID(L2CAP_PROTOCOL_UUID, 0x00000100, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB);
87
88#ifndef NS_BTH
89# define NS_BTH 16
90#endif
91
92#define LUP_CONTAINERS 0x0002
93#define LUP_RETURN_NAME 0x0010
94#define LUP_RETURN_TYPE 0x0020
95#define LUP_RETURN_COMMENT 0x0080
96#define LUP_RETURN_ADDR 0x0100
97#define LUP_RETURN_BLOB 0x0200
98 #define LUP_FLUSHCACHE 0x1000
99#define LUP_RES_SERVICE 0x8000
100
101#define WSAAPI FAR PASCAL
102
103#ifndef WINSOCK_API_LINKAGE
104#ifdef DECLSPEC_IMPORT
105#define WINSOCK_API_LINKAGE DECLSPEC_IMPORT
106#else
107#define WINSOCK_API_LINKAGE
108#endif
109#endif
110
111WINSOCK_API_LINKAGE INT WSAAPI
112WSALookupServiceBeginA(
113 IN LPWSAQUERYSETA lpqsRestrictions,
114 IN DWORD dwControlFlags,
115 OUT LPHANDLE lphLookup
116 );
117
118#define WSALookupServiceBegin WSALookupServiceBeginA
119
120WINSOCK_API_LINKAGE INT WSAAPI
121WSALookupServiceNextA(
122 IN HANDLE hLookup,
123 IN DWORD dwControlFlags,
124 IN OUT LPDWORD lpdwBufferLength,
125 OUT LPWSAQUERYSETA lpqsResults
126 );
127
128#define WSALookupServiceNext WSALookupServiceNextA
129
130WINSOCK_API_LINKAGE INT WSAAPI WSALookupServiceEnd(IN HANDLE hLookup);
131
132#define MAX_PROTOCOL_CHAIN 7
133
134typedef struct _WSAPROTOCOLCHAIN {
135 int ChainLen; /* the length of the chain, */
136 /* length = 0 means layered protocol, */
137 /* length = 1 means base protocol, */
138 /* length > 1 means protocol chain */
139 DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; /* a list of dwCatalogEntryIds */
140} WSAPROTOCOLCHAIN, FAR * LPWSAPROTOCOLCHAIN;
141
142#define WSAPROTOCOL_LEN 255
143
144typedef struct _WSAPROTOCOL_INFOA {
145 DWORD dwServiceFlags1;
146 DWORD dwServiceFlags2;
147 DWORD dwServiceFlags3;
148 DWORD dwServiceFlags4;
149 DWORD dwProviderFlags;
150 GUID ProviderId;
151 DWORD dwCatalogEntryId;
152 WSAPROTOCOLCHAIN ProtocolChain;
153 int iVersion;
154 int iAddressFamily;
155 int iMaxSockAddr;
156 int iMinSockAddr;
157 int iSocketType;
158 int iProtocol;
159 int iProtocolMaxOffset;
160 int iNetworkByteOrder;
161 int iSecurityScheme;
162 DWORD dwMessageSize;
163 DWORD dwProviderReserved;
164 CHAR szProtocol[WSAPROTOCOL_LEN+1];
165} WSAPROTOCOL_INFOA, FAR * LPWSAPROTOCOL_INFOA;
166
167typedef WSAPROTOCOL_INFOA WSAPROTOCOL_INFO;
168
169#define SO_PROTOCOL_INFOA 0x2004 /* WSAPROTOCOL_INFOA structure */
170#define SO_PROTOCOL_INFO SO_PROTOCOL_INFOA
171
172WINSOCK_API_LINKAGE INT WSAAPI
173WSAAddressToStringA(
174 IN LPSOCKADDR lpsaAddress,
175 IN DWORD dwAddressLength,
176 IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
177 IN OUT LPSTR lpszAddressString,
178 IN OUT LPDWORD lpdwAddressStringLength
179 );
180
181#define WSAAddressToString WSAAddressToStringA
182
183#endif
184#endif
185
186/* How should editor hadle tabs in this file? Add editor commands here.
187 * vim: noexpandtab sw=8 ts=8 sts=8:
188 */
diff --git a/gammu/emb/common/device/bluetoth/bluetoth.c b/gammu/emb/common/device/bluetoth/bluetoth.c
new file mode 100644
index 0000000..c20e04b
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/bluetoth.c
@@ -0,0 +1,85 @@
1/* (c) 2003-2004 by Marcin Wiacek and Marcel Holtmann and others */
2
3#include "../../gsmstate.h"
4
5#ifdef GSM_ENABLE_BLUETOOTHDEVICE
6#ifndef DJGPP
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <fcntl.h>
11#include <errno.h>
12#include <string.h>
13
14#include "../../misc/coding/coding.h"
15#include "../../gsmcomon.h"
16#include "../devfunc.h"
17#include "bluetoth.h"
18
19#ifdef GSM_ENABLE_BLUEZ
20# include "bluez.h"
21#endif
22#ifdef GSM_ENABLE_AFFIX
23# include "affix.h"
24#endif
25#ifdef WIN32
26# include "blue_w32.h"
27#endif
28
29GSM_Error bluetooth_findrfchannel(GSM_StateMachine *s)
30{
31 GSM_Error error;
32
33#ifdef BLUETOOTH_RF_SEARCHING
34 if (!mystrncasecmp(s->CurrentConfig->Connection, "bluerf", 6)) return bluetooth_findchannel(s);
35#endif
36
37 switch (s->ConnectionType) {
38 case GCT_BLUEAT:
39 return bluetooth_connect(s,1,s->CurrentConfig->Device);
40 case GCT_BLUEOBEX:
41 return bluetooth_connect(s,9,s->CurrentConfig->Device);
42 case GCT_BLUEPHONET:
43 error = bluetooth_connect(s,14,s->CurrentConfig->Device); //older Series 40 - 8910, 6310
44 if (error == ERR_NONE) return error;
45 return bluetooth_connect(s,15,s->CurrentConfig->Device); //new Series 40 - 6310i, 6230
46 default:
47 return ERR_UNKNOWN;
48 }
49}
50
51static int bluetooth_read(GSM_StateMachine *s, void *buf, size_t nbytes)
52{
53 return socket_read(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone);
54}
55
56#ifdef WIN32
57static int bluetooth_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes)
58#else
59static int bluetooth_write(GSM_StateMachine *s, void *buf, size_t nbytes)
60#endif
61{
62 return socket_write(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone);
63}
64
65static GSM_Error bluetooth_close(GSM_StateMachine *s)
66{
67 return socket_close(s, s->Device.Data.BlueTooth.hPhone);
68}
69
70GSM_Device_Functions BlueToothDevice = {
71 bluetooth_findrfchannel,
72 bluetooth_close,
73 NONEFUNCTION,
74 NONEFUNCTION,
75 NONEFUNCTION,
76 bluetooth_read,
77 bluetooth_write
78};
79
80#endif
81#endif
82
83/* How should editor hadle tabs in this file? Add editor commands here.
84 * vim: noexpandtab sw=8 ts=8 sts=8:
85 */
diff --git a/gammu/emb/common/device/bluetoth/bluetoth.h b/gammu/emb/common/device/bluetoth/bluetoth.h
new file mode 100644
index 0000000..8a7fdf4
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/bluetoth.h
@@ -0,0 +1,15 @@
1
2#ifndef DJGPP
3#ifndef unixbluetooth_h
4#define unixbluetooth_h
5
6typedef struct {
7 int hPhone;
8} GSM_Device_BlueToothData;
9
10#endif
11#endif
12
13/* How should editor hadle tabs in this file? Add editor commands here.
14 * vim: noexpandtab sw=8 ts=8 sts=8:
15 */
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 */
diff --git a/gammu/emb/common/device/bluetoth/bluez.h b/gammu/emb/common/device/bluetoth/bluez.h
new file mode 100644
index 0000000..896ecbe
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/bluez.h
@@ -0,0 +1,3 @@
1
2GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device);
3GSM_Error bluetooth_findchannel(GSM_StateMachine *s);