Low level MQTTSN packet library, part of the Eclipse Paho project: http://eclipse.org/paho
Dependents: MQTTSN sara-n200-hello-mqtt-sn MQTTSN_2
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
Generated on Tue Jul 12 2022 20:35:37 by 1.7.2