Why my CGI Script can't access to ttyUSB0? - linux

I'm having a CGI script in C language, which open the serial port ttyUSB0 in my Raspberry pi, send a data at my device and get it response.
This script perform correctly when i'm launch it manually in the terminal but my web page can't access to this port to open it.
My code :
int main (void) {
printf("Content-type: text/html\n\n");
const int fd = open ("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_SYNC);
if (fd == -1)
{
printf ("error %d opening %s: %s", errno, "ttyUSB0", strerror (errno));
return 0;
}
And the response in the web page : "error 13 opening ttyUSB0: Permission denied"
And below the output of the command "id -Gn pi" :
pi adm tty uucp dialout cdrom sudo audio video plugdev games users input netdev spi i2c gpio lpadmin
Thanks.

The command below solved my problem :
sudo adduser www-data dialout

Related

Serial port information like manufacturer/description is unavailable on Windows but available on Linux, using node.js with serialport package

I wrote a node.js script that connects to an external device via an USB serial port. The external device uses a chip from FTDI that converts to and from USB signals. I programmed basic device information like manufacturer, description, serial number etc. to that chip with FT_Prog, assuming this information is provided when I read the port information in my node.js script (using serialport package).
However it seems that I cannot retrieve that information on my Windows system. When I read the serial port information I am connected to, the manufacturer always is FTDI, description is undefined. But when using a Linux system, that information is available.
This seems to be the same topic. But as far as I understand I should be able to get the information as soon as I programmed the chip with FT_Prog. But it's still not working.
So why is it, that I cannot retrieve this information on Windows, but on Linux?
Thanks in advance!
EDIT
The code I am using:
'use strict';
const serialPort = require('serialport');
searchFscPort();
function searchFscPort() {
serialPort.list().then(ports => {
for(let i = 0; i < ports.length; i++) {
if(ports[i].manufacturer == 'FTDI' || ports[i].manufacturer == 'ME') {
console.log('Path: ', ports[i].path);
console.log('Manufacturer: ', ports[i].manufacturer);
console.log('SN: ', ports[i].serialNumber);
console.log('lID: ', ports[i].locationId);
console.log('pID: ', ports[i].productId);
console.log('vID: ', ports[i].vendorId);
console.log('pnpID: ', ports[i].pnpId);
return;
}
}
});
}
Result on Windows:
path: COM4
manufacturer: FTDI
SN: 110
lID: undefined
pID: 6015
vID: 0403
pnpID: FTDIBUS\VID_0403+PID_6015+110A\0000
Result on Linux:
path: /dev/ttyUSB0
manufacturer: ME
SN: 110
lID: undefined
pID: 6015
vID: 0403
pnpID: usb-ME_FSC1_7_110-if00-port0
This is what I have programmed into the chip:
By the way, there seems to be no node.js property to get the "Manufacturer Desc"?

How to get return status of ssh command when i use popen() to run ssh?

My indent to create reverse ssh tunnel/ssh port forwarding mechanism.
Here is the actual reverse ssh command :
ssh -fN -R 101:localhost:22 computer#123.123.0.27 -p 2320
I need to run this command from my C api using popen(), i was implemented like as follows.
Note: system's public & private keys are already shared i.e, no need to give the password.
int create_tunnel (void)
{
FILE *fptr_ssh = NULL;
char sshcmd[100] = {0};
char response[100] = {0};
sprintf(sshcmd, "ssh -fN -R 101:localhost:22 computer#123.123.0.27 -p 2320");
fptr_ssh = popen(sshcmd, "r"); /* Executing ssh */
if(NULL == fptr_ssh) {
perror("popen failed");
return -1;
}
/* Getting message from fp */
if(!fgets(response, (sizeof(response)-1), fptr_ssh)) {
perror("fgets failed");
return -1;
}
printf("Msg: %s\n", response);
pclose(fptr_ssh);
return 0;
}
Success Case: if every thing fine, port forwarding will success no problem.
In Failure Case : Consider this example:
if no connectivity following message will displays in stdout (terminal).
ssh: connect to host 123.123.0.27 port 2320: Network is unreachable
but i unable to get any information from my C api /fgets() from file pointer fptr_ssh.
It return success and no message from fgets.
fgets failed: Success

GPIO over Raspberry Pi 3 model B using Node.js

I am trying to blink the led using raspberry pi 3 model B,
I have all the required modules installed on my machine i.e. npm , nodejs , pi-gpio (fixed the minor changes to detect the gpio )
Code is :
var gpio = require("pi-gpio");
gpio.open(16, "output", function(err) {
gpio.write(16, 1, function() {
gpio.close(16);
});
});
//reading the data on the pin i.e pin : 16
gpio.open(16, "output", function (err) {
gpio.read(16, function (err, value) {
console.log("Data is "+ value);
gpio.close(16);
});
});
But above code throws error while running it,
node app.js
error :
Error when trying to open pin 16
gpio-admin : could not flush data to /sys/class/gpio/export : Device or resource busy
Thanks in advance
Any links where I can see the circuit diagram and code.
Concern : I dont want to change the platform i.e. node.js
pi-gpio which i am using is : https://github.com/rakeshpai/pi-gpio
pi-gpio is just writing to the GPIO device in the background so you can skip node.js and pi-gpio and do the same manually for testing purposes.
Example:
gpio.open(16, ...
# is the same as writing in terminal:
echo 16 > /sys/class/gpio/export
and
... "output" ...
# is the same as writing in terminal:
echo "out" > /sys/class/gpio/gpio16/direction
etc.
First of all, try rebooting the Pi and see if that takes care of the issue.
If that didn't help, try manually closing/unexporting the pin as root and then re-run the script.
# unexport the pin as root in case something's holding on to it
sudo echo 16 > /sys/class/gpio/unexport
The commands below basically constitute the pi-gpio API. These lines are what you would put in a shell script to control your GPIOs. Test them without sudo first in the order I've written them and if they don't work, try with sudo. If they still don't work, I think you have a wiring/hardware problem or need to change some system settings elsewhere.
# unexport the pin
sudo echo 16 > /sys/class/gpio/unexport
# export it again
sudo echo 16 > /sys/class/gpio/export
# make it an output
sudo echo "out" > /sys/class/gpio/gpio16/direction
# write a HIGH - is the LED on now?
sudo echo 1 > /sys/class/gpio/gpio16/value
# read the value of the pin - is it 1 after writing a 1 to the pin?
cat /sys/class/gpio/gpio16/value
# write a LOW - did it turn off?
sudo echo 0 > /sys/class/gpio/gpio16/value
Let's use 'rpio' module instead of 'pi-gpio'.
https://github.com/jperkin/node-rpio
It works fine on Pi3, zero etc.
As pi-gpio has already fixed the old and new sysPath (issue# https://github.com/rakeshpai/pi-gpio )
But it is dependent on quick2wire-gpio-admin lib.
So small fix required in quick2wire-gpio-admin
git clone https://github.com/quick2wire/quick2wire-gpio-admin.git
cd quick2wire-gpio-admin
The src/gpio-admin.c has
int size = snprintf(path, PATH_MAX, "/sys/devices/virtual/gpio/gpio%u/%s", pin, filename);
replace with :
int size = snprintf(path, PATH_MAX, GPIO_CLASS_PATH "gpio%u/%s", pin, filename);
Then go to cd quick2wire-gpio-admin directory
Then sudo make uninstall and
sudo make install
Then it is running fine.
The Code for is as follows : (filename : blinking12.js)
var gpio = require("pi-gpio");
var intervalId;
var durationId;
var gpioPin = 12;
gpio.open(gpioPin, "output", function (err) {
var on =1 ;
console.log("GPIO pin "+gpioPin+" is open toggling LED every 100mS for 10s");
intervalId = setInterval( function () {
gpio.write(gpioPin, on, function () {
on = (on + 1)% 2;
});
}, 100);
});
durationId = setTimeout (function () {
clearInterval(intervalId);
clearTimeout(durationId);
console.log('10 seconds blinking completed');
gpio.write(gpioPin, 0, function () {
gpio.close(gpioPin);
//process.exit(0);
});
}, 10000);
To run the code :
node blinking12.js
Output on my machine :
GPIO pin 12 is open toggling LED every 100mS for 10s
10 seconds blinking completed

linux open a usb device failed errno EACCES

I want to connect with a usb device on linux. and I use libusb to connect. but when I call usb_open(dev) ,it return NULL, find check the libusb source,in linux.c I find the implementaiton of usb_open.as
int usb_os_open(usb_dev_handle *dev)
{
char filename[PATH_MAX + 1];
snprintf(filename, sizeof(filename) - 1, "%s/%s/%s",
usb_path, dev->bus->dirname, dev->device->filename);
dev->fd = open(filename, O_RDWR);
if (dev->fd < 0) {
dev->fd = open(filename, O_RDONLY);
if (dev->fd < 0)
USB_ERROR_STR(-errno, "failed to open %s: %s",
filename, strerror(errno));
}
return 0;
}
so it failed when open, and errno is set EACCES. But I check the device permission like this:
crw-rw-rw- 1 root root 189, 139 8月 26 10:38 /dev/bus/usb/002/012
so , is there any other conditions limit to open the device?

How to open tap device on android using native code C?

I am trying build a VPN client mobile for Android based applications that connect to virtual infrastructure over VPN tunnel. I have a similar application for Linux/Windows and I know how to open a tun/tap device (open /dev/net/tun). How do we do the same for Android using C ?
Also what does the class VpnService in the android.net API do exactly ?
If you still wants to open a tunnel on android - native C, I suggest to take a look how android itself open it (from file: services/jni/com_android_server_connectivity_Vpn.cpp)
static int create_interface(int mtu)
{
int tun = open("/dev/tun", O_RDWR | O_NONBLOCK);
ifreq ifr4;
memset(&ifr4, 0, sizeof(ifr4));
// Allocate interface.
ifr4.ifr_flags = IFF_TUN | IFF_NO_PI;
if (ioctl(tun, TUNSETIFF, &ifr4)) {
ALOGE("Cannot allocate TUN: %s", strerror(errno));
goto error;
}
// Activate interface.
ifr4.ifr_flags = IFF_UP;
if (ioctl(inet4, SIOCSIFFLAGS, &ifr4)) {
ALOGE("Cannot activate %s: %s", ifr4.ifr_name, strerror(errno));
goto error;
}
// Set MTU if it is specified.
ifr4.ifr_mtu = mtu;
if (mtu > 0 && ioctl(inet4, SIOCSIFMTU, &ifr4)) {
ALOGE("Cannot set MTU on %s: %s", ifr4.ifr_name, strerror(errno));
goto error;
}
return tun;
error:
close(tun);
return SYSTEM_ERROR;
}
The VpnService class does exactly what you need. It provides an access to the tun device. You cannot directly open /dev/net/tun without having root rights. See the ToyVPN example project or an open source VPN project like OpenVPN for Android.
You need to be root to open tuntap on Android.
this->_handle = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
if (this->_handle < 0) {
this->_handle = open("/dev/net/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
}
For details:
https://android.googlesource.com/platform/frameworks/base.git/+/android-4.3_r2.1/services/jni/com_android_server_connectivity_Vpn.cpp
Supplement:
/dev/tun and /dev/net/tun both require an attempt to open the device. There are too many distributions of Android, each with individual changes, and tuntap devices are also slightly different.
Native-code may not be a good idea to open a tuntap!

Resources