Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for connect over raw tcp socket #425

Merged
merged 3 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
101 changes: 89 additions & 12 deletions js/serial.js
@@ -1,6 +1,9 @@
'use strict';

var serial = {
connectionType: 'serial', // 'serial' or 'tcp'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for maintainability, can you please add new stuff to the bottom of the list?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after failed, before transmitting?
or after outputBuffer, before connect?
Sorry for my bad English.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where it is now is good. Having new stuff at the beginning is confusing. And don't worry about English, it isn't my first language either, and the same goes for many contributors here.

connectionIP: '127.0.0.1',
connectionPort: 2323,
connectionId: false,
openRequested: false,
openCanceled: false,
Expand All @@ -12,10 +15,76 @@ var serial = {
transmitting: false,
outputBuffer: [],

LOGHEAD: 'SERIAL: ',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a constant, so it should be logHead.


connect: function (path, options, callback) {
var self = this;
self.openRequested = true;

var testUrl = path.match(/tcp:\/\/(.*):(.*)/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be more specific here: /^http:\/\/([A-Za-z0-9\.-]+)\:(\d+)$/. This will also ensure that the port number is numeric.

if (testUrl) {
self.connectionIP = testUrl[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd stick the two clauses of this if statement into connectTcp and connectSerial respectively to increase readability.

self.connectionPort = testUrl[2] || self.connectionPort;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testUrl[2] will always be defined. If you want it to default to the predefined port, make the port number optional in the regex: /^http:\/\/([A-Za-z0-9\.-]+)(?:\:(\d+))?$.

self.connectionPort = parseInt(self.connectionPort);
self.connectionType = 'tcp';
self.LOGHEAD = 'SERIAL-TCP: ';
console.log('connect to raw tcp:', self.connectionIP + ':' + self.connectionPort)

chrome.sockets.tcp.create({}, function(createInfo) {
console.log('chrome.sockets.tcp.create', createInfo)
if (createInfo && !self.openCanceled) {
self.connectionId = createInfo.socketId;
self.bitrate = 115200; // fake
self.bytesReceived = 0;
self.bytesSent = 0;
self.failed = 0;
self.openRequested = false;
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double linebreak.

chrome.sockets.tcp.connect(createInfo.socketId, self.connectionIP, self.connectionPort, function (result){
if (chrome.runtime.lastError) {
console.error('onConnectedCallback', chrome.runtime.lastError.message);
}

console.log('onConnectedCallback', result)
if(result == 0) {
chrome.sockets.tcp.setNoDelay(createInfo.socketId, true, function (noDelayResult){
if (chrome.runtime.lastError) {
console.error('setNoDelay', chrome.runtime.lastError.message);
}

console.log('setNoDelay', noDelayResult)
if(noDelayResult != 0) {
self.openRequested = false;
console.log(self.LOGHEAD + 'Failed to setNoDelay');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a case where the app requires additional permissions? If so, we should log it to the application's log with GUI.log(chrome.i18n.getMessage('<messageName>')). (Messages are in messaages.json.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

app only requires 1 more permissions,
already in manifest.json.
setNoDelay is to disable Nagle's Algorithm,
which cause a little delay between data input and real send out.
Maybe change it as an option?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No that's all good then. There are cases where apps need to be given special permissions in chrome (i.e. outside of the app), but if this isn't one of them then just logging it to the console is fine.

}
self.onReceive.addListener(function log_bytesReceived(info) {
if (info.socketId != self.connectionId) return;
self.bytesReceived += info.data.byteLength;
});
self.onReceiveError.addListener(function watch_for_on_receive_errors(info) {
console.error(info);
if (info.socketId != self.connectionId) return;
});

console.log(self.LOGHEAD + 'Connection opened with ID: ' + createInfo.socketId + ', url: ' + self.connectionIP + ':' + self.connectionPort);

if (callback) callback(createInfo);
});
} else {
self.openRequested = false;
console.log(self.LOGHEAD + 'Failed to connect');
if (callback) callback(false);
}

});
});

} else {
self.connectionType = 'serial';
self.LOGHEAD = 'SERIAL: ';

chrome.serial.connect(path, options, function (connectionInfo) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
Expand Down Expand Up @@ -142,6 +211,7 @@ var serial = {
if (callback) callback(false);
}
});
}
},
disconnect: function (callback) {
var self = this;
Expand All @@ -158,15 +228,16 @@ var serial = {
self.onReceiveError.removeListener(self.onReceiveError.listeners[i]);
}

chrome.serial.disconnect(this.connectionId, function (result) {
var disconnectFn = (self.connectionType == 'serial') ? chrome.serial.disconnect : chrome.sockets.tcp.close;
disconnectFn(this.connectionId, function (result) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}

if (result) {
console.log('SERIAL: Connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
console.log(self.LOGHEAD + 'Connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
} else {
console.log('SERIAL: Failed to close connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
console.log(self.LOGHEAD + 'Failed to close connection with ID: ' + self.connectionId + ' closed, Sent: ' + self.bytesSent + ' bytes, Received: ' + self.bytesReceived + ' bytes');
}

self.connectionId = false;
Expand All @@ -191,13 +262,14 @@ var serial = {
});
},
getInfo: function (callback) {
chrome.serial.getInfo(this.connectionId, callback);
var chromeType = (self.connectionType == 'serial') ? chrome.serial : chrome.sockets.tcp;
chromeType.getInfo(this.connectionId, callback);
},
getControlSignals: function (callback) {
chrome.serial.getControlSignals(this.connectionId, callback);
if (self.connectionType == 'serial') chrome.serial.getControlSignals(this.connectionId, callback);
},
setControlSignals: function (signals, callback) {
chrome.serial.setControlSignals(this.connectionId, signals, callback);
if (self.connectionType == 'serial') chrome.serial.setControlSignals(this.connectionId, signals, callback);
},
send: function (data, callback) {
var self = this;
Expand All @@ -208,7 +280,8 @@ var serial = {
var data = self.outputBuffer[0].data,
callback = self.outputBuffer[0].callback;

chrome.serial.send(self.connectionId, data, function (sendInfo) {
var sendFn = (self.connectionType == 'serial') ? chrome.serial.send : chrome.sockets.tcp.send;
sendFn(self.connectionId, data, function (sendInfo) {
// track sent bytes for statistics
self.bytesSent += sendInfo.bytesSent;

Expand All @@ -229,7 +302,7 @@ var serial = {
counter++;
}

console.log('SERIAL: Send buffer overflowing, dropped: ' + counter + ' entries');
console.log(self.LOGHEAD + 'Send buffer overflowing, dropped: ' + counter + ' entries');
}

send();
Expand All @@ -248,13 +321,15 @@ var serial = {
listeners: [],

addListener: function (function_reference) {
chrome.serial.onReceive.addListener(function_reference);
var chromeType = (serial.connectionType == 'serial') ? chrome.serial : chrome.sockets.tcp;
chromeType.onReceive.addListener(function_reference);
this.listeners.push(function_reference);
},
removeListener: function (function_reference) {
var chromeType = (serial.connectionType == 'serial') ? chrome.serial : chrome.sockets.tcp;
for (var i = (this.listeners.length - 1); i >= 0; i--) {
if (this.listeners[i] == function_reference) {
chrome.serial.onReceive.removeListener(function_reference);
chromeType.onReceive.removeListener(function_reference);

this.listeners.splice(i, 1);
break;
Expand All @@ -266,13 +341,15 @@ var serial = {
listeners: [],

addListener: function (function_reference) {
chrome.serial.onReceiveError.addListener(function_reference);
var chromeType = (serial.connectionType == 'serial') ? chrome.serial : chrome.sockets.tcp;
chromeType.onReceiveError.addListener(function_reference);
this.listeners.push(function_reference);
},
removeListener: function (function_reference) {
var chromeType = (serial.connectionType == 'serial') ? chrome.serial : chrome.sockets.tcp;
for (var i = (this.listeners.length - 1); i >= 0; i--) {
if (this.listeners[i] == function_reference) {
chrome.serial.onReceiveError.removeListener(function_reference);
chromeType.onReceiveError.removeListener(function_reference);

this.listeners.splice(i, 1);
break;
Expand Down
7 changes: 6 additions & 1 deletion manifest.json
Expand Up @@ -22,7 +22,7 @@
"pages": ["tabs/map.html"]
},

"permissions": [
"permissions": [
"https://maps.googleapis.com/*",
"https://*.github.com/",
"https://*.githubusercontent.com/",
Expand All @@ -40,6 +40,11 @@
{"vendorId": 1155, "productId": 57105}
]}
],
"sockets": {
"tcp": {
"connect": "*:*"
}
},

"icons": {
"128": "images/bf_icon_128.png"
Expand Down