an old afLib which supports both SPI and UART
Embed:
(wiki syntax)
Show/hide line numbers
Command.cpp
00001 /** 00002 * Copyright 2015 Afero, Inc. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 #include <stdio.h> 00019 #include "Command.h" 00020 #include "msg_types.h" 00021 00022 #define CMD_HDR_LEN 4 // 4 byte header on all commands 00023 #define CMD_VAL_LEN 2 // 2 byte value length for commands that have a value 00024 00025 const char *CMD_NAMES[] = {"SET ", "GET ", "UPDATE"}; 00026 00027 00028 Command::Command(Stream *serial,uint16_t len, uint8_t *bytes) { 00029 _serial = serial; 00030 int index = 0; 00031 00032 _cmd = bytes[index++]; 00033 _requestId = bytes[index++]; 00034 _attrId = bytes[index + 0] | bytes[index + 1] << 8; 00035 index += 2; 00036 00037 if (_cmd == MSG_TYPE_GET) { 00038 return; 00039 } 00040 if (_cmd == MSG_TYPE_UPDATE) { 00041 _status = bytes[index++]; 00042 _reason = bytes[index++]; 00043 } 00044 00045 _valueLen = bytes[index + 0] | bytes[index + 1] << 8; 00046 index += 2; 00047 _value = new uint8_t[_valueLen]; 00048 for (int i = 0; i < _valueLen; i++) { 00049 _value[i] = bytes[index + i]; 00050 } 00051 } 00052 00053 #if 1 00054 char *strdup(const char *str) 00055 { 00056 int len ; 00057 char *ptr = 0 ; 00058 if (str) { 00059 len = strlen(str) ; 00060 ptr = (char*)malloc(len + 1) ; 00061 strcpy(ptr, str) ; 00062 } 00063 return(ptr) ; 00064 } 00065 #endif 00066 00067 Command::Command(Stream *serial,uint8_t requestId, const char *str) { 00068 _serial = serial; 00069 _requestId = requestId & 0xff; 00070 00071 char *cp = strdup(str); 00072 char *tok = strtok(cp, " "); 00073 _cmd = strToCmd(tok); 00074 00075 tok = strtok(NULL, " "); 00076 _attrId = strToAttrId(tok); 00077 00078 if (_cmd == MSG_TYPE_GET) { 00079 _valueLen = 0; 00080 _value = NULL; 00081 } else { 00082 tok = strtok(NULL, " "); 00083 _valueLen = strlen(tok) / 2; 00084 _value = new uint8_t[_valueLen]; 00085 strToValue(tok, _value); 00086 } 00087 00088 free(cp); 00089 } 00090 00091 Command::Command(Stream *serial,uint8_t requestId, uint8_t cmd, uint16_t attrId) { 00092 _serial = serial; 00093 _requestId = requestId; 00094 _cmd = cmd; 00095 _attrId = attrId; 00096 _valueLen = 0; 00097 _value = NULL; 00098 } 00099 00100 Command::Command(Stream *serial,uint8_t requestId, uint8_t cmd, uint16_t attrId, uint16_t valueLen, uint8_t *value) { 00101 _serial = serial; 00102 _requestId = requestId; 00103 _cmd = cmd; 00104 _attrId = attrId; 00105 _valueLen = valueLen; 00106 _value = new uint8_t[_valueLen]; 00107 memcpy(_value, value, valueLen); 00108 } 00109 00110 Command::Command(Stream *serial,uint8_t requestId, uint8_t cmd, uint16_t attrId, uint8_t status, uint8_t reason, uint16_t valueLen, 00111 uint8_t *value) { 00112 _serial = serial; 00113 _requestId = requestId; 00114 _cmd = cmd; 00115 _attrId = attrId; 00116 _status = status; 00117 _reason = reason; 00118 _valueLen = valueLen; 00119 _value = new uint8_t[_valueLen]; 00120 memcpy(_value, value, valueLen); 00121 } 00122 00123 Command::Command(Stream *serial) { 00124 _serial = serial; 00125 00126 } 00127 00128 Command::~Command() { 00129 if (_value != NULL) { 00130 delete (_value); 00131 } 00132 } 00133 00134 int Command::strToValue(char *valueStr, uint8_t *value) { 00135 for (int i = 0; i < (int) (strlen(valueStr) / 2); i++) { 00136 int j = i * 2; 00137 value[i] = getVal(valueStr[j + 1]) + (getVal(valueStr[j]) << 4); 00138 } 00139 00140 return 0; 00141 } 00142 00143 uint16_t Command::strToAttrId(char *attrIdStr) { 00144 return atoi(attrIdStr); 00145 //return String(attrIdStr).toInt(); 00146 } 00147 00148 uint8_t Command::strToCmd(char *cmdStr) { 00149 char c = cmdStr[0]; 00150 if (c == 'g' || c == 'G') { 00151 return MSG_TYPE_GET; 00152 } else if (c == 's' || c == 'S') { 00153 return MSG_TYPE_SET; 00154 } else if (c == 'u' || c == 'U') { 00155 return MSG_TYPE_UPDATE; 00156 } 00157 00158 return -1; 00159 } 00160 00161 uint8_t Command::getCommand() { 00162 return _cmd; 00163 } 00164 00165 uint8_t Command::getReqId() { 00166 return _requestId; 00167 } 00168 00169 uint16_t Command::getAttrId() { 00170 return _attrId; 00171 } 00172 00173 uint16_t Command::getValueLen() { 00174 return _valueLen; 00175 } 00176 00177 void Command::getValue(uint8_t *value) { 00178 for (int i = 0; i < _valueLen; i++) { 00179 value[i] = _value[i]; 00180 } 00181 } 00182 00183 uint8_t *Command::getValueP() { 00184 return _value; 00185 } 00186 00187 uint16_t Command::getSize() { 00188 uint16_t len = CMD_HDR_LEN; 00189 00190 if (_cmd != MSG_TYPE_GET) { 00191 len += CMD_VAL_LEN + _valueLen; 00192 } 00193 00194 if (_cmd == MSG_TYPE_UPDATE) { 00195 len += 2; // status byte + reason byte 00196 } 00197 00198 return len; 00199 } 00200 00201 uint16_t Command::getBytes(uint8_t *bytes) { 00202 uint16_t len = getSize(); 00203 00204 int index = 0; 00205 00206 bytes[index++] = (_cmd); 00207 00208 bytes[index++] = (_requestId); 00209 00210 bytes[index++] = (_attrId & 0xff); 00211 bytes[index++] = ((_attrId >> 8) & 0xff); 00212 00213 if (_cmd == MSG_TYPE_GET) { 00214 return len; 00215 } 00216 00217 if (_cmd == MSG_TYPE_UPDATE) { 00218 bytes[index++] = (_status); 00219 bytes[index++] = (_reason); 00220 } 00221 00222 bytes[index++] = (_valueLen & 0xff); 00223 bytes[index++] = ((_valueLen >> 8) & 0xff); 00224 00225 for (int i = 0; i < _valueLen; i++) { 00226 bytes[index++] = (_value[i]); 00227 } 00228 00229 return len; 00230 } 00231 00232 uint8_t Command::getReason() { 00233 return _reason; 00234 } 00235 00236 bool Command::isValid() { 00237 return (_cmd == MSG_TYPE_SET) || (_cmd == MSG_TYPE_GET) || (_cmd == MSG_TYPE_UPDATE); 00238 } 00239 00240 void Command::dumpBytes() { 00241 uint16_t len = getSize(); 00242 uint8_t bytes[len]; 00243 getBytes(bytes); 00244 00245 _printBuf[0] = 0; 00246 sprintf(_printBuf, "len: %d value: ", len); 00247 for (int i = 0; i < len; i++) { 00248 int b = bytes[i] & 0xff; 00249 sprintf(&_printBuf[strlen(_printBuf)], "%02x", b); 00250 } 00251 _serial->printf(_printBuf); 00252 } 00253 00254 void Command::dump() { 00255 _printBuf[0] = 0; 00256 sprintf(_printBuf, "cmd: %s attr: %d value: ", 00257 CMD_NAMES[_cmd - MESSAGE_CHANNEL_BASE - 1], 00258 _attrId 00259 ); 00260 if (_cmd != MSG_TYPE_GET) { 00261 for (int i = 0; i < _valueLen; i++) { 00262 int b = _value[i] & 0xff; 00263 sprintf(&_printBuf[strlen(_printBuf)], "%02x", b); 00264 } 00265 } 00266 _serial->printf(_printBuf); 00267 } 00268 00269 uint8_t Command::getVal(char c) { 00270 if (c >= '0' && c <= '9') 00271 return (uint8_t)(c - '0'); 00272 else if (c >= 'A' && c <= 'F') 00273 return (uint8_t)(c - 'A' + 10); 00274 else if (c >= 'a' && c <= 'f') 00275 return (uint8_t)(c - 'a' + 10); 00276 00277 _serial->printf("bad hex char: 0x%02X\n", c); 00278 00279 return 0; 00280 } 00281
Generated on Wed Jul 13 2022 19:00:06 by
1.7.2