xpl lib
Dependents: XPL-App4_cleanup XPL-App5
xPL.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.h" |
richnash | 0:23c0d0e1c31d | 29 | |
richnash | 0:23c0d0e1c31d | 30 | #define XPL_LINE_MESSAGE_BUFFER_MAX 128 // max length of a line // maximum command in a xpl message |
richnash | 0:23c0d0e1c31d | 31 | #define XPL_END_OF_LINE 10 |
richnash | 0:23c0d0e1c31d | 32 | |
richnash | 0:23c0d0e1c31d | 33 | // define the line number identifier |
richnash | 0:23c0d0e1c31d | 34 | #define XPL_MESSAGE_TYPE_IDENTIFIER 1 |
richnash | 0:23c0d0e1c31d | 35 | #define XPL_OPEN_HEADER 2 |
richnash | 0:23c0d0e1c31d | 36 | #define XPL_HOP_COUNT 3 |
richnash | 0:23c0d0e1c31d | 37 | #define XPL_SOURCE 4 |
richnash | 0:23c0d0e1c31d | 38 | #define XPL_TARGET 5 |
richnash | 0:23c0d0e1c31d | 39 | #define XPL_CLOSE_HEADER 6 |
richnash | 0:23c0d0e1c31d | 40 | #define XPL_SCHEMA_IDENTIFIER 7 |
richnash | 0:23c0d0e1c31d | 41 | #define XPL_OPEN_SCHEMA 8 |
richnash | 0:23c0d0e1c31d | 42 | |
richnash | 0:23c0d0e1c31d | 43 | // Heartbeat request class definition |
richnash | 0:23c0d0e1c31d | 44 | //prog_char XPL_HBEAT_REQUEST_CLASS_ID[] PROGMEM = "hbeat"; |
richnash | 0:23c0d0e1c31d | 45 | //prog_char XPL_HBEAT_REQUEST_TYPE_ID[] PROGMEM = "request"; |
richnash | 0:23c0d0e1c31d | 46 | //prog_char XPL_HBEAT_ANSWER_CLASS_ID[] PROGMEM = "hbeat"; |
richnash | 0:23c0d0e1c31d | 47 | //prog_char XPL_HBEAT_ANSWER_TYPE_ID[] PROGMEM = "basic"; //app, basic |
richnash | 0:23c0d0e1c31d | 48 | #define XPL_HBEAT_REQUEST_CLASS_ID "hbeat" |
richnash | 0:23c0d0e1c31d | 49 | #define XPL_HBEAT_REQUEST_TYPE_ID "request" |
richnash | 0:23c0d0e1c31d | 50 | #define XPL_HBEAT_ANSWER_CLASS_ID "hbeat" |
richnash | 0:23c0d0e1c31d | 51 | #define XPL_HBEAT_ANSWER_TYPE_ID "app" |
richnash | 0:23c0d0e1c31d | 52 | |
richnash | 0:23c0d0e1c31d | 53 | /* xPL Class */ |
richnash | 0:23c0d0e1c31d | 54 | xPL::xPL() |
richnash | 0:23c0d0e1c31d | 55 | { |
richnash | 0:23c0d0e1c31d | 56 | udp_port = XPL_UDP_PORT; |
richnash | 0:23c0d0e1c31d | 57 | |
richnash | 0:23c0d0e1c31d | 58 | SendExternal = NULL; |
richnash | 0:23c0d0e1c31d | 59 | |
richnash | 0:23c0d0e1c31d | 60 | #ifdef ENABLE_PARSING |
richnash | 0:23c0d0e1c31d | 61 | AfterParseAction = NULL; |
richnash | 0:23c0d0e1c31d | 62 | |
richnash | 0:23c0d0e1c31d | 63 | last_heartbeat = 0; |
richnash | 0:23c0d0e1c31d | 64 | hbeat_interval = XPL_DEFAULT_HEARTBEAT_INTERVAL; |
richnash | 0:23c0d0e1c31d | 65 | xpl_accepted = XPL_ACCEPT_ALL; |
richnash | 0:23c0d0e1c31d | 66 | #endif |
richnash | 0:23c0d0e1c31d | 67 | } |
richnash | 0:23c0d0e1c31d | 68 | |
richnash | 0:23c0d0e1c31d | 69 | xPL::~xPL() |
richnash | 0:23c0d0e1c31d | 70 | { |
richnash | 0:23c0d0e1c31d | 71 | } |
richnash | 0:23c0d0e1c31d | 72 | |
richnash | 0:23c0d0e1c31d | 73 | /// Set the source of outgoing xPL messages |
richnash | 0:23c0d0e1c31d | 74 | void xPL::SetSource(const char * _vendorId, const char * _deviceId, const char * _instanceId) |
richnash | 0:23c0d0e1c31d | 75 | { |
richnash | 0:23c0d0e1c31d | 76 | memcpy(source.vendor_id, _vendorId, XPL_VENDOR_ID_MAX); |
richnash | 0:23c0d0e1c31d | 77 | memcpy(source.device_id, _deviceId, XPL_DEVICE_ID_MAX); |
richnash | 0:23c0d0e1c31d | 78 | memcpy(source.instance_id, _instanceId, XPL_INSTANCE_ID_MAX); |
richnash | 0:23c0d0e1c31d | 79 | } |
richnash | 0:23c0d0e1c31d | 80 | |
richnash | 0:23c0d0e1c31d | 81 | /** |
richnash | 0:23c0d0e1c31d | 82 | * \brief Send an xPL message |
richnash | 0:23c0d0e1c31d | 83 | * \details There is no validation of the message, it is sent as is. |
richnash | 0:23c0d0e1c31d | 84 | * \param buffer buffer containing the xPL message. |
richnash | 0:23c0d0e1c31d | 85 | */ |
richnash | 0:23c0d0e1c31d | 86 | void xPL::SendMessage(char *_buffer) |
richnash | 0:23c0d0e1c31d | 87 | { |
richnash | 0:23c0d0e1c31d | 88 | (*SendExternal)(_buffer); |
richnash | 0:23c0d0e1c31d | 89 | } |
richnash | 0:23c0d0e1c31d | 90 | |
richnash | 0:23c0d0e1c31d | 91 | /** |
richnash | 0:23c0d0e1c31d | 92 | * \brief Send an xPL message |
richnash | 0:23c0d0e1c31d | 93 | * \details There is no validation of the message, it is sent as is. |
richnash | 0:23c0d0e1c31d | 94 | * \param message An xPL message. |
richnash | 0:23c0d0e1c31d | 95 | * \param _useDefaultSource if true, insert the default source (defined in SetSource) on the message. |
richnash | 0:23c0d0e1c31d | 96 | */ |
richnash | 0:23c0d0e1c31d | 97 | void xPL::SendMessage(xPL_Message *_message, bool _useDefaultSource) |
richnash | 0:23c0d0e1c31d | 98 | { |
richnash | 0:23c0d0e1c31d | 99 | if(_useDefaultSource) |
richnash | 0:23c0d0e1c31d | 100 | { |
richnash | 0:23c0d0e1c31d | 101 | _message->SetSource(source.vendor_id, source.device_id, source.instance_id); |
richnash | 0:23c0d0e1c31d | 102 | } |
richnash | 0:23c0d0e1c31d | 103 | |
richnash | 0:23c0d0e1c31d | 104 | SendMessage(_message->toString()); |
richnash | 0:23c0d0e1c31d | 105 | } |
richnash | 0:23c0d0e1c31d | 106 | |
richnash | 0:23c0d0e1c31d | 107 | #ifdef ENABLE_PARSING |
richnash | 0:23c0d0e1c31d | 108 | |
richnash | 0:23c0d0e1c31d | 109 | /** |
richnash | 0:23c0d0e1c31d | 110 | * \brief xPL Stuff |
richnash | 0:23c0d0e1c31d | 111 | * \details Send heartbeat messages at "hbeat_interval" interval |
richnash | 0:23c0d0e1c31d | 112 | */ |
richnash | 0:23c0d0e1c31d | 113 | void xPL::Process() |
richnash | 0:23c0d0e1c31d | 114 | { |
richnash | 0:23c0d0e1c31d | 115 | static bool bFirstRun = true; |
richnash | 0:23c0d0e1c31d | 116 | |
richnash | 0:23c0d0e1c31d | 117 | // Check heartbeat + send |
richnash | 0:23c0d0e1c31d | 118 | //if ((millis()-last_heartbeat >= (unsigned long)hbeat_interval * 1000) |
richnash | 0:23c0d0e1c31d | 119 | // || (bFirstRun && millis() > 3000)) |
richnash | 0:23c0d0e1c31d | 120 | if ((clock()-last_heartbeat >= (unsigned long)hbeat_interval * 1000) |
richnash | 0:23c0d0e1c31d | 121 | || (bFirstRun && clock() > 3000)) |
richnash | 0:23c0d0e1c31d | 122 | { |
richnash | 0:23c0d0e1c31d | 123 | SendHBeat(); |
richnash | 0:23c0d0e1c31d | 124 | bFirstRun = false; |
richnash | 0:23c0d0e1c31d | 125 | } |
richnash | 0:23c0d0e1c31d | 126 | } |
richnash | 0:23c0d0e1c31d | 127 | |
richnash | 0:23c0d0e1c31d | 128 | /** |
richnash | 0:23c0d0e1c31d | 129 | * \brief Parse an ingoing xPL message |
richnash | 0:23c0d0e1c31d | 130 | * \details Parse a message, check for hearbeat request and call user defined callback for post processing. |
richnash | 0:23c0d0e1c31d | 131 | * \param buffer buffer of the ingoing UDP Packet |
richnash | 0:23c0d0e1c31d | 132 | */ |
richnash | 0:23c0d0e1c31d | 133 | void xPL::ParseInputMessage(char* _buffer) |
richnash | 0:23c0d0e1c31d | 134 | { |
richnash | 0:23c0d0e1c31d | 135 | xPL_Message* xPLMessage = new xPL_Message(); |
richnash | 0:23c0d0e1c31d | 136 | Parse(xPLMessage, _buffer); |
richnash | 0:23c0d0e1c31d | 137 | |
richnash | 0:23c0d0e1c31d | 138 | // check if the message is an hbeat.request to send a heartbeat |
richnash | 0:23c0d0e1c31d | 139 | if (CheckHBeatRequest(xPLMessage)) |
richnash | 0:23c0d0e1c31d | 140 | { |
richnash | 0:23c0d0e1c31d | 141 | SendHBeat(); |
richnash | 0:23c0d0e1c31d | 142 | } |
richnash | 0:23c0d0e1c31d | 143 | |
richnash | 0:23c0d0e1c31d | 144 | // call the user defined callback to execute an action |
richnash | 0:23c0d0e1c31d | 145 | if(AfterParseAction != NULL) |
richnash | 0:23c0d0e1c31d | 146 | { |
richnash | 0:23c0d0e1c31d | 147 | (*AfterParseAction)(xPLMessage); |
richnash | 0:23c0d0e1c31d | 148 | } |
richnash | 0:23c0d0e1c31d | 149 | |
richnash | 0:23c0d0e1c31d | 150 | delete xPLMessage; |
richnash | 0:23c0d0e1c31d | 151 | } |
richnash | 0:23c0d0e1c31d | 152 | |
richnash | 0:23c0d0e1c31d | 153 | /** |
richnash | 0:23c0d0e1c31d | 154 | * \brief Check the xPL message target |
richnash | 0:23c0d0e1c31d | 155 | * \details Check if the xPL message is for us |
richnash | 0:23c0d0e1c31d | 156 | * \param _message an xPL message |
richnash | 0:23c0d0e1c31d | 157 | */ |
richnash | 0:23c0d0e1c31d | 158 | bool xPL::TargetIsMe(xPL_Message * _message) |
richnash | 0:23c0d0e1c31d | 159 | { |
richnash | 0:23c0d0e1c31d | 160 | if (memcmp(_message->target.vendor_id, source.vendor_id, strlen(source.vendor_id)) != 0) |
richnash | 0:23c0d0e1c31d | 161 | return false; |
richnash | 0:23c0d0e1c31d | 162 | |
richnash | 0:23c0d0e1c31d | 163 | if (memcmp(_message->target.device_id, source.device_id, strlen(source.device_id)) != 0) |
richnash | 0:23c0d0e1c31d | 164 | return false; |
richnash | 0:23c0d0e1c31d | 165 | |
richnash | 0:23c0d0e1c31d | 166 | if (memcmp(_message->target.instance_id, source.instance_id, strlen(source.instance_id)) != 0) |
richnash | 0:23c0d0e1c31d | 167 | return false; |
richnash | 0:23c0d0e1c31d | 168 | |
richnash | 0:23c0d0e1c31d | 169 | return true; |
richnash | 0:23c0d0e1c31d | 170 | } |
richnash | 0:23c0d0e1c31d | 171 | |
richnash | 0:23c0d0e1c31d | 172 | /** |
richnash | 0:23c0d0e1c31d | 173 | * \brief Send a heartbeat message |
richnash | 0:23c0d0e1c31d | 174 | */ |
richnash | 0:23c0d0e1c31d | 175 | void xPL::SendHBeat() |
richnash | 0:23c0d0e1c31d | 176 | { |
richnash | 0:23c0d0e1c31d | 177 | last_heartbeat = clock(); //millis(); |
richnash | 0:23c0d0e1c31d | 178 | char buffer[XPL_MESSAGE_BUFFER_MAX]; |
richnash | 0:23c0d0e1c31d | 179 | |
richnash | 0:23c0d0e1c31d | 180 | // sprintf_P(buffer, PSTR("xpl-stat\n{\nhop=1\nsource=%s-%s.%s\ntarget=*\n}\n%s.%s\n{\ninterval=%d\n}\n"), source.vendor_id, source.device_id, source.instance_id, XPL_HBEAT_ANSWER_CLASS_ID, XPL_HBEAT_ANSWER_TYPE_ID, hbeat_interval); |
richnash | 0:23c0d0e1c31d | 181 | //sprintf(buffer, "xpl-stat\r\n{\r\nhop=1\r\nsource=%s-%s.%s\r\ntarget=*\r\n}\r\n%s.%s\r\n{\r\ninterval=%d\r\nport=3865\r\nremote-ip=8.8.8.8\r\nversion=1.0\r\n}\r\n", source.vendor_id, source.device_id, source.instance_id, XPL_HBEAT_ANSWER_CLASS_ID, XPL_HBEAT_ANSWER_TYPE_ID, hbeat_interval); |
richnash | 0:23c0d0e1c31d | 182 | sprintf(buffer, "xpl-stat\n{\nhop=1\nsource=%s-%s.%s\ntarget=*\n}\n%s.%s\n{\ninterval=%d\nport=3865\nremote-ip=8.8.8.8\nversion=1.0\n}\n", source.vendor_id, source.device_id, source.instance_id, XPL_HBEAT_ANSWER_CLASS_ID, XPL_HBEAT_ANSWER_TYPE_ID, hbeat_interval); |
richnash | 0:23c0d0e1c31d | 183 | |
richnash | 0:23c0d0e1c31d | 184 | //(*SendExternal)(buffer); |
richnash | 0:23c0d0e1c31d | 185 | SendMessage(buffer); |
richnash | 0:23c0d0e1c31d | 186 | |
richnash | 0:23c0d0e1c31d | 187 | printf("XPL: HB Sent\r\n"); |
richnash | 0:23c0d0e1c31d | 188 | } |
richnash | 0:23c0d0e1c31d | 189 | |
richnash | 0:23c0d0e1c31d | 190 | /** |
richnash | 0:23c0d0e1c31d | 191 | * \brief Check if the message is a heartbeat request |
richnash | 0:23c0d0e1c31d | 192 | * \param _message an xPL message |
richnash | 0:23c0d0e1c31d | 193 | */ |
richnash | 0:23c0d0e1c31d | 194 | inline bool xPL::CheckHBeatRequest(xPL_Message* _message) |
richnash | 0:23c0d0e1c31d | 195 | { |
richnash | 0:23c0d0e1c31d | 196 | if (!TargetIsMe(_message)) |
richnash | 0:23c0d0e1c31d | 197 | return false; |
richnash | 0:23c0d0e1c31d | 198 | |
richnash | 0:23c0d0e1c31d | 199 | return _message->IsSchema(XPL_HBEAT_REQUEST_CLASS_ID, XPL_HBEAT_REQUEST_TYPE_ID); |
richnash | 0:23c0d0e1c31d | 200 | } |
richnash | 0:23c0d0e1c31d | 201 | |
richnash | 0:23c0d0e1c31d | 202 | /** |
richnash | 0:23c0d0e1c31d | 203 | * \brief Parse a buffer and generate a xPL_Message |
richnash | 0:23c0d0e1c31d | 204 | * \details Line based xPL parser |
richnash | 0:23c0d0e1c31d | 205 | * \param _xPLMessage the result xPL message |
richnash | 0:23c0d0e1c31d | 206 | * \param _message the buffer |
richnash | 0:23c0d0e1c31d | 207 | */ |
richnash | 0:23c0d0e1c31d | 208 | void xPL::Parse(xPL_Message* _xPLMessage, char* _buffer) |
richnash | 0:23c0d0e1c31d | 209 | { |
richnash | 0:23c0d0e1c31d | 210 | int len = strlen(_buffer); |
richnash | 0:23c0d0e1c31d | 211 | |
richnash | 0:23c0d0e1c31d | 212 | short j=0; |
richnash | 0:23c0d0e1c31d | 213 | short line=0; |
richnash | 0:23c0d0e1c31d | 214 | int result=0; |
richnash | 0:23c0d0e1c31d | 215 | char lineBuffer[XPL_LINE_MESSAGE_BUFFER_MAX+1]; |
richnash | 0:23c0d0e1c31d | 216 | |
richnash | 0:23c0d0e1c31d | 217 | // read each character of the message |
richnash | 0:23c0d0e1c31d | 218 | for(short i = 0; i < len; i++) |
richnash | 0:23c0d0e1c31d | 219 | { |
richnash | 0:23c0d0e1c31d | 220 | // load byte by byte in 'line' buffer, until '\n' is detected |
richnash | 0:23c0d0e1c31d | 221 | if(_buffer[i] == XPL_END_OF_LINE) // is it a linefeed (ASCII: 10 decimal) |
richnash | 0:23c0d0e1c31d | 222 | { |
richnash | 0:23c0d0e1c31d | 223 | ++line; |
richnash | 0:23c0d0e1c31d | 224 | lineBuffer[j]='\0'; // add the end of string id |
richnash | 0:23c0d0e1c31d | 225 | |
richnash | 0:23c0d0e1c31d | 226 | if(line <= XPL_OPEN_SCHEMA) |
richnash | 0:23c0d0e1c31d | 227 | { |
richnash | 0:23c0d0e1c31d | 228 | // first part: header and schema determination |
richnash | 0:23c0d0e1c31d | 229 | // we analyse the line, function of the line number in the xpl message |
richnash | 0:23c0d0e1c31d | 230 | result = AnalyseHeaderLine(_xPLMessage, lineBuffer ,line); |
richnash | 0:23c0d0e1c31d | 231 | } |
richnash | 0:23c0d0e1c31d | 232 | |
richnash | 0:23c0d0e1c31d | 233 | if(line > XPL_OPEN_SCHEMA) |
richnash | 0:23c0d0e1c31d | 234 | { |
richnash | 0:23c0d0e1c31d | 235 | // second part: command line |
richnash | 0:23c0d0e1c31d | 236 | // we analyse the specific command line, function of the line number in the xpl message |
richnash | 0:23c0d0e1c31d | 237 | result = AnalyseCommandLine(_xPLMessage, lineBuffer, line-9, j); |
richnash | 0:23c0d0e1c31d | 238 | |
richnash | 0:23c0d0e1c31d | 239 | if(result == _xPLMessage->command_count+1) |
richnash | 0:23c0d0e1c31d | 240 | break; |
richnash | 0:23c0d0e1c31d | 241 | } |
richnash | 0:23c0d0e1c31d | 242 | |
richnash | 0:23c0d0e1c31d | 243 | if (result < 0) break; |
richnash | 0:23c0d0e1c31d | 244 | |
richnash | 0:23c0d0e1c31d | 245 | j = 0; // reset the buffer pointer |
richnash | 0:23c0d0e1c31d | 246 | clearStr(lineBuffer); // clear the buffer |
richnash | 0:23c0d0e1c31d | 247 | } |
richnash | 0:23c0d0e1c31d | 248 | else |
richnash | 0:23c0d0e1c31d | 249 | { |
richnash | 0:23c0d0e1c31d | 250 | // next character |
richnash | 0:23c0d0e1c31d | 251 | lineBuffer[j++] = _buffer[i]; |
richnash | 0:23c0d0e1c31d | 252 | } |
richnash | 0:23c0d0e1c31d | 253 | } |
richnash | 0:23c0d0e1c31d | 254 | } |
richnash | 0:23c0d0e1c31d | 255 | |
richnash | 0:23c0d0e1c31d | 256 | /** |
richnash | 0:23c0d0e1c31d | 257 | * \brief Parse the header part of the xPL message line by line |
richnash | 0:23c0d0e1c31d | 258 | * \param _xPLMessage the result xPL message |
richnash | 0:23c0d0e1c31d | 259 | * \param _buffer the line to parse |
richnash | 0:23c0d0e1c31d | 260 | * \param _line the line number |
richnash | 0:23c0d0e1c31d | 261 | */ |
richnash | 0:23c0d0e1c31d | 262 | short xPL::AnalyseHeaderLine(xPL_Message* _xPLMessage, char* _buffer, short _line) |
richnash | 0:23c0d0e1c31d | 263 | { |
richnash | 0:23c0d0e1c31d | 264 | switch (_line) |
richnash | 0:23c0d0e1c31d | 265 | { |
richnash | 0:23c0d0e1c31d | 266 | case XPL_MESSAGE_TYPE_IDENTIFIER: //message type identifier |
richnash | 0:23c0d0e1c31d | 267 | |
richnash | 0:23c0d0e1c31d | 268 | if (memcmp(_buffer,"xpl-",4)==0) //xpl |
richnash | 0:23c0d0e1c31d | 269 | { |
richnash | 0:23c0d0e1c31d | 270 | if (memcmp(_buffer+4,"cmnd",4)==0) //command type |
richnash | 0:23c0d0e1c31d | 271 | { |
richnash | 0:23c0d0e1c31d | 272 | _xPLMessage->type=XPL_CMND; //xpl-cmnd |
richnash | 0:23c0d0e1c31d | 273 | } |
richnash | 0:23c0d0e1c31d | 274 | else if (memcmp(_buffer+4,"stat",4)==0) //statut type |
richnash | 0:23c0d0e1c31d | 275 | { |
richnash | 0:23c0d0e1c31d | 276 | _xPLMessage->type=XPL_STAT; //xpl-stat |
richnash | 0:23c0d0e1c31d | 277 | } |
richnash | 0:23c0d0e1c31d | 278 | else if (memcmp(_buffer+4,"trig",4)==0) // trigger type |
richnash | 0:23c0d0e1c31d | 279 | { |
richnash | 0:23c0d0e1c31d | 280 | _xPLMessage->type=XPL_TRIG; //xpl-trig |
richnash | 0:23c0d0e1c31d | 281 | } |
richnash | 0:23c0d0e1c31d | 282 | } |
richnash | 0:23c0d0e1c31d | 283 | else |
richnash | 0:23c0d0e1c31d | 284 | { |
richnash | 0:23c0d0e1c31d | 285 | return 0; //unknown message |
richnash | 0:23c0d0e1c31d | 286 | } |
richnash | 0:23c0d0e1c31d | 287 | |
richnash | 0:23c0d0e1c31d | 288 | return 1; |
richnash | 0:23c0d0e1c31d | 289 | |
richnash | 0:23c0d0e1c31d | 290 | //break; |
richnash | 0:23c0d0e1c31d | 291 | |
richnash | 0:23c0d0e1c31d | 292 | case XPL_OPEN_HEADER: //header begin |
richnash | 0:23c0d0e1c31d | 293 | |
richnash | 0:23c0d0e1c31d | 294 | if (memcmp(_buffer,"{",1)==0) |
richnash | 0:23c0d0e1c31d | 295 | { |
richnash | 0:23c0d0e1c31d | 296 | return 2; |
richnash | 0:23c0d0e1c31d | 297 | } |
richnash | 0:23c0d0e1c31d | 298 | //else |
richnash | 0:23c0d0e1c31d | 299 | //{ |
richnash | 0:23c0d0e1c31d | 300 | return -2; |
richnash | 0:23c0d0e1c31d | 301 | //} |
richnash | 0:23c0d0e1c31d | 302 | |
richnash | 0:23c0d0e1c31d | 303 | //break; |
richnash | 0:23c0d0e1c31d | 304 | |
richnash | 0:23c0d0e1c31d | 305 | case XPL_HOP_COUNT: //hop |
richnash | 0:23c0d0e1c31d | 306 | if (sscanf(_buffer, XPL_HOP_COUNT_PARSER, &_xPLMessage->hop)) |
richnash | 0:23c0d0e1c31d | 307 | { |
richnash | 0:23c0d0e1c31d | 308 | return 3; |
richnash | 0:23c0d0e1c31d | 309 | } |
richnash | 0:23c0d0e1c31d | 310 | //else |
richnash | 0:23c0d0e1c31d | 311 | //{ |
richnash | 0:23c0d0e1c31d | 312 | return -3; |
richnash | 0:23c0d0e1c31d | 313 | //} |
richnash | 0:23c0d0e1c31d | 314 | |
richnash | 0:23c0d0e1c31d | 315 | //break; |
richnash | 0:23c0d0e1c31d | 316 | |
richnash | 0:23c0d0e1c31d | 317 | case XPL_SOURCE: //source |
richnash | 0:23c0d0e1c31d | 318 | if (sscanf(_buffer, XPL_SOURCE_PARSER, &_xPLMessage->source.vendor_id, &_xPLMessage->source.device_id, &_xPLMessage->source.instance_id) == 3) |
richnash | 0:23c0d0e1c31d | 319 | { |
richnash | 0:23c0d0e1c31d | 320 | return 4; |
richnash | 0:23c0d0e1c31d | 321 | } |
richnash | 0:23c0d0e1c31d | 322 | //else |
richnash | 0:23c0d0e1c31d | 323 | //{ |
richnash | 0:23c0d0e1c31d | 324 | return -4; |
richnash | 0:23c0d0e1c31d | 325 | //} |
richnash | 0:23c0d0e1c31d | 326 | |
richnash | 0:23c0d0e1c31d | 327 | //break; |
richnash | 0:23c0d0e1c31d | 328 | |
richnash | 0:23c0d0e1c31d | 329 | case XPL_TARGET: //target |
richnash | 0:23c0d0e1c31d | 330 | |
richnash | 0:23c0d0e1c31d | 331 | if (sscanf(_buffer, XPL_TARGET_PARSER, &_xPLMessage->target.vendor_id, &_xPLMessage->target.device_id, &_xPLMessage->target.instance_id) == 3) |
richnash | 0:23c0d0e1c31d | 332 | { |
richnash | 0:23c0d0e1c31d | 333 | return 5; |
richnash | 0:23c0d0e1c31d | 334 | } |
richnash | 0:23c0d0e1c31d | 335 | //else |
richnash | 0:23c0d0e1c31d | 336 | //{ |
richnash | 0:23c0d0e1c31d | 337 | if(memcmp(_xPLMessage->target.vendor_id,"*", 1) == 0) // check if broadcast message |
richnash | 0:23c0d0e1c31d | 338 | { |
richnash | 0:23c0d0e1c31d | 339 | return 5; |
richnash | 0:23c0d0e1c31d | 340 | } |
richnash | 0:23c0d0e1c31d | 341 | //else |
richnash | 0:23c0d0e1c31d | 342 | //{ |
richnash | 0:23c0d0e1c31d | 343 | return -5; |
richnash | 0:23c0d0e1c31d | 344 | //} |
richnash | 0:23c0d0e1c31d | 345 | //} |
richnash | 0:23c0d0e1c31d | 346 | //break; |
richnash | 0:23c0d0e1c31d | 347 | |
richnash | 0:23c0d0e1c31d | 348 | case XPL_CLOSE_HEADER: //header end |
richnash | 0:23c0d0e1c31d | 349 | if (memcmp(_buffer,"}",1)==0) |
richnash | 0:23c0d0e1c31d | 350 | { |
richnash | 0:23c0d0e1c31d | 351 | return 6; |
richnash | 0:23c0d0e1c31d | 352 | } |
richnash | 0:23c0d0e1c31d | 353 | //else |
richnash | 0:23c0d0e1c31d | 354 | //{ |
richnash | 0:23c0d0e1c31d | 355 | return -6; |
richnash | 0:23c0d0e1c31d | 356 | //} |
richnash | 0:23c0d0e1c31d | 357 | |
richnash | 0:23c0d0e1c31d | 358 | //break; |
richnash | 0:23c0d0e1c31d | 359 | |
richnash | 0:23c0d0e1c31d | 360 | case XPL_SCHEMA_IDENTIFIER: //schema |
richnash | 0:23c0d0e1c31d | 361 | sscanf(_buffer, XPL_SCHEMA_PARSER, &_xPLMessage->schema.class_id, &_xPLMessage->schema.type_id); |
richnash | 0:23c0d0e1c31d | 362 | return 7; |
richnash | 0:23c0d0e1c31d | 363 | |
richnash | 0:23c0d0e1c31d | 364 | case XPL_OPEN_SCHEMA: //header begin |
richnash | 0:23c0d0e1c31d | 365 | if (memcmp(_buffer,"{",1)==0) |
richnash | 0:23c0d0e1c31d | 366 | { |
richnash | 0:23c0d0e1c31d | 367 | return 8; |
richnash | 0:23c0d0e1c31d | 368 | } |
richnash | 0:23c0d0e1c31d | 369 | //else |
richnash | 0:23c0d0e1c31d | 370 | //{ |
richnash | 0:23c0d0e1c31d | 371 | return -8; |
richnash | 0:23c0d0e1c31d | 372 | //} |
richnash | 0:23c0d0e1c31d | 373 | //break; |
richnash | 0:23c0d0e1c31d | 374 | } |
richnash | 0:23c0d0e1c31d | 375 | |
richnash | 0:23c0d0e1c31d | 376 | return -100; |
richnash | 0:23c0d0e1c31d | 377 | } |
richnash | 0:23c0d0e1c31d | 378 | |
richnash | 0:23c0d0e1c31d | 379 | /** |
richnash | 0:23c0d0e1c31d | 380 | * \brief Parse the body part of the xPL message line by line |
richnash | 0:23c0d0e1c31d | 381 | * \param _xPLMessage the result xPL message |
richnash | 0:23c0d0e1c31d | 382 | * \param _buffer the line to parse |
richnash | 0:23c0d0e1c31d | 383 | * \param _command_line the line number |
richnash | 0:23c0d0e1c31d | 384 | */ |
richnash | 0:23c0d0e1c31d | 385 | short xPL::AnalyseCommandLine(xPL_Message * _xPLMessage, char *_buffer, short _command_line, short line_length) |
richnash | 0:23c0d0e1c31d | 386 | { |
richnash | 0:23c0d0e1c31d | 387 | if (memcmp(_buffer,"}",1) == 0) // End of schema |
richnash | 0:23c0d0e1c31d | 388 | { |
richnash | 0:23c0d0e1c31d | 389 | return _xPLMessage->command_count+1; |
richnash | 0:23c0d0e1c31d | 390 | } |
richnash | 0:23c0d0e1c31d | 391 | else // parse the next command |
richnash | 0:23c0d0e1c31d | 392 | { |
richnash | 0:23c0d0e1c31d | 393 | struct_command newcmd; |
richnash | 0:23c0d0e1c31d | 394 | |
richnash | 0:23c0d0e1c31d | 395 | sscanf(_buffer, XPL_COMMAND_PARSER, &newcmd.name, &newcmd.value); |
richnash | 0:23c0d0e1c31d | 396 | |
richnash | 0:23c0d0e1c31d | 397 | _xPLMessage->AddCommand(newcmd.name, newcmd.value); |
richnash | 0:23c0d0e1c31d | 398 | |
richnash | 0:23c0d0e1c31d | 399 | return _command_line; |
richnash | 0:23c0d0e1c31d | 400 | } |
richnash | 0:23c0d0e1c31d | 401 | } |
richnash | 0:23c0d0e1c31d | 402 | #endif |