Sebastián Pastor / EtheriosCloudConnector
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers connector_sm_utils.h Source File

connector_sm_utils.h

00001 /*
00002  * Copyright (c) 2013 Digi International Inc.,
00003  * All rights not expressly granted are reserved.
00004  *
00005  * This Source Code Form is subject to the terms of the Mozilla Public
00006  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
00007  * You can obtain one at http://mozilla.org/MPL/2.0/.
00008  *
00009  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
00010  * =======================================================================
00011  */
00012 
00013 static uint16_t const crc_table[] =
00014 {
00015     0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
00016     0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
00017     0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
00018     0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
00019     0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
00020     0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
00021     0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
00022     0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
00023     0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
00024     0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
00025     0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
00026     0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
00027     0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
00028     0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
00029     0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
00030     0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
00031     0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
00032     0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
00033     0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
00034     0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
00035     0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
00036     0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
00037     0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
00038     0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
00039     0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
00040     0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
00041     0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
00042     0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
00043     0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
00044     0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
00045     0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
00046     0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
00047 };
00048 
00049 #define SmCRC16(crcval, newchar) crcval = ((crcval) >> 8) ^ crc_table[((crcval) ^ (newchar)) & 0x00ff]
00050 
00051 static uint16_t sm_calculate_crc16(uint16_t crc, uint8_t const * const data, size_t const bytes)
00052 {
00053     size_t i;
00054 
00055     for (i = 0; i < bytes; i++)
00056         SmCRC16(crc, data[i]);
00057 
00058     return crc;
00059 }
00060 
00061 #if (defined CONNECTOR_TRANSPORT_SMS)
00062 /* Base85 encoding lookup table. */
00063 static uint8_t const encode85_table[] =
00064 {
00065     '!', '\"', '#', '$', '%', '&', '\'', '(', ')', '*',
00066     '+', ',', '-', '.', '/',  '0', '1',  '2', '3', '4',
00067     '5', '6', '7', '8', '9',  ':', ';',  '<', '=', '>',
00068     '?', '@', 'A', 'B', 'C',  'D', 'E',  'F', 'G', 'H',
00069     'I', 'J', 'K', 'L', 'M',  'N', 'O',  'P', 'Q', 'R',
00070     'S', 'T', 'U', 'V', 'W',  'X', 'Y',  'Z', '_', 'a',
00071     'b', 'c', 'd', 'e', 'f',  'g', 'h',  'i', 'j', 'k',
00072     'l', 'm', 'n', 'o', 'p',  'q', 'r',  's', 't', 'u',
00073     'v', 'w', 'x', 'y', 'z'
00074 };
00075 
00076 /* Base85 decoding lookup table. */
00077 static uint8_t const decode85_table[] =
00078 {
00079     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00080     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,
00081     7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
00082     27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
00083     47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0,  0,  0,  0,  58, 0,  59, 60, 61,
00084     62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
00085     82, 83, 84, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00086     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00087     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00088     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00089     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00090     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
00091     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
00092 };
00093 
00094 
00095 static unsigned long const pow85[] =
00096 {
00097     85*85*85*85, 85*85*85, 85*85, 85, 1
00098 };
00099 
00100 static int sm_encode85(uint8_t * dest, size_t dest_len, uint8_t const * const src, size_t const src_len)
00101 {
00102     uint8_t buf[5];
00103     uint32_t tuple = 0;
00104     size_t src_count = 0;
00105     size_t dest_count = 0;
00106     size_t count = 0;
00107     size_t i;
00108     unsigned char *s;
00109 
00110     while (src_count < src_len)
00111     {
00112         unsigned const c = (*(src + src_count)) & 0xFF;
00113 
00114         switch (count++) {
00115         case 0:
00116             tuple |= (c << 24);
00117             break;
00118         case 1:
00119             tuple |= (c << 16);
00120             break;
00121         case 2:
00122             tuple |= (c <<  8);
00123             break;
00124         case 3:
00125             tuple |= c;
00126             i = 5;
00127             s = buf;
00128             do {
00129                 *s++ = tuple % 85;
00130                 tuple /= 85;
00131             } while (--i > 0);
00132             i = count;
00133             do {
00134                 *dest++ = encode85_table[*--s];
00135                 dest_count++;
00136                 if (dest_count >= dest_len) {
00137                     return dest_count;
00138                 }
00139             } while (i-- > 0);
00140 
00141             tuple = 0;
00142             count = 0;
00143             break;
00144         }
00145         src_count++;
00146     }
00147 
00148     /* Cleanup any remaining bytes... */
00149     if (count > 0) {
00150         i = 5;
00151         s = buf;
00152         do {
00153             *s++ = tuple % 85;
00154             tuple /= 85;
00155         } while (--i > 0);
00156         i = count;
00157         do {
00158             *dest++ = encode85_table[*--s];
00159             dest_count++;
00160             if (dest_count >= dest_len) {
00161                 return dest_count;
00162             }
00163         } while (i-- > 0);
00164     }
00165 
00166     return dest_count;
00167 }
00168 
00169 static int sm_decode85(uint8_t * dest, size_t dest_len, uint8_t const * const src, size_t const src_len)
00170 {
00171     unsigned long tuple = 0;
00172     int c;
00173     size_t count = 0;
00174     size_t src_count = 0;
00175     size_t dest_count = 0;
00176 
00177     ASSERT_GOTO(dest_len >= (src_len * 4)/5, error);
00178     while (src_count < src_len) {
00179         c = (*(src + src_count)) & 0xFF;
00180         tuple += decode85_table[c] * pow85[count++];
00181         if (count == 5) {
00182             *dest++ = tuple >> 24;
00183             *dest++ = tuple >> 16;
00184             *dest++ = tuple >>  8;
00185             *dest++ = tuple;
00186             dest_count += 4;
00187             count = 0;
00188             tuple = 0;
00189         }
00190         src_count++;
00191     }
00192 
00193     /* Cleanup any remaining bytes... */
00194     if (count > 0) {
00195         count--;
00196         tuple += pow85[count];
00197 
00198         switch (count) {
00199         case 4:
00200             *dest++ = tuple >> 24;
00201             *dest++ = tuple >> 16;
00202             *dest++ = tuple >>  8;
00203             *dest++ = tuple;
00204             dest_count += 4;
00205             break;
00206         case 3:
00207             *dest++ = tuple >> 24;
00208             *dest++ = tuple >> 16;
00209             *dest++ = tuple >>  8;
00210             dest_count += 3;
00211             break;
00212         case 2:
00213             *dest++ = tuple >> 24;
00214             *dest++ = tuple >> 16;
00215             dest_count += 2;
00216             break;
00217         case 1:
00218             *dest++ = tuple >> 24;
00219             dest_count++;;
00220             break;
00221         }
00222     }
00223 
00224 error:
00225     return dest_count;
00226 }
00227 #endif