xpl lib

Dependents:   XPL-App4_cleanup XPL-App5

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?

UserRevisionLine numberNew 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