an old afLib which supports both SPI and UART

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Command.cpp Source File

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