SerialHelper.cpp
Go to the documentation of this file.
00001 /*
00002  * SerialHelper.cpp
00003  *
00004  *  Created on: Nov 24, 2011
00005  *      Author: mriedel
00006  */
00007 
00008 #include <telekyb_serial/SerialHelper.hpp>
00009 
00010 #include <string.h>
00011 
00012 #include <ros/console.h>
00013 
00014 namespace TELEKYB_NAMESPACE {
00015 
00016 int SerialHelper::appendCRC ( char* buffer, unsigned int bufferPosition )
00017 {
00018         unsigned int tmpCRC = 0;
00019         for ( unsigned int i = 0; i < bufferPosition; i++ )
00020         {
00021                 tmpCRC += buffer[i];
00022         }
00023         tmpCRC %= 4096;
00024         buffer[bufferPosition] = '=' + tmpCRC / 64;
00025         buffer[bufferPosition+1] = '=' + tmpCRC % 64;
00026         return 2;
00027 }
00028 
00029 //** Warning Prefix must be encoded so that it does not create binary 11 at the Beginning or a direct \r
00030 int SerialHelper::encodeData ( char* buffer, // buffer to write to must be at least prefixLength + 3 (crc1,2 and \r) + messageLength*4/3
00031                 const char* prefix, unsigned int prefixLength,
00032                 const char* message, unsigned int messageLength )
00033 {
00034         unsigned int pt = 0;
00035         unsigned char a,b,c;
00036         unsigned char ptr = 0;
00037 
00038 //      buff[pt++] = '#'; // Startchar
00039 //      buff[pt++] = modul; // Address b, c, d
00040 //      buff[pt++] = cmd; // Command
00041 
00042         // set Prefix
00043         memcpy(buffer, prefix, prefixLength);
00044         pt += prefixLength;
00045 
00046         while ( messageLength ){
00047                 if ( messageLength ){
00048                         a = message[ptr++];
00049                         messageLength--;
00050                 }
00051                 else a = 0;
00052                 if ( messageLength ){
00053                         b = message[ptr++];
00054                         messageLength--;
00055                 }
00056                 else b = 0;
00057                 if ( messageLength ){
00058                         c = message[ptr++];
00059                         messageLength--;
00060                 }
00061                 else{
00062                         c = 0;
00063                 }
00064                 buffer[pt++] = '=' + ( a >> 2 );
00065 
00066                 buffer[pt++] = '=' + ( ( ( a & 0x03 ) << 4 ) | ( ( b & 0xf0 ) >> 4 ) );
00067                 buffer[pt++] = '=' + ( ( ( b & 0x0f ) << 2 ) | ( ( c & 0xc0 ) >> 6 ) );
00068                 buffer[pt++] = '=' + ( c & 0x3f );
00069         }
00070 
00071         pt += appendCRC ( buffer, pt );
00072         // Terminal
00073         buffer[pt++] = '\r';
00074 
00075         return pt;
00076 }
00077 
00078 //** This requires the TargetLength! You have to know what you want to decode!!!
00079 int SerialHelper::decodeData(char* buffer, unsigned int targetLength, const char* message)
00080 {
00081         unsigned char a,b,c,d;
00082         unsigned char ptr = 0;
00083         unsigned char x,y,z;
00084         // ignore Prefix
00085         int ptrIn = 0;
00086 
00087         while (targetLength) {
00088                 a = message[ptrIn++] - '=';
00089                 b = message[ptrIn++] - '=';
00090                 c = message[ptrIn++] - '=';
00091                 d = message[ptrIn++] - '=';
00092                 //if (ptrIn > max - 2) break; // nicht mehr Daten verarbeiten, als empfangen wurden
00093 
00094                 x = (a << 2) | (b >> 4);
00095                 y = ((b & 0x0f) << 4) | (c >> 2);
00096                 z = ((c & 0x03) << 6) | d;
00097 
00098                 if (targetLength--) buffer[ptr++] = x; else break;
00099                 if (targetLength--) buffer[ptr++] = y; else break;
00100                 if (targetLength--) buffer[ptr++] = z; else break;
00101         }
00102 
00103         // number of decoded bytes
00104         return ptr;
00105 }
00106 
00107 // message must be of structure [msg][crc1][crc2]'\r'
00108 bool SerialHelper::checkCRC(const char* message, unsigned int messageLength)
00109 {
00110         if (messageLength < 4) {
00111                 ROS_ERROR("CRC Message too short!");
00112                 return false;
00113         }
00114 
00115         if (message[messageLength-1] != '\r' && message[messageLength-1] != '\n') {
00116                 ROS_WARN("CheckCRC without \\r or \\n terminated message!");
00117         }
00118 
00119         int tmpCRC = 0;
00120         for ( unsigned int i = 0; i < messageLength-3; i++ )
00121         {
00122                 tmpCRC += message[i];
00123         }
00124         tmpCRC %= 4096;
00125         //ROS_INFO("CRC Should be 1: %d 2: %d", (int)('=' + tmpCRC / 64),(int)('=' + tmpCRC % 64));
00126         return (message[messageLength-3] == '=' + tmpCRC / 64) && (message[messageLength-2] == '=' + tmpCRC % 64);
00127 }
00128 
00129 
00130 } /* namespace telekyb */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


telekyb_serial
Author(s): Martin Riedel
autogenerated on Mon Nov 11 2013 11:14:08