Skip to content

Commit 8b7cfe3

Browse files
committed
ble
1 parent 92923f8 commit 8b7cfe3

14 files changed

Lines changed: 3407 additions & 19 deletions

File tree

configure.ac

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,23 @@ AS_IF([test "x$with_bluez" != "xno"], [
129129
])
130130
])
131131

132+
# Checks for Glib support.
133+
AC_ARG_WITH([glib],
134+
[AS_HELP_STRING([--without-glib],
135+
[Build without the Glib library])],
136+
[], [with_glib=auto])
137+
AS_IF([test "x$with_glib" != "xno"], [
138+
PKG_CHECK_MODULES([GLIB], [glib-2.0 gio-2.0], [have_glib=yes], [have_glib=no])
139+
AS_IF([test "x$have_glib" = "xyes"], [
140+
AC_DEFINE([HAVE_GLIB], [1], [GLib library])
141+
DEPENDENCIES="$DEPENDENCIES glib-2.0 gio-2.0"
142+
])
143+
])
144+
132145
AC_SUBST([DEPENDENCIES])
133146

134147
# Checks for Windows bluetooth support.
135-
AC_CHECK_HEADERS([winsock2.h ws2bth.h], , , [
148+
AC_CHECK_HEADERS([winsock2.h ws2bth.h bluetoothleapis.h], , , [
136149
#if HAVE_WINSOCK2_H
137150
# include <winsock2.h>
138151
# endif
@@ -225,11 +238,12 @@ fi
225238
if test "$platform" = "windows"; then
226239
transport_irda="$ac_cv_header_af_irda_h"
227240
transport_bluetooth="$ac_cv_header_ws2bth_h"
241+
transport_ble="$ac_cv_header_bluetoothleapis_h"
228242
else
229243
transport_irda="$ac_cv_header_linux_irda_h"
230244
transport_bluetooth="${have_bluez-no}"
245+
transport_ble="${have_glib-no}"
231246
fi
232-
transport_ble="no"
233247

234248
AC_CONFIG_FILES([
235249
libdivecomputer.pc

contrib/android/Android.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ LOCAL_SRC_FILES := \
7676
src/parser.c \
7777
src/pelagic_i330r.c \
7878
src/platform.c \
79+
src/queue.c \
7980
src/rbstream.c \
8081
src/reefnet_sensus.c \
8182
src/reefnet_sensus_parser.c \

contrib/msvc/libdivecomputer.vcxproj

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@
9090
<ClCompile>
9191
<Optimization>Disabled</Optimization>
9292
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
93-
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
93+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;HAVE_BLUETOOTHLEAPIS_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9494
<PrecompiledHeader />
9595
<WarningLevel>Level3</WarningLevel>
9696
<SDLCheck>true</SDLCheck>
9797
</ClCompile>
9898
<Link>
99-
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
99+
<AdditionalDependencies>ws2_32.lib;setupapi.lib;bluetoothapis.lib;%(AdditionalDependencies)</AdditionalDependencies>
100100
<ModuleDefinitionFile>$(OutDir)libdivecomputer.def</ModuleDefinitionFile>
101101
<GenerateDebugInformation>true</GenerateDebugInformation>
102102
<SubSystem>Windows</SubSystem>
@@ -109,14 +109,14 @@
109109
<ClCompile>
110110
<Optimization>Disabled</Optimization>
111111
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
112-
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
112+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;HAVE_BLUETOOTHLEAPIS_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
113113
<PrecompiledHeader>
114114
</PrecompiledHeader>
115115
<WarningLevel>Level3</WarningLevel>
116116
<SDLCheck>true</SDLCheck>
117117
</ClCompile>
118118
<Link>
119-
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
119+
<AdditionalDependencies>ws2_32.lib;setupapi.lib;bluetoothapis.lib;%(AdditionalDependencies)</AdditionalDependencies>
120120
<ModuleDefinitionFile>$(OutDir)libdivecomputer.def</ModuleDefinitionFile>
121121
<GenerateDebugInformation>true</GenerateDebugInformation>
122122
<SubSystem>Windows</SubSystem>
@@ -130,14 +130,14 @@
130130
<Optimization>MaxSpeed</Optimization>
131131
<IntrinsicFunctions>true</IntrinsicFunctions>
132132
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
133-
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
133+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;HAVE_BLUETOOTHLEAPIS_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
134134
<FunctionLevelLinking>true</FunctionLevelLinking>
135135
<PrecompiledHeader />
136136
<WarningLevel>Level3</WarningLevel>
137137
<SDLCheck>true</SDLCheck>
138138
</ClCompile>
139139
<Link>
140-
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
140+
<AdditionalDependencies>ws2_32.lib;setupapi.lib;bluetoothapis.lib;%(AdditionalDependencies)</AdditionalDependencies>
141141
<ModuleDefinitionFile>$(OutDir)libdivecomputer.def</ModuleDefinitionFile>
142142
<GenerateDebugInformation>true</GenerateDebugInformation>
143143
<SubSystem>Windows</SubSystem>
@@ -153,15 +153,15 @@
153153
<Optimization>MaxSpeed</Optimization>
154154
<IntrinsicFunctions>true</IntrinsicFunctions>
155155
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
156-
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
156+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_VERSION_SUFFIX;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;HAVE_BLUETOOTHLEAPIS_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
157157
<FunctionLevelLinking>true</FunctionLevelLinking>
158158
<PrecompiledHeader>
159159
</PrecompiledHeader>
160160
<WarningLevel>Level3</WarningLevel>
161161
<SDLCheck>true</SDLCheck>
162162
</ClCompile>
163163
<Link>
164-
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
164+
<AdditionalDependencies>ws2_32.lib;setupapi.lib;bluetoothapis.lib;%(AdditionalDependencies)</AdditionalDependencies>
165165
<ModuleDefinitionFile>$(OutDir)libdivecomputer.def</ModuleDefinitionFile>
166166
<GenerateDebugInformation>true</GenerateDebugInformation>
167167
<SubSystem>Windows</SubSystem>
@@ -244,6 +244,7 @@
244244
<ClCompile Include="..\..\src\parser.c" />
245245
<ClCompile Include="..\..\src\pelagic_i330r.c" />
246246
<ClCompile Include="..\..\src\platform.c" />
247+
<ClCompile Include="..\..\src\queue.c" />
247248
<ClCompile Include="..\..\src\rbstream.c" />
248249
<ClCompile Include="..\..\src\reefnet_sensus.c" />
249250
<ClCompile Include="..\..\src\reefnet_sensuspro.c" />
@@ -365,6 +366,7 @@
365366
<ClInclude Include="..\..\src\parser-private.h" />
366367
<ClInclude Include="..\..\src\pelagic_i330r.h" />
367368
<ClInclude Include="..\..\src\platform.h" />
369+
<ClInclude Include="..\..\src\queue.h" />
368370
<ClInclude Include="..\..\src\rbstream.h" />
369371
<ClInclude Include="..\..\src\reefnet_sensus.h" />
370372
<ClInclude Include="..\..\src\reefnet_sensuspro.h" />

examples/common.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <libdivecomputer/serial.h>
3232
#include <libdivecomputer/bluetooth.h>
33+
#include <libdivecomputer/ble.h>
3334
#include <libdivecomputer/irda.h>
3435
#include <libdivecomputer/usb.h>
3536
#include <libdivecomputer/usbhid.h>
@@ -569,6 +570,52 @@ dctool_bluetooth_open (dc_iostream_t **out, dc_context_t *context, dc_descriptor
569570
return status;
570571
}
571572

573+
static dc_status_t
574+
dctool_ble_open (dc_iostream_t **out, dc_context_t *context, dc_descriptor_t *descriptor, const char *devname)
575+
{
576+
dc_status_t status = DC_STATUS_SUCCESS;
577+
dc_iostream_t *iostream = NULL;
578+
dc_ble_address_t address = 0;
579+
580+
if (devname) {
581+
// Use the address.
582+
address = dc_ble_str2addr(devname);
583+
} else {
584+
// Discover the device address.
585+
dc_iterator_t *iterator = NULL;
586+
dc_ble_device_t *device = NULL;
587+
dc_ble_iterator_new (&iterator, context, descriptor);
588+
while (dc_iterator_next (iterator, &device) == DC_STATUS_SUCCESS) {
589+
address = dc_ble_device_get_address (device);
590+
dc_ble_device_free (device);
591+
break;
592+
}
593+
dc_iterator_free (iterator);
594+
}
595+
596+
if (address == 0) {
597+
if (devname) {
598+
ERROR ("No valid device address specified.");
599+
} else {
600+
ERROR ("No dive computer found.");
601+
}
602+
status = DC_STATUS_NODEVICE;
603+
goto cleanup;
604+
}
605+
606+
// Open the BLE device.
607+
status = dc_ble_open (&iostream, context, address);
608+
if (status != DC_STATUS_SUCCESS) {
609+
ERROR ("Failed to open the ble device.");
610+
goto cleanup;
611+
}
612+
613+
*out = iostream;
614+
615+
cleanup:
616+
return status;
617+
}
618+
572619
dc_status_t
573620
dctool_iostream_open (dc_iostream_t **iostream, dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname)
574621
{
@@ -583,6 +630,8 @@ dctool_iostream_open (dc_iostream_t **iostream, dc_context_t *context, dc_descri
583630
return dctool_irda_open (iostream, context, descriptor, devname);
584631
case DC_TRANSPORT_BLUETOOTH:
585632
return dctool_bluetooth_open (iostream, context, descriptor, devname);
633+
case DC_TRANSPORT_BLE:
634+
return dctool_ble_open (iostream, context, descriptor, devname);
586635
default:
587636
return DC_STATUS_UNSUPPORTED;
588637
}

examples/dctool_scan.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <libdivecomputer/serial.h>
3939
#include <libdivecomputer/irda.h>
4040
#include <libdivecomputer/bluetooth.h>
41+
#include <libdivecomputer/ble.h>
4142
#include <libdivecomputer/usb.h>
4243
#include <libdivecomputer/usbhid.h>
4344

@@ -62,6 +63,9 @@ scan (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transpo
6263
case DC_TRANSPORT_BLUETOOTH:
6364
status = dc_bluetooth_iterator_new (&iterator, context, descriptor);
6465
break;
66+
case DC_TRANSPORT_BLE:
67+
status = dc_ble_iterator_new (&iterator, context, descriptor);
68+
break;
6569
case DC_TRANSPORT_USB:
6670
status = dc_usb_iterator_new (&iterator, context, descriptor);
6771
break;
@@ -96,6 +100,12 @@ scan (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transpo
96100
dc_bluetooth_device_get_name (device));
97101
dc_bluetooth_device_free (device);
98102
break;
103+
case DC_TRANSPORT_BLE:
104+
printf ("%s\t%s\n",
105+
dc_ble_addr2str(dc_ble_device_get_address (device), buffer, sizeof(buffer)),
106+
dc_ble_device_get_name (device));
107+
dc_bluetooth_device_free (device);
108+
break;
99109
case DC_TRANSPORT_USB:
100110
printf ("%04x:%04x\n", dc_usb_device_get_vid (device), dc_usb_device_get_pid (device));
101111
dc_usb_device_free (device);

include/libdivecomputer/ble.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
#ifndef DC_BLE_H
2323
#define DC_BLE_H
2424

25+
#include "common.h"
26+
#include "context.h"
27+
#include "iostream.h"
28+
#include "iterator.h"
29+
#include "descriptor.h"
2530
#include "ioctl.h"
2631

2732
#ifdef __cplusplus
@@ -60,17 +65,65 @@ extern "C" {
6065
#define DC_IOCTL_BLE_CHARACTERISTIC_READ DC_IOCTL_IOR('b', 3, DC_IOCTL_SIZE_VARIABLE)
6166
#define DC_IOCTL_BLE_CHARACTERISTIC_WRITE DC_IOCTL_IOW('b', 3, DC_IOCTL_SIZE_VARIABLE)
6267

68+
/**
69+
* The minimum number of bytes (including the terminating null byte) for
70+
* formatting a bluetooth address as a string.
71+
*/
72+
#define DC_BLE_ADDRESS_SIZE 18
73+
6374
/**
6475
* The minimum number of bytes (including the terminating null byte) for
6576
* formatting a bluetooth UUID as a string.
6677
*/
6778
#define DC_BLE_UUID_SIZE 37
6879

80+
/**
81+
* Bluetooth address (48 bits).
82+
*/
83+
#if defined (_WIN32) && !defined (__GNUC__)
84+
typedef unsigned __int64 dc_ble_address_t;
85+
#else
86+
typedef unsigned long long dc_ble_address_t;
87+
#endif
88+
6989
/**
7090
* Bluetooth UUID (128 bits).
7191
*/
7292
typedef unsigned char dc_ble_uuid_t[16];
7393

94+
/**
95+
* Opaque object representing a bluetooth device.
96+
*/
97+
typedef struct dc_ble_device_t dc_ble_device_t;
98+
99+
/**
100+
* Convert a bluetooth address to a string.
101+
*
102+
* The bluetooth address is formatted as XX:XX:XX:XX:XX:XX, where each
103+
* XX is a hexadecimal number specifying an octet of the 48-bit address.
104+
* The minimum size for the buffer is #DC_BLE_ADDRESS_SIZE bytes.
105+
*
106+
* @param[in] address A bluetooth address.
107+
* @param[in] str The memory buffer to store the result.
108+
* @param[in] size The size of the memory buffer.
109+
* @returns The null-terminated string on success, or NULL on failure.
110+
*/
111+
char *
112+
dc_ble_addr2str(dc_ble_address_t address, char *str, size_t size);
113+
114+
/**
115+
* Convert a string to a bluetooth address.
116+
*
117+
* The string is expected to be in the format XX:XX:XX:XX:XX:XX, where
118+
* each XX is a hexadecimal number specifying an octet of the 48-bit
119+
* address.
120+
*
121+
* @param[in] address A null-terminated string.
122+
* @returns The bluetooth address on success, or zero on failure.
123+
*/
124+
dc_ble_address_t
125+
dc_ble_str2addr(const char *address);
126+
74127
/**
75128
* Convert a bluetooth UUID to a string.
76129
*
@@ -101,6 +154,54 @@ dc_ble_uuid2str (const dc_ble_uuid_t uuid, char *str, size_t size);
101154
int
102155
dc_ble_str2uuid (const char *str, dc_ble_uuid_t uuid);
103156

157+
/**
158+
* Get the address of the bluetooth device.
159+
*
160+
* @param[in] device A valid bluetooth device.
161+
*/
162+
dc_ble_address_t
163+
dc_ble_device_get_address (dc_ble_device_t *device);
164+
165+
/**
166+
* Get the name of the bluetooth device.
167+
*
168+
* @param[in] device A valid bluetooth device.
169+
*/
170+
const char *
171+
dc_ble_device_get_name (dc_ble_device_t *device);
172+
173+
/**
174+
* Destroy the bluetooth device and free all resources.
175+
*
176+
* @param[in] device A valid bluetooth device.
177+
*/
178+
void
179+
dc_ble_device_free (dc_ble_device_t *device);
180+
181+
/**
182+
* Create an iterator to enumerate the bluetooth devices.
183+
*
184+
* @param[out] iterator A location to store the iterator.
185+
* @param[in] context A valid context object.
186+
* @param[in] descriptor A valid device descriptor or NULL.
187+
* @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code
188+
* on failure.
189+
*/
190+
dc_status_t
191+
dc_ble_iterator_new (dc_iterator_t **iterator, dc_context_t *context, dc_descriptor_t *descriptor);
192+
193+
/**
194+
* Open an bluetooth connection.
195+
*
196+
* @param[out] iostream A location to store the bluetooth connection.
197+
* @param[in] context A valid context object.
198+
* @param[in] address The bluetooth device address.
199+
* @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code
200+
* on failure.
201+
*/
202+
dc_status_t
203+
dc_ble_open (dc_iostream_t **iostream, dc_context_t *context, dc_ble_address_t address);
204+
104205
#ifdef __cplusplus
105206
}
106207
#endif /* __cplusplus */

src/Makefile.am

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
2-
AM_CFLAGS = $(LIBUSB_CFLAGS) $(HIDAPI_CFLAGS) $(BLUEZ_CFLAGS)
2+
AM_CFLAGS = $(LIBUSB_CFLAGS) $(HIDAPI_CFLAGS) $(BLUEZ_CFLAGS) $(GLIB_CFLAGS)
33

44
lib_LTLIBRARIES = libdivecomputer.la
55

6-
libdivecomputer_la_LIBADD = $(LIBUSB_LIBS) $(HIDAPI_LIBS) $(BLUEZ_LIBS) -lm
6+
libdivecomputer_la_LIBADD = $(LIBUSB_LIBS) $(HIDAPI_LIBS) $(BLUEZ_LIBS) $(GLIB_LIBS) -lm
77
libdivecomputer_la_LDFLAGS = \
88
-version-info $(DC_VERSION_LIBTOOL) \
99
-no-undefined \
1010
-export-symbols libdivecomputer.exp
1111

1212
if OS_WIN32
13-
libdivecomputer_la_LIBADD += -lws2_32
13+
libdivecomputer_la_LIBADD += -lws2_32 -lsetupapi -lbluetoothapis
1414
libdivecomputer_la_LDFLAGS += -Wc,-static-libgcc
1515
endif
1616

@@ -66,6 +66,7 @@ libdivecomputer_la_SOURCES = \
6666
citizen_aqualand.h citizen_aqualand.c citizen_aqualand_parser.c \
6767
divesystem_idive.h divesystem_idive.c divesystem_idive_parser.c \
6868
platform.h platform.c \
69+
queue.h queue.c \
6970
ringbuffer.h ringbuffer.c \
7071
rbstream.h rbstream.c \
7172
checksum.h checksum.c \

0 commit comments

Comments
 (0)