Richard Nash / xpl

Dependents:   XPL-App4_cleanup XPL-App5

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xPL_Message.cpp Source File

xPL_Message.cpp

00001 /*
00002  * xPL.Arduino v0.1, xPL Implementation for Arduino
00003  *
00004  * This code is parsing a xPL message stored in 'received' buffer
00005  * - isolate and store in 'line' buffer each part of the message -> detection of EOL character (DEC 10)
00006  * - analyse 'line', function of its number and store information in xpl_header memory
00007  * - check for each step if the message respect xPL protocol
00008  * - parse each command line
00009  *
00010  * Copyright (C) 2012 johan@pirlouit.ch, olivier.lebrun@gmail.com
00011  * Original version by Gromain59@gmail.com
00012  *
00013  * This program is free software; you can redistribute it and/or
00014  * modify it under the terms of the GNU General Public License
00015  * as published by the Free Software Foundation; either version 2
00016  * of the License, or (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00026 */
00027  
00028 #include "xPL_Message.h"
00029 
00030 xPL_Message::xPL_Message()
00031 {
00032     command = NULL;
00033     command_count = 0;
00034 }
00035 
00036 xPL_Message::~xPL_Message()
00037 {
00038     if(command != NULL)
00039     {
00040         free(command);
00041     }
00042 }
00043 
00044 /**
00045  * \brief       Set source of the message (optional)
00046  * \param    _vendorId         vendor id.
00047  * \param    _deviceId         device id.
00048  * \param    _instanceId      instance id.
00049  */
00050 void xPL_Message::SetSource(char * _vendorId, char * _deviceId, char * _instanceId)
00051 {
00052     memcpy(source.vendor_id, _vendorId, XPL_VENDOR_ID_MAX + 1);
00053     memcpy(source.device_id, _deviceId, XPL_DEVICE_ID_MAX + 1);
00054     memcpy(source.instance_id, _instanceId, XPL_INSTANCE_ID_MAX + 1);
00055 }
00056 
00057 /**
00058  * \brief       Set Target of the message
00059  * \details   insert "*" into _vendorId to broadcast the message
00060  * \param    _vendorId         vendor id.
00061  * \param    _deviceId         device id.       (optional)
00062  * \param    _instanceId      instance id.    (optional)
00063  */
00064 void xPL_Message::SetTarget(const char * _vendorId, const char * _deviceId, const char * _instanceId)
00065 {
00066     memcpy(target.vendor_id, _vendorId, XPL_VENDOR_ID_MAX + 1);
00067     if(_deviceId != NULL) memcpy(target.device_id, _deviceId, XPL_DEVICE_ID_MAX + 1);
00068     if(_instanceId != NULL) memcpy(target.instance_id, _instanceId, XPL_INSTANCE_ID_MAX + 1);
00069 }
00070 
00071 /**
00072  * \brief       Set Schema of the message
00073   * \param   _classId       Class
00074  * \param    _typeId         Type
00075   */
00076 void xPL_Message::SetSchema(const char * _classId, const char * _typeId)
00077 {
00078     memcpy(schema.class_id, _classId, XPL_CLASS_ID_MAX + 1);
00079     memcpy(schema.type_id, _typeId, XPL_TYPE_ID_MAX + 1);
00080 }
00081 
00082 /**
00083  * \brief       Create a new command/value pair
00084  * \details   Check if maximun command is reach and add memory to command array
00085  */
00086 bool xPL_Message::CreateCommand()
00087 {
00088     struct_command  *ncommand;
00089 
00090     // Maximun command reach
00091     // To avoid oom, we arbitrary accept only XPL_MESSAGE_COMMAND_MAX command
00092     if(command_count > XPL_MESSAGE_COMMAND_MAX)
00093         return false;
00094         
00095     ncommand = (struct_command*)realloc ( command, (command_count + 1) * sizeof(struct_command) );
00096     
00097     if (ncommand != NULL) {
00098         command = ncommand;
00099         command_count++;
00100         return true;
00101     }
00102     else
00103         return false;
00104 }
00105 
00106 /**
00107  * \brief       Add a command to the message's body
00108  * \details   PROGMEM Version
00109  * \param    _name         name of the command
00110  * \param    _value         value of the command
00111  */
00112 bool xPL_Message::AddCommand(const char* _name, const char* _value)
00113 {
00114     if(!CreateCommand()) return false;
00115 
00116     struct_command newcmd;
00117     memcpy(newcmd.name, _name, XPL_NAME_LENGTH_MAX + 1);
00118     memcpy(newcmd.value, _value, XPL_VALUE_LENGTH_MAX + 1);
00119     command[command_count-1] = newcmd;
00120     return true;
00121 }
00122 
00123 /**
00124  * \brief       Add a command to the message's body
00125  * \details   char* Version
00126  * \param    _name         name of the command
00127  * \param    _value         value of the command
00128  */
00129 bool xPL_Message::AddCommand(char* _name, char* _value)
00130 {
00131     if(!CreateCommand()) return false;
00132 
00133     struct_command newcmd;
00134     memcpy(newcmd.name, _name, XPL_NAME_LENGTH_MAX + 1);
00135     memcpy(newcmd.value, _value, XPL_VALUE_LENGTH_MAX + 1);
00136     command[command_count-1] = newcmd;
00137     return true;
00138 }
00139 
00140 /**
00141  * \brief       Convert xPL_Message to char* buffer
00142  */
00143 char message_buffer[XPL_MESSAGE_BUFFER_MAX];
00144 char* xPL_Message::toString()
00145 {
00146   int pos;
00147 
00148   clearStr(message_buffer);
00149 
00150   switch(type)
00151   {
00152     case (XPL_CMND):
00153       pos = sprintf(message_buffer, "xpl-cmnd");
00154       break;
00155     case (XPL_STAT):
00156       pos = sprintf(message_buffer, "xpl-stat");
00157       break;
00158     case (XPL_TRIG):
00159       pos = sprintf(message_buffer, "xpl-trig");
00160       break;
00161   }
00162 
00163   pos += sprintf(message_buffer + pos, "\n{\nhop=1\nsource=%s-%s.%s\ntarget=", source.vendor_id, source.device_id, source.instance_id);
00164 
00165   if(memcmp(target.vendor_id,"*", 1) == 0)  // check if broadcast message
00166   {
00167     pos += sprintf(message_buffer + pos, "*\n}\n");
00168   }
00169   else
00170   {
00171     pos += sprintf(message_buffer + pos, "%s-%s.%s\n}\n",target.vendor_id, target.device_id, target.instance_id);
00172   }
00173 
00174   pos += sprintf(message_buffer + pos, "%s.%s\n{\n",schema.class_id, schema.type_id);
00175 
00176   for (short i=0; i<command_count; i++)
00177   {
00178     pos += sprintf(message_buffer + pos, "%s=%s\n", command[i].name, command[i].value);
00179   }
00180 
00181   sprintf(message_buffer + pos, "}\n");
00182 
00183   return message_buffer;
00184 }
00185 
00186 bool xPL_Message::IsSchema(char* _classId, char* _typeId)
00187 {
00188   if (strcmp(schema.class_id, _classId) == 0)
00189   {
00190     if (strcmp(schema.type_id, _typeId) == 0)
00191     {
00192       return true;
00193     }   
00194   }  
00195 
00196   return false;
00197 }
00198 
00199 /**
00200  * \brief       Check the message's schema
00201   * \param   _classId        class
00202  * \param    _typeId         type
00203  */
00204 bool xPL_Message::IsSchema(const char* _classId, const char* _typeId)
00205 {
00206     if (strncmp(schema.class_id, _classId, XPL_CLASS_ID_MAX) == 0)
00207       {
00208         if (strncmp(schema.type_id, _typeId, XPL_TYPE_ID_MAX) == 0)
00209         {
00210           return true;
00211         }
00212       }
00213 
00214       return false;
00215 }