I2C hang recover function added
Dependencies: UniGraphic mbed vt100
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 //wsugi #include "Arduino.h" 00018 #include "mbed.h" 00019 #include <stdio.h> 00020 #include "Command.h" 00021 #include "msg_types.h" 00022 00023 #define SERIAL_PRINT_DBG_ASR_ON 0 00024 00025 #define CMD_HDR_LEN 4 // 4 byte header on all commands 00026 #define CMD_VAL_LEN 2 // 2 byte value length for commands that have a value 00027 00028 const char *CMD_NAMES[] = {"SET ", "GET ", "UPDATE"}; 00029 00030 00031 Command::Command(uint16_t len, uint8_t *bytes) { 00032 int index = 0; 00033 00034 _cmd = bytes[index++]; 00035 _requestId = bytes[index++]; 00036 _attrId = bytes[index + 0] | bytes[index + 1] << 8; 00037 index += 2; 00038 00039 if (_cmd == MSG_TYPE_GET) { 00040 return; 00041 } 00042 if (_cmd == MSG_TYPE_UPDATE) { 00043 _status = bytes[index++]; 00044 _reason = bytes[index++]; 00045 } 00046 00047 _valueLen = bytes[index + 0] | bytes[index + 1] << 8; 00048 index += 2; 00049 _value = new uint8_t[_valueLen]; 00050 for (int i = 0; i < _valueLen; i++) { 00051 _value[i] = bytes[index + i]; 00052 } 00053 } 00054 00055 Command::Command(uint8_t requestId, const char *str) { 00056 _requestId = requestId & 0xff; 00057 00058 char *cp; //wsugi = strdup(str); 00059 //wsugi 00 start 00060 { 00061 int length = strlen(str)+1; 00062 cp = (char*)malloc(length); 00063 strcpy(cp,str); 00064 } 00065 //wsugi 00 end 00066 char *tok = strtok(cp, " "); 00067 _cmd = strToCmd(tok); 00068 00069 tok = strtok(NULL, " "); 00070 _attrId = strToAttrId(tok); 00071 00072 if (_cmd == MSG_TYPE_GET) { 00073 _valueLen = 0; 00074 _value = NULL; 00075 } else { 00076 tok = strtok(NULL, " "); 00077 _valueLen = strlen(tok) / 2; 00078 _value = new uint8_t[_valueLen]; 00079 strToValue(tok, _value); 00080 } 00081 00082 free(cp); 00083 } 00084 00085 Command::Command(uint8_t requestId, uint8_t cmd, uint16_t attrId) { 00086 _requestId = requestId; 00087 _cmd = cmd; 00088 _attrId = attrId; 00089 _valueLen = 0; 00090 _value = NULL; 00091 } 00092 00093 Command::Command(uint8_t requestId, uint8_t cmd, uint16_t attrId, uint16_t valueLen, uint8_t *value) { 00094 _requestId = requestId; 00095 _cmd = cmd; 00096 _attrId = attrId; 00097 _valueLen = valueLen; 00098 _value = new uint8_t[_valueLen]; 00099 memcpy(_value, value, valueLen); 00100 } 00101 00102 Command::Command(uint8_t requestId, uint8_t cmd, uint16_t attrId, uint8_t status, uint8_t reason, uint16_t valueLen, 00103 uint8_t *value) { 00104 _requestId = requestId; 00105 _cmd = cmd; 00106 _attrId = attrId; 00107 _status = status; 00108 _reason = reason; 00109 _valueLen = valueLen; 00110 _value = new uint8_t[_valueLen]; 00111 memcpy(_value, value, valueLen); 00112 } 00113 00114 Command::Command() { 00115 } 00116 00117 Command::~Command() { 00118 if (_value != NULL) { 00119 delete[] _value; //wsugi delete (_value); 00120 } 00121 } 00122 00123 int Command::strToValue(char *valueStr, uint8_t *value) { 00124 for (int i = 0; i < (int) (strlen(valueStr) / 2); i++) { 00125 int j = i * 2; 00126 value[i] = getVal(valueStr[j + 1]) + (getVal(valueStr[j]) << 4); 00127 } 00128 00129 return 0; 00130 } 00131 00132 uint16_t Command::strToAttrId(char *attrIdStr) { 00133 return atoi(attrIdStr); 00134 //return String(attrIdStr).toInt(); 00135 } 00136 00137 uint8_t Command::strToCmd(char *cmdStr) { 00138 char c = cmdStr[0]; 00139 if (c == 'g' || c == 'G') { 00140 return MSG_TYPE_GET; 00141 } else if (c == 's' || c == 'S') { 00142 return MSG_TYPE_SET; 00143 } else if (c == 'u' || c == 'U') { 00144 return MSG_TYPE_UPDATE; 00145 } 00146 00147 return 0xFF ; 00148 } 00149 00150 uint8_t Command::getCommand() { 00151 return _cmd; 00152 } 00153 00154 uint8_t Command::getReqId() { 00155 return _requestId; 00156 } 00157 00158 uint16_t Command::getAttrId() { 00159 return _attrId; 00160 } 00161 00162 uint16_t Command::getValueLen() { 00163 return _valueLen; 00164 } 00165 00166 void Command::getValue(uint8_t *value) { 00167 for (int i = 0; i < _valueLen; i++) { 00168 value[i] = _value[i]; 00169 } 00170 } 00171 00172 uint8_t *Command::getValueP() { 00173 return _value; 00174 } 00175 00176 uint16_t Command::getSize() { 00177 uint16_t len = CMD_HDR_LEN; 00178 00179 if (_cmd != MSG_TYPE_GET) { 00180 len += CMD_VAL_LEN + _valueLen; 00181 } 00182 00183 if (_cmd == MSG_TYPE_UPDATE) { 00184 len += 2; // status byte + reason byte 00185 } 00186 00187 return len; 00188 } 00189 00190 uint16_t Command::getBytes(uint8_t *bytes) { 00191 uint16_t len = getSize(); 00192 00193 int index = 0; 00194 00195 bytes[index++] = (_cmd); 00196 00197 bytes[index++] = (_requestId); 00198 00199 bytes[index++] = (_attrId & 0xff); 00200 bytes[index++] = ((_attrId >> 8) & 0xff); 00201 00202 if (_cmd == MSG_TYPE_GET) { 00203 return len; 00204 } 00205 00206 if (_cmd == MSG_TYPE_UPDATE) { 00207 bytes[index++] = (_status); 00208 bytes[index++] = (_reason); 00209 } 00210 00211 bytes[index++] = (_valueLen & 0xff); 00212 bytes[index++] = ((_valueLen >> 8) & 0xff); 00213 00214 for (int i = 0; i < _valueLen; i++) { 00215 bytes[index++] = (_value[i]); 00216 } 00217 00218 return len; 00219 } 00220 00221 bool Command::isValid() { 00222 return (_cmd == MSG_TYPE_SET) || (_cmd == MSG_TYPE_GET) || (_cmd == MSG_TYPE_UPDATE); 00223 } 00224 00225 void Command::dumpBytes() { 00226 #if SERIAL_PRINT_DBG_ASR_ON 00227 uint16_t len = getSize(); 00228 uint8_t bytes[len]; 00229 getBytes(bytes); 00230 00231 _printBuf[0] = 0; 00232 sprintf(_printBuf, "len: %d value: ", len); 00233 for (int i = 0; i < len; i++) { 00234 int b = bytes[i] & 0xff; 00235 sprintf(&_printBuf[strlen(_printBuf)], "%02x", b); 00236 } 00237 printf("%s\n",_printBuf); 00238 #endif 00239 } 00240 00241 void Command::dump() { 00242 #if SERIAL_PRINT_DBG_ASR_ON 00243 _printBuf[0] = 0; 00244 sprintf(_printBuf, "cmd: %s attr: %d value: ", 00245 CMD_NAMES[_cmd - MESSAGE_CHANNEL_BASE - 1], 00246 _attrId 00247 ); 00248 if (_cmd != MSG_TYPE_GET) { 00249 for (int i = 0; i < _valueLen; i++) { 00250 int b = _value[i] & 0xff; 00251 sprintf(&_printBuf[strlen(_printBuf)], "%02x", b); 00252 } 00253 } 00254 printf("%s\n",_printBuf); 00255 #endif 00256 } 00257 00258 uint8_t Command::getVal(char c) { 00259 if (c >= '0' && c <= '9') 00260 return (uint8_t)(c - '0'); 00261 else if (c >= 'A' && c <= 'F') 00262 return (uint8_t)(c - 'A' + 10); 00263 else if (c >= 'a' && c <= 'f') 00264 return (uint8_t)(c - 'a' + 10); 00265 00266 printf("bad hex char: %c\n",c); 00267 00268 return 0; 00269 }
Generated on Sat Jul 16 2022 08:26:44 by 1.7.2