Low level MQTTSN packet library, part of the Eclipse Paho project: http://eclipse.org/paho

Dependents:   MQTTSN sara-n200-hello-mqtt-sn MQTTSN_2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MQTTSNPacket.c Source File

MQTTSNPacket.c

00001 /*******************************************************************************
00002  * Copyright (c) 2014 IBM Corp.
00003  *
00004  * All rights reserved. This program and the accompanying materials
00005  * are made available under the terms of the Eclipse Public License v1.0
00006  * and Eclipse Distribution License v1.0 which accompany this distribution.
00007  *
00008  * The Eclipse Public License is available at
00009  *    http://www.eclipse.org/legal/epl-v10.html
00010  * and the Eclipse Distribution License is available at
00011  *   http://www.eclipse.org/org/documents/edl-v10.php.
00012  *
00013  * Contributors:
00014  *    Ian Craggs - initial API and implementation and/or initial documentation
00015  *******************************************************************************/
00016 
00017 #include "StackTrace.h"
00018 #include "MQTTSNPacket.h"
00019 
00020 #include <string.h>
00021 
00022 static char* packet_names[] =
00023 {
00024         "ADVERTISE", "SEARCHGW", "GWINFO", "RESERVED", "CONNECT", "CONNACK",
00025         "WILLTOPICREQ", "WILLTOPIC", "WILLMSGREQ", "WILLMSG", "REGISTER", "REGACK",
00026         "PUBLISH", "PUBACK", "PUBCOMP", "PUBREC", "PUBREL", "RESERVED",
00027         "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP",
00028         "DISCONNECT", "RESERVED", "WILLTOPICUPD", "WILLTOPICRESP", "WILLMSGUPD",
00029         "WILLMSGRESP"
00030 };
00031 
00032 
00033 /**
00034  * Returns a character string representing the packet name given a MsgType code
00035  * @param code MsgType code
00036  * @return the corresponding packet name
00037  */
00038 char* MQTTSNPacket_name(int code)
00039 {
00040     return (code >= 0 && code <= MQTTSN_WILLMSGRESP) ? packet_names[code] : "UNKNOWN";
00041 }
00042 
00043 
00044 /**
00045  * Calculates the full packet length including length field
00046  * @param length the length of the MQTT-SN packet without the length field
00047  * @return the total length of the MQTT-SN packet including the length field
00048  */
00049 int MQTTSNPacket_len(int length)
00050 {
00051     return (length > 255) ? length + 3 : length + 1;
00052 }
00053 
00054 
00055 /**
00056  * Encodes the MQTT-SN message length
00057  * @param buf the buffer into which the encoded data is written
00058  * @param length the length to be encoded
00059  * @return the number of bytes written to the buffer
00060  */
00061 int MQTTSNPacket_encode(unsigned char* buf, int length)
00062 {
00063     int rc = 0;
00064 
00065     FUNC_ENTRY;
00066     if (length > 255)
00067     {
00068         buf[rc++] = 0x01;
00069         MQTTSNPacket_writeInt(&buf, length);
00070         rc += 2;
00071     }
00072     else
00073         buf[rc++] = length;
00074 
00075     FUNC_EXIT_RC(rc);
00076     return rc;
00077 }
00078 
00079 
00080 /**
00081  * Obtains the MQTT-SN packet length from received data
00082  * @param getcharfn pointer to function to read the next character from the data source
00083  * @param value the decoded length returned
00084  * @return the number of bytes read from the socket
00085  */
00086 int MQTTSNPacket_decode(unsigned char* buf, int buflen, int* value)
00087 {
00088     int len = MQTTSNPACKET_READ_ERROR;
00089 #define MAX_NO_OF_LENGTH_BYTES 3
00090 
00091     FUNC_ENTRY;
00092     if (buflen <= 0)
00093         goto exit;
00094 
00095     if (buf[0] == 1)
00096     {
00097         unsigned char* bufptr = &buf[1];
00098         if (buflen < 3)
00099             goto exit;
00100         *value = MQTTSNPacket_readInt(&bufptr);
00101         len = 3;
00102     }
00103     else
00104     {
00105         *value = buf[0];
00106         len = 1;
00107     }
00108 exit:
00109     FUNC_EXIT_RC(len);
00110     return len;
00111 }
00112 
00113 
00114 /**
00115  * Calculates an integer from two bytes read from the input buffer
00116  * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
00117  * @return the integer value calculated
00118  */
00119 int MQTTSNPacket_readInt(unsigned char** pptr)
00120 {
00121     unsigned char* ptr = *pptr;
00122     int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
00123     *pptr += 2;
00124     return len;
00125 }
00126 
00127 
00128 /**
00129  * Reads one character from the input buffer.
00130  * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
00131  * @return the character read
00132  */
00133 char MQTTSNPacket_readChar(unsigned char** pptr)
00134 {
00135     char c = **pptr;
00136     (*pptr)++;
00137     return c;
00138 }
00139 
00140 
00141 /**
00142  * Writes one character to an output buffer.
00143  * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
00144  * @param c the character to write
00145  */
00146 void MQTTSNPacket_writeChar(unsigned char** pptr, char c)
00147 {
00148     **pptr = (unsigned char)c;
00149     (*pptr)++;
00150 }
00151 
00152 
00153 /**
00154  * Writes an integer as 2 bytes to an output buffer.
00155  * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
00156  * @param anInt the integer to write: 0 to 65535
00157  */
00158 void MQTTSNPacket_writeInt(unsigned char** pptr, int anInt)
00159 {
00160     **pptr = (unsigned char)(anInt / 256);
00161     (*pptr)++;
00162     **pptr = (unsigned char)(anInt % 256);
00163     (*pptr)++;
00164 }
00165 
00166 
00167 /**
00168  * Writes a "UTF" string to an output buffer.  Converts C string to length-delimited.
00169  * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
00170  * @param string the C string to write
00171  */
00172 void MQTTSNPacket_writeCString(unsigned char** pptr, char* string)
00173 {
00174     int len = strlen(string);
00175     memcpy(*pptr, string, len);
00176     *pptr += len;
00177 }
00178 
00179 
00180 int MQTTSNPacket_getLenStringLen(char* ptr)
00181 {
00182     int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
00183     return len;
00184 }
00185 
00186 
00187 void writeMQTTSNString(unsigned char** pptr, MQTTSNString MQTTSNString)
00188 {
00189     if (MQTTSNString.lenstring.len > 0)
00190     {
00191         memcpy(*pptr, MQTTSNString.lenstring.data, MQTTSNString.lenstring.len);
00192         *pptr += MQTTSNString.lenstring.len;
00193     }
00194     else if (MQTTSNString.cstring)
00195         MQTTSNPacket_writeCString(pptr, MQTTSNString.cstring);
00196 }
00197 
00198 
00199 /**
00200  * @param MQTTSNString the MQTTSNString structure into which the data is to be read
00201  * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
00202  * @param enddata pointer to the end of the data: do not read beyond
00203  * @return 1 if successful, 0 if not
00204  */
00205 int readMQTTSNString(MQTTSNString* MQTTSNString, unsigned char** pptr, unsigned char* enddata)
00206 {
00207     int rc = 0;
00208 
00209     FUNC_ENTRY;
00210     MQTTSNString->lenstring.len = enddata - *pptr;
00211     if (MQTTSNString->lenstring.len > 0)
00212     {
00213         MQTTSNString->lenstring.data = (char*)*pptr;
00214         *pptr += MQTTSNString->lenstring.len;
00215     }
00216     else
00217         MQTTSNString->lenstring.data = NULL;
00218     MQTTSNString->cstring = NULL;
00219     rc = 1;
00220     FUNC_EXIT_RC(rc);
00221     return rc;
00222 }
00223 
00224 
00225 /**
00226  * Return the length of the MQTTSNString - C string if there is one, otherwise the length delimited string
00227  * @param MQTTSNString the string to return the length of
00228  * @return the length of the string
00229  */
00230 int MQTTSNstrlen(MQTTSNString MQTTSNString)
00231 {
00232     int rc = 0;
00233 
00234     if (MQTTSNString.cstring)
00235         rc = strlen(MQTTSNString.cstring);
00236     else
00237         rc = MQTTSNString.lenstring.len;
00238     return rc;
00239 }
00240 
00241 
00242 /**
00243  * Helper function to read packet data from some source into a buffer
00244  * @param buf the buffer into which the packet will be serialized
00245  * @param buflen the length in bytes of the supplied buffer
00246  * @param getfn pointer to a function which will read any number of bytes from the needed source
00247  * @return integer MQTT packet type, or MQTTSNPACKET_READ_ERROR on error
00248  */
00249 int MQTTSNPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int))
00250 {
00251     int rc = MQTTSNPACKET_READ_ERROR;
00252     const int MQTTSN_MIN_PACKET_LENGTH = 3;
00253     int len = 0;  /* the length of the whole packet including length field */
00254     int lenlen = 0;
00255     int datalen = 0;
00256 
00257     /* 1. read a packet - UDP style */
00258     if ((len = (*getfn)(buf, buflen)) < MQTTSN_MIN_PACKET_LENGTH)
00259         goto exit;
00260 
00261     /* 2. read the length.  This is variable in itself */
00262     lenlen = MQTTSNPacket_decode(buf, len, &datalen);
00263     if (datalen != len)
00264         goto exit; /* there was an error */
00265 
00266     rc = buf[lenlen]; /* return the packet type */
00267 exit:
00268     return rc;
00269 }
00270 
00271 
00272