bluetooth 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ #import "ruby_bluetooth.h"
2
+
3
+ @implementation HCIDelegate
4
+
5
+ - (VALUE) device {
6
+ return device;
7
+ }
8
+
9
+ - (void) setDevice: (VALUE)input {
10
+ device = input;
11
+ }
12
+
13
+
14
+ - (void) controllerClassOfDeviceReverted: (id)sender {
15
+ printf("class of device reverted!\n");
16
+ }
17
+
18
+ - (void) readLinkQualityForDeviceComplete: (id)controller
19
+ device: (IOBluetoothDevice*)bt_device
20
+ info: (BluetoothHCILinkQualityInfo*)info
21
+ error: (IOReturn)error {
22
+ CFRunLoopStop(CFRunLoopGetCurrent());
23
+
24
+ rb_iv_set(device, "@link_quality_error", INT2NUM(error));
25
+ rb_iv_set(device, "@link_quality", UINT2NUM(info->qualityValue));
26
+ }
27
+
28
+ - (void) readRSSIForDeviceComplete: (id)controller
29
+ device: (IOBluetoothDevice*)bt_device
30
+ info: (BluetoothHCIRSSIInfo*)info
31
+ error: (IOReturn)error {
32
+ CFRunLoopStop(CFRunLoopGetCurrent());
33
+
34
+ rb_iv_set(device, "@rssi_error", INT2NUM(error));
35
+ rb_iv_set(device, "@rssi", INT2NUM(info->RSSIValue));
36
+ }
37
+
38
+ @end
39
+
@@ -0,0 +1,69 @@
1
+ #import <Cocoa/Cocoa.h>
2
+
3
+ #import <IOBluetooth/IOBluetoothUserLib.h>
4
+ #import <IOBluetooth/objc/IOBluetoothDevice.h>
5
+ #import <IOBluetooth/objc/IOBluetoothDeviceInquiry.h>
6
+ #import <IOBluetooth/objc/IOBluetoothHostController.h>
7
+
8
+ #import <ruby.h>
9
+
10
+ void init_rbt_error();
11
+
12
+ void rbt_check_status(IOReturn status, NSAutoreleasePool *pool);
13
+
14
+ VALUE rbt_scan(VALUE);
15
+
16
+ VALUE rbt_device_link_quality(VALUE);
17
+ VALUE rbt_device_open_connection(VALUE);
18
+ VALUE rbt_device_pair(VALUE);
19
+ VALUE rbt_device_request_name(VALUE);
20
+ VALUE rbt_device_rssi(VALUE);
21
+
22
+ @interface BluetoothDeviceScanner : NSObject {
23
+ IOBluetoothDeviceInquiry * _inquiry;
24
+ BOOL _busy;
25
+ VALUE _devices;
26
+ }
27
+
28
+ - (void) stopSearch;
29
+ - (IOReturn) startSearch;
30
+ - (VALUE) devices;
31
+ @end
32
+
33
+ @interface PairingDelegate : NSObject {
34
+ VALUE device;
35
+ }
36
+
37
+ - (VALUE) device;
38
+ - (void) setDevice: (VALUE)input;
39
+
40
+ - (void) devicePairingConnecting: (id)sender;
41
+ - (void) devicePairingStarted: (id)sender;
42
+ - (void) devicePairingFinished: (id)sender
43
+ error: (IOReturn)error;
44
+
45
+ - (void) devicePairingPasskeyNotification: (id)sender
46
+ passkey: (BluetoothPasskey)passkey;
47
+ - (void) devicePairingPINCodeRequest: (id)sender;
48
+ - (void) devicePairingUserConfirmationRequest: (id)sender
49
+ numericValue: (BluetoothNumericValue)numericValue;
50
+ @end
51
+
52
+ @interface HCIDelegate : NSObject {
53
+ VALUE device;
54
+ }
55
+
56
+ - (VALUE) device;
57
+ - (void) setDevice: (VALUE)input;
58
+
59
+ - (void) controllerClassOfDeviceReverted: (id)sender;
60
+ - (void) readLinkQualityForDeviceComplete: (id)controller
61
+ device: (IOBluetoothDevice*)bt_device
62
+ info: (BluetoothHCILinkQualityInfo*)info
63
+ error: (IOReturn)error;
64
+ - (void) readRSSIForDeviceComplete: (id)controller
65
+ device: (IOBluetoothDevice*)bt_device
66
+ info: (BluetoothHCIRSSIInfo*)info
67
+ error: (IOReturn)error;
68
+ @end
69
+
@@ -0,0 +1,29 @@
1
+ #import "ruby_bluetooth.h"
2
+
3
+ VALUE rbt_mBluetooth = Qnil;
4
+
5
+ VALUE rbt_cBluetoothDevice = Qnil;
6
+ VALUE rbt_cBluetoothERRORS = Qnil;
7
+ VALUE rbt_cBluetoothError = Qnil;
8
+
9
+ void Init_bluetooth() {
10
+ rbt_mBluetooth = rb_define_module("Bluetooth");
11
+
12
+ rbt_cBluetoothError = rb_const_get(rbt_mBluetooth, rb_intern("Error"));
13
+
14
+ rb_define_singleton_method(rbt_mBluetooth, "scan", rbt_scan, 0);
15
+
16
+ rbt_cBluetoothDevice = rb_const_get(rbt_mBluetooth, rb_intern("Device"));
17
+
18
+ rb_define_method(rbt_cBluetoothDevice, "connect",
19
+ rbt_device_open_connection, 0);
20
+ rb_define_method(rbt_cBluetoothDevice, "_link_quality",
21
+ rbt_device_link_quality, 0);
22
+ rb_define_method(rbt_cBluetoothDevice, "pair", rbt_device_pair, 0);
23
+ rb_define_method(rbt_cBluetoothDevice, "request_name",
24
+ rbt_device_request_name, 0);
25
+ rb_define_method(rbt_cBluetoothDevice, "_rssi", rbt_device_rssi, 0);
26
+
27
+ init_rbt_error();
28
+ }
29
+
@@ -0,0 +1,87 @@
1
+ #import "ruby_bluetooth.h"
2
+
3
+ extern VALUE rbt_cBluetoothDevice;
4
+
5
+ VALUE rbt_scan(VALUE self) {
6
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
7
+ BluetoothDeviceScanner *bds = [BluetoothDeviceScanner new];
8
+
9
+ [bds startSearch];
10
+
11
+ CFRunLoopRun();
12
+
13
+ [pool release];
14
+
15
+ return [bds devices];
16
+ }
17
+
18
+ @implementation BluetoothDeviceScanner
19
+
20
+ - (void) deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender
21
+ error:(IOReturn)error aborted:(BOOL)aborted {
22
+ CFRunLoopStop(CFRunLoopGetCurrent());
23
+ }
24
+
25
+ - (void) deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender
26
+ device:(IOBluetoothDevice*)device {
27
+ VALUE address;
28
+ VALUE name = Qnil;
29
+ const char * device_name = [[device name] UTF8String];
30
+
31
+ address = rb_str_new2([[device getAddressString] UTF8String]);
32
+
33
+ if (device_name)
34
+ name = rb_str_new2(device_name);
35
+
36
+ VALUE dev = rb_funcall(rbt_cBluetoothDevice, rb_intern("new"), 2,
37
+ address, name);
38
+
39
+ rb_ary_push(_devices, dev);
40
+ }
41
+
42
+ - (void) deviceInquiryDeviceNameUpdated:(IOBluetoothDeviceInquiry*)sender
43
+ device:(IOBluetoothDevice*)device
44
+ devicesRemaining:(uint32_t)devicesRemaining {
45
+ // do something
46
+ }
47
+
48
+ - (void) deviceInquiryUpdatingDeviceNamesStarted:(IOBluetoothDeviceInquiry*)sender
49
+ devicesRemaining:(uint32_t)devicesRemaining {
50
+ // do something
51
+ }
52
+
53
+ - (IOReturn) startSearch {
54
+ IOReturn status;
55
+
56
+ [self stopSearch];
57
+
58
+ _inquiry = [IOBluetoothDeviceInquiry inquiryWithDelegate:self];
59
+ _devices = rb_ary_new();
60
+
61
+ [_inquiry setUpdateNewDeviceNames: TRUE];
62
+
63
+ status = [_inquiry start];
64
+
65
+ if (status == kIOReturnSuccess) {
66
+ [_inquiry retain];
67
+
68
+ _busy = TRUE;
69
+ }
70
+
71
+ return status;
72
+ }
73
+
74
+ - (void) stopSearch {
75
+ if (_inquiry) {
76
+ [_inquiry stop];
77
+
78
+ [_inquiry release];
79
+ _inquiry = nil;
80
+ }
81
+ }
82
+
83
+ - (VALUE) devices {
84
+ return _devices;
85
+ }
86
+ @end
87
+
@@ -0,0 +1,112 @@
1
+ // Include the Ruby headers and goodies
2
+ #include <ruby.h>
3
+ #include <rubyio.h>
4
+ #include <rubysig.h>
5
+ #include <util.h>
6
+ //#include <unistd.h>
7
+ //#include <winsock2.h>
8
+ #include <Ws2bth.h>
9
+ #include <BluetoothAPIs.h>
10
+
11
+ #include <stdio.h>
12
+
13
+ #include "ruby_bluetooth.h"
14
+
15
+ #pragma comment(lib, "irprops.lib")
16
+
17
+ #pragma comment(lib, "ws2_32.lib")
18
+
19
+
20
+ VALUE bt_module;
21
+ VALUE bt_devices_class;
22
+ VALUE bt_cBluetoothDevice;
23
+
24
+ // The initialization method for this module
25
+ void Init_bluetooth()
26
+ {
27
+ bt_module = rb_define_module("Bluetooth");
28
+ bt_devices_class = rb_define_class_under(bt_module, "Devices", rb_cObject);
29
+ rb_define_singleton_method(bt_devices_class, "scan", RUBY_METHOD_FUNC(bt_devices_scan), 0);
30
+ rb_undef_method(bt_devices_class, "initialize");
31
+
32
+ bt_cBluetoothDevice = rb_const_get(mBluetooth, rb_intern("Device"));
33
+ }
34
+
35
+ // Scan local network for visible remote devices
36
+ static VALUE bt_devices_scan(VALUE self)
37
+ {
38
+ WORD wVersionRequested = 0x202;
39
+ HANDLE hRadio;
40
+ BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) };
41
+
42
+ HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio );
43
+
44
+ VALUE devices_array = rb_ary_new();
45
+ if ( NULL != hFind )
46
+ {
47
+ do
48
+ {
49
+ BLUETOOTH_DEVICE_INFO_STRUCT deviceInfo;
50
+
51
+ deviceInfo.dwSize = sizeof(deviceInfo);
52
+
53
+ BLUETOOTH_DEVICE_SEARCH_PARAMS deviceSearchParams;
54
+
55
+ memset(&deviceSearchParams, 0, sizeof(deviceSearchParams));
56
+
57
+ deviceSearchParams.dwSize = sizeof(deviceSearchParams);
58
+
59
+ deviceSearchParams.fReturnAuthenticated = true;
60
+ deviceSearchParams.fReturnRemembered = false;
61
+ deviceSearchParams.fReturnUnknown = true;
62
+ deviceSearchParams.fReturnConnected = true;
63
+ deviceSearchParams.fIssueInquiry = true;
64
+ deviceSearchParams.cTimeoutMultiplier = 1;
65
+
66
+ deviceSearchParams.hRadio = hRadio;
67
+
68
+ HANDLE hDeviceFind = BluetoothFindFirstDevice(&deviceSearchParams, &deviceInfo);
69
+
70
+ if (NULL != hDeviceFind)
71
+ {
72
+ do
73
+ {
74
+ BYTE *rgBytes = deviceInfo.Address.rgBytes;
75
+ //BluetoothDisplayDeviceProperties(0, &deviceInfo);
76
+ char addr[19] = { 0 };
77
+ char name[248] = { 0 };
78
+ wcstombs(name, deviceInfo.szName, sizeof(name));
79
+
80
+ snprintf(addr, sizeof(addr), "%02x:%02x:%02x:%02x:%02x:%02x",
81
+ rgBytes[5],
82
+ rgBytes[4],
83
+ rgBytes[3],
84
+ rgBytes[2],
85
+ rgBytes[1],
86
+ rgBytes[0]);
87
+
88
+ VALUE bt_dev = rb_funcall(bt_cBluetoothDevice,
89
+ rb_intern("new"), 2,
90
+ rb_str_new2(name), rb_str_new2(addr));
91
+ rb_ary_push(devices_array, bt_dev);
92
+ }
93
+ while(BluetoothFindNextDevice(hDeviceFind, &deviceInfo));
94
+
95
+ BluetoothFindDeviceClose(hDeviceFind);
96
+ }
97
+
98
+ GUID guidServices[10];
99
+
100
+ DWORD numServices = sizeof(guidServices);
101
+
102
+ DWORD result = BluetoothEnumerateInstalledServices(hRadio, &deviceInfo, &numServices, guidServices);
103
+
104
+ CloseHandle( hRadio );
105
+ } while( BluetoothFindNextRadio( hFind, &hRadio ) );
106
+
107
+ BluetoothFindRadioClose( hFind );
108
+ }
109
+
110
+ return devices_array;
111
+
112
+ }
@@ -0,0 +1,24 @@
1
+ // Prototype for the initialization method - Ruby calls this, not you
2
+ void Init_ruby_bluetooth();
3
+
4
+ struct bluetooth_device_struct
5
+ {
6
+ VALUE addr;
7
+ VALUE name;
8
+ };
9
+
10
+ static VALUE bt_device_new(VALUE self, VALUE name, VALUE addr);
11
+
12
+ static VALUE bt_devices_scan(VALUE self);
13
+
14
+ static VALUE bt_socket_s_for_fd(VALUE klass, VALUE fd);
15
+
16
+ static VALUE bt_socket_inspect(VALUE self);
17
+
18
+ static VALUE bt_init_sock(VALUE sock, int fd);
19
+
20
+ static int bt_ruby_socket(int domain, int type, int proto);
21
+
22
+ static VALUE bt_rfcomm_socket_init(int argc, VALUE *argv, VALUE sock);
23
+
24
+ static VALUE bt_rfcomm_socket_connect(VALUE self, VALUE host, VALUE port);
@@ -0,0 +1,21 @@
1
+ module Bluetooth
2
+
3
+ VERSION = '1.0'
4
+
5
+ ERRORS = {}
6
+
7
+ class Error < RuntimeError
8
+ def self.raise status
9
+ err = Bluetooth::ERRORS[status]
10
+ super(*err) if err
11
+
12
+ super self, "unknown error (#{status})"
13
+ end
14
+ end
15
+
16
+ autoload :Device, 'bluetooth/device'
17
+
18
+ end
19
+
20
+ require 'bluetooth/bluetooth'
21
+
@@ -0,0 +1,79 @@
1
+ ##
2
+ # A bluetooth device
3
+
4
+ class Bluetooth::Device
5
+
6
+ ##
7
+ # The address of this device in XX-XX-XX-XX-XX-XX format
8
+
9
+ attr_accessor :address
10
+
11
+ ##
12
+ # Sets the name of this device
13
+
14
+ attr_writer :name
15
+
16
+ ##
17
+ # Creates a new Device with an +address+ and an optional +name+
18
+
19
+ def initialize address, name = nil
20
+ @address = address
21
+ @name = name
22
+
23
+ @pair_error = nil
24
+ @pair_confirmation_callback = nil
25
+ end
26
+
27
+ ##
28
+ # The bytes of this address
29
+
30
+ def address_bytes
31
+ @address.split('-').map { |c| c.to_i(16) }.pack 'C*'
32
+ end
33
+
34
+ ##
35
+ # Returns the link quality for the device.
36
+
37
+ def link_quality
38
+ connect do
39
+ _link_quality
40
+ end
41
+ end
42
+
43
+ ##
44
+ # The name of this Device. It will be automatically looked up if not
45
+ # already known.
46
+
47
+ def name
48
+ return @name if @name
49
+
50
+ @name = request_name
51
+
52
+ return '(unknown)' unless @name
53
+
54
+ @name
55
+ end
56
+
57
+ ##
58
+ # Called during pairing if user confirmation is required with a number
59
+ # to match with the device. Return true if the number matches.
60
+
61
+ def pair_confirmation &block
62
+ @pair_confirmation_callback = block
63
+ end
64
+
65
+ ##
66
+ # Returns the RSSI for the device
67
+
68
+ def rssi
69
+ connect do
70
+ _rssi
71
+ end
72
+ end
73
+
74
+ def to_s # :nodoc:
75
+ "#{name} at #{address}"
76
+ end
77
+
78
+ end
79
+