Example #1
0
        }// ParseMessage

        /// <summary>
        /// Try processing the data as a DocCap/SigCap message
        /// </summary>
        /// <param name="d">Decoded data from USB HID channel</param>
        /// <returns>true if processed as a DocCap message, false otherwise</returns>
        public Boolean ParseMessage(DecodeData d)
        {
            if (d.CodeType == DecodeData.CodeTypes.SignatureCapture)
            {
                processSigCapContent(d.RawData, true);
                return(true);
            }

            // Document Capture messages can be formatted as one of two data packets:
            //  - a multi-barcode (0x98) (Obsolete, decoded here for backward compatibility)
            //  - a ISO15434 (0xB5) (Format generated by scanner)
            if (d.CodeType == (DecodeData.CodeTypes) 0x98) // BT_MULTI_BARCODE_SSI_PACKET_TYPE
            {
                processOldDocCapContent(d.RawData, usbBus.HID);
                return(true);
            }

            if (d.CodeType == (DecodeData.CodeTypes) 0xB5) // BT_ISO15434 (New DocCap format)
            {
                processISO15434DocCap(d.RawData, usbBus.HID);
                return(true);
            }

            return(false);
        } // ParseMessage
Example #2
0
        } // processOldDocCapContent

        private void processISO15434DocCap(byte[] rawData, usbBus theBus)
        {
            // Validate the basic message structure first
            try
            {
                // Header: is PacketLength correct?
                //   Packet length does not include itself in the count
                int packetLength = (rawData[0] << 24) |
                                   (rawData[1] << 16) |
                                   (rawData[2] << 08) |
                                   rawData[3];
                if (packetLength + 4 != rawData.Length)
                {
                    throw new Exception("bytes received doesn't match packet length (" + (packetLength + 4) + " vs " + rawData.GetLength(0) + ")");
                }

                // Header: is Message Type correct ?
                if (rawData[4] != MSG_EASYCAP)
                {
                    throw new Exception("invalid MSG type. Got " + rawData[4] + " expected " + MSG_EASYCAP);
                }

                // ISO15434 Envelope: is message header correct?
                if ((rawData[5] != '[') || (rawData[6] != ')') || (rawData[7] != '>') || (rawData[8] != ISO_RS))
                {
                    throw new Exception("invalid MSG header");
                }

                // ISO15434 Envelope: is message header correct?
                if (rawData[rawData.Length - 1] != ISO_EOT)
                {
                    throw new Exception("invalid MSG trailer. Got " + rawData[rawData.Length - 1] + " expected " + ISO_EOT);
                }
            }
            catch (Exception e)
            {
                throw new Exception("Bad ISO15434 envelope: " + e.Message);
            }

            // At this point the basic header and ISO15434 has been validated.
            // Now we can extract the format envelope(s)and call the appropriate function for processing.
            // We currently expect and support only two types: Bar Code and Image. We can get none or multiples of either.
            try
            {
                ISO15434formatEnvelope anEnvelope = new ISO15434formatEnvelope(rawData, 9);
                while (anEnvelope.getNext())
                {
                    if (anEnvelope.getFileType() == "BarCode")
                    {
                        // We have extracted bar code data - send the event so it can be displayed
                        byte[] decRaw = new byte[anEnvelope.getDataLength() - 1];
                        Array.Copy(rawData, anEnvelope.getDataIndex() + 1, decRaw, 0, anEnvelope.getDataLength() - 1);
                        DecodeData d = new DecodeData((DecodeData.CodeTypes)(rawData[anEnvelope.getDataIndex()]), decRaw);
                        DocCapDecode(this, d); // fire the event
                    }
                    else
                    {
                        // Display the image, which is an specialized Signature capture format:
                        // byte0   = Bitmap typeof (BMP/TIFF/JPEG)
                        // byte1   = Signature capture type (0 = DocCap)
                        // byte2-5 = Size of image data
                        // byte6.. = image data
                        SsiImageTypes thisFormat;
                        int           i            = anEnvelope.getDataIndex();
                        int           bitmapLength = (rawData[i + 2] << 24) |
                                                     (rawData[i + 3] << 16) |
                                                     (rawData[i + 4] << 08) |
                                                     rawData[i + 5];
                        // Verify some of the data. Not required for application, but a nice sanity check
                        thisFormat = (SsiImageTypes)rawData[i];
                        if (thisFormat.ToString().ToLower() != anEnvelope.getFileType().ToLower())
                        {
                            throw new Exception("BITMAP type mismatch between bitmap and ISO msg:" + thisFormat + " vs " + anEnvelope.getFileType());
                        }

                        if (rawData[i + 1] != 0)
                        {
                            throw new Exception("expected sigcap type of 0. Got " + rawData[i + 1]);
                        }
                        if (bitmapLength + 6 != anEnvelope.getDataLength()) // the extra six bytes are those listed above.
                        {
                            throw new Exception("length mismatch between bitmap and ISO msg:" + (bitmapLength + 6) + " vs " + anEnvelope.getDataLength());
                        }

                        // Looks OK, send the event to display the message
                        SendCaptureImage(rawData, anEnvelope.getDataIndex(), theBus == usbBus.HID);
                    }
                } // while (anEnvelope.getNext())
            }
            catch (Exception e)
            {
                throw new Exception("Bad ISO15434 message: " + e.Message);
            }
        } // processISO15434Message
Example #3
0
        } // processSigCapContent

        /// <summary>
        ///
        /// </summary>
        /// <param name="rawData"></param>
        /// <param name="theBus"></param>
        private void processOldDocCapContent(byte[] rawData, usbBus theBus)
        {
            // length of first barcode (plus its symtype leader)
            int offset = (rawData[2] << 8) | rawData[3];

            // starting position of the 2nd barcode content
            int index = 4 + offset;

            bool isValid =
                // must have 2 barcodes
                (rawData[0] == 2)
                // second barcode must be a SigCap type (69H)
                && ((index < (rawData.Length - 3)) && (rawData[index + 3] == 0x69));

            if (!isValid)
            {
                throw new Exception("unknown symbology type/format(legacy message)");
            }

            // Offset is now pointing at the beginning of the first chunk,
            // Each packet has a 4 header:
            //        byte0   - continue? (0=last chunck)
            //        byte1,2 - length of packet data
            //        byte3   - barcode type

            // The first chunk (only), has a special Sigcap header of 6 bytes:
            //        byte0   - FMT type (BMP,TIFF,JPEG)
            //        byte1   - 0 (DocCap)
            //        byte2-5 - image length (big endian)

            // Get the total length of the image from the Sigcap header
            int totalLength = (rawData[index + 6] << 24) |
                              (rawData[index + 7] << 16) |
                              (rawData[index + 8] << 08) |
                              rawData[index + 9];

            // .. And allocate a memory stream for it, and assign the initial data,
            //    which starts after the 4 and 6 byte headers described above.
            int chunkSt  = index; // Chunk start
            int chunkLen = ((rawData[chunkSt + 1] << 8) | rawData[chunkSt + 2]) - 1;

            try
            {
                rawData[index + 5] = 0; // Make sure it says DocCap
                MemoryStream ms = new MemoryStream();
                ms.SetLength(totalLength);
                ms.Write(rawData, chunkSt + 4, chunkLen);

                // Point to the next chunk, which may not exist
                chunkSt += (chunkLen + 4);

                // Process multiple chunks, if present
                while (chunkSt < rawData.Length)
                {
                    // extract the next chunk's length and advance our offset past the header
                    chunkLen = ((rawData[chunkSt + 1] << 8) | rawData[chunkSt + 2]) - 1;

                    // append this next chunk to our memory buffer
                    if ((chunkSt + chunkLen) < rawData.Length)
                    {
                        ms.Write(rawData, chunkSt + 4, chunkLen);
                    }

                    // advance to (potentially) next chunk
                    chunkSt += (chunkLen + 4);
                }

                // Display the decoded image
                // Looks OK, send the event to display the message
                SendCaptureImage(ms.ToArray(), 0, theBus == usbBus.HID);

                // Send the decoded data
                byte[] decRaw = new byte[offset - 1];
                Array.Copy(rawData, 5, decRaw, 0, offset - 1);
                DecodeData d = new DecodeData((DecodeData.CodeTypes)(rawData[0]), decRaw);
                DocCapDecode(this, d); // fire the event
            }
            catch
            {
                throw new Exception("Image conversion error (legacy message)");
            }
        } // processOldDocCapContent