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?
Related
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
public class Watcher: Object
{
private int _fd;
private uint _watch;
private IOChannel _channel;
private uint8[] _buffer;
private int BUFFER_LENGTH;
public Watcher(string path, Linux.InotifyMaskFlags mask){
_buffer = new uint8[BUFFER_LENGTH];
//➔ Initialize notify subsystem
_fd = Linux.inotify_init();
if(_fd < 0){
error(#"Failed to initialize the notify subsystem: $(strerror(errno))");
}
//➔ actually adding abstraction to linux file descriptor
_channel = new IOChannel.unix_new(_fd);
//➔ watch the channel for given condition
//➔ IOCondition.IN => When the channel is ready for reading , IOCondition.HUP=>Hangup(Error)
_watch = _channel.add_watch(IOCondition.IN | IOCondition.HUP, onNotified);
if(_watch < 0){
error(#"Failed to add watch to channel");
}
//➔ Tell linux kernel to watch for any mask(for ex; access, modify) on a given filepath
var ok = Linux.inotify_add_watch(_fd, path, mask);
if(ok < 0){
error(#"Failed to add watch to path -- $path : $(strerror(errno))");
}
print(#"Watching for $(mask) on $path");
}
protected bool onNotified(IOChannel src, IOCondition condition)
{
if( (condition & IOCondition.HUP) == IOCondition.HUP){
error(#"Received hang up from inotify, can't get update");
}
if( (condition & IOCondition.IN) == IOCondition.IN){
var bytesRead = Posix.read(_fd, _buffer, BUFFER_LENGTH);
Linux.InotifyEvent *pevent = (Linux.InotifyEvent*) _buffer;
handleEvent(*pevent);
}
return true;
}
protected void handleEvent(Linux.InotifyEvent ev){
print("Access Detected!\n");
Posix.exit(0);
}
~Watcher(){
if(_watch != 0){
Source.remove(_watch);
}
if(_fd != -1){
Posix.close(_fd);
}
}
}
int main(string[] args) requires (args.length > 1)
{
var watcher = new Watcher(args[1], Linux.InotifyMaskFlags.ACCESS);
var loop = new MainLoop();
loop.run();
return 0;
}
The above code can be found on "Introducing Vala Programming - Michael Lauer"
Proof of failure:
Image displaying failure on access to the file being watched for access
Terminal 1:
./inotifyWatcher
Terminal 2:
cat
As soon as I access the file, segmentation fault occurs.
I have also tried using gdb for the cause of failure, but it's mostly cryptic for me. I am using parrot(debian/64-bit) on my machine. Also, I am new to this(stackoverflow, linux kernel program).
Vala source line numbers can be included in the binary when compiling with the --debug switch. The line numbers appear in the .debug_line DWARF section of an ELF binary:
valac --debug --pkg linux inotifyWatcher.vala
Run the binary using gdb in the first terminal:
gdb --args ./inotifyWatcher .
(gdb) run
The dot specifies to watch the current directory. Then when the current directory is access with a command like ls the watching program segmentation faults. The output from GDB is:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401a86 in watcher_onNotified (self=0x412830, src=0x40e6e0, condition=G_IO_IN) at inotifyWatcher.vala:51
51 handleEvent(*pevent);
GDB includes the line number, 51, from the source file and shows the line.
So the problem is to do with reading from the file descriptor then passing the buffer to handleEvent. You probably want to check bytesRead is greater than zero and I'm not sure about the use of pointers in this example. Explicit pointers like that should rarely need to be used in Vala, it may require a change to the binding, e.g. using ref to modify the way the argument is passed.
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
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!
I am trying to create a NodeJS library that allows usage of the BeagleBone's serial (uart) ports. Some of the pins are muxed so some configuration bits have to be written to two files. Here is my function that writes the configuration bits to enable the uart:
var setMuxForUart = function (uart, next) {
var txFd, rxFd;
var txBuf = new Buffer(uart.muxTx.config, 'ascii');
var rxBuf = new Buffer(uart.muxRx.config, 'ascii');
var txBytesWritten, rxBytesWritten;
console.log ("Configuring UART MUX for " + uart.path);
txFd = fs.openSync (MUX_PATH + uart.muxTx.path, 'w');
rxFd = fs.openSync (MUX_PATH + uart.muxRx.path, 'w');
if (txFd && rxFd) {
try {
txBytesWritten = fs.writeSync (txFd, txBuf, 0, txBuf.length, 0);
}
catch (e) {
fs.closeSync (txFd);
fs.closeSync (rxFd);
console.log ('Error Writing to file: '+ MUX_PATH + uart.muxTx.path + ' | ' + util.inspect (e));
return;
}
try {
rxBytesWritten = fs.writeSync (rxFd, rxBuf, 0, rxBuf.length, 0);
}
catch (e) {
fs.closeSync (txFd);
fs.closeSync (rxFd);
console.log ('Error Writing to file: ' + MUX_PATH + uart.muxRx.path + ' | ' + util.inspect(e));
return;
}
fs.closeSync (txFd);
fs.closeSync (rxFd);
if (txBytesWritten && rxBytesWritten) {
console.log ("Uart MUX finished configuration");
next ();
}
else {
console.log ("An error occured writing to the UART MUX.");
}
}
else {
console.log ("An error occured while opening the UART MUX files.");
}
};
Here is the file containing this funcion.
Here is the output from running this function:
root#beaglebone:~/workspace/BonescriptSerial# node BonescriptSerial.js
The "sys" module is now called "util". It should have a similar interface.
Opening Serial Port for: /dev/ttyO1
Configuring UART MUX for /dev/ttyO1
Error Writing to file: /sys/kernel/debug/omap_mux/uart1_txd | { [Error: UNKNOWN, unknown error] errno: -1, code: 'UNKNOWN', syscall: 'write' }
I have verified that the correct output is written to test files, I have tried numerous mode parameters ('0777' doesn't matter), I have tried this with the sync and async functions to no avail, and I have also tried, successfully, writing to these files in python. If you have any ideas that would help solve this problem I would be very grateful.
Here is a github repo of the project, its in its infancy right now so there isn't alot of documentation. The python version is in the repo as well.
Thanks to Ben Noordhuis on the NodeJS google group I was pointed to the following issue that was causing the problem. The device driver that I was trying to write to apparently doesn't accept arbitrary seek writes, so in order to get around that I needed to trick NodeJS into using write instead of pwrite. The trick is to tell the write command to start writing at -1 instead of 0.
fs.writeSync (txFd, txBuf, 0, txBuf.length, -1);