Topic: Bidirectional pipe communication between Flash and C program

I have written a C program that takes a line from standard input (terminated by a \n), formats it, and sends it to the serial port.  The same executable also receives data from the serial port, formats it, and sends it to standard out (also terminated by a \n).

After reviewing the ASnative() calls for _pipeOpen(), _pipeRead(), and _pipeWrite(), I can't seem to figure out how to hook this C program into my Flash program.  All of the examples I can find that use both _pipeRead() and _pipeWrite() pass different command lines to their respective _pipeOpen() calls.

Has anyone developed a Flash program to handle a bidirectional pipe?

Re: Bidirectional pipe communication between Flash and C program

Using _pipeRead(), _pipeWrite(), and _pipeOpen() makes a lot more sense if you understand that they're basically wrappers around pread(), pwrite(), and popen().

So you pass the program's name to _pipeOpen(), pass the string to print to _pipeWrite(), and read the string back from _pipeRead().

Re: Bidirectional pipe communication between Flash and C program

I think I understand that the _pipeOpen(), _pipeRead(), and _pipeWrite() are equivalent to C's popen(), pread(), and pwrite(), respectively.

But, popen() wants either a "r" or a "w" argument for reading _or_ writing.  It can't do both.  So, I need two separate _pipeOpen() calls -- one for the read pipe and one for the write pipe.  I'd like to do this with only one program running -- I'd rather not pipe the output into a temporary file and then cat that file for the second _pipeOpen().  Also, this would eventually fill up the file.

I've seen some implementations of popen2() in C, which provides a read file descriptor and a write file descriptor for one program.  But, I don't see how to use that same model in Flash.

Re: Bidirectional pipe communication between Flash and C program

Sadly, Linux is not like that.  From the manpage of pipe(7):

Portability Notes:
On some systems (but not Linux), pipes are bidirectional

perl and python have a version of popen as a module called popen2 or popen3 that behave that way, but they work in a different way.  Unfortunately, the version that got put in the Flashplayer is just a Linux pipe, so it's unidirectional.

Re: Bidirectional pipe communication between Flash and C program

I wasn't sure whether the ASnative() calls were put in by Adobe or chumby.  If it were the chumby folks, I guess I'm asking whether they think bidirectional pipe support is worth adding.

The web page: http://snippets.dzone.com/posts/show/1134

shows a C implementation of popen2() (I think the correct implementation is about a 1/3 of the way down the page), so it looks like it is possible to do.

Re: Bidirectional pipe communication between Flash and C program

The ASnative() calls that we publish were added by chumby.  They're sort of like a two-dimensional syscall() for Flash.

I'll make the suggestion to the flash guys to implement bidirectional _pipe calls.

Re: Bidirectional pipe communication between Flash and C program

Are named pipes available ? Those should be bidirectional.

Redge

Re: Bidirectional pipe communication between Flash and C program

redge76 wrote:

Are named pipes available ? Those should be bidirectional.

Redge

I would assume so, since the Chumby uses a couple for btplay.  /tmp/.btplay-cmdin /tmp/.btplay-cmdout and I just noticed some called ".fpcmdrecv" and ".fpcmdsend" in the /tmp dir also.

Linux Guy - Occasional Chumby Hacker

Re: Bidirectional pipe communication between Flash and C program

I got some email from Henry Groover that provided the answer.  Code snippet is below, where mycmd is an executable that takes stdin and provides stdout:

_backtick = ASnative(5, 52);
_pipeOpen = ASnative(5, 191);
_pipeRead = ASnative(5, 193);
_pipeWrite = ASnative(5, 194);
_pipeClose = ASnative(5, 195);

_backtick("mkfifo /tmp/.outpipe"); // Create named pipe

/* You need to create the read pipe before creating the write pipe, otherwise your process will block until there's a process reading. */
rHandle = _pipeOpen("cat - </tmp/.outpipe", "r"); // Create read pipe

/* If you read at this time, you'll block.  So, no reading until the write pipe is created and mycmd is executed. */
wHandle = _pipeOpen("mycmd >/tmp/.outpipe", "w"); // Create write pipe

/* Now it's safe to read and write.  To avoid deadlocks, it's best if mycmd doesn't depend on getting data on stdin to generate data on stdout. */
_pipeWrite(wHandle, "this will be sent to stdin of mycmd");
s = _pipeRead(rHandle); // Read from stdout of mycmd

_pipeClose(wHandle);
_pipeClose(rHandle);

Re: Bidirectional pipe communication between Flash and C program

This all works great if I run my widget standalone using

chumbyflashplayer.x -i mywidget.swf

But if I add mywidget.swf to /mnt/usb/profile.xml, I don't get any pipe communication.  I also don't get any messages that explain what's going on.  I even tried stop_control_panel, then start_control_panel to see if there were any diagnostics printed, but I got nothing of any value when mywidget.swf was executed.

I added some trace outputs to print the return values of calling _backtick() and _pipeOpen().  For the standalone case, they return sensible values.  When it's running under the control panel, I get undefined for the return values.

Is there a difference in how pipes are accessed between running standalone and running under the control panel?

Re: Bidirectional pipe communication between Flash and C program

It could be that you're running into privilege problems, where the master widget has access to many more functions than the slave widget.  Try creating /psp/flashplayer.cfg and adding the following line:

PrivilegedCallExceptions 0x8000

Then restart flashplayer.  That should give slave widgets permission to use pipe calls.

Note that this could present a security risk.  Any widget could then make calls to pipe objects, which is why we normally have it turned off.

Re: Bidirectional pipe communication between Flash and C program

0x8000 didn't work, but 65535 did.  Is there a list of which bits control which privileged call exceptions?

I'm a little disappointed that local widgets don't have hardware access.  I thought the "no hardware access" was only for widgets that were loaded over the web.  Since I have physical control over my chumby, I would propose that if I put a widget on my chumby, it should be allowed pipe calls.

Also, I did a search for PrivilegedCallExceptions in the forum, and it looks like there's some confusion regarding the syntax.  Some posts show the line as

PrivilegedCallExceptions=65535

and some show the line as

PrivilegedCallExceptions 65535

(no equals sign).  It looks like the latter is correct.

13 (edited by agprimatic 2010-01-03 17:06:36)

Re: Bidirectional pipe communication between Flash and C program

Found one of my answers.  The wiki page http://wiki.chumby.com/mediawiki/index.php/ChumbyNative has values which seem to be also the argument to PrivilegedCallExceptions:

    static var PRIVILEGES_VOLUME:Number = 0x0001;
    static var PRIVILEGES_AUDIO_PLAYER:Number = 0x0002;
    static var PRIVILEGES_BRIGHTNESS:Number = 0x0004;
    static var PRIVILEGES_POWER:Number = 0x0008;
    static var PRIVILEGES_GET_FILE:Number = 0x0010;
    static var PRIVILEGES_PUT_FILE:Number = 0x0020;
    static var PRIVILEGES_BACKTICK:Number = 0x0040;
    static var PRIVILEGES_FILEINFO:Number = 0x0080;
    static var PRIVILEGES_UNLINK:Number = 0x0100;
    static var PRIVILEGES_CACHE_CONTROL:Number = 0x0200;
    static var PRIVILEGES_OVERLAY_BLENDING:Number = 0x0400;
    static var PRIVILEGES_OVERLAY_CHROMA:Number = 0x0800;
    static var PRIVILEGES_MEDIA_PLAYER:Number = 0x1000;
    static var PRIVILEGES_FORCE_RESTART:Number = 0x2000;
    static var PRIVILEGES_TIME:Number = 0x4000;
    static var PRIVILEGES_PIPE:Number = 0x8000;
    static var PRIVILEGES_ALL:Number = 0xFFFF;