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.
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 const 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 static const char* encapsulation_packet_name = "ENCAPSULATED"; 00033 00034 /** 00035 * Returns a character string representing the packet name given a MsgType code 00036 * @param code MsgType code 00037 * @return the corresponding packet name 00038 */ 00039 const char* MQTTSNPacket_name(int code) 00040 { 00041 if ( code == MQTTSN_ENCAPSULATED ) 00042 { 00043 return encapsulation_packet_name; 00044 } 00045 return (code >= 0 && code <= MQTTSN_WILLMSGRESP) ? packet_names[code] : "UNKNOWN"; 00046 } 00047 00048 00049 /** 00050 * Calculates the full packet length including length field 00051 * @param length the length of the MQTT-SN packet without the length field 00052 * @return the total length of the MQTT-SN packet including the length field 00053 */ 00054 int MQTTSNPacket_len(int length) 00055 { 00056 return (length > 255) ? length + 3 : length + 1; 00057 } 00058 00059 /** 00060 * Encodes the MQTT-SN message length 00061 * @param buf the buffer into which the encoded data is written 00062 * @param length the length to be encoded 00063 * @return the number of bytes written to the buffer 00064 */ 00065 int MQTTSNPacket_encode(unsigned char* buf, int length) 00066 { 00067 int rc = 0; 00068 00069 FUNC_ENTRY; 00070 if (length > 255) 00071 { 00072 writeChar(&buf, 0x01); 00073 writeInt(&buf, length); 00074 rc += 3; 00075 } 00076 else 00077 buf[rc++] = length; 00078 00079 FUNC_EXIT_RC(rc); 00080 return rc; 00081 } 00082 00083 00084 /** 00085 * Obtains the MQTT-SN packet length from received data 00086 * @param getcharfn pointer to function to read the next character from the data source 00087 * @param value the decoded length returned 00088 * @return the number of bytes read from the socket 00089 */ 00090 int MQTTSNPacket_decode(unsigned char* buf, int buflen, int* value) 00091 { 00092 int len = MQTTSNPACKET_READ_ERROR; 00093 #define MAX_NO_OF_LENGTH_BYTES 3 00094 00095 FUNC_ENTRY; 00096 if (buflen <= 0) 00097 goto exit; 00098 00099 if (buf[0] == 1) 00100 { 00101 unsigned char* bufptr = &buf[1]; 00102 if (buflen < MAX_NO_OF_LENGTH_BYTES) 00103 goto exit; 00104 *value = readInt(&bufptr); 00105 len = 3; 00106 } 00107 else 00108 { 00109 *value = buf[0]; 00110 len = 1; 00111 } 00112 exit: 00113 FUNC_EXIT_RC(len); 00114 return len; 00115 } 00116 00117 /** 00118 * Check if two MQTT-SN topics are equal. Long names are not checked. 00119 * @param a pointer to first topic 00120 * @param b pointer to second topic 00121 * @return boolean true if topics are equal and flase otherwise 00122 */ 00123 int MQTTSNTopic_equals(const MQTTSN_topicid* const a, const MQTTSN_topicid* const b) 00124 { 00125 if ((a->type == b->type) 00126 && (a->data.id == b->data.id) 00127 && (a->data.short_name[0] == b->data.short_name[0]) 00128 && (a->data.short_name[1] == b->data.short_name[1])) { 00129 return 1; 00130 } else { 00131 return 0; 00132 } 00133 } 00134 00135 #if 0 // Those are already defined in MQTTPacket.c 00136 /** 00137 * Calculates an integer from two bytes read from the input buffer 00138 * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned 00139 * @return the integer value calculated 00140 */ 00141 int readInt(unsigned char** pptr) 00142 { 00143 unsigned char* ptr = *pptr; 00144 int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1)); 00145 *pptr += 2; 00146 return len; 00147 } 00148 00149 00150 /** 00151 * Reads one character from the input buffer. 00152 * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned 00153 * @return the character read 00154 */ 00155 char readChar(unsigned char** pptr) 00156 { 00157 char c = **pptr; 00158 (*pptr)++; 00159 return c; 00160 } 00161 00162 00163 /** 00164 * Writes one character to an output buffer. 00165 * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 00166 * @param c the character to write 00167 */ 00168 void writeChar(unsigned char** pptr, char c) 00169 { 00170 **pptr = (unsigned char)c; 00171 (*pptr)++; 00172 } 00173 00174 00175 /** 00176 * Writes an integer as 2 bytes to an output buffer. 00177 * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 00178 * @param anInt the integer to write: 0 to 65535 00179 */ 00180 void writeInt(unsigned char** pptr, int anInt) 00181 { 00182 **pptr = (unsigned char)(anInt / 256); 00183 (*pptr)++; 00184 **pptr = (unsigned char)(anInt % 256); 00185 (*pptr)++; 00186 } 00187 00188 00189 /** 00190 * Writes a "UTF" string to an output buffer. Converts C string to length-delimited. 00191 * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 00192 * @param string the C string to write 00193 */ 00194 void writeCString(unsigned char** pptr, char* string) 00195 { 00196 int len = strlen(string); 00197 memcpy(*pptr, string, len); 00198 *pptr += len; 00199 } 00200 00201 00202 int getLenStringLen(char* ptr) 00203 { 00204 int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1)); 00205 return len; 00206 } 00207 #endif 00208 00209 void writeMQTTSNString(unsigned char** pptr, MQTTSNString MQTTSNString) 00210 { 00211 if (MQTTSNString.lenstring.len > 0) 00212 { 00213 memcpy(*pptr, (const unsigned char*)MQTTSNString.lenstring.data, MQTTSNString.lenstring.len); 00214 *pptr += MQTTSNString.lenstring.len; 00215 } 00216 else if (MQTTSNString.cstring) 00217 writeCString(pptr, MQTTSNString.cstring); 00218 } 00219 00220 00221 /** 00222 * @param MQTTSNString the MQTTSNString structure into which the data is to be read 00223 * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 00224 * @param enddata pointer to the end of the data: do not read beyond 00225 * @return 1 if successful, 0 if not 00226 */ 00227 int readMQTTSNString(MQTTSNString* MQTTSNString, unsigned char** pptr, unsigned char* enddata) 00228 { 00229 int rc = 0; 00230 00231 FUNC_ENTRY; 00232 MQTTSNString->lenstring.len = enddata - *pptr; 00233 if (MQTTSNString->lenstring.len > 0) 00234 { 00235 MQTTSNString->lenstring.data = (char*)*pptr; 00236 *pptr += MQTTSNString->lenstring.len; 00237 } 00238 else 00239 { 00240 MQTTSNString->lenstring.data = NULL; 00241 MQTTSNString->cstring = NULL; 00242 } 00243 rc = 1; 00244 FUNC_EXIT_RC(rc); 00245 return rc; 00246 } 00247 00248 00249 /** 00250 * Return the length of the MQTTSNString - C string if there is one, otherwise the length delimited string 00251 * @param MQTTSNString the string to return the length of 00252 * @return the length of the string 00253 */ 00254 int MQTTSNstrlen(MQTTSNString MQTTSNString) 00255 { 00256 int rc = 0; 00257 00258 if (MQTTSNString.cstring) 00259 rc = strlen(MQTTSNString.cstring); 00260 else 00261 rc = MQTTSNString.lenstring.len; 00262 return rc; 00263 } 00264 00265 00266 /** 00267 * Helper function to read packet data from some source into a buffer 00268 * @param buf the buffer into which the packet will be serialized 00269 * @param buflen the length in bytes of the supplied buffer 00270 * @param getfn pointer to a function which will read any number of bytes from the needed source 00271 * @return integer MQTT packet type, or MQTTSNPACKET_READ_ERROR on error 00272 */ 00273 int MQTTSNPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int)) 00274 { 00275 int rc = MQTTSNPACKET_READ_ERROR; 00276 const int MQTTSN_MIN_PACKET_LENGTH = 2; 00277 int len = 0; /* the length of the whole packet including length field */ 00278 int lenlen = 0; 00279 int datalen = 0; 00280 00281 /* 1. read a packet - UDP style */ 00282 if ((len = (*getfn)(buf, buflen)) < MQTTSN_MIN_PACKET_LENGTH) 00283 goto exit; 00284 00285 /* 2. read the length. This is variable in itself */ 00286 lenlen = MQTTSNPacket_decode(buf, len, &datalen); 00287 if (datalen != len) 00288 goto exit; /* there was an error */ 00289 00290 rc = buf[lenlen]; /* return the packet type */ 00291 exit: 00292 return rc; 00293 } 00294 00295 int MQTTSNPacket_read_nb(unsigned char* buf, int buflen) 00296 { 00297 int rc = MQTTSNPACKET_READ_ERROR; 00298 int len = buflen; /* the length of the whole packet including length field */ 00299 int lenlen = 0; 00300 int datalen = 0; 00301 00302 /* 2. read the length. This is variable in itself */ 00303 lenlen = MQTTSNPacket_decode(buf, len, &datalen); 00304 if (datalen != len) 00305 goto exit; /* there was an error */ 00306 00307 rc = buf[lenlen]; /* return the packet type */ 00308 exit: 00309 return rc; 00310 } 00311
Generated on Thu Jul 14 2022 12:58:42 by
