Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of kpn_senml by
senml_helpers.cpp
00001 /* _ __ ____ _ _ 00002 * | |/ / | _ \ | \ | | 00003 * | ' / | |_) | | \| | 00004 * | . \ | __/ | |\ | 00005 * |_|\_\ |_| |_| \_| 00006 * 00007 * (c) 2018 KPN 00008 * License: MIT License. 00009 * Author: Jan Bogaerts 00010 * 00011 * felper functions 00012 */ 00013 00014 #include <senml_helpers.h> 00015 00016 #ifdef ESP32 00017 #include <base64.h> 00018 #include <arduino.h> //needed for sprintf 00019 #elif __MBED__ 00020 #include <base64.h> 00021 int base64_enc_len(int plainLen) { 00022 int n = plainLen; 00023 return (n + 2 - ((n + 2) % 3)) / 3 * 4; 00024 } 00025 #else 00026 #include <Base64.h> 00027 #endif 00028 00029 00030 00031 //global reference to the stream and stream configuration. This should save us memory 00032 //by not having to pass these values continuously on the stack. 00033 StreamContext* _streamCtx = NULL; 00034 00035 void printDouble(double f, unsigned int digits) 00036 { 00037 #ifdef __MBED__ 00038 char s[30]; 00039 sprintf(s, "%f", f); 00040 printText(s, strlen(s)); 00041 #else 00042 String temp(f, digits); 00043 const char* s = temp.c_str(); 00044 int length = temp.length(); 00045 00046 for(int i = length -1; i >0; i--){ //remove unwanted trailing 0 00047 if(s[i] != '0'){ 00048 length = i; 00049 if(s[i] == '.') //if we end on something like x. then add a last 0, so that it becomes x.0 00050 length++; 00051 break; 00052 } 00053 } 00054 printText(s, length + 1); 00055 #endif 00056 } 00057 00058 00059 00060 void printBinaryAsBase64(const unsigned char* data, unsigned int length) 00061 { 00062 #ifdef ESP32 00063 String encoded = base64::encode((uint8_t*)data, length); 00064 printText(encoded.c_str(), encoded.length()); 00065 #else 00066 int encodedLen = base64_enc_len(length); 00067 char encoded[encodedLen]; 00068 00069 #ifdef __MBED__ 00070 // todo: check result of function 00071 size_t olen; 00072 mbedtls_base64_encode((unsigned char*)encoded, encodedLen, &olen, data, length); 00073 #else 00074 // note input is consumed in this step: it will be empty afterwards 00075 base64_encode(encoded, (char*)data, length); 00076 #endif 00077 printText(encoded, encodedLen); 00078 #endif 00079 } 00080 00081 void printUnit(SenMLUnit unit) 00082 { 00083 if(unit != SENML_UNIT_NONE) 00084 printText(senml_units_names[unit], strlen(senml_units_names[unit])); 00085 } 00086 00087 void printText(const char* value, int len) 00088 { 00089 char hexTable[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 00090 00091 if(_streamCtx->dataAsBlob){ 00092 if(_streamCtx->format == SENML_RAW){ 00093 for(int i = 0; i < len; i++){ 00094 if(_streamCtx->data.blob.curPos >= _streamCtx->data.blob.length) return; //if we reached the end of the buffer, stop rendering otherwise we overwrite some other mem which is not good. 00095 _streamCtx->data.blob.data[_streamCtx->data.blob.curPos++] = value[i]; 00096 } 00097 } 00098 else{ 00099 for(int i = 0; i < len; i++){ 00100 if(_streamCtx->data.blob.curPos >= _streamCtx->data.blob.length) return; //if we reached the end of the buffer, stop rendering otherwise we overwrite some other mem which is not good. 00101 _streamCtx->data.blob.data[_streamCtx->data.blob.curPos++] = hexTable[value[i] / 16]; 00102 _streamCtx->data.blob.data[_streamCtx->data.blob.curPos++] = hexTable[value[i] % 16]; 00103 } 00104 } 00105 } 00106 else{ 00107 if(_streamCtx->format == SENML_RAW){ 00108 #ifdef __MBED__ 00109 for(int i = 0; i < len; i++) 00110 _streamCtx->data.stream->putc(value[i]); 00111 #else 00112 _streamCtx->data.stream->write(value, len); 00113 #endif 00114 } 00115 else if (_streamCtx->format == SENML_HEX){ 00116 for(int i = 0; i< len; i++){ 00117 #ifdef __MBED__ 00118 _streamCtx->data.stream->putc(hexTable[value[i] / 16]); 00119 _streamCtx->data.stream->putc(hexTable[value[i] % 16]); 00120 #else 00121 _streamCtx->data.stream->print(hexTable[value[i] / 16]); 00122 _streamCtx->data.stream->print(hexTable[value[i] % 16]); 00123 #endif 00124 } 00125 } 00126 } 00127 } 00128 00129 static bool peeked = false; //if we peek the stream in HEX format, we actually need to read 2 bytes, so the peek doesn't work, but we need to read the actual value. 00130 static int peekVal = 0; //these values are removed by the compiler if no cbor is used. 00131 00132 int readChar(){ 00133 if(peeked == true){ 00134 peeked = false; 00135 return peekVal; 00136 } 00137 int res; 00138 if(_streamCtx->dataAsBlob){ 00139 if(_streamCtx->data.blob.curPos < _streamCtx->data.blob.length) //peekchar has to return -1 if there is no more data, so check for this. 00140 res = _streamCtx->data.blob.data[_streamCtx->data.blob.curPos++]; 00141 else 00142 return -1; 00143 if(_streamCtx->format == SENML_HEX){ 00144 int resB = _streamCtx->data.blob.data[_streamCtx->data.blob.curPos++]; 00145 res = (res > '9')? (res &~ 0x20) - 'A' + 10: (res - '0'); 00146 resB = (resB > '9')? (resB &~ 0x20) - 'A' + 10: (resB - '0'); 00147 res = (res * 16) + resB; 00148 } 00149 } 00150 else { //data is comming from the stream, this already returns -1 if there is no data. 00151 if(_streamCtx->format == SENML_RAW){ 00152 #ifdef __MBED__ 00153 res = _streamCtx->data.stream->getc(); 00154 #else 00155 res = _streamCtx->data.stream->available() ? _streamCtx->data.stream->read() : -1; //arduino stream, check if something is available, if not, we can't read anymore. 00156 #endif 00157 } 00158 else{ 00159 int resB; 00160 #ifdef __MBED__ 00161 res = _streamCtx->data.stream->getc(); 00162 resB = _streamCtx->data.stream->getc(); 00163 #else 00164 00165 if(_streamCtx->data.stream->available()) 00166 res = _streamCtx->data.stream->read(); 00167 else 00168 return -1; 00169 if(_streamCtx->data.stream->available()) 00170 resB = _streamCtx->data.stream->read(); 00171 else 00172 return -1; 00173 #endif 00174 res = (res > '9')? (res &~ 0x20) - 'A' + 10: (res - '0'); 00175 resB = (resB > '9')? (resB &~ 0x20) - 'A' + 10: (resB - '0'); 00176 res = (res * 16) + resB; 00177 } 00178 } 00179 return res; 00180 }; 00181 00182 int peekChar(){ 00183 if(peeked == true) //if already peeked, return the currently buffered value. 00184 return peekVal; 00185 peekVal = readChar(); 00186 if(peekVal != -1) //if no more data, don't try to buffer it, some new data might arrive later on 00187 peeked = true; 00188 return peekVal; 00189 }; 00190 00191 void flush(){ 00192 peeked = false; 00193 } 00194 00195 00196
Generated on Tue Jul 12 2022 23:07:21 by
1.7.2
