Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions experiments/paired-devices-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(function() {
"use strict";

var util = require('util');
var DeviceINQ = require("../lib/device-inquiry.js").DeviceINQ;
var BluetoothSerialPort = require("../lib/bluetooth-serial-port.js").BluetoothSerialPort;
var serial = new BluetoothSerialPort();

serial.listPairedDevices(function(pairedDevices) {
pairedDevices.forEach(function(device) {
console.log(device);
});
})
})();
4 changes: 4 additions & 0 deletions lib/bluetooth-serial-port.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
util.inherits(BluetoothSerialPort, EventEmitter);
exports.BluetoothSerialPort = BluetoothSerialPort;

BluetoothSerialPort.prototype.listPairedDevices = function(callback) {
this.inq.listPairedDevices(callback);
};

BluetoothSerialPort.prototype.inquire = function() {
this.inq.inquire();
};
Expand Down
1 change: 1 addition & 0 deletions src/DeviceINQ.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class DeviceINQ : public node::ObjectWrap {
static v8::Handle<v8::Value> New(const v8::Arguments& args);
static v8::Handle<v8::Value> Inquire(const v8::Arguments& args);
static v8::Handle<v8::Value> SdpSearch(const v8::Arguments& args);
static v8::Handle<v8::Value> ListPairedDevices(const v8::Arguments& args);
};

#endif
35 changes: 35 additions & 0 deletions src/linux/DeviceINQ.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ void DeviceINQ::Init(Handle<Object> target) {

NODE_SET_PROTOTYPE_METHOD(t, "inquire", Inquire);
NODE_SET_PROTOTYPE_METHOD(t, "findSerialPortChannel", SdpSearch);
NODE_SET_PROTOTYPE_METHOD(t, "listPairedDevices", ListPairedDevices);
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
}
Expand Down Expand Up @@ -273,3 +275,36 @@ Handle<Value> DeviceINQ::SdpSearch(const Arguments& args) {

return Undefined();
}

Handle<Value> DeviceINQ::ListPairedDevices(const Arguments& args) {
HandleScope scope;

const char *usage = "usage: listPairedDevices(callback)";
if (args.Length() != 1) {
return scope.Close(ThrowException(Exception::Error(String::New(usage))));
}

if(!args[0]->IsFunction()) {
return scope.Close(ThrowException(Exception::TypeError(String::New("First argument must be a function"))));
}
Local<Function> cb = Local<Function>::Cast(args[0]);

Local<Array> resultArray = Array::New(0);

// TODO: build an array of objects representing a paired device:
// ex: {
// name: 'MyBluetoothDeviceName',
// address: '12-34-56-78-90',
// services: [
// { name: 'SPP', channel: 1 },
// { name: 'iAP', channel: 2 }
// ]
// }

Local<Value> argv[1] = {
resultArray
};
cb->Call(Context::GetCurrent()->Global(), 1, argv);

return scope.Close(Undefined());
}
66 changes: 66 additions & 0 deletions src/osx/DeviceINQ.mm
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
}

#import <Foundation/NSObject.h>
#import <IOBluetooth/objc/IOBluetoothDevice.h>
#import <IOBluetooth/objc/IOBluetoothRFCOMMChannel.h>
#import <IOBluetooth/objc/IOBluetoothSDPUUID.h>
#import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h>
#import "BluetoothWorker.h"

using namespace node;
Expand Down Expand Up @@ -79,6 +83,8 @@

NODE_SET_PROTOTYPE_METHOD(t, "inquire", Inquire);
NODE_SET_PROTOTYPE_METHOD(t, "findSerialPortChannel", SdpSearch);
NODE_SET_PROTOTYPE_METHOD(t, "listPairedDevices", ListPairedDevices);
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
}
Expand Down Expand Up @@ -185,3 +191,63 @@

return Undefined();
}

Handle<Value> DeviceINQ::ListPairedDevices(const Arguments& args) {
HandleScope scope;

const char *usage = "usage: listPairedDevices(callback)";
if (args.Length() != 1) {
return scope.Close(ThrowException(Exception::Error(String::New(usage))));
}

if(!args[0]->IsFunction()) {
return scope.Close(ThrowException(Exception::TypeError(String::New("First argument must be a function"))));
}
Local<Function> cb = Local<Function>::Cast(args[0]);

NSArray *pairedDevices = [IOBluetoothDevice pairedDevices];

Local<Array> resultArray = Array::New((int)pairedDevices.count);

// Builds an array of objects representing a paired device:
// ex: {
// name: 'MyBluetoothDeviceName',
// address: '12-34-56-78-90',
// services: [
// { name: 'SPP', channel: 1 },
// { name: 'iAP', channel: 2 }
// ]
// }
for (int i = 0; i < (int)pairedDevices.count; ++i) {
IOBluetoothDevice *device = [pairedDevices objectAtIndex:i];

Local<Object> deviceObj = Object::New();

deviceObj->Set(String::NewSymbol("name"), String::New([device.nameOrAddress UTF8String]));
deviceObj->Set(String::NewSymbol("address"), String::New([device.addressString UTF8String]));

// A device may have multiple services, so enumerate each one
Local<Array> servicesArray = Array::New((int)device.services.count);
for (int j = 0; j < (int)device.services.count; ++j) {
IOBluetoothSDPServiceRecord *service = [device.services objectAtIndex:j];
BluetoothRFCOMMChannelID channelID;
[service getRFCOMMChannelID:&channelID];

Local<Object> serviceObj = Object::New();
serviceObj->Set(String::NewSymbol("channel"), Int32::New((int)channelID));
serviceObj->Set(String::NewSymbol("name"), [service getServiceName] ?
String::New([[service getServiceName] UTF8String]) : Undefined());
servicesArray->Set(j, serviceObj);
}
deviceObj->Set(String::NewSymbol("services"), servicesArray);

resultArray->Set(i, deviceObj);
}

Local<Value> argv[1] = {
resultArray
};
cb->Call(Context::GetCurrent()->Global(), 1, argv);

return scope.Close(Undefined());
}
35 changes: 35 additions & 0 deletions src/windows/DeviceINQ.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ void DeviceINQ::Init(Handle<Object> target) {

NODE_SET_PROTOTYPE_METHOD(t, "inquire", Inquire);
NODE_SET_PROTOTYPE_METHOD(t, "findSerialPortChannel", SdpSearch);
NODE_SET_PROTOTYPE_METHOD(t, "listPairedDevices", ListPairedDevices);
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
target->Set(String::NewSymbol("DeviceINQ"), t->GetFunction());
}
Expand Down Expand Up @@ -278,3 +280,36 @@ Handle<Value> DeviceINQ::SdpSearch(const Arguments& args) {

return Undefined();
}

Handle<Value> DeviceINQ::ListPairedDevices(const Arguments& args) {
HandleScope scope;

const char *usage = "usage: listPairedDevices(callback)";
if (args.Length() != 1) {
return scope.Close(ThrowException(Exception::Error(String::New(usage))));
}

if(!args[0]->IsFunction()) {
return scope.Close(ThrowException(Exception::TypeError(String::New("First argument must be a function"))));
}
Local<Function> cb = Local<Function>::Cast(args[0]);

Local<Array> resultArray = Array::New(0);

// TODO: build an array of objects representing a paired device:
// ex: {
// name: 'MyBluetoothDeviceName',
// address: '12-34-56-78-90',
// services: [
// { name: 'SPP', channel: 1 },
// { name: 'iAP', channel: 2 }
// ]
// }

Local<Value> argv[1] = {
resultArray
};
cb->Call(Context::GetCurrent()->Global(), 1, argv);

return scope.Close(Undefined());
}