709 lines
23 KiB
Plaintext
709 lines
23 KiB
Plaintext
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: CHello.cs
|
||
|
//
|
||
|
// Note: Simple Singularity test program.
|
||
|
//
|
||
|
using System;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
using System.Threading;
|
||
|
|
||
|
using Microsoft.Singularity;
|
||
|
using Microsoft.Singularity.Directory;
|
||
|
using Microsoft.Singularity.V1.Services;
|
||
|
using Microsoft.Singularity.Io;
|
||
|
|
||
|
namespace Microsoft.Singularity.Applications
|
||
|
{
|
||
|
public class CHello
|
||
|
{
|
||
|
public static int Main(String[] args)
|
||
|
{
|
||
|
Console.WriteLine("Hello World!");
|
||
|
|
||
|
ProtocolTester.UnitTest_LDPC o = new ProtocolTester.UnitTest_LDPC();
|
||
|
|
||
|
o.Run();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace Microsoft.SPOT
|
||
|
{
|
||
|
/// <include file='doc\Debug.uex' path='docs/doc[@for="Trace"]/*' />
|
||
|
public abstract class Trace
|
||
|
{
|
||
|
/// <include file='doc\Debug.uex' path='docs/doc[@for="Trace.Print"]/*' />
|
||
|
[System.Diagnostics.ConditionalAttribute("TINYCLR_TRACE")]
|
||
|
static public void Print( string text )
|
||
|
{
|
||
|
Debug.Print( text );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\Debug.uex' path='docs/doc[@for="Debug"]/*' />
|
||
|
public abstract class Debug
|
||
|
{
|
||
|
static public void Print( string text )
|
||
|
{
|
||
|
Console.WriteLine( text );
|
||
|
}
|
||
|
|
||
|
static public void DumpBuffer( byte[] buf, bool fCRC, bool fOffset )
|
||
|
{
|
||
|
if(buf == null) return;
|
||
|
|
||
|
int offset = 0;
|
||
|
int len = buf.Length;
|
||
|
|
||
|
while(len > 0)
|
||
|
{
|
||
|
int row = len > 16 ? 16 : len;
|
||
|
int i;
|
||
|
|
||
|
if(fOffset) Console.Write( "{0:X8}:", offset );
|
||
|
|
||
|
for(i=0; i<16; i++)
|
||
|
{
|
||
|
if(i<row)
|
||
|
{
|
||
|
Console.Write( " {0:X2}", buf[i+offset] );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Console.Write( " " );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Console.Write( " " );
|
||
|
|
||
|
for(i=0; i<row; i++)
|
||
|
{
|
||
|
byte c = buf[i+offset];
|
||
|
|
||
|
if(c <= 0x1F) c = (byte)'.';
|
||
|
if(c >= 0x7F) c = (byte)'.';
|
||
|
|
||
|
Console.Write( "{0}", (char)c );
|
||
|
}
|
||
|
|
||
|
offset += row;
|
||
|
len -= row;
|
||
|
|
||
|
Console.WriteLine();
|
||
|
}
|
||
|
|
||
|
Console.WriteLine();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public abstract class Math
|
||
|
{
|
||
|
static System.Random s_rnd = new System.Random();
|
||
|
|
||
|
static public int Random( int modulo )
|
||
|
{
|
||
|
return s_rnd.Next( modulo );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace Microsoft.SPOT.Hardware
|
||
|
{
|
||
|
public abstract class Radio
|
||
|
{
|
||
|
static public void XorData( byte[]! left, byte[]! right )
|
||
|
{
|
||
|
for(int i=0; i<left.Length; i++)
|
||
|
{
|
||
|
left[i] ^= right[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace Microsoft.DirectBand
|
||
|
{
|
||
|
internal class CreateNonNullArray<T>
|
||
|
{
|
||
|
T[]! elements;
|
||
|
int count;
|
||
|
|
||
|
public CreateNonNullArray( int n )
|
||
|
{
|
||
|
this.elements = new T[n];
|
||
|
this.count = 0;
|
||
|
base();
|
||
|
}
|
||
|
|
||
|
public void InitNext( T elem )
|
||
|
{
|
||
|
if(this.count < elements.Length)
|
||
|
{
|
||
|
this.elements[this.count++] = elem;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw new InvalidOperationException( "Too many elements initialized" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public T[]! GetArray()
|
||
|
{
|
||
|
if(count != elements.Length)
|
||
|
{
|
||
|
throw new InvalidOperationException("Not all elements initialized");
|
||
|
}
|
||
|
|
||
|
return this.elements;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public class LDPC
|
||
|
{
|
||
|
public static T[]![]! ConstructArray<T>( int i, int j )
|
||
|
{
|
||
|
CreateNonNullArray<T[]!> nna = new CreateNonNullArray<T[]!>( i );
|
||
|
|
||
|
for(int k=0; k < i; k++)
|
||
|
{
|
||
|
nna.InitNext( new T[j] );
|
||
|
}
|
||
|
|
||
|
return nna.GetArray();
|
||
|
}
|
||
|
|
||
|
static public byte[]![]! Solve( byte[][] dataPackets, byte[][] eccPackets, int[] eccIndex, int totalEccPackets, int totalDataPackets, int missedDataPackets, int receivedEccPackets, int pktLen )
|
||
|
{
|
||
|
// dataPackets x0 = actual N - k data packets received (blanks in the missing locations)
|
||
|
// eccPackets rhs = actual kp EC packets received
|
||
|
// eccIndex gotec = array contains indices of EC packet received
|
||
|
// totalEccPackets M = total length of EC stream
|
||
|
// totalDataPackets N = total length of data stream
|
||
|
// missedDataPackets kk = number of data packets missed
|
||
|
// receivedEccPackets kp = number of EC packets received
|
||
|
// AA = M * N matrix used to get the EC packets at encoder
|
||
|
|
||
|
if(dataPackets == null) throw new NullReferenceException();
|
||
|
if(eccPackets == null) throw new NullReferenceException();
|
||
|
if(eccIndex == null) throw new NullReferenceException();
|
||
|
|
||
|
int maxMN = (totalEccPackets > totalDataPackets) ? totalEccPackets : totalDataPackets;
|
||
|
bool[] pseudo = new bool[maxMN];
|
||
|
int i;
|
||
|
int j;
|
||
|
int k;
|
||
|
|
||
|
for(i=0; i < maxMN; i += 5) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 7) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 13) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 17) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 19) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 33) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 37) pseudo[i] = true;
|
||
|
|
||
|
//bool[][] A = new bool[receivedEccPackets][];
|
||
|
//for(i=0; i < receivedEccPackets; i++)
|
||
|
//{
|
||
|
// A[i] = new bool[missedDataPackets];
|
||
|
//} // The actual matrix to be inverted (submatrix of AA)
|
||
|
bool[]![]! A = ConstructArray<bool>( receivedEccPackets, missedDataPackets );
|
||
|
|
||
|
int[]! miss = new int[missedDataPackets + 1]; // Indices of the missing data packets
|
||
|
|
||
|
int c = 0;
|
||
|
|
||
|
for(i = 0; i < missedDataPackets; i++)
|
||
|
{
|
||
|
while(c < totalDataPackets && dataPackets[c] != null)
|
||
|
{
|
||
|
c++;
|
||
|
}
|
||
|
|
||
|
//Microsoft.SPOT.Debug.Print( "Missing: " + c );
|
||
|
miss[i] = c++;
|
||
|
}
|
||
|
// Get miss array
|
||
|
miss[missedDataPackets] = -1;
|
||
|
|
||
|
for(i=0; i < receivedEccPackets; i++)
|
||
|
{
|
||
|
byte[] t = eccPackets[i]; if(t == null) throw new NullReferenceException();
|
||
|
|
||
|
t = (byte[])t.Clone(); if(t == null) throw new NullReferenceException();
|
||
|
|
||
|
eccPackets[i] = t;
|
||
|
|
||
|
// What's the actual system we have to solve
|
||
|
|
||
|
for(j=0; j < missedDataPackets; j++)
|
||
|
{
|
||
|
int idx = eccIndex[i] + miss[j];
|
||
|
|
||
|
//A[i][j] = AA[eccIndex[i]][miss[j]];
|
||
|
A[i][j] = pseudo[ idx < maxMN ? idx : idx - maxMN ];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(j = 0; j < totalDataPackets; j++)
|
||
|
{
|
||
|
byte[] dataPacket = dataPackets[j];
|
||
|
|
||
|
if(dataPacket != null)
|
||
|
{
|
||
|
// Packet j is not a missing packet
|
||
|
for(i = 0; i < receivedEccPackets; i++)
|
||
|
{
|
||
|
int idx = eccIndex[i] + j;
|
||
|
|
||
|
if(pseudo[ idx < maxMN ? idx : idx - maxMN ]) /*AA[eccIndex[i]][j]*/
|
||
|
{
|
||
|
//Microsoft.SPOT.Debug.Print( "XOR: eccPackets[" + i + "], dataPackets[" + j + "]" );
|
||
|
byte[] eccPacket = eccPackets[i];
|
||
|
|
||
|
if(eccPacket != null)
|
||
|
{
|
||
|
Microsoft.SPOT.Hardware.Radio.XorData( eccPacket, dataPacket );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//DumpMatrix( "Beginning:", A, kp, kk );
|
||
|
|
||
|
// Now set up some variables and do the LU decomposition
|
||
|
|
||
|
//byte[][] y = new byte[missedDataPackets+1][]; // Intermediate solution
|
||
|
//byte[][] xhat = new byte[missedDataPackets+1][];
|
||
|
//
|
||
|
//
|
||
|
//for(i=0; i < missedDataPackets+1; i++)
|
||
|
//{
|
||
|
// y [i] = new byte[ pktLen ];
|
||
|
// xhat[i] = new byte[ pktLen ];
|
||
|
//}
|
||
|
byte[]![]! y = ConstructArray<byte>( missedDataPackets+1, missedDataPackets+1 );
|
||
|
byte[]![]! xhat = ConstructArray<byte>( missedDataPackets+1, missedDataPackets+1 );
|
||
|
|
||
|
int i2;
|
||
|
int j2;
|
||
|
int p;
|
||
|
|
||
|
//DumpMatrix( "Beginning:", A, kp, kk );
|
||
|
|
||
|
for(k = 0; k < missedDataPackets; k++)
|
||
|
{
|
||
|
p = k;
|
||
|
|
||
|
// Find a remaining row with non-zero k-th element
|
||
|
while(A[p][k] == false)
|
||
|
{
|
||
|
p++;
|
||
|
|
||
|
if(p == receivedEccPackets)
|
||
|
{
|
||
|
//Microsoft.SPOT.Debug.Print( "Non-triangular matrix?" );
|
||
|
//return null;
|
||
|
throw new Exception( "Non-triangular matrix?" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if(p != k)
|
||
|
{
|
||
|
//Microsoft.SPOT.Debug.Print( "Swap: " + p + " " + k );
|
||
|
// Swap row k and row p
|
||
|
for(j2 = 0; j2 < missedDataPackets; j2++)
|
||
|
{
|
||
|
bool temp = A[k][j2];
|
||
|
A[k][j2] = A[p][j2];
|
||
|
A[p][j2] = temp;
|
||
|
}
|
||
|
|
||
|
byte[] packetTemp = eccPackets[k];
|
||
|
eccPackets[k] = eccPackets[p];
|
||
|
eccPackets[p] = packetTemp;
|
||
|
|
||
|
//DumpMatrix( "After:", A, kp, kk );
|
||
|
}
|
||
|
|
||
|
for(i2 = k + 1; i2 < receivedEccPackets; i2++)
|
||
|
{
|
||
|
if(A[i2][k] == A[k][k])
|
||
|
{
|
||
|
//Microsoft.SPOT.Debug.Print( "Mix rows: " + i2 + " " + k );
|
||
|
for(j2 = k + 1; j2 < missedDataPackets; j2++)
|
||
|
{
|
||
|
A[i2][j2] ^= A[k][j2];
|
||
|
}
|
||
|
|
||
|
//DumpMatrix( "After:", A, kp, kk );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//DumpMatrix( "After:", A, kp, kk );
|
||
|
|
||
|
//////////////////////////////////////////////////////////
|
||
|
|
||
|
// Solve Ly = Pb
|
||
|
|
||
|
for(i2 = 0; i2 < missedDataPackets; i2++)
|
||
|
{
|
||
|
y[i2] = (byte[]!)eccPackets[i2];
|
||
|
|
||
|
for(j2 = 0; j2 < i2; j2++)
|
||
|
{
|
||
|
//y[i2] = (sbyte) (((y[i2] ^ (A[i2][j2] * y[j2])) & 0x000000ff));
|
||
|
|
||
|
if(A[i2][j2])
|
||
|
{
|
||
|
//Microsoft.SPOT.Debug.Print( "XOR: y[" + i2 + "], y[" + j2 + "]" );
|
||
|
Microsoft.SPOT.Hardware.Radio.XorData( y[i2], y[j2] );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Now solve Ux = y
|
||
|
for(i2 = missedDataPackets - 1; i2 >= 0; i2--)
|
||
|
{
|
||
|
xhat[i2] = y[i2];
|
||
|
|
||
|
for(j2 = i2 + 1; j2 < missedDataPackets; j2++)
|
||
|
{
|
||
|
//xhat[i2] = (sbyte) (((xhat[i2] ^ (A[i2][j2] * xhat[j2])) & 0x000000ff));
|
||
|
if(A[i2][j2])
|
||
|
{
|
||
|
//Microsoft.SPOT.Debug.Print( "XOR: xhat[" + i2 + "], xhat[" + j2 + "]" );
|
||
|
Microsoft.SPOT.Hardware.Radio.XorData( xhat[i2], xhat[j2] );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(i2 = 0; i2 < missedDataPackets; i2++)
|
||
|
{
|
||
|
// Rogue value to indicate non-invertible
|
||
|
if(A[i2][i2] == false)
|
||
|
{
|
||
|
//return null;
|
||
|
throw new Exception( "Non-invertible matrix?" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return xhat;
|
||
|
}
|
||
|
|
||
|
static public byte[][] GenerateEC( byte[][] dataPackets, int totalEccPackets, int totalDataPackets, int pktLen )
|
||
|
{
|
||
|
int maxMN = (totalEccPackets > totalDataPackets) ? totalEccPackets : totalDataPackets;
|
||
|
int i;
|
||
|
int j;
|
||
|
|
||
|
if(dataPackets == null) throw new NullReferenceException();
|
||
|
|
||
|
bool[] pseudo = new bool[maxMN];
|
||
|
|
||
|
for(i=0; i < maxMN; i += 5) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 7) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 13) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 17) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 19) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 33) pseudo[i] = true;
|
||
|
for(i=0; i < maxMN; i += 37) pseudo[i] = true;
|
||
|
|
||
|
byte[][] eccPackets = new byte[totalEccPackets][];
|
||
|
|
||
|
for(i=0; i < totalEccPackets; i++)
|
||
|
{
|
||
|
eccPackets[i] = new byte[ pktLen ];
|
||
|
}
|
||
|
|
||
|
for(i=0; i < totalEccPackets; i++)
|
||
|
{
|
||
|
// Generate the EC stream
|
||
|
|
||
|
for(j=0; j < totalDataPackets; j++)
|
||
|
{
|
||
|
//ec[i] = (sbyte) (((ec[i] ^ (AA[i][j] * x[j])) & 0x000000ff));
|
||
|
|
||
|
int idx = i + j;
|
||
|
|
||
|
if(pseudo[ idx < maxMN ? idx : idx - maxMN ]) /*AA[i][j]*/
|
||
|
{
|
||
|
byte[] eccPacket = eccPackets[i];
|
||
|
byte[] dataPacket = dataPackets[j];
|
||
|
|
||
|
if(eccPacket != null && dataPacket != null)
|
||
|
{
|
||
|
Microsoft.SPOT.Hardware.Radio.XorData( eccPacket, dataPacket );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return eccPackets;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace ProtocolTester
|
||
|
{
|
||
|
public class UnitTest_LDPC
|
||
|
{
|
||
|
// main program written by hpleung
|
||
|
// Procedure:
|
||
|
// 1. Generate Random Data Unit
|
||
|
// 2. Generate Error Correction Unit
|
||
|
// 3. Inject Errors in The Random Data Unit
|
||
|
// 4. Decode
|
||
|
// 5. Make sure after decoding data is fully received
|
||
|
// Run it with run.exe nDataPacket nErrorCorrection nPercentageLoss nIteration
|
||
|
//
|
||
|
public void Run()
|
||
|
{
|
||
|
//for quick correctness verification
|
||
|
Microsoft.SPOT.Debug.Print( "LPDC Test Started" );
|
||
|
|
||
|
// for(int i=0; i<100; i++)
|
||
|
// {
|
||
|
// RunPass( 40, 40, 40, 106 );
|
||
|
// }
|
||
|
// return;
|
||
|
for(int nPacketLength=10; nPacketLength <= 120; nPacketLength = nPacketLength + 10)
|
||
|
{
|
||
|
RunPass( nPacketLength, nPacketLength, 40, 106 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void RunPass( int nDataPacketCount, int nErrorCorrectionCount, int nPercentageLoss, int nPacketSize )
|
||
|
{
|
||
|
byte[][] arrDataPacket = new byte[nDataPacketCount][];
|
||
|
byte[][] arrDataReceived = new byte[nDataPacketCount][];
|
||
|
byte[][] arrErrorCorrectionStream = null;
|
||
|
int nDataLossCount = 0;
|
||
|
int i;
|
||
|
|
||
|
//randomly generate some data
|
||
|
PopulatePacket( arrDataPacket, nPacketSize );
|
||
|
|
||
|
for(i=0; i<nDataPacketCount; i++)
|
||
|
{
|
||
|
Randomize( arrDataPacket[i] );
|
||
|
}
|
||
|
Microsoft.SPOT.Debug.Print( "Randomly generated packets" );
|
||
|
|
||
|
//
|
||
|
// Now do the encoding
|
||
|
//
|
||
|
// Generate the full EC stream
|
||
|
//
|
||
|
arrErrorCorrectionStream = Microsoft.DirectBand.LDPC.GenerateEC( arrDataPacket, nErrorCorrectionCount, nDataPacketCount, nPacketSize );
|
||
|
if(arrErrorCorrectionStream == null) throw new NullReferenceException();
|
||
|
Microsoft.SPOT.Debug.Print( "Encoding Finished" );
|
||
|
|
||
|
|
||
|
// we do not like this- we want to make sure we lose
|
||
|
// appropriately the number of packets
|
||
|
// why? Because we want to know exactly how much we lose
|
||
|
// as the cpu utilization depends on the number of packet to correct
|
||
|
|
||
|
int nPacketToLossFix = (nPercentageLoss * nDataPacketCount) / 100;
|
||
|
|
||
|
#if LDPC_DROPINORDER
|
||
|
for(i=0; i<nDataPacketCount; i++)
|
||
|
{
|
||
|
if(i >= nPacketToLossFix)
|
||
|
{
|
||
|
arrDataReceived[i] = arrDataPacket[i];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
arrDataReceived[i] = null;
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
int nPacketToGet = nDataPacketCount - nPacketToLossFix;
|
||
|
while(nPacketToGet > 0)
|
||
|
{
|
||
|
i = Microsoft.SPOT.Math.Random( nDataPacketCount - 1 );
|
||
|
//Microsoft.SPOT.Debug.Print( "Picked " + i );
|
||
|
|
||
|
if(arrDataReceived[i] == null)
|
||
|
{
|
||
|
arrDataReceived[i] = arrDataPacket[i];
|
||
|
nPacketToGet--;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
for(i=0; i<nDataPacketCount; i++)
|
||
|
{
|
||
|
if(arrDataReceived[i] == null)
|
||
|
{
|
||
|
nDataLossCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
Microsoft.SPOT.Debug.Print( "We have simulated Packet receiving with loss " + nDataLossCount );
|
||
|
|
||
|
// Now we determine how many EC packet we want to receive
|
||
|
int nErrorPacketToReceive;
|
||
|
|
||
|
if(nDataLossCount * 108 > (nDataLossCount + 5) * 100)
|
||
|
{
|
||
|
nErrorPacketToReceive = (int)((nDataLossCount * 108)/100) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
nErrorPacketToReceive = nDataLossCount + 5;
|
||
|
}
|
||
|
|
||
|
if(nErrorPacketToReceive > nErrorCorrectionCount)
|
||
|
{
|
||
|
nErrorPacketToReceive = nErrorCorrectionCount;
|
||
|
}
|
||
|
|
||
|
int[]! arrECPacketReceived = new int [nErrorPacketToReceive];
|
||
|
byte[][] arrRHS = new byte[nErrorPacketToReceive][];
|
||
|
|
||
|
// Randomly Pick up Error Packets
|
||
|
for(i=0; i<arrECPacketReceived.Length;i++)
|
||
|
{
|
||
|
int nECPacketPositionReceived = GetNextRandomPosition( arrECPacketReceived, i );
|
||
|
|
||
|
arrRHS [i] = arrErrorCorrectionStream[nECPacketPositionReceived];
|
||
|
arrECPacketReceived[i] = nECPacketPositionReceived;
|
||
|
}
|
||
|
|
||
|
Microsoft.SPOT.Debug.Print( "Error Correction Packet Pickup Simulation Done" );
|
||
|
|
||
|
//--//
|
||
|
|
||
|
//Now let decode it
|
||
|
|
||
|
DateTime start = DateTime.Now;
|
||
|
byte[]![]! arrCorrectedPackets = Microsoft.DirectBand.LDPC.Solve( arrDataReceived ,
|
||
|
arrRHS ,
|
||
|
arrECPacketReceived ,
|
||
|
nErrorCorrectionCount ,
|
||
|
nDataPacketCount ,
|
||
|
nDataLossCount ,
|
||
|
nErrorPacketToReceive ,
|
||
|
nPacketSize );
|
||
|
|
||
|
TimeSpan totalExecutionTime = DateTime.Now - start;
|
||
|
//int calls = Microsoft.SPOT.Hardware.Radio.XorDataCalls;
|
||
|
Microsoft.SPOT.Debug.Print( "Data = " + nDataPacketCount + " EC = " + nErrorCorrectionCount + " Loss = " + nPercentageLoss + " Picked EC = " + nErrorPacketToReceive + " Duration: " + totalExecutionTime.ToString() );
|
||
|
|
||
|
bool bSame = true;
|
||
|
|
||
|
if(arrCorrectedPackets != null)
|
||
|
{
|
||
|
//Microsoft.SPOT.Debug.Print( "Cormac Says : All Data Has Been Recovered" );
|
||
|
|
||
|
int pos = 0;
|
||
|
|
||
|
for(i=0; i<arrDataPacket.Length; i++)
|
||
|
{
|
||
|
if(arrDataReceived[i] == null)
|
||
|
{
|
||
|
if(SameContents( arrCorrectedPackets[pos], arrDataPacket[i] ) == false)
|
||
|
{
|
||
|
Microsoft.SPOT.Debug.Print( "Mismatch: " + i );
|
||
|
Microsoft.SPOT.Debug.DumpBuffer( arrCorrectedPackets[pos], false, true );
|
||
|
Microsoft.SPOT.Debug.DumpBuffer( arrDataPacket [i ], false, true );
|
||
|
bSame = false;
|
||
|
}
|
||
|
|
||
|
pos++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bSame = false;
|
||
|
|
||
|
//Microsoft.SPOT.Debug.Print( "Cormac Says: All Data Has not been recovered" );
|
||
|
}
|
||
|
|
||
|
if(bSame)
|
||
|
{
|
||
|
Microsoft.SPOT.Debug.Print( "SUCCESS --- No Mismatch" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Microsoft.SPOT.Debug.Print( "BUGBUG - We have a mismatch" );
|
||
|
}
|
||
|
|
||
|
//Microsoft.SPOT.Debug.Print( "Total XOR on Packet " + calls );
|
||
|
Microsoft.SPOT.Debug.Print( "" );
|
||
|
}
|
||
|
|
||
|
public int GetNextRandomPosition( int[]! arrECPacketReceived, int nFilled )
|
||
|
{
|
||
|
bool bFound = false;
|
||
|
int nPosition = 0;
|
||
|
|
||
|
while(bFound == false)
|
||
|
{
|
||
|
bFound = true;
|
||
|
nPosition = Microsoft.SPOT.Math.Random( arrECPacketReceived.Length );
|
||
|
|
||
|
//make sure we did not already picked it
|
||
|
for(int i=0;i<nFilled;i++)
|
||
|
{
|
||
|
if(arrECPacketReceived[i] == nPosition)
|
||
|
{
|
||
|
bFound = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nPosition;
|
||
|
}
|
||
|
|
||
|
public void PopulatePacket( byte[][] arrPacket, int nPacketSize )
|
||
|
{
|
||
|
if(arrPacket == null) throw new NullReferenceException();
|
||
|
|
||
|
for(int i=0; i<arrPacket.Length; i++)
|
||
|
{
|
||
|
arrPacket[i] = new byte[ nPacketSize ];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int last = 0;
|
||
|
|
||
|
public void Randomize( byte[] data )
|
||
|
{
|
||
|
if(data == null) throw new NullReferenceException();
|
||
|
|
||
|
for(int i=0; i<data.Length; i++)
|
||
|
{
|
||
|
data[i] = (byte)(last+i);//(byte)Microsoft.SPOT.Math.Random( 255 );
|
||
|
}
|
||
|
last++;
|
||
|
}
|
||
|
|
||
|
public bool SameContents( byte[] left, byte[] right )
|
||
|
{
|
||
|
if(left == null) throw new NullReferenceException();
|
||
|
if(right == null) throw new NullReferenceException();
|
||
|
|
||
|
for(int i=0; i<left.Length; i++)
|
||
|
{
|
||
|
if(left[i] != right[i]) return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|