xpl lib
Dependents: XPL-App4_cleanup XPL-App5
xPL_Message.cpp@0:23c0d0e1c31d, 2018-10-09 (annotated)
- Committer:
- richnash
- Date:
- Tue Oct 09 17:37:05 2018 +0000
- Revision:
- 0:23c0d0e1c31d
ready to move to cli to explore D11 pin fix
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
richnash | 0:23c0d0e1c31d | 1 | /* |
richnash | 0:23c0d0e1c31d | 2 | * xPL.Arduino v0.1, xPL Implementation for Arduino |
richnash | 0:23c0d0e1c31d | 3 | * |
richnash | 0:23c0d0e1c31d | 4 | * This code is parsing a xPL message stored in 'received' buffer |
richnash | 0:23c0d0e1c31d | 5 | * - isolate and store in 'line' buffer each part of the message -> detection of EOL character (DEC 10) |
richnash | 0:23c0d0e1c31d | 6 | * - analyse 'line', function of its number and store information in xpl_header memory |
richnash | 0:23c0d0e1c31d | 7 | * - check for each step if the message respect xPL protocol |
richnash | 0:23c0d0e1c31d | 8 | * - parse each command line |
richnash | 0:23c0d0e1c31d | 9 | * |
richnash | 0:23c0d0e1c31d | 10 | * Copyright (C) 2012 johan@pirlouit.ch, olivier.lebrun@gmail.com |
richnash | 0:23c0d0e1c31d | 11 | * Original version by Gromain59@gmail.com |
richnash | 0:23c0d0e1c31d | 12 | * |
richnash | 0:23c0d0e1c31d | 13 | * This program is free software; you can redistribute it and/or |
richnash | 0:23c0d0e1c31d | 14 | * modify it under the terms of the GNU General Public License |
richnash | 0:23c0d0e1c31d | 15 | * as published by the Free Software Foundation; either version 2 |
richnash | 0:23c0d0e1c31d | 16 | * of the License, or (at your option) any later version. |
richnash | 0:23c0d0e1c31d | 17 | * |
richnash | 0:23c0d0e1c31d | 18 | * This program is distributed in the hope that it will be useful, |
richnash | 0:23c0d0e1c31d | 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
richnash | 0:23c0d0e1c31d | 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
richnash | 0:23c0d0e1c31d | 21 | * GNU General Public License for more details. |
richnash | 0:23c0d0e1c31d | 22 | * |
richnash | 0:23c0d0e1c31d | 23 | * You should have received a copy of the GNU General Public License |
richnash | 0:23c0d0e1c31d | 24 | * along with this program; if not, write to the Free Software |
richnash | 0:23c0d0e1c31d | 25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
richnash | 0:23c0d0e1c31d | 26 | */ |
richnash | 0:23c0d0e1c31d | 27 | |
richnash | 0:23c0d0e1c31d | 28 | #include "xPL_Message.h" |
richnash | 0:23c0d0e1c31d | 29 | |
richnash | 0:23c0d0e1c31d | 30 | xPL_Message::xPL_Message() |
richnash | 0:23c0d0e1c31d | 31 | { |
richnash | 0:23c0d0e1c31d | 32 | command = NULL; |
richnash | 0:23c0d0e1c31d | 33 | command_count = 0; |
richnash | 0:23c0d0e1c31d | 34 | } |
richnash | 0:23c0d0e1c31d | 35 | |
richnash | 0:23c0d0e1c31d | 36 | xPL_Message::~xPL_Message() |
richnash | 0:23c0d0e1c31d | 37 | { |
richnash | 0:23c0d0e1c31d | 38 | if(command != NULL) |
richnash | 0:23c0d0e1c31d | 39 | { |
richnash | 0:23c0d0e1c31d | 40 | free(command); |
richnash | 0:23c0d0e1c31d | 41 | } |
richnash | 0:23c0d0e1c31d | 42 | } |
richnash | 0:23c0d0e1c31d | 43 | |
richnash | 0:23c0d0e1c31d | 44 | /** |
richnash | 0:23c0d0e1c31d | 45 | * \brief Set source of the message (optional) |
richnash | 0:23c0d0e1c31d | 46 | * \param _vendorId vendor id. |
richnash | 0:23c0d0e1c31d | 47 | * \param _deviceId device id. |
richnash | 0:23c0d0e1c31d | 48 | * \param _instanceId instance id. |
richnash | 0:23c0d0e1c31d | 49 | */ |
richnash | 0:23c0d0e1c31d | 50 | void xPL_Message::SetSource(char * _vendorId, char * _deviceId, char * _instanceId) |
richnash | 0:23c0d0e1c31d | 51 | { |
richnash | 0:23c0d0e1c31d | 52 | memcpy(source.vendor_id, _vendorId, XPL_VENDOR_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 53 | memcpy(source.device_id, _deviceId, XPL_DEVICE_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 54 | memcpy(source.instance_id, _instanceId, XPL_INSTANCE_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 55 | } |
richnash | 0:23c0d0e1c31d | 56 | |
richnash | 0:23c0d0e1c31d | 57 | /** |
richnash | 0:23c0d0e1c31d | 58 | * \brief Set Target of the message |
richnash | 0:23c0d0e1c31d | 59 | * \details insert "*" into _vendorId to broadcast the message |
richnash | 0:23c0d0e1c31d | 60 | * \param _vendorId vendor id. |
richnash | 0:23c0d0e1c31d | 61 | * \param _deviceId device id. (optional) |
richnash | 0:23c0d0e1c31d | 62 | * \param _instanceId instance id. (optional) |
richnash | 0:23c0d0e1c31d | 63 | */ |
richnash | 0:23c0d0e1c31d | 64 | void xPL_Message::SetTarget(const char * _vendorId, const char * _deviceId, const char * _instanceId) |
richnash | 0:23c0d0e1c31d | 65 | { |
richnash | 0:23c0d0e1c31d | 66 | memcpy(target.vendor_id, _vendorId, XPL_VENDOR_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 67 | if(_deviceId != NULL) memcpy(target.device_id, _deviceId, XPL_DEVICE_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 68 | if(_instanceId != NULL) memcpy(target.instance_id, _instanceId, XPL_INSTANCE_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 69 | } |
richnash | 0:23c0d0e1c31d | 70 | |
richnash | 0:23c0d0e1c31d | 71 | /** |
richnash | 0:23c0d0e1c31d | 72 | * \brief Set Schema of the message |
richnash | 0:23c0d0e1c31d | 73 | * \param _classId Class |
richnash | 0:23c0d0e1c31d | 74 | * \param _typeId Type |
richnash | 0:23c0d0e1c31d | 75 | */ |
richnash | 0:23c0d0e1c31d | 76 | void xPL_Message::SetSchema(const char * _classId, const char * _typeId) |
richnash | 0:23c0d0e1c31d | 77 | { |
richnash | 0:23c0d0e1c31d | 78 | memcpy(schema.class_id, _classId, XPL_CLASS_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 79 | memcpy(schema.type_id, _typeId, XPL_TYPE_ID_MAX + 1); |
richnash | 0:23c0d0e1c31d | 80 | } |
richnash | 0:23c0d0e1c31d | 81 | |
richnash | 0:23c0d0e1c31d | 82 | /** |
richnash | 0:23c0d0e1c31d | 83 | * \brief Create a new command/value pair |
richnash | 0:23c0d0e1c31d | 84 | * \details Check if maximun command is reach and add memory to command array |
richnash | 0:23c0d0e1c31d | 85 | */ |
richnash | 0:23c0d0e1c31d | 86 | bool xPL_Message::CreateCommand() |
richnash | 0:23c0d0e1c31d | 87 | { |
richnash | 0:23c0d0e1c31d | 88 | struct_command *ncommand; |
richnash | 0:23c0d0e1c31d | 89 | |
richnash | 0:23c0d0e1c31d | 90 | // Maximun command reach |
richnash | 0:23c0d0e1c31d | 91 | // To avoid oom, we arbitrary accept only XPL_MESSAGE_COMMAND_MAX command |
richnash | 0:23c0d0e1c31d | 92 | if(command_count > XPL_MESSAGE_COMMAND_MAX) |
richnash | 0:23c0d0e1c31d | 93 | return false; |
richnash | 0:23c0d0e1c31d | 94 | |
richnash | 0:23c0d0e1c31d | 95 | ncommand = (struct_command*)realloc ( command, (command_count + 1) * sizeof(struct_command) ); |
richnash | 0:23c0d0e1c31d | 96 | |
richnash | 0:23c0d0e1c31d | 97 | if (ncommand != NULL) { |
richnash | 0:23c0d0e1c31d | 98 | command = ncommand; |
richnash | 0:23c0d0e1c31d | 99 | command_count++; |
richnash | 0:23c0d0e1c31d | 100 | return true; |
richnash | 0:23c0d0e1c31d | 101 | } |
richnash | 0:23c0d0e1c31d | 102 | else |
richnash | 0:23c0d0e1c31d | 103 | return false; |
richnash | 0:23c0d0e1c31d | 104 | } |
richnash | 0:23c0d0e1c31d | 105 | |
richnash | 0:23c0d0e1c31d | 106 | /** |
richnash | 0:23c0d0e1c31d | 107 | * \brief Add a command to the message's body |
richnash | 0:23c0d0e1c31d | 108 | * \details PROGMEM Version |
richnash | 0:23c0d0e1c31d | 109 | * \param _name name of the command |
richnash | 0:23c0d0e1c31d | 110 | * \param _value value of the command |
richnash | 0:23c0d0e1c31d | 111 | */ |
richnash | 0:23c0d0e1c31d | 112 | bool xPL_Message::AddCommand(const char* _name, const char* _value) |
richnash | 0:23c0d0e1c31d | 113 | { |
richnash | 0:23c0d0e1c31d | 114 | if(!CreateCommand()) return false; |
richnash | 0:23c0d0e1c31d | 115 | |
richnash | 0:23c0d0e1c31d | 116 | struct_command newcmd; |
richnash | 0:23c0d0e1c31d | 117 | memcpy(newcmd.name, _name, XPL_NAME_LENGTH_MAX + 1); |
richnash | 0:23c0d0e1c31d | 118 | memcpy(newcmd.value, _value, XPL_VALUE_LENGTH_MAX + 1); |
richnash | 0:23c0d0e1c31d | 119 | command[command_count-1] = newcmd; |
richnash | 0:23c0d0e1c31d | 120 | return true; |
richnash | 0:23c0d0e1c31d | 121 | } |
richnash | 0:23c0d0e1c31d | 122 | |
richnash | 0:23c0d0e1c31d | 123 | /** |
richnash | 0:23c0d0e1c31d | 124 | * \brief Add a command to the message's body |
richnash | 0:23c0d0e1c31d | 125 | * \details char* Version |
richnash | 0:23c0d0e1c31d | 126 | * \param _name name of the command |
richnash | 0:23c0d0e1c31d | 127 | * \param _value value of the command |
richnash | 0:23c0d0e1c31d | 128 | */ |
richnash | 0:23c0d0e1c31d | 129 | bool xPL_Message::AddCommand(char* _name, char* _value) |
richnash | 0:23c0d0e1c31d | 130 | { |
richnash | 0:23c0d0e1c31d | 131 | if(!CreateCommand()) return false; |
richnash | 0:23c0d0e1c31d | 132 | |
richnash | 0:23c0d0e1c31d | 133 | struct_command newcmd; |
richnash | 0:23c0d0e1c31d | 134 | memcpy(newcmd.name, _name, XPL_NAME_LENGTH_MAX + 1); |
richnash | 0:23c0d0e1c31d | 135 | memcpy(newcmd.value, _value, XPL_VALUE_LENGTH_MAX + 1); |
richnash | 0:23c0d0e1c31d | 136 | command[command_count-1] = newcmd; |
richnash | 0:23c0d0e1c31d | 137 | return true; |
richnash | 0:23c0d0e1c31d | 138 | } |
richnash | 0:23c0d0e1c31d | 139 | |
richnash | 0:23c0d0e1c31d | 140 | /** |
richnash | 0:23c0d0e1c31d | 141 | * \brief Convert xPL_Message to char* buffer |
richnash | 0:23c0d0e1c31d | 142 | */ |
richnash | 0:23c0d0e1c31d | 143 | char message_buffer[XPL_MESSAGE_BUFFER_MAX]; |
richnash | 0:23c0d0e1c31d | 144 | char* xPL_Message::toString() |
richnash | 0:23c0d0e1c31d | 145 | { |
richnash | 0:23c0d0e1c31d | 146 | int pos; |
richnash | 0:23c0d0e1c31d | 147 | |
richnash | 0:23c0d0e1c31d | 148 | clearStr(message_buffer); |
richnash | 0:23c0d0e1c31d | 149 | |
richnash | 0:23c0d0e1c31d | 150 | switch(type) |
richnash | 0:23c0d0e1c31d | 151 | { |
richnash | 0:23c0d0e1c31d | 152 | case (XPL_CMND): |
richnash | 0:23c0d0e1c31d | 153 | pos = sprintf(message_buffer, "xpl-cmnd"); |
richnash | 0:23c0d0e1c31d | 154 | break; |
richnash | 0:23c0d0e1c31d | 155 | case (XPL_STAT): |
richnash | 0:23c0d0e1c31d | 156 | pos = sprintf(message_buffer, "xpl-stat"); |
richnash | 0:23c0d0e1c31d | 157 | break; |
richnash | 0:23c0d0e1c31d | 158 | case (XPL_TRIG): |
richnash | 0:23c0d0e1c31d | 159 | pos = sprintf(message_buffer, "xpl-trig"); |
richnash | 0:23c0d0e1c31d | 160 | break; |
richnash | 0:23c0d0e1c31d | 161 | } |
richnash | 0:23c0d0e1c31d | 162 | |
richnash | 0:23c0d0e1c31d | 163 | pos += sprintf(message_buffer + pos, "\n{\nhop=1\nsource=%s-%s.%s\ntarget=", source.vendor_id, source.device_id, source.instance_id); |
richnash | 0:23c0d0e1c31d | 164 | |
richnash | 0:23c0d0e1c31d | 165 | if(memcmp(target.vendor_id,"*", 1) == 0) // check if broadcast message |
richnash | 0:23c0d0e1c31d | 166 | { |
richnash | 0:23c0d0e1c31d | 167 | pos += sprintf(message_buffer + pos, "*\n}\n"); |
richnash | 0:23c0d0e1c31d | 168 | } |
richnash | 0:23c0d0e1c31d | 169 | else |
richnash | 0:23c0d0e1c31d | 170 | { |
richnash | 0:23c0d0e1c31d | 171 | pos += sprintf(message_buffer + pos, "%s-%s.%s\n}\n",target.vendor_id, target.device_id, target.instance_id); |
richnash | 0:23c0d0e1c31d | 172 | } |
richnash | 0:23c0d0e1c31d | 173 | |
richnash | 0:23c0d0e1c31d | 174 | pos += sprintf(message_buffer + pos, "%s.%s\n{\n",schema.class_id, schema.type_id); |
richnash | 0:23c0d0e1c31d | 175 | |
richnash | 0:23c0d0e1c31d | 176 | for (short i=0; i<command_count; i++) |
richnash | 0:23c0d0e1c31d | 177 | { |
richnash | 0:23c0d0e1c31d | 178 | pos += sprintf(message_buffer + pos, "%s=%s\n", command[i].name, command[i].value); |
richnash | 0:23c0d0e1c31d | 179 | } |
richnash | 0:23c0d0e1c31d | 180 | |
richnash | 0:23c0d0e1c31d | 181 | sprintf(message_buffer + pos, "}\n"); |
richnash | 0:23c0d0e1c31d | 182 | |
richnash | 0:23c0d0e1c31d | 183 | return message_buffer; |
richnash | 0:23c0d0e1c31d | 184 | } |
richnash | 0:23c0d0e1c31d | 185 | |
richnash | 0:23c0d0e1c31d | 186 | bool xPL_Message::IsSchema(char* _classId, char* _typeId) |
richnash | 0:23c0d0e1c31d | 187 | { |
richnash | 0:23c0d0e1c31d | 188 | if (strcmp(schema.class_id, _classId) == 0) |
richnash | 0:23c0d0e1c31d | 189 | { |
richnash | 0:23c0d0e1c31d | 190 | if (strcmp(schema.type_id, _typeId) == 0) |
richnash | 0:23c0d0e1c31d | 191 | { |
richnash | 0:23c0d0e1c31d | 192 | return true; |
richnash | 0:23c0d0e1c31d | 193 | } |
richnash | 0:23c0d0e1c31d | 194 | } |
richnash | 0:23c0d0e1c31d | 195 | |
richnash | 0:23c0d0e1c31d | 196 | return false; |
richnash | 0:23c0d0e1c31d | 197 | } |
richnash | 0:23c0d0e1c31d | 198 | |
richnash | 0:23c0d0e1c31d | 199 | /** |
richnash | 0:23c0d0e1c31d | 200 | * \brief Check the message's schema |
richnash | 0:23c0d0e1c31d | 201 | * \param _classId class |
richnash | 0:23c0d0e1c31d | 202 | * \param _typeId type |
richnash | 0:23c0d0e1c31d | 203 | */ |
richnash | 0:23c0d0e1c31d | 204 | bool xPL_Message::IsSchema(const char* _classId, const char* _typeId) |
richnash | 0:23c0d0e1c31d | 205 | { |
richnash | 0:23c0d0e1c31d | 206 | if (strncmp(schema.class_id, _classId, XPL_CLASS_ID_MAX) == 0) |
richnash | 0:23c0d0e1c31d | 207 | { |
richnash | 0:23c0d0e1c31d | 208 | if (strncmp(schema.type_id, _typeId, XPL_TYPE_ID_MAX) == 0) |
richnash | 0:23c0d0e1c31d | 209 | { |
richnash | 0:23c0d0e1c31d | 210 | return true; |
richnash | 0:23c0d0e1c31d | 211 | } |
richnash | 0:23c0d0e1c31d | 212 | } |
richnash | 0:23c0d0e1c31d | 213 | |
richnash | 0:23c0d0e1c31d | 214 | return false; |
richnash | 0:23c0d0e1c31d | 215 | } |