Contiki 2.6

gcr.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2006, Swedish Institute of Computer Science
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  *
00031  * @(#)$Id: gcr.c,v 1.2 2011/01/07 11:55:36 nifi Exp $
00032  */
00033 
00034 /**
00035  * \file
00036  *         Implementation of GCR coding/decoding
00037  * \author
00038  *         Joakim Eriksson <joakime@sics.se>
00039  *
00040  */
00041 
00042 /* GCR conversion table - used for converting ordinary byte to 10-bits */
00043 /* (or 4 bits to 5) */
00044 static const unsigned char GCR_encode[16] = {
00045     0x0a, 0x0b, 0x12, 0x13,
00046     0x0e, 0x0f, 0x16, 0x17,
00047     0x09, 0x19, 0x1a, 0x1b,
00048     0x0d, 0x1d, 0x1e, 0x15
00049 };
00050 
00051 /*  5 bits > 4 bits (0xff => invalid) */
00052 static const unsigned char GCR_decode[32] = {
00053     0xff, 0xff, 0xff, 0xff, // 0 - 3invalid...
00054     0xff, 0xff, 0xff, 0xff, // 4 - 7 invalid...
00055     0xff, 0x08, 0x00, 0x01, // 8 invalid... 9 = 8, a = 0, b = 1
00056     0xff, 0x0c, 0x04, 0x05, // c invalid... d = c, e = 4, f = 5
00057 
00058     0xff, 0xff, 0x02, 0x03, // 10-11 invalid...
00059     0xff, 0x0f, 0x06, 0x07, // 14 invalid...
00060     0xff, 0x09, 0x0a, 0x0b, // 18 invalid...
00061     0xff, 0x0d, 0x0e, 0xff, // 1c, 1f invalid...
00062   };
00063 
00064 static unsigned char gcr_bits = 0;
00065 static unsigned short gcr_val = 0;
00066 
00067 /* Call before starting encoding or decoding */
00068 void gcr_init() {
00069   gcr_val = 0;
00070   gcr_bits = 0;
00071 }
00072 
00073 /* Use this to check if encoding / decoding is complete for now */
00074 unsigned char gcr_finished() {
00075   return gcr_bits == 0;
00076 }
00077 
00078 /* Encode one character - and store in bits - get encoded with get_encoded */
00079 void gcr_encode(unsigned char raw_data) {
00080   gcr_val |=
00081     ((GCR_encode[raw_data >> 4u] << 5u ) |
00082      GCR_encode[raw_data & 0xf]) << gcr_bits;
00083   gcr_bits += 10;
00084 }
00085 
00086 /* Gets the current char of the encoded stream */
00087 unsigned char gcr_get_encoded(unsigned char *raw_data) {
00088   if (gcr_bits >= 8) {
00089     *raw_data = (unsigned char) (gcr_val & 0xff);
00090     gcr_val = gcr_val >> 8u;
00091     gcr_bits = gcr_bits - 8;
00092     return 1;
00093   }
00094   return 0;
00095 }
00096 
00097 /* Decode one char - result can be get from get_decoded */
00098 void gcr_decode(unsigned char gcr_data) {
00099   gcr_val |= gcr_data << gcr_bits;
00100   gcr_bits += 8;
00101 }
00102 
00103 /* check if the current decoded stream is correct */
00104 unsigned char gcr_valid() {
00105   if (gcr_bits >= 10) {
00106     unsigned short val = gcr_val & 0x3ff;
00107     if ((GCR_decode[val >> 5u] << 4u) == 0xff ||
00108         (GCR_decode[val & 0x1f]) == 0xff) {
00109       return 0;
00110     }
00111   }
00112   return 1;
00113 }
00114 
00115 /* gets the decoded stream - if any char is available */
00116 unsigned char gcr_get_decoded(unsigned char *raw_data) {
00117   if (gcr_bits >= 10) {
00118     unsigned short val = gcr_val & 0x3ff;
00119     *raw_data = (unsigned char) ((GCR_decode[val >> 5] << 4) |
00120                                  (GCR_decode[val & 0x1f]));
00121     gcr_val = gcr_val >> 10;
00122     gcr_bits = gcr_bits - 10;
00123     return 1;
00124   }
00125   return 0;
00126 }
00127 
00128 /*
00129 static const char encoded[] = {
00130   0x4a, 0x25, 0xa5, 0xfc, 0x96, 0xff, 0xff, 0xb5, 0xd4, 0x5a, 0xea, 0xff, 0xff, 0xaa, 0xd3, 0xff
00131 };
00132 
00133 int main(int argc, char **argv) {
00134   // unsigned char c[] = "testing gcr 1 2 3 4 5 6...";
00135   unsigned char c[] = { 0, 8, 0xe0, 0x2b, 0xac, 0x10, 0x01, 0x11, 0x50, 0xff, 0xf4, 0xa4, 0x00 };
00136   unsigned char c2[200];
00137   int pos = 0, pos2 = 0, i = 0;
00138 
00139   printf("Testing GCR on: %s \n", c);
00140 
00141   gcr_init();
00142   for (i = 0; i < sizeof(c); i++) {
00143     gcr_encode(c[i]);
00144     while(gcr_get_encoded(&c2[pos])) {
00145       printf("%02x=>%02x ", c[i], c2[pos]);
00146       pos++;
00147     }
00148   }
00149   printf("\n");
00150   printf("Encoded result %d chars (from %d) \n", pos, i);
00151   gcr_init();
00152   for (i = 0; i < pos; i++) {
00153     gcr_decode(c2[i]);
00154     if(!gcr_valid()) {
00155       printf("GCR: not valid\n");
00156     }
00157     while(gcr_get_decoded(&c[pos2])) {
00158       pos2++;
00159     }
00160   }
00161   printf("GCR: %s\n",c);
00162 }
00163 */