January 06th, 2012

Telit GM862-GPS hex() bug

Written by Dave BarkerTopics: Code, News, Python, Embedded

My SHA1 code was returning a different hex digest when run on my Telit GM862 GPS. I eventually tracked the problem down to the hex() function. Simply put hex(3181490320L) does not return the right result!

Run this test script and post your results below.

import sys, SER, MDM

# Set up printing to serial
SER.set_speed('115200', '8N1')
class SerWriter:
  def write(self, s):
    SER.send(s + "\r")
sys.stdout = sys.stderr = SerWriter()

# Simplistic AT command function
def at_command(command):
  # Clear the command interface buffer
  MDM.read()
  # Send the command
  MDM.send(command + '\r', 0)
  # Create a buffer
  buffer = ''
  while 1:
    # Listen to serial port for click
    incoming = MDM.receive(1)
    # If we got some data handle it
    if incoming:
      buffer = buffer + incoming
      if buffer.find("OK") > -1:
        return buffer
      elif buffer.find("ERROR") > -1:
        return ''

# Run the tests
print at_command("AT+CGMM")
print at_command("AT+CGMR")
i = 3181490320L
print i
print long(hex(i), 16)

# Restore standard out
sys.stdout = sys.stderr = sys.__stdout__

My output was:

OK

GM862-GPS

OK


07.03.402

OK

3181490320
2376183952

Cheers, Dave.

Edit: In case anyone's interested here's my hex() replacement. It's probably much slower but it works and can pad the hex string to x bytes.

def write_hex(x, bytes=1):
  h = ['0'] * bytes * 2
  i = 0
  while x > 0:
    if i < bytes * 2:
      h[i] = '0123456789abcdef'[x & 0xf]
    else:
      h.append('0123456789abcdef'[x & 0xf])
    x = x >> 4
    i = i + 1
  h.reverse()
  return ''.join(h)

December 08th, 2011

SEO contact form spammers

Written by Dave BarkerTopics: News

I get loads of emails from SEO peddlers via my contact form, it's irritating. Anyway I've decided to do something about it, each time they mail I'll fain interest and then post the details of those responsible online.

So without further ado I present the SEO contact form spammers gist of shame, first up is Bibin Alexander from Clearpath Technology.

I'll keep updating the gist as the spam comes in, if you want to avoid being shamed please stop spamming me!

Cheers, Dave.

November 28th, 2011

Privilege request explanations

Written by Dave BarkerTopics: Idea

With a lot of "app stores" applications are sandboxed, requiring the user to allow various privileges. I think it's a great idea but there are two flaws:

  1. There's no option to pick and choose the permissions given, it's all or nothing.
  2. There are no explanations given for the required permissions, often you can't make an informed choice.

My suggestion is that Facebook, Google and the likes update their APIs to require an additional parameter when requesting permissions - a reason or explanation. "I need full access to your phone because ...". When you think about it, it's incredible that it's not already a requirement! I suggest empowering users to say no if the reason isn't strong enough, give them the option to say no to permissions they're not comfortable with.

Oh, one thing worth mentioning; there's an interesting looking Chrome app to reduce given Facebook permissions. I've not tried it but I think the author's on to something.

Cheers, Dave.

August 22th, 2011

bit-ratchet, easier binary parsing in PHP

Written by Dave BarkerTopics: Php, Project, Code

Recently I needed to write some code to parse a binary protocol in PHP. Given a ASCII hex string representation of the message I needed to pull off bits and bytes, using them in lots of different ways.

Problem was that you have to read a byte at a time from the hex string, then manually shift bits each time to get what you want. This gets old and confusing very quickly! To solve this I've written bit-ratchet, a small class that lets you read bits and bytes from a hex string very simply.

The idea is you create a bit-ratchet object of your hex string. You then ask for bits and bytes, signed or not and bit-ratchet provides them whilst keeping track of your current position in the data. Additionally I added a few useful methods allowing you to skip, jump and pull off hex.

Things like scaling are left to the user, the one exception being signed numbers which are handled by bit-ratchet. I wanted to avoid creating a complex library like bindata, in my opinion although it's great the DSL it provides is constraining. Better to let the user use the host language and as far as possible stay out of the way!

It scratched my itch but let me know if you've got any ideas about how to expand on the abstraction.

Cheers, Dave

May 14th, 2011

Embedded development setup with Macbook

Written by Dave BarkerTopics: Python, Howto, Embedded

I've been put onto an interesting project recently, doing some embedded Python development for a Telit GM862-GPS unit. Being new to this type of thing it took me a while to get a development enviroment set up that I was happy with. In an effort to share what I've learned, here's my setup:

(To be clear I'm using the Roundsolutions development starter kit for the Telit GM862-GPS with my Macbook pro.)

Roundsolutions dev board

First of all I had to install the usb-serial driver (PL2303_1.2.1r2.dmg) to get the serial port working. Once that's installed and it's connected the serial device /dev/tty.usbserial appeared for use.

Next I followed this guide and connected to the device using the GNU Screen command that's included with Snowleopard. This command worked nicely:

screen -S telit -T vt100 /dev/tty.usbserial 115200,crtcts,-parity,-cstopb

Typing AT returned OK and I knew I was in business!

I soon found that deploying code over serial manually was pretty tedious, it's easy to mess up the AT commands. I wrote this script to automate the process, making deployment as easy as

telit-send-python.py telit example.py

The next issue I hit was that my code was sometimes being crapped up during transfer. I eventually figured out I was using the wrong line terminators for my files, Unix style just uses \n where as the Telit module demands \n\r (DOS style). To convert my files in Emacs I used the buffer-file-coding-system command, so

M-x set buffer-file-coding-system undecided dos

Next I realised backspace wasn't being transmitted properly across Screen, there's an option in the Advanced section of Terminal preferences "Delete sends Cntrl-H" which resolved it for me. Unfortunately I found it messed up my normal SSH sessions, a better solution is to have this fixed in GNU Screen, add these lines to your ~/.screenrc:

 
bindkey -d ^? stuff ^H
bindkey -d ^@ stuff ^H

Another annoyance with Screen was that I wasn't able to scroll up like normal in my Terminal windows. Luckily fixing that was pretty easy, I added this to my ~/.screenrc :

termcapinfo xterm* ti@:te@

Messing with SMS at commands I realised that the body of a SMS needs to be terminated with 0x1a, it bit tricky to type but there's a solution, Screen's "digraph" feature. To send 0x1a here's what I did:

C-a C-v 0x1a

So the next thing I really wanted to was to get the Telit version of Python running locally, allowing me to test things interactively at a 'REPL'. The units run a modified version of Python 1.5.2 and unfortunately I had no luck compiling or installing a version that old under Snowleopard. My solution in the end was to install the Windows version TelitPy1.5.2+_V4.1.exe using Wine. I then set up a little shell-script shortcut to launch it easily. (It installs to ~/.wine/drive_c/Program\ Files/Python/python.exe )

Now I've got a pretty sweet set up, but having the PCB dangling off the side of my Macbook in Starbucks isn't really an option. So I plugged it into my Linux server at home and then I can SSH in and deploy code / interact with the Terminal. (Using Emacs' tramp feature I can edit the code directly over SSH too.)

Only thing worth noting is that the naming convention for serial devices seems different in Linux. Also I found that sometimes the LANG environment variable ended up corrupting the binary transfer. Here's the Screen command I ended up using:

unset LANG && screen -S telit -T vt100 /dev/ttyUSB0 115200,crtcts,-parity,-cstopb

Read the Stty man page for details about those serial options at the end.

I also sometimes needed to check what Screen's _really_ sending out, helpful for debugging problems with transmitting binary data. It's not hard though, just start a Screen session and run this command inside it:

stty raw; cat > binary-file-name

(Just make sure to exit using the C-a :quit screen command rather, most special keys will be sent directly through into your file.)

Finaly while I'm waiting for the Python debugging board to arrive I needed to have some way of getting output through to the serial port. Otherwise t's hard to know if your code even ran at all. Turns out it's not too hard, here's a (noddy) example:

import SER, MOD, MDM, GPS, sys

# Set the baud rate
SER.set_speed('115200', '8N1')

# Send stout and stderr over serial
# http://forum.sparkfun.com/viewtopic.php?t=6289
class SerWriter:
  def write(self, s):
    SER.send(s + '\r')
sys.stdout = sys.stderr = SerWriter()

# You get the idea...
print "Lovely stuff"

Thanks for reading, I'd be interested to hear how any tips you've got in the comments. Also if anyone knows a better support forum / community than the Roundsolutions one let me know.

Cheers, Dave.

Edit: I've just discovered Sparkfun's evaluation board. The board looks a lot nicer, it's cheaper and Sparkfun actually list prices and stock. I've just been browsing their forum and it's way friendlier too, I would definately go with Sparkfun over Roundsolutions if you get the choice.

Edit 2: I've had all sorts of problems uploading Python scripts larger than about 7kb to the Telit module. In the end I updated my script to send files in chunks with enough delay for the module to catch up. I also had problems deleting large files until I removed the quotes around a file name. Much much more details on this forum post.

Edit 3: I've just been shown this great guide about Telit Python development, well worth reading.

Older posts