Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
70418e6
Refactored to remove the need for the transmissionId variable.
PropGit Sep 11, 2018
8110d51
Disabled Nagle timer.
PropGit Sep 11, 2018
4576f44
Removed conversion from string or buffer to ArrayBuffer inside of sen…
PropGit Sep 12, 2018
921431f
Increased max packet delay for debugging and fixed max packet size to…
PropGit Sep 13, 2018
6361b52
Added byPHID and byPTID port identifier types and enhanced serial onR…
PropGit Sep 13, 2018
7f7cfb6
Fixed bugs and added better error message.
PropGit Sep 13, 2018
0f21f8a
Patched loose ends in loadPropeller() so that debug messages transpor…
PropGit Sep 14, 2018
b2f50d2
Added protection to debugReceiver()'s sendDebug() to prevent sending …
PropGit Sep 17, 2018
5fb281a
Fixed bug causing downloads to fail due to previous execution's debug…
PropGit Sep 19, 2018
6440537
Compressed dataSource into ternary logic and restructured to do zero …
PropGit Sep 21, 2018
a207289
Set default port mode to 'none' throughout code and updated serialTer…
PropGit Sep 21, 2018
701f1af
Removed received-data console output.
PropGit Sep 21, 2018
2ddfef9
Added openSocket() and updated related code to open HTTP or Telnet po…
PropGit Sep 27, 2018
918297b
Combined wired and wireless portions of serialTerminal().
PropGit Sep 28, 2018
8d81c1a
Fixed bug in http.js from failure to check chrome.runtime.lastError. …
PropGit Sep 30, 2018
3c4cba3
Removed sockets[] list and related management code. This required so…
PropGit Oct 1, 2018
4add10a
Added more socket-related debugging statements.
PropGit Oct 1, 2018
3077ebf
Resolved two separate sendPortList() calls into one intent. Added so…
PropGit Oct 1, 2018
1a0a9cd
Fixed socket handling bugs.
PropGit Oct 1, 2018
d9ffad9
Removed some old debug statements in openSocket() and send().
PropGit Oct 1, 2018
1483585
Separated the wired port scanning process from the port list sending …
PropGit Oct 1, 2018
964f68b
Made wired and wireless interval names consistent.
PropGit Oct 1, 2018
9a98ff9
Fixed bug in port.js causing colliding debug streams when there are m…
PropGit Oct 2, 2018
2b37689
Updated version to v0.9.1. Removed two socket debug messages.
PropGit Oct 2, 2018
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: 10 additions & 4 deletions http.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,16 @@ PSocket.prototype.write = function(data) {
var that = this;
return new Promise(function(resolve, reject) {
chrome.sockets.tcp.send(that.socketId, data, function(info) {
if (info && info.resultCode >= 0)
resolve(info.bytesSent);
else
reject(new Error('chrome sockets.tcp error ' + (info && info.resultCode)));
if (!chrome.runtime.lastError) {
if (info.resultCode === 0)
resolve(info.bytesSent);
else
reject(new Error('Socket TCP error ' + (info.resultCode)));
} else {
let emsg = 'Socket ID ' + that.socketId + ' error: ' + chrome.runtime.lastError.message;
console.log(emsg);
reject(new Error(emsg));
}
});
});
};
Expand Down
211 changes: 99 additions & 112 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,14 @@ var platform = pfUnk;
Unknown ChromeOS Linux macOS Windows */
portPattern = ["", "/dev/ttyUSB", "dev/tty", "/dev/cu.usbserial", "COM"];

// A list of connected websockets.
var sockets = [];

// Http and ws servers
var server = new http.Server();
var wsServer = new http.WebSocketServer(server);
var isServer = false;

// Keep track of the interval that sends the port list so it can be turned off
var portListener = null;
// Timer(s) to scan and send the port list
var wScannerInterval = null;
var portLister = [];

// Is verbose loggin turned on?
var verboseLogging = false;
Expand Down Expand Up @@ -226,10 +224,14 @@ document.addEventListener('DOMContentLoaded', function() {

function connect() {
connect_ws($('bpc-port').value, $('bpc-url').value);
scanWPorts();
wScannerInterval = setInterval(scanWPorts, 6010); // 6010: Scan at different intervals than send processes
}

function disconnect() {
closeSockets();
clearInterval(wScannerInterval);
wScannerInterval = null;
}

function updateStatus(connected) {
Expand All @@ -254,36 +256,17 @@ function closeServer() {
isServer = false;
}

function findSocketIdx(socket) {
/* Return index of socket in sockets list
Returns -1 if not found*/
return sockets.findIndex(function(s) {return s.socket === socket});
}

function closeSockets() {
// Close all sockets and remove them from the list
while (sockets.length) {
sockets[0].socket.close();
deleteSocket(0);
}
}

function deleteSocket(socketOrIdx) {
/* Delete socket from lists (sockets and ports)
socketOrIdx is socket object or index of socket record to delete*/
let idx = (typeof socketOrIdx === "number") ? socketOrIdx : findSocketIdx(socketOrIdx);
// log("Deleting socket at index " + idx, mDbug);
if (idx > -1 && idx < sockets.length) {
// Clear port's knowledge of socket connection record
if (sockets[idx].portIdx > -1) {
// log(" Clearing port index " + sockets[idx].portIdx + " reference to this socket", mDbug);
ports[sockets[idx].portIdx].bSocket = null;
ports[sockets[idx].portIdx].bSocketIdx = -1;
// Close all sockets and remove them from the ports and portLister lists
ports.forEach(function(p) {
if (p.bSocket) {
p.bSocket.close();
p.bSocket = null;
}});
while (portLister.length) {
clearInterval(portLister[0].scanner);
portLister.splice(0, 1);
}
// Delete socket connection record and adjust ports' later references down, if any
sockets.splice(idx, 1);
ports.forEach(function(v) {if (v.bSocketIdx > idx) {v.bSocketIdx--}});
}
}

function connect_ws(ws_port, url_path) {
Expand All @@ -308,14 +291,7 @@ function connect_ws(ws_port, url_path) {

wsServer.addEventListener('request', function(req) {
var socket = req.accept();
// log("Adding socket at index " + sockets.length, mDbug);
sockets.push({socket:socket, portIdx:-1});

//Listen for ports
if(portListener === null) {
portListener = setInterval(function() {sendPortList();}, 5000);
}


socket.addEventListener('message', function(e) {
if (isJson(e.data)) {
var ws_msg = JSON.parse(e.data);
Expand All @@ -329,7 +305,11 @@ function connect_ws(ws_port, url_path) {
serialTerminal(socket, ws_msg.action, ws_msg.portPath, ws_msg.baudrate, ws_msg.msg); // action is "open", "close" or "msg"
// send an updated port list
} else if (ws_msg.type === "port-list-request") {
sendPortList();
// Send port list now and set up scanner to send port list on regular interval
// log("Browser requested port-list for socket " + socket.pSocket_.socketId, mDbug);
sendPortList(socket);
let s = setInterval(function() {sendPortList(socket)}, 5000);
portLister.push({socket: socket, scanner: s});
// Handle unknown messages
} else if (ws_msg.type === "hello-browser") {
helloClient(socket, ws_msg.baudrate || 115200);
Expand All @@ -347,14 +327,18 @@ function connect_ws(ws_port, url_path) {
});


// When a socket is closed, remove it from the list of connected sockets.
// Browser socket closed; terminate its port scans and remove it from list of ports.
socket.addEventListener('close', function() {
deleteSocket(socket);
if (sockets.length === 0) {
updateStatus(false);
clearInterval(portListener);
portListener = null;
chrome.app.window.current().drawAttention();
log("Browser socket closing: " + socket.pSocket_.socketId, mDbug);
let Idx = portLister.findIndex(function(s) {return s.socket === socket});
if (Idx > -1) {
clearInterval(portLister[Idx].scanner);
portLister.splice(Idx, 1);
}
ports.forEach(function(p) {if (p.bSocket === socket) {p.bSocket = null}});
if (!portLister.length) {
updateStatus(false);
chrome.app.window.current().drawAttention();
}
});

Expand Down Expand Up @@ -405,49 +389,57 @@ function connect_ws(ws_port, url_path) {
}

function enableWX() {
wx_scanner_interval = setInterval(function() {
discoverWirelessPorts();
ageWirelessPorts();
displayWirelessPorts();
}, 3500);
scanWXPorts();
wScannerInterval = setInterval(scanWXPorts, 3500);
}

function disableWX() {
if(wx_scanner_interval) {
clearInterval(wx_scanner_interval);
if(wScannerInterval) {
clearInterval(wScannerInterval);
$('wx-list').innerHTML = '';
}
}

function sendPortList() {
// find and send list of communication ports (filtered according to platform and type)
chrome.serial.getDevices(
function(portlist) {
let wn = [];
let wln = [];
// update wired ports
portlist.forEach(function(port) {
if ((port.path.indexOf(portPattern[platform]) === 0) && (port.displayName.indexOf(' bt ') === -1 && port.displayName.indexOf('bluetooth') === -1)) {
addPort({path: port.path});
}
});
ageWiredPorts(); //Note, wired ports age here (just scanned) and wireless ports age elsewhere (where they are scanned)

// gather separated and sorted port lists (wired names and wireless names)
ports.forEach(function(p) {if (p.isWired) {wn.push(p.path)} else {wln.push(p.path)}});
wn.sort();
wln.sort();

// report back to editor
var msg_to_send = {type:'port-list',ports:wn.concat(wln)};
for (var i = 0; i < sockets.length; i++) {
sockets[i].socket.send(JSON.stringify(msg_to_send));
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
function scanWPorts() {
// Generate list of current wired ports (filtered according to platform and type)
chrome.serial.getDevices(
function(portlist) {
let wn = [];
let wln = [];
// update wired ports
portlist.forEach(function(port) {
if ((port.path.indexOf(portPattern[platform]) === 0) && (port.displayName.indexOf(' bt ') === -1 && port.displayName.indexOf('bluetooth') === -1)) {
addPort({path: port.path});
}
});
ageWiredPorts(); //Note, wired ports age here (just scanned) and wireless ports age elsewhere (where they are scanned)
}
);
}

function scanWXPorts() {
// Generate list of current wireless ports
discoverWirelessPorts();
ageWirelessPorts();
displayWirelessPorts();
}

function sendPortList(socket) {
// Find and send list of communication ports (filtered according to platform and type) to browser via socket
let wn = [];
let wln = [];
// log("sendPortList() for socket " + socket.pSocket_.socketId, mDbug);
// gather separated and sorted port lists (wired names and wireless names)
ports.forEach(function(p) {if (p.isWired) {wn.push(p.path)} else {wln.push(p.path)}});
wn.sort();
wln.sort();

// report back to editor
var msg_to_send = {type:'port-list',ports:wn.concat(wln)};
socket.send(JSON.stringify(msg_to_send));
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
}
}
);
}


Expand All @@ -462,39 +454,34 @@ function serialTerminal(sock, action, portPath, baudrate, msg) {
// Find port from portPath
let port = findPort(byPath, portPath);
if (port) {
if(port.isWired) {
if (action === "open") {
// Open port for terminal use
openPort(sock, portPath, baudrate, 'debug')
.then(function() {log('Connected terminal to ' + portPath + ' at ' + baudrate + ' baud.');})
.catch(function() {
log('Unable to connect terminal to ' + portPath);
var msg_to_send = {type:'serial-terminal', msg:'Failed to connect.\rPlease close this terminal and select a connected serial port.'};
sock.send(JSON.stringify(msg_to_send));
});
} else if (action === "close") {
/* Terminal closed. Keep port open because chrome.serial always toggles DTR upon closing (resetting the Propeller) which causes
lots of unnecessary confusion (especially if an older version of the user's app is in the Propeller's EEPROM).
Instead, update the connection mode so that serial debug data halts.*/
port.mode = 'none';
} else if (action === "msg") {
// Message to send to the Propeller
if (port.connId) {
send(port, msg, false);
}
}
// Convert msg from string or buffer to an ArrayBuffer
if (typeof msg === 'string') {
msg = str2ab(msg);
} else {
// TODO add WX module debug passthrough functions
if (action === 'open') {

} else if (action === 'close') {

} else if (action === 'msg') {

if (msg instanceof ArrayBuffer === false) {msg = buf2ab(msg);}
}
if (action === "open") {
// Open port for terminal use
openPort(sock, portPath, baudrate, 'debug')
.then(function() {log('Connected terminal to ' + portPath + ' at ' + baudrate + ' baud.');})
.catch(function() {
log('Unable to connect terminal to ' + portPath);
var msg_to_send = {type:'serial-terminal', msg:'Failed to connect.\rPlease close this terminal and select a connected port.'};
sock.send(JSON.stringify(msg_to_send));
});
} else if (action === "close") {
/* Terminal closed. Keep wired port open because chrome.serial always toggles DTR upon closing (resetting the Propeller) which causes
lots of unnecessary confusion (especially if an older version of the user's app is in the Propeller's EEPROM).
Instead, update the connection mode so that serial debug data halts.*/
port.mode = 'none';
} else if (action === "msg") {
// Message to send to the Propeller
if ((port.isWired && port.connId) || (port.isWireless && port.ptSocket)) { //Send only if port is open
send(port, msg, false);
}
}
} else {
var msg_to_send = {type:'serial-terminal', msg:'Failed to connect.\rPlease close this terminal and select a valid serial port.'};
var msg_to_send = {type:'serial-terminal', msg:'Port ' + portPath + ' not found.\rPlease close this terminal and select an existing port.'};
sock.send(JSON.stringify(msg_to_send));
}
}
Expand Down
Loading