Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: XPL-App4_cleanup XPL-App5
Diff: xPL_Message.cpp
- Revision:
- 0:23c0d0e1c31d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xPL_Message.cpp Tue Oct 09 17:37:05 2018 +0000
@@ -0,0 +1,215 @@
+/*
+ * xPL.Arduino v0.1, xPL Implementation for Arduino
+ *
+ * This code is parsing a xPL message stored in 'received' buffer
+ * - isolate and store in 'line' buffer each part of the message -> detection of EOL character (DEC 10)
+ * - analyse 'line', function of its number and store information in xpl_header memory
+ * - check for each step if the message respect xPL protocol
+ * - parse each command line
+ *
+ * Copyright (C) 2012 johan@pirlouit.ch, olivier.lebrun@gmail.com
+ * Original version by Gromain59@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "xPL_Message.h"
+
+xPL_Message::xPL_Message()
+{
+ command = NULL;
+ command_count = 0;
+}
+
+xPL_Message::~xPL_Message()
+{
+ if(command != NULL)
+ {
+ free(command);
+ }
+}
+
+/**
+ * \brief Set source of the message (optional)
+ * \param _vendorId vendor id.
+ * \param _deviceId device id.
+ * \param _instanceId instance id.
+ */
+void xPL_Message::SetSource(char * _vendorId, char * _deviceId, char * _instanceId)
+{
+ memcpy(source.vendor_id, _vendorId, XPL_VENDOR_ID_MAX + 1);
+ memcpy(source.device_id, _deviceId, XPL_DEVICE_ID_MAX + 1);
+ memcpy(source.instance_id, _instanceId, XPL_INSTANCE_ID_MAX + 1);
+}
+
+/**
+ * \brief Set Target of the message
+ * \details insert "*" into _vendorId to broadcast the message
+ * \param _vendorId vendor id.
+ * \param _deviceId device id. (optional)
+ * \param _instanceId instance id. (optional)
+ */
+void xPL_Message::SetTarget(const char * _vendorId, const char * _deviceId, const char * _instanceId)
+{
+ memcpy(target.vendor_id, _vendorId, XPL_VENDOR_ID_MAX + 1);
+ if(_deviceId != NULL) memcpy(target.device_id, _deviceId, XPL_DEVICE_ID_MAX + 1);
+ if(_instanceId != NULL) memcpy(target.instance_id, _instanceId, XPL_INSTANCE_ID_MAX + 1);
+}
+
+/**
+ * \brief Set Schema of the message
+ * \param _classId Class
+ * \param _typeId Type
+ */
+void xPL_Message::SetSchema(const char * _classId, const char * _typeId)
+{
+ memcpy(schema.class_id, _classId, XPL_CLASS_ID_MAX + 1);
+ memcpy(schema.type_id, _typeId, XPL_TYPE_ID_MAX + 1);
+}
+
+/**
+ * \brief Create a new command/value pair
+ * \details Check if maximun command is reach and add memory to command array
+ */
+bool xPL_Message::CreateCommand()
+{
+ struct_command *ncommand;
+
+ // Maximun command reach
+ // To avoid oom, we arbitrary accept only XPL_MESSAGE_COMMAND_MAX command
+ if(command_count > XPL_MESSAGE_COMMAND_MAX)
+ return false;
+
+ ncommand = (struct_command*)realloc ( command, (command_count + 1) * sizeof(struct_command) );
+
+ if (ncommand != NULL) {
+ command = ncommand;
+ command_count++;
+ return true;
+ }
+ else
+ return false;
+}
+
+/**
+ * \brief Add a command to the message's body
+ * \details PROGMEM Version
+ * \param _name name of the command
+ * \param _value value of the command
+ */
+bool xPL_Message::AddCommand(const char* _name, const char* _value)
+{
+ if(!CreateCommand()) return false;
+
+ struct_command newcmd;
+ memcpy(newcmd.name, _name, XPL_NAME_LENGTH_MAX + 1);
+ memcpy(newcmd.value, _value, XPL_VALUE_LENGTH_MAX + 1);
+ command[command_count-1] = newcmd;
+ return true;
+}
+
+/**
+ * \brief Add a command to the message's body
+ * \details char* Version
+ * \param _name name of the command
+ * \param _value value of the command
+ */
+bool xPL_Message::AddCommand(char* _name, char* _value)
+{
+ if(!CreateCommand()) return false;
+
+ struct_command newcmd;
+ memcpy(newcmd.name, _name, XPL_NAME_LENGTH_MAX + 1);
+ memcpy(newcmd.value, _value, XPL_VALUE_LENGTH_MAX + 1);
+ command[command_count-1] = newcmd;
+ return true;
+}
+
+/**
+ * \brief Convert xPL_Message to char* buffer
+ */
+char message_buffer[XPL_MESSAGE_BUFFER_MAX];
+char* xPL_Message::toString()
+{
+ int pos;
+
+ clearStr(message_buffer);
+
+ switch(type)
+ {
+ case (XPL_CMND):
+ pos = sprintf(message_buffer, "xpl-cmnd");
+ break;
+ case (XPL_STAT):
+ pos = sprintf(message_buffer, "xpl-stat");
+ break;
+ case (XPL_TRIG):
+ pos = sprintf(message_buffer, "xpl-trig");
+ break;
+ }
+
+ pos += sprintf(message_buffer + pos, "\n{\nhop=1\nsource=%s-%s.%s\ntarget=", source.vendor_id, source.device_id, source.instance_id);
+
+ if(memcmp(target.vendor_id,"*", 1) == 0) // check if broadcast message
+ {
+ pos += sprintf(message_buffer + pos, "*\n}\n");
+ }
+ else
+ {
+ pos += sprintf(message_buffer + pos, "%s-%s.%s\n}\n",target.vendor_id, target.device_id, target.instance_id);
+ }
+
+ pos += sprintf(message_buffer + pos, "%s.%s\n{\n",schema.class_id, schema.type_id);
+
+ for (short i=0; i<command_count; i++)
+ {
+ pos += sprintf(message_buffer + pos, "%s=%s\n", command[i].name, command[i].value);
+ }
+
+ sprintf(message_buffer + pos, "}\n");
+
+ return message_buffer;
+}
+
+bool xPL_Message::IsSchema(char* _classId, char* _typeId)
+{
+ if (strcmp(schema.class_id, _classId) == 0)
+ {
+ if (strcmp(schema.type_id, _typeId) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * \brief Check the message's schema
+ * \param _classId class
+ * \param _typeId type
+ */
+bool xPL_Message::IsSchema(const char* _classId, const char* _typeId)
+{
+ if (strncmp(schema.class_id, _classId, XPL_CLASS_ID_MAX) == 0)
+ {
+ if (strncmp(schema.type_id, _typeId, XPL_TYPE_ID_MAX) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}