supplierdeeply

Wireless investigations

  • 55 Replies
  • 13602 Views
*

Offline reyalp

  • ******
  • 11707
Re: Wireless investigations
« Reply #20 on: 04 / December / 2013, 13:57:13 »
Advertisements
Note that to make input appear to come *from* the UART, you will need to do something different. Opening and *writing* to the uart will send output. What you want to do is write to something and have what you wrote be read from the UART FD.

I think this can be done with driver hooks something like the vxworks console log hack (see generic/main.c) but hooking the read function instead of the write function.

Essentially, you'd make a buffer that you can write to from the script task, and then make a hook for the read function in the driver that returns the contents of the buffer instead of what it would normally get form the UART. There's some task synchronization and other details to think about...

An alternative would be to try to replace /tyCo/0 with a pipe, if you can figure out how to create such a thing in vxworks...
Don't forget what the H stands for.

*

Offline ahull

  • *****
  • 634
Re: Wireless investigations
« Reply #21 on: 05 / December / 2013, 01:49:11 »
Note that to make input appear to come *from* the UART, you will need to do something different. Opening and *writing* to the uart will send output. What you want to do is write to something and have what you wrote be read from the UART FD.

I would indeed, at the moment I am playing with io control and allocation of memory via lua, in the hope that I can write the whole thing in lua, this is not absolutely necessary, but does make experimentation much quicker for obvious reasons. 

Quote
I think this can be done with driver hooks something like the vxworks console log hack (see generic/main.c) but hooking the read function instead of the write function.

Essentially, you'd make a buffer that you can write to from the script task, and then make a hook for the read function in the driver that returns the contents of the buffer instead of what it would normally get form the UART. There's some task synchronization and other details to think about...

That will be my next line of attack if I cant manipulate vxworks from lua

Quote
An alternative would be to try to replace /tyCo/0 with a pipe, if you can figure out how to create such a thing in vxworks...

VxWorks does indeed support pipes, so I am also investigating this as a possibility.

VxWorks also supports redirection of the console, and there is also the possibility of manipulating or re-allocating the file descriptor for /tyCo/0 by brute force so this *might* be simple... I have my doubts however. 

What I have so far lets me theoretically read and write from and to /tyCo/0, but since it is not actually  exposed to the world or attached to anything, I cant be sure this works. I have only managed to crash the camera once with a typo when using VxWorks AllocateMemory to set up my read buffer.. Its never a good idea to read or write things to incorrectly referenced random chunks of RAM  ::)   

*

Offline ahull

  • *****
  • 634
Re: Wireless investigations
« Reply #22 on: 05 / December / 2013, 11:18:17 »
I have demonstrated I can read and write to VxWorks fds using lua and VxWorks basic io functions open(),close(),read(),write(),ioctl() with a bit of memory allocation thrown in for good measure.

Code: [Select]
--
-- Test routine, defines the pointers, and attempt to read a file from VxWorks directly for example the serial port on /tyCo/0
-- NOTE: These entries are specific to the SD430 and were found in stubs_entry.S
--
fptr_open=0xffc1aef0
fptr_ioctl=0xffc1a9ec
fptr_close=0xffc1a8ac
fptr_write=0xffc1a97c
fptr_read=0xffc1a90c
fptr_readdir=0xffc16818
fptr_malloc=0xffc1d8ec

fptr_AllocateMemory=0xff8141dc
fptr_FreeMemory=0xff8141e8



-- Open the file or console device
FIOBAUDRATE=4 -- vxworks IOCTL number, found on google
-- consoleDev="/tyCo/0" -- This works, as does ioctrl

-- consoleDev="/pipe/pipe0" -- This fails.
consoleDev="A/chdklog.txt"

console=call_func_ptr(fptr_open,consoleDev,0,0)
print('open returned file handle',console) -- >= 0 indicates open works
if console < 0 then
  error('open failed')
end

-- Call the serial port ioctl..
--status=call_func_ptr(fptr_ioctl,console,FIOBAUDRATE,115200)
--print('ioctl returned',status) -- 0 probably means success

--- Do *stuff*
print("console:",console)
readBufferSize=100
readBuffer=call_func_ptr(fptr_AllocateMemory,readBufferSize)
print("readBuffer memory allocated at:",readBuffer)

-- Read the data in to our buffer (call returns number of bytes read)
-- readBufferDataNumBytes=call_func_ptr(fptr_read,console,readBuffer)

-- Read the buffer a few times.
for loops=1,100 do
   -- Read the data in to our buffer (call returns number of bytes read)
   readBufferDataNumBytes=call_func_ptr(fptr_read,console,readBuffer)
   -- print("Bytes read:",readBufferDataNumBytes)
   for readBytes=0, 1 do
      readByte=peek(readBuffer+readBytes,1)

      -- print("Byte:",readByte)
      print( string.char(readByte))
      sleep(1000)
   end
end

Note: Someone with a moment to spare might enlighten me as to why I get two bytes (16bits presumably) per buffer read...

Not exactly the most earth shattering news (although I was pretty chuffed to see "The quick brown fox..." doing a vertical marquee up the console, I'm easily pleased though) ...

It also means I can presumably read and write to any VxWorks files, including those not on the SD card file system...

Writing to the console (/tyCo/0) for one, seems to work, but with nothing on the other end of the wire, I cant be sure... Chris Stubb's previous work suggests this is working however.

Reading /tyCo/0 gives me no errors and a single zero byte as a response..

Presumably I should also be able to read from the flash file system and any other VxWorks devices directly...

Maybe I am oversimplifying this, but surely if I call a (network) routine or indeed anything else that needs data, in the words of the VxWorks manual, the task gets its own stdin, stdout, stderr, but in this case, those will be the stdin,stdout and stderr of the calling task, that is to say, in our case the task that is running lua, so I should therefore be able to read and write to these fds to control the routine.... and since I already know the fds will be 0,1 and 2 ...

Time for some more experiments...

If you smell smoke .....  ;)
« Last Edit: 05 / December / 2013, 11:28:26 by ahull »

*

Offline reyalp

  • ******
  • 11707
Re: Wireless investigations
« Reply #23 on: 05 / December / 2013, 16:29:57 »
Note: Someone with a moment to spare might enlighten me as to why I get two bytes (16bits presumably) per buffer read...
It doesn't look like you aren't specifying the number of bytes to read. If that is the case, it will just use whatever junk happens to be in that register as the length. read() should have parameters like

http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html


Quote
Maybe I am oversimplifying this, but surely if I call a (network) routine or indeed anything else that needs data, in the words of the VxWorks manual, the task gets its own stdin, stdout, stderr, but in this case, those will be the stdin,stdout and stderr of the calling task, that is to say, in our case the task that is running lua, so I should therefore be able to read and write to these fds to control the routine.... and since I already know the fds will be 0,1 and 2 ...
I wouldn't assume stdin/stdout/stderr are configured this way in canon's vxworks implementation. I believe open() frequently returns filehandle values of 0 or 1 when used on files (although I might be mis-remembering).

OT lua tip:
To make your call_func_ptr code more readable, you can do something like this (off the top of my head, untested)

Code: [Select]
function bind_fptr(ptr)
   return function(...)
      return call_func_ptr(ptr,...)
  end
end

open=bind_fptr(0xffc1aef0)
fd=open("A/foo",0,0)
Each time you call bind_fptr, it creates a closure with it's own "ptr" bound to it. The ... construct allows you to pass on a variable number of arguments.
Don't forget what the H stands for.


*

Offline ahull

  • *****
  • 634
Re: Wireless investigations
« Reply #24 on: 06 / December / 2013, 00:09:45 »
Note: Someone with a moment to spare might enlighten me as to why I get two bytes (16bits presumably) per buffer read...
It doesn't look like you are specifying the number of bytes to read. If that is the case, it will just use whatever junk happens to be in that register as the length. read() should have parameters like

http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html

This wasn't clear (or indeed specified) in the VxWorks documentation I was looking at, but based on your suggestion, I added the read length as the final parameter

This code..
Code: [Select]
readBufferDataNumBytes=call_func_ptr(fptr_read,console,readBuffer,2)
..produces the previous behaviour, and setting the last parameter to other values does indeed read the corresponding number of bytes. Mystery solved, thanks.

Quote
Quote
Maybe I am oversimplifying this, but surely if I call a (network) routine or indeed anything else that needs data, in the words of the VxWorks manual, the task gets its own stdin, stdout, stderr, but in this case, those will be the stdin,stdout and stderr of the calling task, that is to say, in our case the task that is running lua, so I should therefore be able to read and write to these fds to control the routine.... and since I already know the fds will be 0,1 and 2 ...
I wouldn't assume stdin/stdout/stderr are configured this way in canon's vxworks implementation. I believe open() frequently returns filehandle values of 0 or 1 when used on files (although I might be mis-remembering).

An interesting observation, I'll play with this and see if I can figure out how it works..

Quote
OT lua tip:
To make your call_func_ptr code more readable, you can do something like this (off the top of my head, untested)

Code: [Select]
function bind_fptr(ptr)
   return function(...)
      return call_func_ptr(ptr,...)
  end
end

open=bind_fptr(0xffc1aef0)
fd=open("A/foo",0,0)
Each time you call bind_fptr, it creates a closure with it's own "ptr" bound to it. The ... construct allows you to pass on a variable number of arguments.


Good tip, it certainly makes things a lot easier to follow.
« Last Edit: 06 / December / 2013, 00:14:13 by ahull »

*

Offline reyalp

  • ******
  • 11707
Re: Wireless investigations
« Reply #25 on: 06 / December / 2013, 01:00:17 »
..produces the previous behaviour, and setting the last parameter to other values does indeed read the corresponding number of bytes. Mystery solved, thanks.
Hmm, what comes out of it? I would expect it to block until there was actual data available.
Don't forget what the H stands for.

*

Offline ahull

  • *****
  • 634
Re: Wireless investigations
« Reply #26 on: 06 / December / 2013, 10:08:35 »
..produces the previous behaviour, and setting the last parameter to other values does indeed read the corresponding number of bytes. Mystery solved, thanks.
Hmm, what comes out of it? I would expect it to block until there was actual data available.

"What comes out of it.." depend on what I am trying to connect to.. If I use a pre-existing text file say "A/SOMEFILE.TXT" I can read without any trouble. For what is is worth, in my experiments, I was usually allocated file descriptor 8. I can continue to read past EOF without crashing (I simply get a -1 result code and zero bytes of data).

If I set the mode to 1 (write mode) I can write to the file, over writing the data at the start of the file, rather than appending to it, presumably I need to be a little more sophisticated than basic io allows if I want to find the file length, and append to the file..

Setting the file mode to 2 (rw mode), appears to allow me to write to and read from the file, but I don't see the results of the write, probably I am going about this incorrectly, or perhaps mode 2 is not supported.

If I select file descriptor 0..5 for reading the script does block (I haven't yet tried opening these fds mode 1 or mode 2  (w, or r/w) yet. The camera doesn't completely crash, for example the console timeout kicks in after 10 seconds, but none of the switches work (presumably we are blocking the keyboard task).

If I attempt to open file descriptors 9 onwards, they will open, but beyond 13 I get an error. Presumably we are limited to 12 fds per task.

I tried a couple of other file descriptor names. 

/tyCo/0 as discussed before, allows me to both read and write, and honours ioctl , however with nothing on the other end of the UART, the results are unknown...

Presumably however I could wire up the serial port and talk to the camera with a script on the lua end, and a terminal on the other, which opens up some interesting possibilities, for example wiring one of the many cheap blue-tooth modules to any camera and talking to it this way.

I can write to /null (so if you need any data sent down a deep dark hole... )

One other note, perhaps this is already known,  malloc() exists, but free() doesn't appear to, at least I couldn't see it in the stubs, however AllocateMemory() and FreeMemory() work for the purposes of this exercise, and this is what I used to allocate the read and write buffers.

Current very messy and hacky lua script attached.
« Last Edit: 07 / December / 2013, 06:40:09 by ahull »

*

Offline reyalp

  • ******
  • 11707
Re: Wireless investigations
« Reply #27 on: 06 / December / 2013, 13:19:36 »
"What comes out of it.." depend on what I am trying to connect to.. If I use a pre-existing text file say "A/SOMEFILE.TXT" I can read without any trouble, I am usually allocate file descriptor 8. I can continue to read past EOF without crashing (I simply get a -1 result code and zero bytes of data).
Oh, I see. I thought you were getting characters from the /tyCo/0

It's expected that read() etc work, these are known functions we use.  Although it should be noted that read() and write() expect the buffer to be in uncached memory, and may fail if it isn't. You can turn your pointer from AllocateMemory to an uncached one by bitwise ORing in the CAM_UNCACHED_BIT from your cameras cameras.h, or allocate it using AllocateUncacheableMemory
Don't forget what the H stands for.


*

Offline ahull

  • *****
  • 634
Re: Wireless investigations
« Reply #28 on: 07 / December / 2013, 00:29:22 »
"What comes out of it.." depend on what I am trying to connect to.. If I use a pre-existing text file say "A/SOMEFILE.TXT" I can read without any trouble, I am usually allocate file descriptor 8. I can continue to read past EOF without crashing (I simply get a -1 result code and zero bytes of data).
Oh, I see. I thought you were getting characters from the /tyCo/0

Well I seem to only get a single <NULL> (i.e. a single zero byte) when I read from /tyCo/0

To see if reading from the serial port works, I would have to get out the soldering iron, and actually send some characters in from the outside world. I may have a crack at this at a later date, I was toying with the idea of adding blue-tooth to my A560 or some model where the serial port pins have already been identified.

If I can operate the camera serial port reliably to my laptop with a usb serial converter, it is a short jump from there to adding something like this, but that's a project for another day.

Quote
It's expected that read() etc work, these are known functions we use.  Although it should be noted that read() and write() expect the buffer to be in uncached memory, and may fail if it isn't. You can turn your pointer from AllocateMemory to an uncached one by bitwise ORing in the CAM_UNCACHED_BIT from your cameras cameras.h, or allocate it using AllocateUncacheableMemory

I did think that using AllocateUncacheableMemory might be a smarter move. I'll make that change.

I presumed that CHDK already used read() and write(), but I also assumed that CHDK limits its access to the SD card only (files on A/)

I am also assuming that stdin stdout and stderr for lua are entirely separate entities from stdin stdout and stderr on the VxTask that is running chdk, is this the case?

Since one of my objectives is to try to talk to the OS console without using the serial port I may also try tracking down the existing console buffers and see if I can inject data into, and read from them. Any thoughts on this would be appreciated.
« Last Edit: 07 / December / 2013, 00:43:11 by ahull »

*

Offline reyalp

  • ******
  • 11707
Re: Wireless investigations
« Reply #29 on: 07 / December / 2013, 02:33:54 »
I presumed that CHDK already used read() and write(), but I also assumed that CHDK limits its access to the SD card only (files on A/)
There are several different IO APIs available. open()/read()/write() are the lowest level. Above that are Open()/Read()/Write() which wrap the corresponding lower level functions with some FsIoNotify stuff. The other main one we use is the _Fut functions, which act roughly like C stdio: fopen(), fread() etc. These automatically take care of things like the uncached memory. I believe the Fut functions are limited to A/, not sure about the Open() etc.
Quote
I am also assuming that stdin stdout and stderr for lua are entirely separate entities from stdin stdout and stderr on the VxTask that is running chdk, is this the case?
They aren't implemented in CHDK Lua, the standard file handles are created closed.

Quote
Since one of my objectives is to try to talk to the OS console without using the serial port I may also try tracking down the existing console buffers and see if I can inject data into, and read from them. Any thoughts on this would be appreciated.
There are several console and uart related tasks, but I haven't looked at them closely.
Don't forget what the H stands for.

 

Related Topics