HTTP Headers GPRS Modem HTTP Post

All my initial deployments used a CAT5 cable and my ADSL connection which was great for testing and debugging but not really representative of the connectivity a mobile solution would experience.

For this test I used a seeedstudio GPRS shield on top of a Netduino Plus.

Netduino + SeeedStudio GPRS Modem

SeedStudio GPRS Modem on top of Netduino Plus

The shield is based on a SIM900 module from SIMCom Wireless and can also initiate HTTP requests. This functionality looked useful as it could make my code a bit simpler and reduce the load on the Netduino CPU.

I initially looked at a the Netduino driver for Seeeduino GSM shield on codeplex but it appeared to only support the sending of SMS messages. (Feb2012)

After some more searching I stumbled across the CodeFreak Out SeeedStudio GPRS Driver which is available as a Nuget package or source code. I had to modify the code to allow me to pass a list of HTTP headers to be added into the request

var gsm = new GPRSShield("www.vodafone.net.nz", SerialPorts.COM1);
gsm.Post(@"gpstrackerhttpheaders.cloudapp.net", 80, @"/posV4.aspx", httpHeaders, "application/html", "");

My simulated data used the same header format as in my earlier testing

x-Pos: 5C-86-4A-00-3F-63 20130218081228 F -43.00000 172.00000 31.4 1.31 0 0

I timed 10 requests

4789,3778,3793,3756,3796,3825,3806,3817,3795,3877

Average 3903 mSec

This was a bit slower than I was expecting so i’ll have to do some digging into the code and see if anything looks a bit odd.

HTTP Headers Payload encryption

So far the content of the messages has been sent as clear text which would not be acceptable for many applications. The requirement for data privacy causes a problem on the Netduino+ (Nov 2012) as the standard NetMF crypto libraries are not baked into the platform.

I then set about finding some crypto libraries which were NetMF friendly. RSA and Xtea are included in some of other NetMF platforms in the Microsoft.SPOT.Cryptography assembly so Xtea seemed like a reasonable choice to ensure interoperability.

When looking for crypto implementations one of the best sources is the Legion of the Bouncy Castle which was where I started. I downloaded the the V17.7 zip file had a look at the size of the Xtea code & all the associated support libraries and then parked that approach as I was worried about the size and performance of the resulting binaries.

I then looked at other possible tea, xtea & xxtea implementations (including porting the original C code to C#)

I am not a cryptographer so I can’t personally confirm the quality and correctness of an implementation. So after having interop problems I went back to the Legion of the Bouncy Castle which has been peer reviewed by experts and had another look. To get an Xtea implementation working on a .NetMF platform like the Netduino+ you need to include the following files…

  • CryptoException.cs
  • DataLengthException.cs
  • IBlockCipher.cs
  • ICipherParameters.cs
  • KeyParameter.cs
  • XTEAEngine.cs

On the Azure side of things where size is not so critical I just added a reference to the Bouncy Castle main project.

Xtea requires 128 bit blocks so you need to pad out the data on the client, then trim off the padding on the server.
// Pad out the data to a multiple of 8 bytes with spaces
if (xPosition.Length % 8 != 0)
{
xPosition += new string(' ', 8 - xPosition.Length % 8);
}

The key and the data need to be converted to byte arrarys, the Xtea engine initialised and a buffer for storing the encrypted data created.

byte[] dataBytes = Encoding.UTF8.GetBytes(xPosition);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);

xteaEngine.Init(true, new KeyParameter(keyBytes));

Then the data can be encrypted in 8 byte chunks
byte[] cryptoBytes = new byte[dataBytes.Length];
for (int i = 0; i < dataBytes.Length; i += 8)
{
xteaEngine.ProcessBlock(dataBytes, i, cryptoBytes, i);
}

I hex encoded the encrypted data for transmission. Downside to this was it doubled the size of the payload
string hexEncodedCryptoBytes = ByteArrayToHex(cryptoBytes);

I added a StopWatch so I could measure the time taken to encrypt the position data (roughly 72 chars) on my Netduino+
285,342,277,345,282,345,342,350,278,343
Average 318mSec

The size of the payload had grown a bit
Request - Bytes Sent: 262
POST http://gpstrackerhttpheaders.cloudapp.net/posV7.aspx HTTP/1.1
Host: gpstrackerhttpheaders.cloudapp.net
x-Pos: 693A7AC6EBF4E5848CE8ABBA2BC6CAC1ED20574C1B2384E7E246A202C8A67E3DE14EE5231A5DF98C211F64F8402547F8BFDCC2241AAE3782A820086E5EF37AA2C50744941F588442
Content-Length: 0
Connection: Close

Response - Bytes Received: 132
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html
Date: Sun, 03 Feb 2013 04:53:30 GMT
Content-Length: 0

This increase in size had an impact on the time taken to send the message

1123,1144,1122,1142,1125,1125,1138,1111,1099,1141
Average 1127mSec

The binary downloaded to the Netduino+ had grown to 28K which still left plenty of space for additional functionality.