Thursday 30 May 2013

NeuroPy : Python library for interfacing with Neurosky's Mindwave eeg headset

Neurosky Mindwave is a miniature eeg machine which i used in a project to control a harware based on our thoughts. It involved taking eeg data from the headset and then performing certain actions based on it.
Neurosky provides a lot of developmental resources and sdks and libraries for various platforms.
The support for Python However was missing.

To obtain data from the headset using python i had to write my own library, NeuroPy  based on the excellent description of the protocol provided by the company (google for mindset_communications_protocol).
The headset establishes a spp (serial port profile) connection over Bluetooth thus receiving and transmitting data is as easy as communicating with any other serial port.

The packet structure is fairly easy to understand from the document thus any description of it is not given here. However using the library is explained.

imp. :this library need pyserial for it's operation, thus make sure that dependencies are satisfied. (it also requires thread module but that is available in a standard python installation, pyserial can be downloaded from PyPi)

Installation

  1. Download the source distribution (zip file) from dist directory
  2. unzip and navigate to the folder containing setup.py and other files
  3. run the following command: python setup.py install
There are three main steps involved in connecting the headset to the mindwave headset then a subsequent 4th step which is explained below can be used to fetch data from the device.


  1. Pairing the device

    In windows the bluetooth device can be paired by clicking 'add new device' in the 'devices and printers' settings dialogue. Mindwave will reserve a virtual COM port for it, such as COM1 or COM2. To know which port is reserved check properties of mindwave, which will be visible in 'devices and printers' section

    In linux tools such as rfcomm can be used to pair. After pairing take a note of the device in the /dev/ directory allocated to the headset. I paired the headset using information given on the following links:
              askubuntu.com and
              westernwillow.com
  2. Once the device is paired the library can be initialised in the following manner:
    object1=NeuroPy("COM6",57600) #windows
  3. The library provides data in two ways, either via callback mechanism or via accessing the required properties (variables for eg. object1.attention to get value for attention). This is explained in step 4.
    If required the callbacks are set and the start method is called.
    object1.start()
  4. The data from the device can be obtained using either of the following methods or both of them together:

    a) Obtaining value: variable1=object1.attention #to get value of attention

    #other variables: attention,meditation,rawValue,delta,theta,lowAlpha,highAlpha,lowBeta,highBeta,lowGamma,midGamma, poorSignal and blinkStrength

    b) Setting callback:a call back can be associated with all the above variables so that a function is called when the variable is updated.
    Syntax: setCallBack("variable",callback_function)
    for eg. to set a callback for attention data the syntax will be setCallBack("attention",callback_function)

Sample Program

from NeuroPy import NeuroPy
object1=NeuroPy("COM6") #If port not given 57600 is automatically assumed
                        #object1=NeuroPy("/dev/rfcomm0") for linux
def attention_callback(attention_value):
    "this function will be called everytime NeuroPy has a new value for attention"
    print "Value of attention is",attention_value
    #do other stuff (fire a rocket), based on the obtained value of attention_value
    #do some more stuff
    return None

#set call back:
object1.setCallBack("attention",attention_callback)

#call start method
object1.start()

while True:
    if(object1.meditation>70): #another way of accessing data provided by headset (1st being call backs)
        object1.stop()         #if meditation level reaches above 70, stop fetching data from the headset

Links:



Sunday 31 March 2013

Capturing packets from an Android device and analyzing them on pc in real time

Capturing network packets on Android and analysing them in real time is not a trivial task. Various off the shelf apps exist for capturing packets however none of them comes close to tools available for pc such as Wireshark. Most of them just dump the packets to a file and aren't of much use.

This post explores one of the ways to analyse packets from an android device on a pc. This article on mobile.tutsplus.com is the place from where much of the work has been drawn from. The reason for making a separate post is because i couldn't get the capture to work by exactly following the directions given on the aforementioned website and i had to make a few changes of my own.

The following are the steps by which packets are captured from an android device and then sent to a pc for analysis.


  1. capture packets using tcpdump
  2. pipe the packets to a netcat server (which basically means that we are sending the packets to a netcat server from where they can be fetched by a client connecting to the server).
  3. using adb forward command forward the remote port (the port on which netcat server is listening) of the android device  to a local port of the PC (wiz making a port on the droid available as a port on pc) .
    the syntax of adb forward command is:
    adb forward <local_port (on PC) > <remote_port (on droid) >
  4. connecting a netcat client to the forwarded port on PC and getting the packets.
  5. piping / routing the packets from netcat to wireshark.
before getting started arm images of tcpdump and netcat must be present on the droid. (did i mention that the droid must be rooted?)

to check if you have correct images file command can be used (on Linux, windows users might use web services such as virus total as they also give the description of the file along with virus scan report).

For getting help with installing these tools on droid the mobile.tutsplus.com article can be referenced.

Once we are ready with all the tools the following steps haave to be followed:
  1. obtain a shell on device (adb shell) and switch to root user (su).
  2. execute the following command
    /data/local/tcpdump -n -s 0 -w - | /data/local/nc -l -p 12345 (on my droid tcpdump and netcat executables were present in /data/local)
  3. forward the port 12345 (port on which netcat is listening) of the droid to port number 54321 on the PC. The command for doing this is:
      adb forward tcp:54321 tcp:12345
  4. connect the netcat client on pc to local port 54321 using the following command and redirect its output to /dev/null (i am on a linux machine).
     nc 127.0.0.1 54321 > /dev/null
  5. open wireshark and start capturing packets on the local loopback interface (not awailable on windows).
  6. Apply the following filter in wireshark to limit displaying of packets from port 54321 only
    tcp.port eq 54321
  7. voila! the packets can now be seen in wireshark.
My system configuration:
OS: ubuntu 12.04
android device: micromax canvas 2 (a110) running android 4.0.4 on a dual core processor ;)

Some of the problems i faced and their solutions:

when using a named pipe by creating one with mkfifo command , piping netcat's output to this pipe and then reading from this pipe in wire shark (using -i switch) the packets were not seen by wireshark as TCP packets however when i tried the above mentioned method , it worked correctly.

Next challenge :
When using facebook chat or whatsapp the packets weren't shown in wireshark, maybe tcpdump is at fault. so the next challenge would be to somehow analyse packets from these two apps.
Also since all the output is obtained from one single port, wireshark sees the all the packets as a part of one giant TCP connection.