Linux Virtual Serial Port Not Showing Up In List - linux

None of the solutions from this similar problem help: Socat virtual serial port not recognized
I'm creating a virtual serial port using socat and then linking it properly, but node-serialport is not picking it up.
$ sudo socat -d -d pty,raw,echo=0,link=/dev/ttyS10 pty,raw,echo=0,link=/dev/ttyS11
2015/09/01 01:36:44 socat[22927] N PTY is /dev/pts/9
2015/09/01 01:36:44 socat[22927] N PTY is /dev/pts/10
2015/09/01 01:36:44 socat[22927] N starting data transfer loop with FDs [3,3] and [5,5]
In node using node-serialport:
$ cat test.js
var serialPort = require("serialport");
serialPort.list(function (err, ports) {
if (err) {
console.log(err);
return;
}
ports.forEach(function(port) {
console.log(port.comName);
console.log(port.pnpId);
console.log(port.manufacturer);
});
});
$ node test.js
{ [Error: ENOENT, scandir '/dev/serial/by-id'] errno: -2, code: 'ENOENT', path: '/dev/serial/by-id' }
You'll notice that no serial port is being picked up. What can I do to be able to list this port?

Related

localhost, 127.0.0.1 does not work between 2 containers in a kubernetes node

I have 2 containers in a Kubernetes node.
microk8s kubectl exec -it worker-statefulset-name-0 -c worker-container bash
To connect to the first. It is a python container with a socket interface, not http. Observe the IP address
python
>>> import socket
>>> socket.gethostbyname(socket.gethostname())
'10.1.56.41'
The second is a nodejs container. Opening a socket between these 2 containers works as expected when using the ip address:
microk8s kubectl exec -it worker-statefulset-name-0 -c worker-health-monitor bash
nodejs
socket_utilities.promise_open_socket_send_get_ack('10.1.56.41', 55001, data)
.then((result)=>{console.log(result)})
> { result: 'got work' }
but fails if I use localhost or 127.0.0.1
socket_utilities.promise_open_socket_send_get_ack('127.0.0.1', 55001, data).then((result)=>{console.log(result)})
> 1661547443715ECONNREFUSED
(node:21) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:55001
> socket_utilities.promise_open_socket_send_get_ack('localhost', 55001, data).then((result)=>{console.log(result)})
> 1661547509627ECONNREFUSED
(node:21) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:55001
The promise_open_socket_send_get_act is simply a wrapper around net.createConnection
function promise_open_socket_send_get_ack(host, port, data) {
return new Promise((resolve, reject) => {
try {
//console.log("createConnection host=" + host + ", port:" + port + ", my ip is " + get_my_IPv4_addresses())
const client = net.createConnection({ host: host, port: port })
let data_from_server = null
let to = null
client.on("error", (e) => {
if (e.errno == "ECONNREFUSED") {
console.log(new Date().getTime()+"ECONNREFUSED")
}
clearTimeout(to)
reject(e)
})
....
I know the nodejs container is on the same node as the python container. They are created as part of the same StatefulSet, but to be sure:
> socket_utilities.get_my_IPv4_addresses()
[ '10.1.56.41', eth0: [] ]
function get_my_IPv4_addresses(){
const nets = os.networkInterfaces();
const results = []
for (const name of Object.keys(nets)) {
for (const net of nets[name]) {
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
if (net.family === 'IPv4' && !net.internal) {
if (!results[name]) {
results[name] = [];
}
results.push(net.address);
}
}
}
return results
}
So a kludgy solution is to use get_my_IPv4_addresses and open the socket with this.
Aside from being kludgy, I fear I do not understand something and will run into problems in the future.
So how do I get 127.0.0.1 to work correctly in a kubernetes nodejs container?

Cloud9: Could not find an open port

I'm new to NodeJS and trying to set up an existing project (developed by someone else) in Cloud9 IDE (I'm using an older Cloud9 account; so not running on AWS). I've pulled the git and installed everything. This all seemed to go without problems.
To run the app locally, outside of Cloud9, you would start the server with npm run start (I know from the person who developed the app, this works for him). But I want to set it up in Cloud9, and in Cloud9 it is necessary to set some variables first (if I don't define the host first, it gives the error "Invalid Host header"). Therefore, I use the following two commands:
export HOST=$C9_HOSTNAME && export PORT=8080
npm run start
The npm run start produces the error:
Could not find an open port at appname-username.c9users.io.
Network error message: listen EADDRNOTAVAIL 35.189.252.103
I believe I have the port correct, considering https://docs.c9.io/docs/run-an-application. I’ve also tried the values 8081, 8082 and $PORT but none of these work.
Any ideas how I could get the Cloud9 local preview working?
Upon request some lines from start.js:
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
const HOST = process.env.HOST || '0.0.0.0';
console.log(`1. The host is ${HOST} on port ${DEFAULT_PORT}`); //ADDED
choosePort(HOST, DEFAULT_PORT)
.then(port => {
console.log(`2. The host is ${HOST} on port ${DEFAULT_PORT}`); //ADDED
if (port == null) {
// We have not found a port.
return;
}
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
const urls = prepareUrls(protocol, HOST, port);
// Create a webpack compiler that is configured with custom messages.
const compiler = createCompiler(webpack, config, appName, urls, useYarn);
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
// Serve webpack assets generated by the compiler over a web sever.
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
// Launch WebpackDevServer.
devServer.listen(port, HOST, err => {
if (err) {
return console.log(err);
}
if (isInteractive) {
clearConsole();
}
console.log(chalk.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
});
})
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
netstat --listen responds with the following information:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp6 0 0 [::]:ssh [::]:* LISTEN
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] STREAM LISTENING 1533837857 /home/ubuntu/.c9/6614254/collab.sock
unix 2 [ ACC ] STREAM LISTENING 1533835235 /home/ubuntu/.c9/bridge.socket
unix 2 [ ACC ] STREAM LISTENING 1533836998 /tmp/tmux-1000/cloud92.2
The function choosePort is part of the node module "react-dev-utils" and reads as follows:
function choosePort(host, defaultPort) {
return detect(defaultPort, host).then(
port => new Promise(resolve => {
if (port === defaultPort) {
return resolve(port);
}
if (isInteractive) {
clearConsole();
const existingProcess = getProcessForPort(defaultPort);
const question = {
type: 'confirm',
name: 'shouldChangePort',
message: chalk.yellow(
`Something is already running on port ${defaultPort}.` +
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
) + '\n\nWould you like to run the app on another port instead?',
default: true,
};
inquirer.prompt(question).then(answer => {
if (answer.shouldChangePort) {
resolve(port);
} else {
resolve(null);
}
});
} else {
console.log(
chalk.red(`Something is already running on port ${defaultPort}.`)
);
resolve(null);
}
}),
err => {
throw new Error(
chalk.red(`Could not find an open port at ${chalk.bold(host)}.`) +
'\n' +
('Network error message: ' + err.message || err) +
'\n'
);
}
);
}
I did some googling on this and I think the issue might be with the host value you are setting. Per this Cloud9 support thread which references a similar error:
...You need to use 0.0.0.0 instead since c9user.io is the public address of the proxy. Or modify your /etc/hosts file. echo "0.0.0.0 $C9_HOSTNAME" | sudo tee -a /etc/hosts
So, try setting the host to 0.0.0.0 instead of the public hostname:
export HOST=0.0.0.0 && export PORT=8080 && npm run start
Also just found this on the support page you linked to:
If you're developing a server application, please note that you need to listen to 0.0.0.0 ($IP) and 8080 ($PORT). Listening to this port will enable your app to be viewable at http://-.c9users.io
Listening on 0.0.0.0 should resolve the issue.
Edit (in response to additional error being returned):
For the "Invalid host header" error, I think you're on the right track with setting disableHostCheck to true, but your npm script command isn't likely adhering to the flag from.the CLI. There are probably a few ways to get that flag passed, but the simplest might be to update your code to set the option when creating the dev server. Keep in mind this is just a quick fix to see if we can get it to work. It would be better to update the createDevServerConfig function to set the option:
const devServer = new WebpackDevServer(compiler, { ...serverConfig, disableHostCheck: true});
Another edit:
The disableHostCheck option is insecure and can open you up to vulnerabilities. It's considered a quick fix when testing locally and should only be used in a closed network. To fix the"Invalid host header" in an exposed environment, use the public option, where public is your DNS host name or public IP address:
const devServer = new WebpackDevServer(compiler, { ...serverConfig, public: process.env.PUBLIC_HOST }
You can then have this value passed in via the CLI environment like your other vars:
export HOST=0.0.0.0 && export PORT=8080 && export PUBLIC_HOST=$C9_HOSTNAME:8080 && npm run start
Disclaimer: I don't think the changes above are the best way to go about doing this (it would likely be better to update the createDevServerConfig function, but they should resolve your issues. More information on the disableHostCheck option can be found here, here, and here.

Unable to read serial port with node-serialport on raspberry pi

I'm using a raspberry pi (the first model) running on Jessy (8), node v0.12.6 and serialport 2.0.6. I have connected the pin Rx on the pin Tx of the physical serial port.
It's working fine with cat /dev/ttyAMA0 and echo "Hello" > /dev/ttyAMA0
The writing on the serial port with node-serialport is fine. I am using the code bellow (and using cat to read this) (source: https://www.npmjs.com/package/serialport)
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyAMA0", {
baudrate:9600,
databits: 8,
parity: 'none',
stopBits: 1,
flowControl: false,
parser: serialport.parsers.readline("\n"),
});
sp.on('open', function() {
console.log("sending");
sp.write("Hello");
});
I am now trying to read my serial port with node-serialport, but it doesn't work. When I am trying to read the serialport with node-serialport (and using echo to write on it), the data from echo are not writen in the terminal. The terminal only says "open". I am using this code, same source:
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyAMA0", {
baudrate:9600,
databits: 8,
parity: 'none',
stopBits: 1,
flowControl: false,
parser: serialport.parsers.readline("\n"),
});
sp.on('open', function() {
console.log('open');
sp.on('data', function(data) {
console.log('data received: ' + data);
});
});
I don't understand what's happening here. Any help would be much appreciated!
Thanks a lot! :)
Nicolas
Problem solved, shell and kernel messages on the serial connection wasn't disabled with the raspi-config tool to prevent the kernel from using the serial port. (sudo raspi-config, Advanced-Options, Serial, No)
Thanks to fivdi : https://github.com/voodootikigod/node-serialport/issues/715
Nicolas

Trying to use fs.chmod with node.js

I have this device that will be connected to a computer, and the system i'm developing depends a lot on that device. However, since it will be installed in different places then they might use one usb port or another, and in my case, everytime i plug in the device i have to do a chmod 777 for it to work.
So, i made this file with possible ports the device could be connected to, and it goes like
/dev/ttyUSB0,/dev/ttyUSB1,/dev/ttyUSB2
I read it with this function
var puertoLect = function(callback){
//Busca en el archivo ports la lista de puertos probables donde se encuentra el modem receptor
fs.readFile('ports.txt', 'UTF-8', function (err, data) {
if (err){
console.log(err);
}else{
callback({data:data});
}
});
}
And then I use this function to split it into an array and do a chmod for each value of the array.
var puertoEnable = function(){
puertoLect(function(puertos){
var singlePort = String(puertos.data).split(',');
for(var i=0;i<singlePort.length;i++){
fs.chmod(singlePort[i], '0777', function (err){
if(err){
console.log(singlePort[i]+': Not Enabled');
console.log(err);
}else{
console.log(singlePort[i]+': Enabled');
}
});
}
});
}
What i'm trying to do with this latest function is test if it works. So that if it finds the exact port then it will enabled it and let me know it did, and if it doesn't, just tell me it didn't. However it ends up returning this:
undefined: No se pudo Habilitar
{ [Error: EPERM, chmod '/dev/ttyS24'] errno: 50, code: 'EPERM', path: '/dev/ttyS24' }
undefined: No se pudo Habilitar
{ [Error: ENOENT, chmod '/dev/ttyUSB0'] errno: 34, code: 'ENOENT', path: '/dev/ttyUSB0' }
undefined: No se pudo Habilitar
{ [Error: ENOENT, chmod '/dev/ttyS25
'] errno: 34, code: 'ENOENT', path: '/dev/ttyS25\n' }
I don't know what EPERM or ENOENT mean, however, when I tried to do this, the device was not connected (on purpose), because the files ttyS25 and ttyS24 already exist in "/dev". And ttyUSB0 will only appear when i connect the device.
So, I have to try and find a way to check the path to see if the file i'm trying to chmod exists. If it does, then do the chmod and return a variable with the path so i can use it in my serialPort configuration.
If anyone could help i'd appreciate it.

node.js and serialport cannot list any ports

I am trying to open a serial port on ubuntu using node.js.
I cannot seem to open any ports nor can I list any.
Here is my code for list:
var serialport = require("serialport"),
serialport.list(function (err, ports) {
console.log("thisis the list callback");
ports.forEach(function(port) {
console.log(port.comName);
console.log(port.pnpId);
console.log(port.manufacturer);
});
});
I get no output and no errors. It just returns zero ports. I have two com ports recognized by the OS:
rd#mediaplayer:~/cotto$ dmesg | grep tty
[ 0.000000] console [tty0] enabled
[ 0.732717] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 0.804533] serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[ 1.097341] 00:0a: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 1.168637] 00:0b: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
If I try to explicitly open a com port I get a "not open" error when using it. I assume this is because node serialport does not "see" any of my com ports:
rd#mediaplayer:~/cotto$ sudo node sptest.js
opening serial port: /dev/ttyS0
events.js:72
throw er; // Unhandled 'error' event
^
Error: Serialport not open.
at SerialPortFactory.SerialPort.write (/home/rd/node_modules/serialport/serialport.js:246:17)
at Object.<anonymous> (/home/rd/cotto/sptest.js:33:8)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:902:3
The code to open the serial port is here for reference:
var serialport = require("serialport"),
SerialPort = serialport.SerialPort;
var portName = "/dev/ttyS0";
console.log("opening serial port: " + portName);
var myPort = new SerialPort(portName, { baudrate: 9600,
});
myPort.write("Hello World\r\n");
Is there anything special I need to do to expose the linux com ports to node serialport?
I have a similar problem. I can not list the ports on a raspberry pi. the same code runs just fine on windows.
On the other hand i can open the port and read and write to it without any problem.
you could try:
var SerialPort = require("serialport").SerialPort
var serialPort = new SerialPort("/dev/ttyS0", {
baudrate: 57600
}, false); // this is the openImmediately flag [default is true]
serialPort.open(function (error) {
if ( error ) {
console.log('failed to open: '+error);
} else {
console.log('open');
serialPort.on('data', function(data) {
console.log('data received: ' + data);
});
serialPort.write("ls\n", function(err, results) {
console.log('err ' + err);
console.log('results ' + results);
});
}
});
to see if you get any errors when opening.
EDIT:
for the time being i go with something like this to list the ports, which is a bit hacky but anyways...
var exec = require('child_process').exec;
exec('dmesg | grep tty', function (error, stdout, stderr) {
stdout.split("\n").forEach(function(line){
var words=line.split(" ");
if(words.length>=6 && words[6].substring(0,3)=="tty"){
console.log(words[6])
}
});
});
EDIT 2:
My device is /dev/ttyAMA0
and in /lib/udev/rules.d/60-persistent-serial.rules i see this line:
KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="persistent_serial_end"
which i suspect is the reason its not listed under /dev/serial/by-id. Any ideas what i can do about this?
With the newer versions of node serialport the write will queue until the port is open, however with version 2 and maybe 3 you need to wait for the port to be open before writing to it. The serialport docs for the older versions talk about waiting for the open event before writing.
For version 3 https://github.com/EmergingTechnologyAdvisors/node-serialport/blob/3.1.2/README.md#opening-a-port
I know this question is a bit old, but I wanted to leave an answer for anyone else hitting this problem. I highly recommend you use at least serialport version 3 as it fixes major bugs with v2 with small api changes, however 4 and 5 are faster, use less memory and support backpressure and have more bug fixes.

Resources