/// <summary> /// Create a single packet MDC1200 data array. /// </summary> /// <param name="packet">MDC packet to create</param> public void CreateSingle(MDCPacket packet) { Messages.Trace("Creating single-length MDC1200 packet " + packet.ToString()); // initialize MDC1200 header GenerateHeader(ref dataArray, ref dataLoaded, NumberOfPreambles, true); // create a temporary array DATA_SIZE - 12 (stripping the size used by // the header) byte[] dp = new byte[CODEWORD_LENGTH]; // fill the first bytes with the proper opcode and argument data dp[0] = packet.Operation; dp[1] = packet.Argument; dp[2] = (byte)((packet.UnitID >> 8) & 0x00FF); dp[3] = (byte)(packet.UnitID & 0x00FF); // pack data PackData(dp); // block copy new data into MDC1200 data array Buffer.BlockCopy(dp, 0, this.dataArray, dataLoaded, dp.Length); this.dataLoaded += 14; // dump output data for debug purposes Messages.TraceHex("Raw Data Dump", dataArray); }
/// <summary> /// Internal function to process the bits of a MDC1200 data stream. /// </summary> /// <param name="idx">Decoder Index</param> /// <returns>True, if CRC was matched and decoding succeeded, otherwise false</returns> private bool ProcessBits(int idx) { int[] lbits = new int[MAX_MDC1200_BITS]; int lbc = 0; byte[] data = new byte[14]; ushort ccrc, rcrc; // do deep magic bit manipulation for (int i = 0; i < 16; i++) { // loop through 8 bits for (int j = 0; j < 7; j++) { int k = (j * 16) + i; lbits[lbc] = this.bits[idx, k]; ++lbc; } } for (int i = 0; i < 14; i++) { data[i] = 0; // loop through 8 bits (get each byte) for (int j = 0; j < 8; j++) { int k = (i * 8) + j; if (lbits[k] != 0) { data[i] |= (byte)(1 << j); } } } // compute CRC ccrc = ComputeCRC(data, 4); rcrc = (ushort)(data[5] << 8 | data[4]); // dump output data for debug purposes Messages.TraceHex("Decoded Data Dump CCRC " + ccrc.ToString("X4") + " RCRC " + rcrc.ToString("X4"), data); // compare the computed CRC to the recieved CRC if (ccrc == rcrc) { byte crc; if (this.shstate[idx] == 2) { // copy second packet data second.Operation = data[0]; second.Argument = data[1]; second.UnitID = (ushort)((data[2] << 8) | data[3]); // reset the states for all decoders for (int k = 0; k < MDC_ND; k++) { this.shstate[k] = 0; } this.frameCount = 2; } else { this.frameCount = 1; // copy first packet data first.Operation = data[0]; first.Argument = data[1]; first.UnitID = (ushort)((data[2] << 8) | data[3]); crc = (byte)((data[4] << 8) | data[5]); // reset the states for all decoders for (int k = 0; k < MDC_ND; k++) { this.shstate[k] = 0; } // check if the operation code is for a "double" packet switch (data[0]) { case OpType.DOUBLE_PACKET_TYPE1: case OpType.DOUBLE_PACKET_TYPE2: { // we have a double packet reset the frame count to 0 // and set the state to reflect a double packet this.frameCount = 0; this.shstate[idx] = 2; this.shcount[idx] = 0; ClearBits(idx); } break; default: break; } } // if our frame count is non-zero execute the decoded callback if (this.frameCount > 0) { Messages.Trace("Frame Count: " + frameCount); Messages.Trace("MDC Frame 1 = " + ToString(first)); // if we have a frame count of > 1 then display second packet data if (this.frameCount > 1) { Messages.Trace("MDC Frame 2 = " + ToString(second)); } Messages.Trace("MDC1200 packet First (" + first.ToString() + "), Second (" + second.ToString() + ")"); // fire event if (DecoderCallback != null) { DecoderCallback(this.frameCount, first, second); } // reset frame count this.frameCount = 0; } return(true); } else { Messages.Trace("CRC Mismatch! Bad MDC Frame " + this.frameCount); // since the CRC is bad reset the frame count this.frameCount = 0; this.shstate[idx] = -1; } return(false); }