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.
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