xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

PHP & Serial comm with RPi?

Wed Aug 08, 2018 9:20 pm

I have attempted serial comm via PHP to Arduono using a WAMP install on a PC...

serial comms seemed to work only one way.. and I was told that this was a PC issue, but on MAC/Linux, PHP serial comm works two ways without issue.

I have previously set up a RPi with Apache, MySQL and PHP...... (for some added support/features in an MQTT set-up/project)

I have never attempted to use PHP serial communication when things were on a Pi.

I will have an Arduino connected to the RPi.....
The RPi will have a webpage served up that I write.

What I would like to happen is upon clicking a link/hotspot in the hosted webpage it to send some serial data upon $_POST[] to the connected Arduino via PHP... have the webpage sit in an 'idle' state... and when the Arduino is done doing its task(s).. send out a serial message back to the RPi/PHP script.. and then change the display state/view of the hosted webpage.. (waiting for another 'user interaction' so to speak)


Re-cap:
Is 2-way serial communication possible with PHP when running on an RPi3?

Thanks

User avatar
DougieLawson
Posts: 34166
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: PHP & Serial comm with RPi?

Thu Aug 09, 2018 3:49 pm

If it runs under Apache2, Lighttpd or NGinx then you'll need to add user www-data to the dialout group.
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Thu Aug 09, 2018 9:37 pm

Thank you for the reply.

I have VERY LITTLE linux experience..... so once I get to that point of testing (in like 4 weeks I'm guessing).. I'll have to do some searching about this 'dial out group' stuff..

Clarification:

If sending OUT via PHP works normally under a default WAMP install..

using like so:

Code: Select all

<?PHP

     $pwmValue=$_POST["pwmValue"];

     exec("mode COM4 BAUD=9600 PARITY=N data=8 stop=1 xon=off");

     $fp = fopen("com4", "w");

     if (!$fp) {
        echo "Not open";
     }else {
        fwrite($fp, $pwmValue);
        fclose($fp);
     }

?>


and only the INCOMING data (from Arduino >> PHP) doesnt work...

is it still the 'dialout' group? (That allows for both incoming and outgoing data communication?


Its been a while since I installed MySQL/PHP...etc on a Raspberry Pi (and I've only done it tone time anyways).. I believe it was Apache.


Either way.. sounds like it wont be an issue (just need to 'do it')...

thanks!

User avatar
DougieLawson
Posts: 34166
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: PHP & Serial comm with RPi?

Fri Aug 10, 2018 6:51 am

Open an LXTerminal window and enter these two commands
sudo usermod -a -G dialout www-data
sudo reboot
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Thu Sep 20, 2018 9:35 pm

@DougieLawson

Thank you for the reply..

That seemed to work (no more port not open errors)..

Currently.. I have moved away from testing on my Windows PC/WAMP.. and have moved over to the RPI. Everything as far as set-up and installing apps/packages is working as expected. I have a DB with populated table(s).. and my web app is loading and displaying all dynamically generated content correctly as well.

My current testing phase is actual serial communication (2-way) from RPi/PHP >> Arduino ... and.. Arduino >> RPi/PHP

Since I can not do this in a Windows environment, I have my Arduino connected via USB to my RPI...

I load up the Chromium browser.. and my web page (drink menu) is displayed to me..

I click on the 'order' button.. (which saves the button data to a hidden field, upon $_POST.. that data is sent via PHP to the connected Arduino.)

And here is where I am currently..

* Since the Arduino is now connected via USB to the RPi.. I can not use the serial monitor to know when/what serial data is being sent BACK to the RPi...

* I believe that the Arduino is receiving the (some) serial data.. because when I click on the 'order' button and submit the webpage. I see the RX/TX lights on the Arduino start to blink.


Question:
I'm having trouble thinking of a way I can DEBUG this.. (without serial monitor or a way to see what is being sent BACK to the RPi)..

I was also not clear on how to go about reading (listening) to the serial port.. since the webpage will already be parsed after submission (to display a please wait type message)...

So I figured possibly an AJAX type of approach.. so the page can send initial serial data to connected Arduino.... display a 'please wait' message..... (All done server side via PHP after submit)

and then have a little AJAX snippet call an external PHP script that does the serial read? (also not sure where the best places to open/close the port is.. if using an external script to READ the serial port?) Can 1 php script open the port.. and another still access it?


Here is my current approach to attempt to read the SERIAL data back form the Arduino after it is finished (no telling when this data will come back from the Arduino)

Code: Select all


<?
if ($mode == 'submit') {
    
	//grab posted data (save to var)
    $drinkRecipe = $_POST['selectedDrink'];
    
    //set-up com port    
    exec("mode /dev/ttyACM0 BAUD=9600 PARITY=N data=8 stop=1 xon=off");
	//saw this on several RPi posts?  (but not sure of the difference? or why one would be used over the other?)
    //stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
    
    //open serial port
    $fp = fopen("/dev/ttyACM0", "w+"); //w = write w+ = read/write
        
    //check if open
    if (!$fp) {
        echo "Not open";
        //die();
    } else {
        //if open send data (via PHP) to connected Arduino on serial comm port 1 (ttyACM0)
        fwrite($fp, '<' . $drinkRecipe . '>');
		
		
		//arduino takes serial data, parsed it.. does it duty, 
		//and is supposed to reply back via serial to the awaiting (listening) 
		//PHP script executed via AJAX, since the front end needs to display 
		//a 'waiting' type message.. and the callback 'success' will 
		//re-direct back to menu/initial state
		?>
		<script type="text/JavaScript" language="JavaScript">
			$.ajax({
				//async: false,
				//type: "POST",
				url: "serial_listener.php",
				
				//define success handler actions
				success: function(response) {
					//alert("PHP RETURN CHECK: "+response);
					if($.trim(response) == 'complete'){
						alert("Drink making is complete... return to main menu");
						//do redirect here
					}else{
						alert("Some value other than 'complete' was returned... look into it!");
						//not sure what to do? (back to main menu anyways?)
					}
				},
				//define error handler actions
				error: function(response) {
					alert("PHP SERIAL READ FAIL: "+ 'Ready State: '+ response.readyState + ' Status: ' + response.status);
					
				}
			});	
		</script>		
		<?		        
        
        //close connection
        fclose($fp); //needed? //should this go in the external php script instead now?

    }    

}

Any suggestions to try and wrap my head around this is appreciated.

Thanks!

ghans
Posts: 7817
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: PHP & Serial comm with RPi?

Fri Sep 21, 2018 7:29 am

Linux follows the "everything is a file" motto of Unix. As soon you plug an Arduino into the Raspberry, a file should magically appear in /dev. This file represents a serial port and can be read and written to. The handling has not changed in the last 40 years so software like screen and minicom should directly work with it. Those are bidirectional serial terminals.

For Windows users PuTTY or GTKTerm might be better choices since they are graphical programs. All those programs can be installed via apt-get.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Fri Sep 21, 2018 5:19 pm

Thank you for the reply..

Are these suggestions for DEBUGGING?

I dont know what: "screen and minicom" are...

* So when trying to read/send data over serial via PHP.....I can treat things like a file..

So in the example posted above...

everything is correct?

And in my 'serial_listener.php' file.. I should.... (kinda lost on how to go about READING the serial port... because it wont be an 'instant' response...
The Arduino has to complete its task(s) before it will kick back the serial 'conformation' to the RPi/PHP script...

So what is the best way to 'wait' for this serial data to come?
Do I need to open the port again from a different script? (or is opening it in one file enough for other files to use it as well?)

Here is my PHP script/file.... (a portion of it at least).. that deals with the SUBMISSION... (ie: sending the serial data OUT to the connected Arduino)...

And then the AJAX snippet that calls another (external) .php script that does the SERIAL port listening and returns the data back to the AJAX on success callback..

Code: Select all

if ($mode == 'submit') {
    
	//grab posted data (save to var)
    $drinkRecipe = $_POST['selectedDrink'];
    
    //set-up com port    
    exec("mode /dev/ttyACM0 BAUD=9600 PARITY=N data=8 stop=1 xon=off");
	//saw this on several RPi posts?  (but not sure of the difference? or why one would be used over the other?)
    //stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
    
    //open serial port
    $fp = fopen("/dev/ttyACM0", "w+"); //w = write w+ = read/write
        
    //check if open
    if (!$fp) {
        echo "Not open";
        //die();
    } else {
        //if open send data (via PHP) to connected Arduino on serial comm port 1 (ttyACM0)
        fwrite($fp, '<' . $drinkRecipe . '>');
		
		
		//arduino takes serial data, parsed it.. does it duty, 
		//and is supposed to reply back via serial to the awaiting (listening) 
		//PHP script executed via AJAX, since the front end needs to display 
		//a 'waiting' type message.. and the callback 'success' will 
		//re-direct back to menu/initial state
		?>
		<script type="text/JavaScript" language="JavaScript">
			$.ajax({
				//async: false,
				//type: "POST",
				url: "serial_listener.php",
				
				//define success handler actions
				success: function(response) {
					//alert("PHP RETURN CHECK: "+response);
					if($.trim(response) == 'complete'){
						alert("Drink making is complete... return to main menu");
						//do redirect here
					}else{
						alert("Some value other than 'complete' was returned... look into it!");
						//not sure what to do? (back to main menu anyways?)
					}
				},
				//define error handler actions
				error: function(response) {
					alert("PHP SERIAL READ FAIL: "+ 'Ready State: '+ response.readyState + ' Status: ' + response.status);
					
				}
			});	
		</script>		
		<?		        
        
        //close connection
        fclose($fp); //needed? //should this go in the external php script instead now?

    }    

}

And the contents of the serial_listener.php script:

Code: Select all

//set-up com port    
exec("mode /dev/ttyACM0 BAUD=9600 PARITY=N data=8 stop=1 xon=off");

//open serial port
$fp = fopen("/dev/ttyACM0", "w+"); //w = write w+ = read/write

//check if open
if (!$fp) {
	echo "Not open";
	//die();
	
} else {

	while(!feof($fp)){
		$response = fread($fp, 10);
	}
	echo $response;
	fclose($fp);

}

ghans
Posts: 7817
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: PHP & Serial comm with RPi?

Sun Sep 23, 2018 7:31 am

1) All the programs i mentioned should aid you in debugging serial comms. Since you seem unfamiliar with Linux, GTKTerm or PuTTY might be the better choice instead of the other two options.
2) The "MODE" command does not exist on Linux.
3) You should put the endless loops into your JavaScript instead of the PHP files.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Sun Sep 23, 2018 3:03 pm

Thank you for the reply.

So I set everything up... Arduino , Pi, browser to load the hosted page....etc.

I click on an 'order' button...

* the page submits..
* the 'drink recipe' is sent via PHP to the serial comm
* connected Arduino gets the outgoing serial data
* Arduino parses serial data
* Arduino does what is needs to do (stepper, servo actions..returns to home)
* Arduino fires off 'complete' serial data BACK TO RPi...

And at this point.. I am NOT getting the response data.. the as the page never throws an alert/console.log..etc..

If I it the 'back' button in the browser.. I will actually see the AJAX error callback fired in the BEBUG (Web dev tools) window of FireFox..

Code: Select all

error: function(response) {
     alert("PHP SERIAL READ FAIL: "+ 'Ready State: '+ response.readyState + ' Status: ' + response.status);
}
So for some reason.. I am NOT getting an AJAX response/callback function fired.... (ever)..



To touch on your comments:

1.) MODE ok.. so this line is not valid your saying?

Code: Select all

exec("mode /dev/ttyACM0 BAUD=9600 PARITY=N data=8 stop=1 xon=off");
So what do I use?

this:

Code: Select all

stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
I dont even understand that line.. NOR all the parameters?

but perhaps this is WHY I am not receiving response data? the comm port isnt configured correctly?


2.) Why put the loop in the AJAX call? (not in the external php script that is actually doing the serial port listening?)
Wouldnt (doesnt) the AJAX call just 'wait' until the PHP response is complete in one fashion or another? and then it will execute one of the callback functions once the data arrives? (or fails) I was under the impression that is how the AJAX stuff worked?

let the php stuff does its thing... and the ajax call will handle the response when its ready/there is one.

User avatar
topguy
Posts: 4990
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: PHP & Serial comm with RPi?

Sun Sep 23, 2018 11:28 pm

Yes you use the "stty" command, you dont need to understand the parameters, but if you want : http://man7.org/linux/man-pages/man1/stty.1.html
Linux treats serialports as "terrminals" and might do certain things with some special characters, you are just turning all that OFF.

I would consider the arduino send messages back more often, not only when everything it done.
- "recipe recevied"
- "recipe ok" ( or "not ok" )
- "step 1" ( "step 2", etc )
- and then at the end "complete"

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Mon Sep 24, 2018 1:44 am

Thank you.. and I did run that line anyways.

I would like to send confirmations back more often form the Arduino..... but for now.. I need to start with '1' LOL

For the life of me could NOT get any response form the Arduino back to the RPi..

then all of a sudden 'some combination' of things started working..

with a trimmed down attempt like this:

Code: Select all

$responseValue = "";
	do{
		$incomingChar = fread($fp, 1);
		$responseValue .= $incomingChar;
	}while(strlen($responseValue) < 1);
	echo $responseValue;
However.. for some reason now (and for the last few hours).. I have not been able to get communication back.

Some combination of rebooting,, or capacitor on Arduino to Stop reset.... or 'something' happened.. and I have not been able to connect to port again.

Writing to Arduino has worked flawlessly every time. :(



If I just send back something static to check/ensure the AJAX callback are working.. and will wait until a response comes (whenever that is)..

like:

sleep(5);
echo 'complete';

the 'web page' gets the response without error every time.

So its not an AJAX/callback response thing..

its 100% the READING aspect/approach.


Random thoughts:

* opening the port in the MAIN php file (where the data gets SENT to Arduino from RPi).
-- does it needs to be closed in the file as well?
-- do I need to be opening it in the external serial_listener.php script? (answer: yes..or it throws error.. perhaps trying to pass an instance of that port via the AJAX $_POST?)

* How did I 'magically' get things working before? but can no longer connect to port reading? or get any data returned?

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Fri Sep 28, 2018 12:50 pm

Bummer! I got notification there was a reply! (was hoping someone was going to help me out here!) Must have been spam?

To-recap where I am to see if anyone has some suggestions..

Using USB CABLE from Arduino to RPi...

* Add 'www-data' user to dial-out group
# sudo usermod -a -G dialout www-data
# sudo reboot


* Give read/write permissions to the port for all users to the Raspberry Pi (potentially unsafe):

# sudo chmod 777 /dev/ttyACM0


I can NOT understand why I can SEND data out to Arduino.. but can NOT READ any data..

I open the PORT, (I know this is working because I dont get the NOT OPEN error in my PHP script.. and the SENDING of data TO Arduino works, but the subsequent READ, when the same port is STILL OPEN.. does not return anything)


Here is the MAIN (PHP) page.. that has the content. and submits the data to another PHP script (that does the port opening, and send/receiving).. and returns the data back to the MAIN PHP script.. that has an AJAX call.. and waiting callbacks to handle this response)..

If I hard code something as a response.. it works fine.. even if I add a 10 second delay.. and then hard code a response.. the AJAX callbacks handle it FINE... its the READ of the serial port that is failing.

Main script that has the AJAX handler in it (this not only SENDS data to the Arduino.. which works fine every time,,, but also should handle the RESPOSNE from the same php snippet)

Code: Select all

if ($mode == 'submit') {
    
	//grab posted data (save to var)
    $drinkRecipe = $_POST['selectedDrink'];
	
	?>	
	<div id="waitingContainer">
		<p>Please wait, your brink is being made.</p>
	</div>
	
	<script type="text/JavaScript" language="JavaScript">
		console.log("ajax routine hit");
		
		//var drinkRecipe = "<?php echo $drinkRecipe ?>";
		var drinkRecipe = "<?=$drinkRecipe?>";
		
		var xhr = $.ajax({
			//async: false,
			type: "POST",
			url: "serial_listener.php",
			//datatype: "html",
			datatype: "text",
			data:({"drinkData":drinkRecipe}),
			//define success handler actions
			success:function(response) {
				//alert("PHP RETURN CHECK: "+response);
				if($.trim(response) == 'complete'){
					console.log("Drink making is complete... return to main menu");
					//do redirect here
				}else{
					console.log("Some value other than 'complete' was returned... look into it!");
					console.log("RESPONSE SENT WAS: " + response);
					//not sure what to do? (back to main menu anyways?)
				}
				//kill the request
				xhr.abort();
			},
			//define error handler actions
			error: function(response) {
				console.log("PHP SERIAL READ FAIL: "+ 'Ready State: '+ response.readyState + ' Status: ' + response.status);
				//kill the request
				xhr.abort();
			}
		});		
	</script>
	<?		       
}
Here is the contents of the serial_listener.php script that the above AJAX call loads/executes..

** Again.. sending the data OUT to ARDUINO works every time.. but I can NOT get a READ:

Code: Select all

$drinkData = $_POST['drinkData'];

//open serial port
$fp = fopen("/dev/ttyACM0", "w+"); //w = write w+ = read/write
//$fp = fopen("/dev/ttyUSB0", "w+"); //w = write w+ = read/write  //tried with USB-TTL cable too.. couldnt even send data)

//check if open
if (!$fp) {
	echo "Not open";
	//die();	
} else {

	if($drinkData != ''){	
		//send drink data
		fwrite($fp, '<' . $drinkData . '>');
		
		//wait for response
		$chars = "";
		do{
			$char = fread($fp, 1);
			$chars .= $char;
		}while(strlen($char) < 1);
		echo $char;
	}else{
		echo 'drink recipe is empty';
	}	
}

What can I do here? I'd rather use the USB cable.. and NOT a USB-TTL adapter type of approach.

Is this possible? I believe others have successfully used a USB cable to enable 2-way serial communication from RPI >> Arduino?\

I believe the port has the correct permissions...

I have tried use a capacitor on the Arduino RESET/GND pins to stop the reset when open/closing the ports... (seems to stop things for working properly though)

This is the LAST step in this project (for the front end).. and I have literally been throwing a few hours at this almost every day for a week..

changing the front end code... using AJAX... doing READ/WRITE in one AJAX call... trying USB-TTL cables..etc...

Please, any suggestions are appreciated! :)

ghans
Posts: 7817
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: PHP & Serial comm with RPi?

Sat Sep 29, 2018 1:55 pm

Make the Arduino output much more debug messages (say 5-7 per second) and filter all those debug messages with JavaScript.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Sat Sep 29, 2018 5:31 pm

I'm sorry.. I guess I'm not following or understanding your suggestion here?

I only need the Arduino to output ONE response.. (for now) telling me the actions are complete.... so I can update the state of the webpage.

The php while() function is already waiting/listening for ANY response on the PORT... before its being sent.

The while() function executes.. and I'm stuck in it, because it NEVER gets anything..

I updated the Arduino sketch to output the same 'complete' string.. wait for 1/4 of second.. send it again.. wait another 1/4 second.. send another.. and did like 4-5 times... so we'll see if it that helps getting the data back over to the RPi I guess...

and nothing.

Its got to be the configuration of the port perhaps?

bzt
Posts: 206
Joined: Sat Oct 14, 2017 9:57 pm

Re: PHP & Serial comm with RPi?

Mon Oct 29, 2018 3:32 pm

Hi,

Just a few suggestions:
- don't call "stty" every time, because that resets the serial port. Only call it once during bootup, before you start apache/nginx. The scriptfile "/etc/rc.local" is an ideal place for that.
- make sure you're using the right device. "/dev/ttyUSB0" is very unlikely. Normal serial port (aka COM1) is usually mapped to "/dev/ttyS0", but could be "/dev/ttyACM0". Use the "dmesg" command to list all the detected devices, and look for "serial". Try "dmesg | grep serial" or "dmesg | grep dev/tty".
- check the group of that device with "ls -la /dev/tty*", and make sure your webserver's user is in that group (should be "dialout" as perviously mentioned). Don't change the permissions on a device file, because devfs is generated automatically, meaning your change will be lost.
- by default, Linux sends it's console to the serial port too. To avoid interferece, you must turn that off.
- although it shouldn't needed, but with serial console off, you might need to add "enable_uart=1" to the file "/boot/config.txt"
- also with the latest RPi3, there's an interferece with the bluetooth stack, so might need to turn bluetooth off to enable both PL011 and miniAUX UARTs (bluetooth only conflicts with one of them, but I'm not sure which one, search these forums).

Cheers,
bzt

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Tue Oct 30, 2018 2:13 am

Thanks for the reply.. since there was not much direct help.. (just random suggestions it seemed).. I eventually stumbled upon a 'fix'..

which I understand makes things 'less secure'.. but this is a standalone (for fun) project not connected to any network or wifi..etc..

but running this line (as is) from a remote (Putty) terminal:

echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers

seemed to do the trick. So in the end it was never a 'code' things on the LAMP side of things.. but a permissions thing on the 'Raspbian' side of things... IMO..

I tried to 'execute' the "stty" thing on/in the RPi at start up.. bu it never worked..

I execute the "stty" thing in the PHP script now (and yes upon every 'call' [or drink order/submission to be more clear], I suppose I could re-work the app to use AJAX complete.. and no server side submissions/page loads...but I'm not really at the refactoring stage yet, by any means)


it 'does'....and I 'am'.. using: /dev/ttyACM0

I only tried USB0 once.. when I switched from a straight USB cable to a USB/TTL adapter cable...(but that was a short test, and abandoned quickly)

I wish I would have stumbled upon that line above much earlier in this project... because in between all these posts and using that line.. there was much non-sense, and trial-error stuff done to the RPi... :(

User avatar
DougieLawson
Posts: 34166
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: PHP & Serial comm with RPi?

Tue Oct 30, 2018 8:32 am

xl97 wrote:
Tue Oct 30, 2018 2:13 am

echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers
Do that and EVERYTHING that can access your web server owns your machine and all the machines on your LAN behind it.

It's extremely bad security practice to give open sudo access to www-data. Use suexec if you must, that's marginally safer.
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Tue Oct 30, 2018 12:04 pm

I understand...

and I have reached out and posted over and over about getting help to CORRECTLY configure permissions. (specifically in this thread since... JUNE... and

(random suggestions or half directions at best, especially when explained there is little to no 'linux' CLI experience)..

Even just stating this: "suexec"... doesnt mean much to me... nor how to apply or it use it unfortunately.


Waiting for 2+ months for some sort of 'solid' direction/help... I had no other choice to keep the project moving forward.

Also.. while currently connected to my 'network' for devleopment and testing.. this is a standalone project.. not connected to any type of network or wifi WLAN/LAN...etc..

Heater
Posts: 10235
Joined: Tue Jul 17, 2012 3:02 pm

Re: PHP & Serial comm with RPi?

Tue Oct 30, 2018 3:18 pm

xl97,
Waiting for 2+ months for some sort of 'solid' direction/help... I had no other choice to keep the project moving forward.
I admire your tenacity. Hopefully you have not been waiting because there are tons of tutorials and blogs on the net about setting up Apache and HHP and setting permissions etc.

Sorry to offer more "random suggestions or half directions" but surely if the problem is that PHP does not have permission to access the serial port the answer is to change ownership or group of the serial port. Or add the web server to whatever group the serial port is in.

I'm guessing that reason you don't get concrete suggestions here is that it's a pretty weird and rare thing to be accessing a serial port from a web server with PHP. Off the beaten track, as it were.

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Tue Oct 30, 2018 3:57 pm

I have read so many 'tutorials'...etc....blogs/post.... I cant even keep count.

To be clear.. the initial install/setup of:

Apache
PHP
MySQL
MyPHPAdmin

as well as setting things up to boot to fullscreen/kiosk mode, and load my default (locally hosted) page all went off without a hitch. (some minor issues that were all dealt with)

However.. the 100's of PHP reading SERIAL data all seemed to have 'worked'.. and none mentioned this.. or specifically this line for permission stuff:

Added user to the dial-out group...etc..

except this blog post: (while I didnt need to execute a bash script.. that single line fixed all my troubles)

https://www.brandoncorlett.com/blog/art ... -using-php


From my searches.. it seems MANY people have used, and are using PHP to access the serial port data.. (most use that same class though, but it isnt needed)


And yes, I agree.. "PHP does not have permission to access the serial port the answer is to change ownership or group of the serial port. Or add the web server to whatever group the serial port is in"....

which is what I have been asking over and over (many places actually)... HOW!?? I started off each thread with the disclaimer I am NOT Linux/CLI literate. (So random key words hold no weight if I dont understand how to apply/run/use them)

"I can write.. but not read... seems like a permission thing".. most of the time people got stuck on the AJAX aspect... and couldnt move beyond that to actually READ and ANSWER the real problem.

I even posted (more or less) my WHOLE projects.. form initial RPI set-up steps (including the permissions/dial out groups, MySQL/Apache permissions applied).. down the to whole front end of HTML/CSS, PHP and AJAX routines.


Even now. I posted that I UNDERSTAND this is a security risk (per se`)......(and that this will not be connected to a network/wifi...its a standalone project)... and how can I NOT use that specific line... but one that is more tailored to be less of a risk?


** I also was a bit unclear as to WHY the echo needed to be run in terminal/Putty?

"echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers"

if I didnt have the ECHO in there.. it didnt work. :)

bzt
Posts: 206
Joined: Sat Oct 14, 2017 9:57 pm

Re: PHP & Serial comm with RPi?

Sat Nov 10, 2018 12:39 pm

xl97 wrote:
Tue Oct 30, 2018 3:57 pm
which is what I have been asking over and over (many places actually)... HOW!??
As I've mentioned before, never change the group and permissions on a device file. Devfs is generated, and your modifications are good as last year's snow.

Instead check what group the serial ports belong to, add your user to that group. Example (I don't have serial set up right now, so I'll use /dev/tty as example):

Code: Select all

$ ls -la /dev | grep tty
...
crw--w----   1 root tty       4,   0 Nov 10 11:48 tty0
crw-------   1 user tty       4,   1 Nov 10 11:48 tty1
...
As you can see, both files are character devices (the leading "c"). Both can be read and written by their owners ("rw-"). The tty0 file is owned by root, and tty1 is owned by user (3rd coloumn). Now the second access differs: although both files belong to the same group (4th coloumn), tty0 can be written by the group, tty1 can't be. What does all this mean?

By default I, as the user "user", I can write to the tty1, because I'm it's owner, therefore owner access rights apply. I can't write to tty0, because I'm neither root nor am I in the "tty" group, only in my own "user" group:

Code: Select all

$ groups user
user
Now let's add my user to the tty group:

Code: Select all

$ sudo adduser user tty
Changing user permissions does not change existing security profiles in already existing sessions, so YOU HAVE TO LOGOUT AND LOGIN AGAIN to see them in effect. After that,

Code: Select all

$ groups user
user tty
shows that "user" is in the group "tty", and I, as the user "user" can write to /dev/tty0:

Code: Select all

$ echo "How do you doin, mate?" >/dev/tty0
BUT. If anybody (let's say "user2") is in the "tty" group, that doesn't mean they can write to my terminal, because my "tty1" terminal does not have "w" group permission. So the question is, if you list your serial device under /dev, what do you see? What group it belongs to? Is that really "dialout", or something else? Does it have "rw" group permissions?
** I also was a bit unclear as to WHY the echo needed to be run in terminal/Putty?

"echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers"

if I didnt have the ECHO in there.. it didnt work. :)
"echo" is a command. You enter commands in a terminal :-)
It does nothing else that echoes it's argument back. With the pipe that output is redirected to the "tee" command, and there's two reasons for that. First, tee is called through sudo, which means it will be running with supervisor privileges (required to modify the /etc/sudoers file). Second, it's "-a" argument guarantees that the echo's output will be appended to the file, and you don't accidentaly mess up your sudoers file.
Simply put, it would be enough to have

Code: Select all

echo "www-data ALL=NOPASSWD:ALL" >>/etc/sudoers
which has exactly the same effect. But since you need superuser privileges, you need sudo, and the ">>" append operator would redirect sudo's output and not the echo's output. For that, you'd need

Code: Select all

sudo /bin/bash -c "echo \"www-data ALL=NOPASSWD:ALL\" >>/etc/sudoers"
Whoever wrote that tee soultion though it's simpler to give root permission to tee, and he was right.

Now what's wrong with this. This allows the www-data user to run ANYTHING as supervisor without any authentication. Because your webscript is running under the user "www-data", that means even the slightest issue in your code opens up your ENTIRE system to an attacker without any restrictions.

Let's say you have forgotten to properly escape the shell arguments when you invoke bash from PHP (which I'm pretty sure you have forgotten), and let's say you pass $cmdarg (an otherwise legal and valid) argument to that bash command. In this case a simple query with the
"/index.php?cmdarg=somethinglegal;sudo+rm+-rf+/"
URL would ruin all your work within a blink of an eye. Not to mention it's equally easy to install a backdoor without you even noticing.

Cheers,
bzt

User avatar
DougieLawson
Posts: 34166
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: PHP & Serial comm with RPi?

Sat Nov 10, 2018 1:15 pm

bzt wrote:
Sat Nov 10, 2018 12:39 pm

Code: Select all

echo "www-data ALL=NOPASSWD:ALL" >>/etc/sudoers
which has exactly the same effect. But since you need superuser privileges, you need sudo, and the ">>" append operator would redirect sudo's output and not the echo's output. For that, you'd need

Code: Select all

sudo /bin/bash -c "echo \"www-data ALL=NOPASSWD:ALL\" >>/etc/sudoers"
Whoever wrote that tee soultion though it's simpler to give root permission to tee, and he was right.

Now what's wrong with this. This allows the www-data user to run ANYTHING as supervisor without any authentication. Because your webscript is running under the user "www-data", that means even the slightest issue in your code opens up your ENTIRE system to an attacker without any restrictions.
I'd dispute there's nothing wrong in that except that it opens your webserver as a massive security hole and a vector for the bad actors to get root access. Once they have root access to your Raspberry they own your whole LAN and every device connected to it.

Other than that, go ahead, give www-data sudo access.
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

xl97
Posts: 56
Joined: Thu Jan 12, 2017 3:34 pm

Re: PHP & Serial comm with RPi?

Sat Nov 10, 2018 9:12 pm

Thanks for reply...

I understand the security risk, and as mentioned a couple times.. this is NOT connected to any sort of network/LAN/WAN, WIFI...etc.. this is a standalone project. But I do get it... (also I am NOT executing any bash scripts.. I got that LINE from a tutorial that was... I am not. I am simply sending serial data to be parsed/chopped up from a hosted webpage to the connected Arduino)

I dont understand all of what was given to me.. so I'll start slowly. :)

1.) "echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers"

Thank you for explaining about the 'echo' portion... being a PHP developer, I use 'echo' to output stuff to a page..

2.) How do I 'un-do' this line then?
"echo "www-data ALL=NOPASSWD: ALL" | sudo tee -a /etc/sudoers"


3.) I ran this line in Putty/Terminal: "ls -la /dev | grep tty"

and got a HUGE wall of text returned:

Code: Select all

crw-rw-rw-  1 root tty       5,   2 Nov 10 08:19 ptmx
lrwxrwxrwx  1 root root           7 Oct  8 22:17 serial1 -> ttyAMA0

crw-rw----  1 root dialout 166,   0 Oct  8 22:17 ttyACM0
crw-rw----  1 root dialout 204,  64 Oct  9 07:07 ttyAMA0

crw-rw-rw-  1 root tty       5,   0 Oct  8 22:17 tty
crw--w----  1 root tty       4,   0 Oct  8 22:17 tty0
crw--w----  1 root tty       4,   1 Oct  9 07:07 tty1
crw--w----  1 root tty       4,  10 Oct  8 22:17 tty10
crw--w----  1 root tty       4,  11 Oct  8 22:17 tty11
crw--w----  1 root tty       4,  12 Oct  8 22:17 tty12
crw--w----  1 root tty       4,  13 Oct  8 22:17 tty13
crw--w----  1 root tty       4,  14 Oct  8 22:17 tty14
crw--w----  1 root tty       4,  15 Oct  8 22:17 tty15
crw--w----  1 root tty       4,  16 Oct  8 22:17 tty16
crw--w----  1 root tty       4,  17 Oct  8 22:17 tty17
crw--w----  1 root tty       4,  18 Oct  8 22:17 tty18
crw--w----  1 root tty       4,  19 Oct  8 22:17 tty19
crw--w----  1 root tty       4,   2 Oct  8 22:17 tty2
crw--w----  1 root tty       4,  20 Oct  8 22:17 tty20
crw--w----  1 root tty       4,  21 Oct  8 22:17 tty21
crw--w----  1 root tty       4,  22 Oct  8 22:17 tty22
crw--w----  1 root tty       4,  23 Oct  8 22:17 tty23
crw--w----  1 root tty       4,  24 Oct  8 22:17 tty24
crw--w----  1 root tty       4,  25 Oct  8 22:17 tty25
crw--w----  1 root tty       4,  26 Oct  8 22:17 tty26
crw--w----  1 root tty       4,  27 Oct  8 22:17 tty27
crw--w----  1 root tty       4,  28 Oct  8 22:17 tty28
crw--w----  1 root tty       4,  29 Oct  8 22:17 tty29
crw--w----  1 root tty       4,   3 Oct  8 22:17 tty3
crw--w----  1 root tty       4,  30 Oct  8 22:17 tty30
crw--w----  1 root tty       4,  31 Oct  8 22:17 tty31
crw--w----  1 root tty       4,  32 Oct  8 22:17 tty32
crw--w----  1 root tty       4,  33 Oct  8 22:17 tty33
crw--w----  1 root tty       4,  34 Oct  8 22:17 tty34
crw--w----  1 root tty       4,  35 Oct  8 22:17 tty35
crw--w----  1 root tty       4,  36 Oct  8 22:17 tty36
crw--w----  1 root tty       4,  37 Oct  8 22:17 tty37
crw--w----  1 root tty       4,  38 Oct  8 22:17 tty38
crw--w----  1 root tty       4,  39 Oct  8 22:17 tty39
crw--w----  1 root tty       4,   4 Oct  8 22:17 tty4
crw--w----  1 root tty       4,  40 Oct  8 22:17 tty40
crw--w----  1 root tty       4,  41 Oct  8 22:17 tty41
crw--w----  1 root tty       4,  42 Oct  8 22:17 tty42
crw--w----  1 root tty       4,  43 Oct  8 22:17 tty43
crw--w----  1 root tty       4,  44 Oct  8 22:17 tty44
crw--w----  1 root tty       4,  45 Oct  8 22:17 tty45
crw--w----  1 root tty       4,  46 Oct  8 22:17 tty46
crw--w----  1 root tty       4,  47 Oct  8 22:17 tty47
crw--w----  1 root tty       4,  48 Oct  8 22:17 tty48
crw--w----  1 root tty       4,  49 Oct  8 22:17 tty49
crw--w----  1 root tty       4,   5 Oct  8 22:17 tty5
crw--w----  1 root tty       4,  50 Oct  8 22:17 tty50
crw--w----  1 root tty       4,  51 Oct  8 22:17 tty51
crw--w----  1 root tty       4,  52 Oct  8 22:17 tty52
crw--w----  1 root tty       4,  53 Oct  8 22:17 tty53
crw--w----  1 root tty       4,  54 Oct  8 22:17 tty54
crw--w----  1 root tty       4,  55 Oct  8 22:17 tty55
crw--w----  1 root tty       4,  56 Oct  8 22:17 tty56
crw--w----  1 root tty       4,  57 Oct  8 22:17 tty57
crw--w----  1 root tty       4,  58 Oct  8 22:17 tty58
crw--w----  1 root tty       4,  59 Oct  8 22:17 tty59
crw--w----  1 root tty       4,   6 Oct  8 22:17 tty6
crw--w----  1 root tty       4,  60 Oct  8 22:17 tty60
crw--w----  1 root tty       4,  61 Oct  8 22:17 tty61
crw--w----  1 root tty       4,  62 Oct  8 22:17 tty62
crw--w----  1 root tty       4,  63 Oct  8 22:17 tty63
crw--w----  1 root tty       4,   7 Oct  9 07:07 tty7
crw--w----  1 root tty       4,   8 Oct  8 22:17 tty8
crw--w----  1 root tty       4,   9 Oct  8 22:17 tty9
 
crw-------  1 root root      5,   3 Oct  8 22:17 ttyprintk
crw-rw----  1 root tty       7,   0 Oct  8 22:17 vcs
crw-rw----  1 root tty       7,   1 Oct  8 22:17 vcs1
crw-rw----  1 root tty       7,   2 Oct  8 22:17 vcs2
crw-rw----  1 root tty       7,   3 Oct  8 22:17 vcs3
crw-rw----  1 root tty       7,   4 Oct  8 22:17 vcs4
crw-rw----  1 root tty       7,   5 Oct  8 22:17 vcs5
crw-rw----  1 root tty       7,   6 Oct  8 22:17 vcs6
crw-rw----  1 root tty       7,   7 Oct  9 07:07 vcs7
crw-rw----  1 root tty       7, 128 Oct  8 22:17 vcsa
crw-rw----  1 root tty       7, 129 Oct  8 22:17 vcsa1
crw-rw----  1 root tty       7, 130 Oct  8 22:17 vcsa2
crw-rw----  1 root tty       7, 131 Oct  8 22:17 vcsa3
crw-rw----  1 root tty       7, 132 Oct  8 22:17 vcsa4
crw-rw----  1 root tty       7, 133 Oct  8 22:17 vcsa5
crw-rw----  1 root tty       7, 134 Oct  8 22:17 vcsa6
crw-rw----  1 root tty       7, 135 Oct  9 07:07 vcsa7
This line: "lrwxrwxrwx 1 root root 7 Oct 8 22:17 serial1 -> ttyAMA0"

* Which is my serial port.....correct? (ttyAMA0)

Does -not- start with a 'c'.. so it is NOT a character device?

This line (also my serial port): "crw-rw---- 1 root dialout 204, 64 Oct 9 07:07 ttyAMA0"

does have the 'c' (so it is a character file)

Both are owned by root?


I'll stop here before I get to overwhelmed on what to actually do vs just FYI knowledge...

Thanks!

User avatar
rpdom
Posts: 12945
Joined: Sun May 06, 2012 5:17 am
Location: Ankh-Morpork

Re: PHP & Serial comm with RPi?

Sat Nov 10, 2018 9:20 pm

xl97 wrote:
Sat Nov 10, 2018 9:12 pm
This line: "lrwxrwxrwx 1 root root 7 Oct 8 22:17 serial1 -> ttyAMA0"
The "l" (lower case "L") in front means the file is a link to the real file ttyAMA0. The rwxrwxrwx means that the link is visible to anyone, which is standard and doesn't reflect the permissions on the file it points at.
crw-rw---- 1 root dialout 204, 64 Oct 9 07:07 ttyAMA0
Yes, that is your serial port. It is owned by root, and also the group "dialout". The pi user should be a member of that group and will have read/write access to that interface (the second "rw-" applies to group members).

bzt
Posts: 206
Joined: Sat Oct 14, 2017 9:57 pm

Re: PHP & Serial comm with RPi?

Sun Nov 11, 2018 11:47 am

Hi,

As others pointed out, you have read-write permissions for the group on the serial device, which is exactly what you want.
You only have to add "www-data" to the "dialout" group, reboot and you should be fine without any sudo. (Reboot is required to restart the webserver and it's user session. There are other options, but reboot is the simplest.) If this doesn't work for you, then there's some problem with the "www-data" user's groups. An easy way to check and fix this:

Code: Select all

sudo nano /etc/group
You'll see that group is a simple ':' colon separated database. Each line contains: "group":"x":"id":"comma separated list of users in this group". Look for the line "dialout" and check if "www-data" is listed at the end. If not, then you can manually add it with nano, and save. Don't forget to restart your webserver with a reboot. ("nano" is a very simple, easy to use text editor with keyboard shortcut help at the bottom. If you don't have that, you can try "pico". If even that fails, as a last resort use "vi" which always exists on all UNIXes, but rather tricky to use. Once "vi" loaded, press "i" to enter inserting edit mode. Edit the line, then press "Esc" to return to command mode, and in the bottom command line (prefixed by ":") type "wq!" and press "Enter".)

About removing the sudo. The sudoers file itself is a simple plain text file. I think the easiest way for you is to do

Code: Select all

sudo nano /etc/sudoers
Find that line, delete it and save.

About your network connection: it's good thinking that you don't connect it to the internet if you don't have to. But there's always a chance that some attacker is able to use it's WiFi, so it's best practice to give only the smallest set of access rights to processes.

Cheers,
bzt

Return to “Other programming languages”