Diffstat (limited to 'gammu/emb/common/device/bluetoth') (more/less context) (ignore whitespace changes)
-rw-r--r-- | gammu/emb/common/device/bluetoth/affix.c | 44 | ||||
-rw-r--r-- | gammu/emb/common/device/bluetoth/affix.h | 3 | ||||
-rw-r--r-- | gammu/emb/common/device/bluetoth/blue_w32.c | 216 | ||||
-rw-r--r-- | gammu/emb/common/device/bluetoth/blue_w32.h | 188 | ||||
-rw-r--r-- | gammu/emb/common/device/bluetoth/bluetoth.c | 85 | ||||
-rw-r--r-- | gammu/emb/common/device/bluetoth/bluetoth.h | 15 | ||||
-rw-r--r-- | gammu/emb/common/device/bluetoth/bluez.c | 207 | ||||
-rw-r--r-- | gammu/emb/common/device/bluetoth/bluez.h | 3 |
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 @@ +/* (c) 2004 by Marcin Wiacek */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_BLUETOOTHDEVICE +#ifdef GSM_ENABLE_AFFIX + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <unistd.h> + +#include "../../gsmcomon.h" +#include "../devfunc.h" +#include "bluetoth.h" + +GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device) +{ + d->hPhone = fd; + return ERR_NONE; +} + +#ifdef BLUETOOTH_RF_SEARCHING + +static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, struct search_context *context) +{ +} + +GSM_Error bluetooth_findchannel(GSM_StateMachine *s) +{ + return error; +} + +#endif +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ 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 @@ + +GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device); +GSM_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 @@ +/* (c) 2003-2004 by Marcin Wiacek and Intra */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_BLUETOOTHDEVICE +#ifdef WIN32 + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <windows.h> +#include <io.h> + +#include "../../misc/coding/coding.h" +#include "../../gsmcomon.h" +#include "../devfunc.h" +#include "bluetoth.h" +#include "blue_w32.h" + +GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device) +{ + GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth; + WSADATA wsaData; + SOCKADDR_BTH sab; + int i; + + smprintf(s, "Connecting to RF channel %i\n",port); + + WSAStartup(MAKEWORD(1,1), &wsaData); + + d->hPhone = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); + if (d->hPhone == INVALID_SOCKET) { + i = GetLastError(); + GSM_OSErrorInfo(s, "Socket in bluetooth_open"); + if (i == 10041) return ERR_DEVICENODRIVER;//unknown socket type + return ERR_UNKNOWN; + } + + memset (&sab, 0, sizeof(sab)); + sab.port = port; + sab.addressFamily = AF_BTH; + sab.btAddr = 0; + for (i=0;i<(int)strlen(device);i++) { + if (device[i] >='0' && device[i] <='9') { + sab.btAddr = sab.btAddr * 16; + sab.btAddr = sab.btAddr + (device[i]-'0'); + } + if (device[i] >='a' && device[i] <='f') { + sab.btAddr = sab.btAddr * 16; + sab.btAddr = sab.btAddr + (device[i]-'a'+10); + } + if (device[i] >='A' && device[i] <='F') { + sab.btAddr = sab.btAddr * 16; + sab.btAddr = sab.btAddr + (device[i]-'A'+10); + } + } + dbgprintf("Remote Bluetooth device is %04x%08x\n", + GET_NAP(sab.btAddr), GET_SAP(sab.btAddr)); + + if (connect (d->hPhone, (struct sockaddr *)&sab, sizeof(sab)) != 0) { + i = GetLastError(); + GSM_OSErrorInfo(s, "Connect in bluetooth_open"); + if (i == 10060) return ERR_TIMEOUT; //remote device failed to respond + if (i == 10050) return ERR_DEVICENOTWORK; //socket operation connected with dead network + //noauth + close(d->hPhone); + return ERR_UNKNOWN; + } + + return ERR_NONE; +} + +#ifdef BLUETOOTH_RF_SEARCHING + +#pragma comment(lib, "irprops.lib") +#pragma comment(lib, "ws2_32.lib") + +static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, char *address, WSAPROTOCOL_INFO *protocolInfo) +{ + GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth; + WSAQUERYSET querySet; + DWORD flags; + GUID protocol; + int i, result; + BYTE buffer[2000]; + char addressAsString[1000]; + DWORD bufferLength, addressSize; + WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer; + HANDLE handle; + GSM_Error error; + + memset(&querySet, 0, sizeof(querySet)); + querySet.dwSize = sizeof(querySet); + protocol = L2CAP_PROTOCOL_UUID; + querySet.lpServiceClassId = &protocol; + querySet.dwNameSpace = NS_BTH; + querySet.lpszContext = address; + + flags = LUP_FLUSHCACHE | LUP_RETURN_NAME | + LUP_RETURN_TYPE | LUP_RETURN_ADDR | + LUP_RETURN_BLOB | LUP_RETURN_COMMENT; + + result = WSALookupServiceBegin(&querySet, flags, &handle); + if (result != 0) return ERR_UNKNOWN; + + bufferLength = sizeof(buffer); + while (1) { + result = WSALookupServiceNext(handle, flags, &bufferLength, pResults); + if (result != 0) break; + addressSize = sizeof(addressAsString); + addressAsString[0] = 0; + if (WSAAddressToString(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr, + pResults->lpcsaBuffer->RemoteAddr.iSockaddrLength, protocolInfo, + addressAsString,&addressSize)==0) { + smprintf(s, "%s - ", addressAsString); + } + smprintf(s, "\"%s\"\n", pResults->lpszServiceInstanceName); + if (addressAsString[0] != 0) { + for (i=strlen(addressAsString)-1;i>0;i--) { + if (addressAsString[i] == ':') break; + } + if (bluetooth_checkservicename(s, pResults->lpszServiceInstanceName) == ERR_NONE) { + error = bluetooth_connect(s,atoi(addressAsString+i+1),address+1); + result = WSALookupServiceEnd(handle); + return error; + } + } + } + result = WSALookupServiceEnd(handle); + return ERR_NOTSUPPORTED; +} + +GSM_Error bluetooth_findchannel(GSM_StateMachine *s) +{ + GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth; + WSADATA wsaData; + int i, protocolInfoSize, result; + WSAPROTOCOL_INFO protocolInfo; + HANDLE handle; + DWORD flags; + WSAQUERYSET querySet; + BYTE buffer[2000]; + char addressAsString[1000]; + DWORD bufferLength, addressSize; + WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer; + GSM_Error error; + + if (WSAStartup(MAKEWORD(2,2), &wsaData)!=0x00) return ERR_DEVICENODRIVER; + + d->hPhone = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); + if (d->hPhone == INVALID_SOCKET) { + i = GetLastError(); + GSM_OSErrorInfo(s, "Socket in bluetooth_open"); + if (i == 10041) return ERR_DEVICENODRIVER;//unknown socket type + return ERR_UNKNOWN; + } + + protocolInfoSize = sizeof(protocolInfo); + if (getsockopt(d->hPhone, SOL_SOCKET, SO_PROTOCOL_INFO, + (char*)&protocolInfo, &protocolInfoSize) != 0) + { + close(d->hPhone); + return ERR_UNKNOWN; + } + close(d->hPhone); + + if (!strcmp(s->CurrentConfig->Device,"com2:")) { + bufferLength = sizeof(buffer); + + flags = LUP_RETURN_NAME | LUP_CONTAINERS | + LUP_RETURN_ADDR | LUP_FLUSHCACHE | + LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE; + + memset(&querySet, 0, sizeof(querySet)); + querySet.dwSize = sizeof(querySet); + querySet.dwNameSpace = NS_BTH; + + result = WSALookupServiceBegin(&querySet, flags, &handle); + if (result != 0) return ERR_UNKNOWN; + + while (1) { + result = WSALookupServiceNext(handle, flags, &bufferLength, pResults); + if (result != 0) break; + + smprintf(s, "\"%s\"", pResults->lpszServiceInstanceName); + + addressSize = sizeof(addressAsString); + addressAsString[0] = 0; + if (WSAAddressToString(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr, + pResults->lpcsaBuffer->RemoteAddr.iSockaddrLength, &protocolInfo, + addressAsString,&addressSize)==0) { + smprintf(s, " - %s\n", addressAsString); + error = bluetooth_checkdevice(s, addressAsString,&protocolInfo); + if (error == ERR_NONE) { + result = WSALookupServiceEnd(handle); + return error; + } + } else smprintf(s, "\n"); + } + + result = WSALookupServiceEnd(handle); + return ERR_NOTSUPPORTED; + } else { + return bluetooth_checkdevice(s, s->CurrentConfig->Device,&protocolInfo); + } +} + +#endif +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ 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 @@ + +GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device); +GSM_Error bluetooth_findchannel(GSM_StateMachine *s); + +/* MS Platform SDK */ + +#ifndef __blue_w32_h +#define __blue_w32_h + +#include <pshpack1.h> // Without it compiled code hangs up BT stack + +typedef ULONGLONG BTH_ADDR, *PBTH_ADDR; + +#define NAP_MASK ((ULONGLONG) 0xFFFF00000000) +#define SAP_MASK ((ULONGLONG) 0x0000FFFFFFFF) + +#define NAP_BIT_OFFSET (8 * 4) +#define SAP_BIT_OFFSET (0) + +#define GET_NAP(_bth_addr) ((USHORT) (((_bth_addr) & NAP_MASK) >> NAP_BIT_OFFSET)) +#define GET_SAP(_bth_addr) ((ULONG) (((_bth_addr) & SAP_MASK) >> SAP_BIT_OFFSET)) + +#ifndef AF_BTH +#define AF_BTH 32 +#endif + +typedef struct _SOCKADDR_BTH { + USHORT addressFamily; // Always AF_BTH + BTH_ADDR btAddr; // Bluetooth device address + GUID serviceClassId; // [OPTIONAL] system will query SDP for port + ULONG port; // RFCOMM channel or L2CAP PSM +} SOCKADDR_BTH, *PSOCKADDR_BTH; + +#define BTHPROTO_RFCOMM 0x0003 + +#ifdef BLUETOOTH_RF_SEARCHING + +typedef struct _SOCKET_ADDRESS { + LPSOCKADDR lpSockaddr ; + INT iSockaddrLength ; +} SOCKET_ADDRESS, *PSOCKET_ADDRESS, FAR * LPSOCKET_ADDRESS ; + +typedef struct _CSADDR_INFO { + SOCKET_ADDRESS LocalAddr ; + SOCKET_ADDRESS RemoteAddr ; + INT iSocketType ; + INT iProtocol ; +} CSADDR_INFO, *PCSADDR_INFO, FAR * LPCSADDR_INFO ; + +typedef struct _AFPROTOCOLS { + INT iAddressFamily; + INT iProtocol; +} AFPROTOCOLS, *PAFPROTOCOLS, *LPAFPROTOCOLS; + +typedef enum _WSAEcomparator +{ + COMP_EQUAL = 0, + COMP_NOTLESS +} WSAECOMPARATOR, *PWSAECOMPARATOR, *LPWSAECOMPARATOR; + +typedef struct _WSAVersion +{ + DWORD dwVersion; + WSAECOMPARATOR ecHow; +}WSAVERSION, *PWSAVERSION, *LPWSAVERSION; + +typedef struct _WSAQuerySetA +{ + DWORD dwSize; + LPSTR lpszServiceInstanceName; + LPGUID lpServiceClassId; + LPWSAVERSION lpVersion; + LPSTR lpszComment; + DWORD dwNameSpace; + LPGUID lpNSProviderId; + LPSTR lpszContext; + DWORD dwNumberOfProtocols; + LPAFPROTOCOLS lpafpProtocols; + LPSTR lpszQueryString; + DWORD dwNumberOfCsAddrs; + LPCSADDR_INFO lpcsaBuffer; + DWORD dwOutputFlags; + LPBLOB lpBlob; +} WSAQUERYSET, WSAQUERYSETA, *PWSAQUERYSETA, *LPWSAQUERYSETA; + +DEFINE_GUID(L2CAP_PROTOCOL_UUID, 0x00000100, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB); + +#ifndef NS_BTH +# define NS_BTH 16 +#endif + +#define LUP_CONTAINERS 0x0002 +#define LUP_RETURN_NAME 0x0010 +#define LUP_RETURN_TYPE 0x0020 +#define LUP_RETURN_COMMENT 0x0080 +#define LUP_RETURN_ADDR 0x0100 +#define LUP_RETURN_BLOB 0x0200 +#define LUP_FLUSHCACHE 0x1000 +#define LUP_RES_SERVICE 0x8000 + +#define WSAAPI FAR PASCAL + +#ifndef WINSOCK_API_LINKAGE +#ifdef DECLSPEC_IMPORT +#define WINSOCK_API_LINKAGE DECLSPEC_IMPORT +#else +#define WINSOCK_API_LINKAGE +#endif +#endif + +WINSOCK_API_LINKAGE INT WSAAPI +WSALookupServiceBeginA( + IN LPWSAQUERYSETA lpqsRestrictions, + IN DWORD dwControlFlags, + OUT LPHANDLE lphLookup + ); + +#define WSALookupServiceBegin WSALookupServiceBeginA + +WINSOCK_API_LINKAGE INT WSAAPI +WSALookupServiceNextA( + IN HANDLE hLookup, + IN DWORD dwControlFlags, + IN OUT LPDWORD lpdwBufferLength, + OUT LPWSAQUERYSETA lpqsResults + ); + +#define WSALookupServiceNext WSALookupServiceNextA + +WINSOCK_API_LINKAGE INT WSAAPI WSALookupServiceEnd(IN HANDLE hLookup); + +#define MAX_PROTOCOL_CHAIN 7 + +typedef struct _WSAPROTOCOLCHAIN { + int ChainLen; /* the length of the chain, */ + /* length = 0 means layered protocol, */ + /* length = 1 means base protocol, */ + /* length > 1 means protocol chain */ + DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; /* a list of dwCatalogEntryIds */ +} WSAPROTOCOLCHAIN, FAR * LPWSAPROTOCOLCHAIN; + +#define WSAPROTOCOL_LEN 255 + +typedef struct _WSAPROTOCOL_INFOA { + DWORD dwServiceFlags1; + DWORD dwServiceFlags2; + DWORD dwServiceFlags3; + DWORD dwServiceFlags4; + DWORD dwProviderFlags; + GUID ProviderId; + DWORD dwCatalogEntryId; + WSAPROTOCOLCHAIN ProtocolChain; + int iVersion; + int iAddressFamily; + int iMaxSockAddr; + int iMinSockAddr; + int iSocketType; + int iProtocol; + int iProtocolMaxOffset; + int iNetworkByteOrder; + int iSecurityScheme; + DWORD dwMessageSize; + DWORD dwProviderReserved; + CHAR szProtocol[WSAPROTOCOL_LEN+1]; +} WSAPROTOCOL_INFOA, FAR * LPWSAPROTOCOL_INFOA; + +typedef WSAPROTOCOL_INFOA WSAPROTOCOL_INFO; + +#define SO_PROTOCOL_INFOA 0x2004 /* WSAPROTOCOL_INFOA structure */ +#define SO_PROTOCOL_INFO SO_PROTOCOL_INFOA + +WINSOCK_API_LINKAGE INT WSAAPI +WSAAddressToStringA( + IN LPSOCKADDR lpsaAddress, + IN DWORD dwAddressLength, + IN LPWSAPROTOCOL_INFOA lpProtocolInfo, + IN OUT LPSTR lpszAddressString, + IN OUT LPDWORD lpdwAddressStringLength + ); + +#define WSAAddressToString WSAAddressToStringA + +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ 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 @@ +/* (c) 2003-2004 by Marcin Wiacek and Marcel Holtmann and others */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_BLUETOOTHDEVICE +#ifndef DJGPP + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + +#include "../../misc/coding/coding.h" +#include "../../gsmcomon.h" +#include "../devfunc.h" +#include "bluetoth.h" + +#ifdef GSM_ENABLE_BLUEZ +# include "bluez.h" +#endif +#ifdef GSM_ENABLE_AFFIX +# include "affix.h" +#endif +#ifdef WIN32 +# include "blue_w32.h" +#endif + +GSM_Error bluetooth_findrfchannel(GSM_StateMachine *s) +{ + GSM_Error error; + +#ifdef BLUETOOTH_RF_SEARCHING + if (!mystrncasecmp(s->CurrentConfig->Connection, "bluerf", 6)) return bluetooth_findchannel(s); +#endif + + switch (s->ConnectionType) { + case GCT_BLUEAT: + return bluetooth_connect(s,1,s->CurrentConfig->Device); + case GCT_BLUEOBEX: + return bluetooth_connect(s,9,s->CurrentConfig->Device); + case GCT_BLUEPHONET: + error = bluetooth_connect(s,14,s->CurrentConfig->Device); //older Series 40 - 8910, 6310 + if (error == ERR_NONE) return error; + return bluetooth_connect(s,15,s->CurrentConfig->Device); //new Series 40 - 6310i, 6230 + default: + return ERR_UNKNOWN; + } +} + +static int bluetooth_read(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + return socket_read(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone); +} + +#ifdef WIN32 +static int bluetooth_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes) +#else +static int bluetooth_write(GSM_StateMachine *s, void *buf, size_t nbytes) +#endif +{ + return socket_write(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone); +} + +static GSM_Error bluetooth_close(GSM_StateMachine *s) +{ + return socket_close(s, s->Device.Data.BlueTooth.hPhone); +} + +GSM_Device_Functions BlueToothDevice = { + bluetooth_findrfchannel, + bluetooth_close, + NONEFUNCTION, + NONEFUNCTION, + NONEFUNCTION, + bluetooth_read, + bluetooth_write +}; + +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ 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 @@ + +#ifndef DJGPP +#ifndef unixbluetooth_h +#define unixbluetooth_h + +typedef struct { + int hPhone; +} GSM_Device_BlueToothData; + +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ 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 <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <unistd.h> +#include <bluetooth/bluetooth.h> +#include <bluetooth/rfcomm.h> +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> + +#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<count;i++) { + error = bluetooth_checkdevice(s,&ii[i].bdaddr,&context); + if (error == ERR_NONE) return error; + } + return error; +} + +#endif +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ 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 @@ + +GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device); +GSM_Error bluetooth_findchannel(GSM_StateMachine *s); |