Make the apn library take a cert and a key as a string instead of as a file so i can store multiples of them. Also fixed up a bunch of js lint error, not all of them, but most of them.
This commit is contained in:
Родитель
a3cf8b090b
Коммит
a847befdff
57
README.md
57
README.md
|
@ -24,29 +24,39 @@ As a submodule of your project
|
|||
### Load in the module
|
||||
|
||||
var apns = require('apn');
|
||||
|
||||
|
||||
### Exported Objects
|
||||
- Connection
|
||||
- Notification
|
||||
- Device
|
||||
- Feedback
|
||||
- errors
|
||||
|
||||
### Connecting
|
||||
Create a new connection to the gateway server using a dictionary of options. The defaults are listed below:
|
||||
|
||||
options = { cert: 'cert.pem' /* Certificate file */
|
||||
, key: 'key.pem' /* Key file */
|
||||
, gateway: 'gateway.push.apple.com' /* gateway address */
|
||||
, port: 2195 /* gateway port */
|
||||
, enhanced: true /* enable enhanced format */
|
||||
, errorCallback: undefined /* Callback when error occurs */
|
||||
, cacheLength: 5 /* Notifications to cache for error purposes */
|
||||
};
|
||||
|
||||
var apnsConnection = new apns.connection(options);
|
||||
var options = {
|
||||
cert: 'cert.pem', /* Certificate file */
|
||||
certData: null, /* Optional: if supplied uses this instead of Certificate File */
|
||||
key: 'key.pem', /* Key file */
|
||||
keyData: null, /* Optional: if supplied uses this instead of Key file */
|
||||
gateway: 'gateway.push.apple.com',/* gateway address */
|
||||
port: 2195, /* gateway port */
|
||||
enhanced: true, /* enable enhanced format */
|
||||
errorCallback: undefined, /* Callback when error occurs */
|
||||
cacheLength: 5 /* Number of notifications to cache for error purposes */
|
||||
};
|
||||
|
||||
var apnsConnection = new apns.Connection(options);
|
||||
|
||||
### Sending a notification
|
||||
To send a notification first create a `Device` object. Pass it the device token as either a hexadecimal string, or alternatively as a `Buffer` object containing the binary token, setting the second argument to `false`.
|
||||
|
||||
var myDevice = new apns.device(token /*, ascii=true*/);
|
||||
var myDevice = new apns.Device(token /*, ascii=true*/);
|
||||
|
||||
Next create a notification object and set parameters. See the [payload documentation][pl] for more details
|
||||
|
||||
var note = new apns.notification();
|
||||
var note = new apns.Notification();
|
||||
|
||||
note.badge = 3;
|
||||
note.sound = "ping.aiff";
|
||||
|
@ -76,15 +86,18 @@ Apple recommends checking the feedback service periodically for a list of device
|
|||
|
||||
Using the `Feedback` object it is possible to periodically query the server for the list. You should provide a function which will accept two arguments, the `time` returned by the server (epoch time) and a `Device` object containing the device token. You can also set the query interval in seconds. Again the default options are shown below.
|
||||
|
||||
options = { cert: 'cert.pem' /* Certificate file */
|
||||
, key: 'key.pem' /* Key file */
|
||||
, address: 'feedback.push.apple.com' /* feedback address */
|
||||
, port: 2196 /* feedback port */
|
||||
, feedback: false /* callback function */
|
||||
, interval: 3600 /* query interval in seconds */
|
||||
};
|
||||
var options = {
|
||||
cert: 'cert.pem', /* Certificate file */
|
||||
certData: null, /* Certificate file contents */
|
||||
key: 'key.pem', /* Key file */
|
||||
keyData: null, /* Key file contents */
|
||||
address: 'feedback.push.apple.com', /* feedback address */
|
||||
port: 2196, /* feedback port */
|
||||
feedback: false, /* enable feedback service, set to callback */
|
||||
interval: 3600 /* interval in seconds to connect to feedback service */
|
||||
};
|
||||
|
||||
var feedback = new apns.feedback(options);
|
||||
var feedback = new apns.Feedback(options);
|
||||
|
||||
## Converting your APNs Certificate
|
||||
|
||||
|
@ -175,4 +188,4 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
|
||||
1.0.0:
|
||||
|
||||
* Well I created a module; Version 0.0.0 had no code, and now it does, and it works, so that's pretty neat, right?
|
||||
* Well I created a module; Version 0.0.0 had no code, and now it does, and it works, so that's pretty neat, right?
|
||||
|
|
437
lib/apn.js
437
lib/apn.js
|
@ -3,17 +3,17 @@ var fs = require('fs');
|
|||
var Buffer = require('buffer').Buffer;
|
||||
|
||||
var Errors = {
|
||||
'noErrorsEncountered': 0
|
||||
, 'processingError': 1
|
||||
, 'missingDeviceToken': 2
|
||||
, 'missingTopic': 3
|
||||
, 'missingPayload': 4
|
||||
, 'invalidTokenSize': 5
|
||||
, 'invalidTopicSize': 6
|
||||
, 'invalidPayloadSize': 7
|
||||
, 'invalidToken': 8
|
||||
, 'none': 255
|
||||
}
|
||||
'noErrorsEncountered': 0,
|
||||
'processingError': 1,
|
||||
'missingDeviceToken': 2,
|
||||
'missingTopic': 3,
|
||||
'missingPayload': 4,
|
||||
'invalidTokenSize': 5,
|
||||
'invalidTopicSize': 6,
|
||||
'invalidPayloadSize': 7,
|
||||
'invalidToken': 8,
|
||||
'none': 255
|
||||
};
|
||||
|
||||
var Connection = function (optionArgs) {
|
||||
var currentId = 0;
|
||||
|
@ -25,15 +25,18 @@ var Connection = function (optionArgs) {
|
|||
var socketOptions = {};
|
||||
var openingSocket = false;
|
||||
var writeBuffer = [];
|
||||
|
||||
var options = { cert: 'cert.pem' /* Certificate file */
|
||||
, key: 'key.pem' /* Key file */
|
||||
, gateway: 'gateway.push.apple.com' /* gateway address */
|
||||
, port: 2195 /* gateway port */
|
||||
, enhanced: true /* enable enhanced format */
|
||||
, errorCallback: undefined /* Callback when error occurs */
|
||||
, cacheLength: 5 /* Number of notifications to cache for error purposes */
|
||||
};
|
||||
|
||||
var options = {
|
||||
cert: 'cert.pem' /* Certificate file */,
|
||||
certData: '',
|
||||
key: 'key.pem' /* Key file */,
|
||||
keyData: '',
|
||||
gateway: 'gateway.push.apple.com' /* gateway address */,
|
||||
port: 2195 /* gateway port */,
|
||||
enhanced: true /* enable enhanced format */,
|
||||
errorCallback: undefined /* Callback when error occurs */,
|
||||
cacheLength: 5 /* Number of notifications to cache for error purposes */
|
||||
};
|
||||
|
||||
if (optionArgs) {
|
||||
var keys = Object.keys(options);
|
||||
|
@ -42,77 +45,89 @@ var Connection = function (optionArgs) {
|
|||
if (optionArgs[k] !== undefined) options[k] = optionArgs[k];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var readyToConnect = function () {
|
||||
return (hasKey && hasCert);
|
||||
}
|
||||
};
|
||||
|
||||
var onDrain = function() {
|
||||
var onDrain = function () {
|
||||
while (writeBuffer.length && self.socket.bufferSize == 0) {
|
||||
writeNotificationToSocket(writeBuffer.shift());
|
||||
}
|
||||
};
|
||||
|
||||
var startSocket = function () {
|
||||
if(!self.openingSocket) {
|
||||
process.nextTick(function() {
|
||||
self.socket = tls.connect(options['port'], options['gateway'], socketOptions,
|
||||
function() {
|
||||
if(!self.socket.authorized) {
|
||||
throw self.socket.authorizationError
|
||||
var startSocket = function () {
|
||||
if (!self.openingSocket) {
|
||||
process.nextTick(function () {
|
||||
self.socket = tls.connect(options['port'], options['gateway'], socketOptions,
|
||||
callback = function () {
|
||||
if (!self.socket.authorized) {
|
||||
throw self.socket.authorizationError;
|
||||
}
|
||||
|
||||
|
||||
onDrain();
|
||||
self.openingSocket=false;
|
||||
self.openingSocket = false;
|
||||
});
|
||||
|
||||
self.socket.on('data', function(data) {
|
||||
|
||||
self.socket.on('data', function (data) {
|
||||
handleTransmissionError(data);
|
||||
});
|
||||
|
||||
self.socket.on('error', function(data) {
|
||||
|
||||
self.socket.on('error', function () {
|
||||
self.socket.removeAllListeners();
|
||||
self.socket = undefined;
|
||||
});
|
||||
|
||||
|
||||
self.socket.once('close', function () {
|
||||
if(writeBuffer.length && readyToConnect()) {
|
||||
if (writeBuffer.length && readyToConnect()) {
|
||||
startSocket();
|
||||
}
|
||||
if (!self.socket) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
self.socket.removeAllListeners();
|
||||
self.socket = undefined;
|
||||
});
|
||||
|
||||
|
||||
self.socket.on("drain", onDrain);
|
||||
});
|
||||
self.openingSocket = true;
|
||||
}
|
||||
}
|
||||
|
||||
var connect = invoke_after(function() { startSocket(); });
|
||||
|
||||
fs.readFile(options['cert'], connect(function(err, data) {
|
||||
if(err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['cert'] = data.toString();
|
||||
};
|
||||
|
||||
var connect = invoke_after(function () {
|
||||
startSocket();
|
||||
});
|
||||
|
||||
if (options['certData']) {
|
||||
socketOptions['cert'] = options['certData'];
|
||||
hasCert = true;
|
||||
}));
|
||||
} else {
|
||||
fs.readFile(options['cert'], connect(function (err, data) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['cert'] = data.toString();
|
||||
hasCert = true;
|
||||
}));
|
||||
}
|
||||
|
||||
fs.readFile(options['key'], connect(function(err, data) {
|
||||
if(err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['key'] = data.toString();
|
||||
if (options['keyData']) {
|
||||
socketOptions['key'] = options['keyData'];
|
||||
hasKey = true;
|
||||
}));
|
||||
} else {
|
||||
fs.readFile(options['key'], connect(function (err, data) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['key'] = data.toString();
|
||||
hasKey = true;
|
||||
}));
|
||||
}
|
||||
|
||||
var writeNotificationToSocket = function(data) {
|
||||
if (self.socket === undefined || self.socket.readyState != 'open') {
|
||||
var writeNotificationToSocket = function (data) {
|
||||
if (self.socket === undefined || self.socket.readyState != 'open') {
|
||||
if ((self.socket === undefined || self.socket.readyState == 'closed') && readyToConnect()) {
|
||||
startSocket();
|
||||
}
|
||||
|
@ -126,65 +141,66 @@ var Connection = function (optionArgs) {
|
|||
}
|
||||
};
|
||||
|
||||
var bufferDataForWrite = function(data) {
|
||||
var bufferDataForWrite = function (data) {
|
||||
writeBuffer.push(data);
|
||||
}
|
||||
};
|
||||
|
||||
this.sendNotification = function (note) {
|
||||
var encoding = 'utf8';
|
||||
if(note.encoding) {
|
||||
if (note.encoding) {
|
||||
encoding = note.encoding;
|
||||
}
|
||||
var token = note.device.token;
|
||||
var message = JSON.stringify(note);
|
||||
var messageLength = Buffer.byteLength(message, encoding);
|
||||
var pos = 0;
|
||||
|
||||
if(token === undefined) {
|
||||
|
||||
if (token === undefined) {
|
||||
return Errors['missingDeviceToken'];
|
||||
}
|
||||
if(messageLength > 256) {
|
||||
if (messageLength > 256) {
|
||||
return Errors['invalidPayloadSize'];
|
||||
}
|
||||
|
||||
|
||||
note._uid = currentId++;
|
||||
if(options.enhanced) {
|
||||
var data = new Buffer(1 + 4 + 4 + 2 + token.length + 2 + messageLength);
|
||||
var data;
|
||||
if (options.enhanced) {
|
||||
data = new Buffer(1 + 4 + 4 + 2 + token.length + 2 + messageLength);
|
||||
// Command
|
||||
data[pos] = 1;
|
||||
pos++;
|
||||
|
||||
|
||||
// Identifier
|
||||
pos += int2buf(note._uid, data, pos, 4);
|
||||
|
||||
|
||||
// Expiry
|
||||
pos += int2buf(note.expiry, data, pos, 4);
|
||||
|
||||
|
||||
cachedNotes.push(note);
|
||||
tidyCachedNotes();
|
||||
}
|
||||
else {
|
||||
var data = new Buffer(1 + 2 + token.length + 2 + messageLength);
|
||||
data = new Buffer(1 + 2 + token.length + 2 + messageLength);
|
||||
data[pos] = 0;
|
||||
pos++;
|
||||
}
|
||||
|
||||
|
||||
pos += int2buf(token.length, data, pos, 2);
|
||||
pos += token.copy(data, pos, 0);
|
||||
pos += int2buf(messageLength, data, pos, 2);
|
||||
pos += data.write(message, pos, encoding);
|
||||
|
||||
writeNotificationToSocket(data);
|
||||
}
|
||||
|
||||
var tidyCachedNotes = function() {
|
||||
};
|
||||
|
||||
var tidyCachedNotes = function () {
|
||||
// Maybe a timestamp should be stored for each note and kept for a duration?
|
||||
if(cachedNotes.length > options.cacheLength) {
|
||||
if (cachedNotes.length > options.cacheLength) {
|
||||
cachedNotes.shift();
|
||||
}
|
||||
}
|
||||
|
||||
var handleTransmissionError = function(data) {
|
||||
};
|
||||
|
||||
var handleTransmissionError = function (data) {
|
||||
// Need to check message that errors
|
||||
// return failed notification to owner
|
||||
// purge writeBuffer and start again with cachedNotes
|
||||
|
@ -200,120 +216,127 @@ var Connection = function (optionArgs) {
|
|||
|
||||
// This is an error condition
|
||||
var errorCode = data[1];
|
||||
var identifier = bytes2int(data.slice(2,6), 4);
|
||||
var identifier = bytes2int(data.slice(2, 6), 4);
|
||||
var note = undefined;
|
||||
|
||||
while(cachedNotes.length) {
|
||||
while (cachedNotes.length) {
|
||||
note = cachedNotes.shift();
|
||||
if(note['_uid'] == identifier) {
|
||||
if (note['_uid'] == identifier) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify callback of failed notification
|
||||
if(typeof options.errorCallback == 'function') {
|
||||
if (typeof options.errorCallback == 'function') {
|
||||
options.errorCallback(errorCode, note);
|
||||
}
|
||||
writeBuffer = [];
|
||||
var count = cachedNotes.length;
|
||||
for(var i=0; i<count; i++) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
note = cachedNotes.shift();
|
||||
self.sendNotification(note);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var Notification = function () {
|
||||
this.payload = {};
|
||||
this.expiry = 0;
|
||||
this.identifier = 0;
|
||||
this.device;
|
||||
|
||||
|
||||
this.alert = undefined;
|
||||
this.badge = undefined;
|
||||
this.sound = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
Notification.prototype.toJSON = function() {
|
||||
if(this.payload.aps === undefined) {
|
||||
Notification.prototype.toJSON = function () {
|
||||
if (this.payload === undefined) {
|
||||
this.payload = {};
|
||||
}
|
||||
if (this.payload.aps === undefined) {
|
||||
this.payload.aps = {};
|
||||
}
|
||||
if(typeof this.badge == 'number') {
|
||||
if (typeof this.badge == 'number') {
|
||||
this.payload.aps.badge = this.badge;
|
||||
}
|
||||
if(typeof this.sound == 'string') {
|
||||
if (typeof this.sound == 'string') {
|
||||
this.payload.aps.sound = this.sound;
|
||||
}
|
||||
if(typeof this.alert == 'string' || typeof this.alert == 'object') {
|
||||
if (typeof this.alert == 'string' || typeof this.alert == 'object') {
|
||||
this.payload.aps.alert = this.alert;
|
||||
}
|
||||
return this.payload;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var Device = function (/* deviceToken, ascii=true */) {
|
||||
var self = this;
|
||||
self.token = undefined;
|
||||
|
||||
if(arguments.length > 0) {
|
||||
|
||||
if (arguments.length > 0) {
|
||||
self.setToken.apply(self, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Device.prototype.parseToken = function (token) {
|
||||
token = token.replace(/\s/g, "");
|
||||
length = Math.ceil(token.length / 2);
|
||||
hexToken = new Buffer(length);
|
||||
for(var i=0; i < token.length; i+=2) {
|
||||
word = token[i];
|
||||
if((i + 1) >= token.length || typeof(token[i+1]) === undefined) {
|
||||
var length = Math.ceil(token.length / 2);
|
||||
var hexToken = new Buffer(length);
|
||||
for (var i = 0; i < token.length; i += 2) {
|
||||
var word = token[i];
|
||||
if ((i + 1) >= token.length || typeof(token[i + 1]) === undefined) {
|
||||
word += '0';
|
||||
}
|
||||
else {
|
||||
word += token[i+1];
|
||||
word += token[i + 1];
|
||||
}
|
||||
hexToken[i/2] = parseInt(word, 16);
|
||||
hexToken[i / 2] = parseInt(word, 16);
|
||||
}
|
||||
return hexToken;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Device.prototype.setToken = function (newToken, ascii) {
|
||||
if(ascii === undefined || ascii == true) {
|
||||
if (ascii === undefined || ascii == true) {
|
||||
newToken = this.parseToken(newToken);
|
||||
}
|
||||
this.token = newToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Device.prototype.hexToken = function () {
|
||||
var out = [],
|
||||
len = this.token.length;
|
||||
var out = [];
|
||||
var len = this.token.length;
|
||||
var n;
|
||||
for (var i = 0; i < len; i++) {
|
||||
n = this.token[i];
|
||||
if (n < 16) out[i] = "0" + n.toString(16);
|
||||
else out[i] = n.toString(16);
|
||||
}
|
||||
return out.join("");
|
||||
}
|
||||
};
|
||||
|
||||
var Feedback = function (optionArgs) {
|
||||
var self = this;
|
||||
var hasKey = false;
|
||||
var hasCert = false;
|
||||
var socketOptions = {}
|
||||
|
||||
var responsePacketLength = 38;
|
||||
var socketOptions = {};
|
||||
|
||||
var responsePacketLength = 38;
|
||||
var readBuffer = new Buffer(responsePacketLength);
|
||||
var readLength = 0;
|
||||
|
||||
var options = { cert: 'cert.pem' /* Certificate file */
|
||||
, key: 'key.pem' /* Key file */
|
||||
, address: 'feedback.push.apple.com' /* feedback address */
|
||||
, port: 2196 /* feedback port */
|
||||
, feedback: false /* enable feedback service, set to callback */
|
||||
, interval: 3600 /* interval in seconds to connect to feedback service */
|
||||
};
|
||||
|
||||
|
||||
var options = {
|
||||
cert: 'cert.pem', /* Certificate file */
|
||||
certData: '', /* Certificate data */
|
||||
key: 'key.pem', /* Key file */
|
||||
keyData: '', /* Key data */
|
||||
address: 'feedback.push.apple.com', /* feedback address */
|
||||
port: 2196, /* feedback port */
|
||||
feedback: false, /* enable feedback service, set to callback */
|
||||
interval: 3600, /* interval in seconds to connect to feedback service */
|
||||
};
|
||||
|
||||
if (optionArgs) {
|
||||
var keys = Object.keys(options);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
|
@ -321,62 +344,89 @@ var Feedback = function (optionArgs) {
|
|||
if (optionArgs[k] !== undefined) options[k] = optionArgs[k];
|
||||
}
|
||||
}
|
||||
|
||||
if(typeof options['feedback'] != 'function') {
|
||||
|
||||
if (typeof options['feedback'] != 'function') {
|
||||
return Error(-1, 'A callback function must be specified');
|
||||
}
|
||||
|
||||
|
||||
this.readyToConnect = function () {
|
||||
return (hasKey && hasCert);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
self.startSocket = function () {
|
||||
self.socket = tls.connect(options['port'], options['address'], socketOptions);
|
||||
self.socket.pair.on('secure', function () { if(!self.socket.authorized) { throw self.socket.authorizationError } });
|
||||
self.socket.on('data', function(data) { processData(data); });
|
||||
self.socket.once('error', function(data) {self.socket.removeAllListeners(); self.socket = undefined; });
|
||||
self.socket.once('end', function () { });
|
||||
self.socket.once('close', function () { self.socket.removeAllListeners(); self.socket = undefined; });
|
||||
}
|
||||
|
||||
var connect = invoke_after(function() { self.startSocket(); });
|
||||
|
||||
fs.readFile(options['cert'], connect(function(err, data) {
|
||||
if(err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['cert'] = data.toString();
|
||||
hasCert = true;
|
||||
}));
|
||||
self.socket.pair.on('secure', function () {
|
||||
if (!self.socket.authorized) {
|
||||
throw self.socket.authorizationError;
|
||||
}
|
||||
});
|
||||
self.socket.on('data', function (data) {
|
||||
processData(data);
|
||||
});
|
||||
self.socket.once('error', function () {
|
||||
self.socket.removeAllListeners();
|
||||
self.socket = undefined;
|
||||
});
|
||||
self.socket.once('end', function () {
|
||||
});
|
||||
self.socket.once('close', function () {
|
||||
self.socket.removeAllListeners();
|
||||
self.socket = undefined;
|
||||
});
|
||||
};
|
||||
|
||||
fs.readFile(options['key'], connect(function(err, data) {
|
||||
if(err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['key'] = data.toString();
|
||||
hasKey = true;
|
||||
}));
|
||||
|
||||
if(options['interval'] > 0) {
|
||||
this.interval = setInterval(function() { self.request(); }, options['interval'] * 1000);
|
||||
var connect = invoke_after(function () {
|
||||
self.startSocket();
|
||||
});
|
||||
|
||||
if (options['certData']) {
|
||||
socketOptions['cert'] = options['certData'];
|
||||
hasCert = true;
|
||||
} else {
|
||||
fs.readFile(options['cert'], connect(function (err, data) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['cert'] = data.toString();
|
||||
hasCert = true;
|
||||
}));
|
||||
}
|
||||
|
||||
var processData = function(data) {
|
||||
|
||||
if (options['keyData']) {
|
||||
socketOptions['key'] = options['keyData'];
|
||||
hasKey = true;
|
||||
} else {
|
||||
fs.readFile(options['key'], connect(function (err, data) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
socketOptions['key'] = data.toString();
|
||||
hasKey = true;
|
||||
}));
|
||||
}
|
||||
|
||||
if (options['interval'] > 0) {
|
||||
this.interval = setInterval(function () {
|
||||
self.request();
|
||||
}, options['interval'] * 1000);
|
||||
}
|
||||
|
||||
var processData = function (data) {
|
||||
var pos = 0;
|
||||
// If there is some buffered data, read the remainder and process this first.
|
||||
if(readLength > 0) {
|
||||
if(data.length < (responsePacketLength - readLength)) {
|
||||
if (readLength > 0) {
|
||||
if (data.length < (responsePacketLength - readLength)) {
|
||||
data.copy(readBuffer, readLength, 0);
|
||||
readLength += data.length;
|
||||
return;
|
||||
}
|
||||
data.copy(readBuffer, readLength, 0, responsePacketLength-readLength);
|
||||
data.copy(readBuffer, readLength, 0, responsePacketLength - readLength);
|
||||
decodeResponse(readBuffer, 0);
|
||||
pos = responsePacketLength-readLength;
|
||||
pos = responsePacketLength - readLength;
|
||||
readLength = 0;
|
||||
}
|
||||
while(pos<data.length-1) {
|
||||
if((data.length-pos) < responsePacketLength) {
|
||||
while (pos < data.length - 1) {
|
||||
if ((data.length - pos) < responsePacketLength) {
|
||||
//Buffer remaining data until next time
|
||||
data.copy(readBuffer, 0, pos);
|
||||
readLength = data.length - pos;
|
||||
|
@ -385,66 +435,71 @@ var Feedback = function (optionArgs) {
|
|||
decodeResponse(data, pos);
|
||||
pos += responsePacketLength;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var decodeResponse = function(data, start) {
|
||||
time = bytes2int(data, 4, start);
|
||||
var decodeResponse = function (data, start) {
|
||||
var time = bytes2int(data, 4, start);
|
||||
start += 4;
|
||||
len = bytes2int(data, 2, start);
|
||||
var len = bytes2int(data, 2, start);
|
||||
start += 2;
|
||||
tok = new Buffer(len);
|
||||
data.copy(tok, 0, start, start+len);
|
||||
|
||||
if(typeof options['feedback'] == 'function') {
|
||||
options['feedback'](time, new exports.device(tok, false));
|
||||
var tok = new Buffer(len);
|
||||
data.copy(tok, 0, start, start + len);
|
||||
|
||||
if (typeof options['feedback'] == 'function') {
|
||||
options['feedback'](time, new exports.Device(tok, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Feedback.prototype.request = function () {
|
||||
if((this.socket === undefined || this.socket.readyState == 'closed') && this.readyToConnect()) {
|
||||
if ((this.socket === undefined || this.socket.readyState == 'closed') && this.readyToConnect()) {
|
||||
this.startSocket();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Feedback.prototype.cancel = function () {
|
||||
if(this.interval !== undefined) {
|
||||
if (this.interval !== undefined) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function int2buf(number, buffer, start, length) {
|
||||
function int2buf (number, buffer, start, length) {
|
||||
length -= 1;
|
||||
for(var i=0; i<=length; i++) {
|
||||
buffer[start+length-i] = number & 0xff;
|
||||
for (var i = 0; i <= length; i++) {
|
||||
buffer[start + length - i] = number & 0xff;
|
||||
number = number >> 8;
|
||||
}
|
||||
return length+1;
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
function bytes2int(bytes, length, start) {
|
||||
if(start === undefined) start = 0;
|
||||
function bytes2int (bytes, length, start) {
|
||||
if (start === undefined) start = 0;
|
||||
var num = 0;
|
||||
length -= 1;
|
||||
for(var i=0; i<=length; i++) {
|
||||
num += (bytes[start+i] << ((length - i) * 8));
|
||||
for (var i = 0; i <= length; i++) {
|
||||
num += (bytes[start + i] << ((length - i) * 8));
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
function invoke_after(callback) {
|
||||
function invoke_after (callback) {
|
||||
var n = 0;
|
||||
return function (delegate) {
|
||||
n++;
|
||||
return function() {
|
||||
return function () {
|
||||
delegate.apply(delegate, arguments);
|
||||
if(--n == 0) callback();
|
||||
if (--n == 0) callback();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
exports.Connection = Connection;
|
||||
exports.connection = Connection;
|
||||
exports.Notification = Notification;
|
||||
exports.notification = Notification;
|
||||
exports.Device = Device;
|
||||
exports.device = Device;
|
||||
exports.Feedback = Feedback;
|
||||
exports.feedback = Feedback;
|
||||
exports.error = Errors;
|
||||
exports.error = Errors;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче