diff --git a/.gitignore b/.gitignore index 947c154..cf1cc9f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ opt/ cgi-bin/ bin/ GateWay/ +Release/ diff --git a/Cidn-SH b/Cidn-SH index 565bf3f..910148c 100644 Binary files a/Cidn-SH and b/Cidn-SH differ diff --git a/calculation/Calculation.cpp b/calculation/Calculation.cpp index 7893857..2e6e6ee 100644 --- a/calculation/Calculation.cpp +++ b/calculation/Calculation.cpp @@ -92,7 +92,7 @@ void Calculation::_FFT(std::vector & vecData, std::vector & vecFFT } FFT(vecData.size(), inHilFFt, outHilFFt); - fftShift(outHilFFt, vecData.size()); + //fftShift(outHilFFt, vecData.size()); for (int i = 0; i < vecData.size(); i++) { vecFFTrealData.push_back(outHilFFt[i][0]); vecFFTimageData.push_back(outHilFFt[i][1]); @@ -432,15 +432,44 @@ void Calculation::envSpec(std::vector & vecData, std::vector & vec void Calculation::GenerateSin(std::vector & vecData) { - int i; - int ft = 1; /* 周期 hz */ - int fs = 12800; /* 采样频率*/ + double frequency = 160.0; // Frequency of the sine wave in Hz + double sampling_rate = 3200.0; // Sampling rate in Hz (8 kHz) + size_t num_samples = 8000; // Total number of samples (1 second of data) + double dt = 1.0 / sampling_rate; // Time step in seconds - /* generate data */ - int data_len = (8*1024); + // Vector to hold the sine wave data + //std::vector sine_wave(num_samples); - for (i = 0; i < data_len; i++) { - vecData.push_back(sin(1000 * 2 *3.1415926*ft*i/fs)); - } + // Generate the sine wave + for (size_t i = 0; i < num_samples; ++i) { + vecData.push_back(std::sin(2 * M_PI * frequency * i * dt)); + } } + +void Calculation::Integration(std::vector & vecData,std::vector& retData) +{ + std::vector realshiftfft; + std::vector imageshiftfft; + std::vector realvalue,imagevalue; + _FFT(vecData,realshiftfft,imageshiftfft); + + for (int i = 0; i < 5; i++) { + realshiftfft[i] = 0; + imageshiftfft[i] = 0; + } + for (int i = 1000; i < realshiftfft.size(); i++) { + realshiftfft[i] = 0; + imageshiftfft[i] = 0; + } + + for(int k = 1; k < realshiftfft.size()+1;k++){ + realvalue.push_back((realshiftfft.at(k-1)/(k*2*M_PI))*1000 * 2);//单位转换mm/s,*1000 *2 精度损失 + imagevalue.push_back((imageshiftfft.at(k-1)/(k*2*M_PI))*1000 * 2);//单位转换mm/s,*1000 + } + + //_iFFT(realshiftfft,imageshiftfft,retData); + _iFFT(realvalue,imagevalue,retData); + + +} \ No newline at end of file diff --git a/calculation/Calculation.hpp b/calculation/Calculation.hpp index 6d888be..4948142 100644 --- a/calculation/Calculation.hpp +++ b/calculation/Calculation.hpp @@ -151,6 +151,8 @@ public: void FFTSpec(std::vector & vecData, std::vector & vecFFTSpecData); //包络图谱数据 void envSpec(std::vector & vecData, std::vector & vecEnvSpecData,int StartFrequency,int EndFrequency); + + void Integration(std::vector & vecData,std::vector& retData); }; diff --git a/common/SH_CommonFunc.hpp b/common/SH_CommonFunc.hpp index ac29d82..d075bd4 100644 --- a/common/SH_CommonFunc.hpp +++ b/common/SH_CommonFunc.hpp @@ -571,6 +571,27 @@ struct Param_54 { Param_54():mMode(0),mCmdSerial(""),mDataNodeNo(""),mPackageFlag(0){}; }; + +struct Param_55 { + int mMode; + std::string mChannelId; + std::string mDataNodeNo; + int mPackageFlag; + int StartFrequency; + int EndFrequency; + Param_55():mMode(0),mChannelId(""),mDataNodeNo(""),mPackageFlag(0),StartFrequency(0),EndFrequency(0){}; +}; + +struct Param_56 { + int mMode; + std::string mChannelId; + std::string mDataNodeNo; + int mPackageFlag; + int StartFrequency; + int EndFrequency; + Param_56():mMode(0),mChannelId(""),mDataNodeNo(""),mPackageFlag(0),StartFrequency(0),EndFrequency(0){}; +}; + typedef struct DataNodeUpdate{ std::string strUpdataFileName; std::string strSoftVersion; diff --git a/dbaccess/SH_SqlDB.cpp b/dbaccess/SH_SqlDB.cpp index b4b29db..31aae58 100644 --- a/dbaccess/SH_SqlDB.cpp +++ b/dbaccess/SH_SqlDB.cpp @@ -397,6 +397,7 @@ int SqliteDB::GetTableRows(const char *tablename, const char *whereCon) if (sqlite3_prepare_v2(mDBAcess, strSql.c_str(), -1, &stmt, 0) != SQLITE_OK) { print_error("sqlite3_prepare_v2:%s\n",sqlite3_errmsg(mDBAcess)); sqlite3_finalize(stmt); + g_tDbMutex.UnLock(); return -1; } int retStep = sqlite3_step(stmt); diff --git a/jsonparse/SH_JsonCmd.cpp b/jsonparse/SH_JsonCmd.cpp index f1d9093..23c9032 100644 --- a/jsonparse/SH_JsonCmd.cpp +++ b/jsonparse/SH_JsonCmd.cpp @@ -1805,6 +1805,7 @@ std::string JsonData::JsonCmd_Cgi_30(Param_30 ¶m) } int max = number / sampleRateReference; + print_info("max = %d\n",max); if (max == 0 && number > 0) { max = 1; } @@ -2473,5 +2474,269 @@ std::string JsonData::JsonCmd_Cgi_53(std::vector ¶m) return showValue.write(jsonVal); } +std::string JsonData::JsonCmd_Cgi_55(Param_55 ¶m) +{ + Json::Value jsonVal; + Json::Value jsBody; + Json::Value SystemSetting; + jsonVal.clear(); + jsonVal["cmd"] = "55"; + jsonVal["dataNodeGatewayNo"] = GlobalConfig::MacAddr_G; + jsonVal["success"] = true; + jsonVal["message"] = " "; + std::vector vecWave; + std::vector IntegrationWave; + /* 新增代码 */ + char whereCon[64] = {}; + sprintf(whereCon, "dataNodeNo='%s'",param.mDataNodeNo.c_str()); + vec_t res = sql_ctl->GetDataSingleLine(T_SENSOR_INFO(TNAME)," * ",whereCon); + char localtimestamp[32] = { 0 }; + std::string strWaveData = ""; + std::string filename = "/opt/data/" + param.mChannelId + ".dat"; + if (access(filename.c_str(), 0) >= 0) { + std::ifstream inFile(filename.c_str(),ios::in|ios::binary); + if (!inFile) { + print_error("read channel data error\n"); + jsonVal["success"] = false; + jsonVal["message"] = "error"; + } else { + float fTemp = 0; + + std::vector hanningWave; + inFile.read((char *)localtimestamp,sizeof(localtimestamp)); + while (inFile.read((char *)&fTemp, sizeof(fTemp))) { + vecWave.push_back(fTemp); + } + + // //积分 + pCalculation->Integration(vecWave, IntegrationWave); + + //测试正弦波 + // pCalculation->GenerateSin(vecWave); + // pCalculation->Integration(vecWave, IntegrationWave); + + //添加汉宁窗 + /*pCalculation->Hanning(vecWave, hanningWave); + for(int i = 0; i < vecWave.size();i++){ + vecWave[i] = (vecWave[i]*hanningWave[i]); + }*/ + + int flag = param.mPackageFlag; + flag = (flag + 1) * 1024; + int number = IntegrationWave.size(); + int start = param.mPackageFlag * 1024; + if (number < 1024) { + flag = number; + start = 0; + } + char buf[32]; + for (int i = start; i < flag; i++) { + if ( i == start ) { + memset(buf, 0, 32); + sprintf(buf, "%.2f", IntegrationWave[i]); + std::string waveTemp(buf); + strWaveData = waveTemp; + + } else { + memset(buf, 0, 32); + sprintf(buf, "%.2f", IntegrationWave[i]); + std::string waveTemp(buf); + strWaveData = strWaveData + "," + waveTemp; + } + } + + int max = number / 1024; + if (max == 0 && number > 0) { + max = 1; + } + jsBody["packageMax"] = max; + } + + } else { + jsonVal["success"] = false; + jsonVal["message"] = "没有数据文件"; + } + + jsBody["channelId"] = param.mChannelId; + jsBody["package"] = param.mPackageFlag; + print_info("vecWave.size() = %d,sample = %d,second = %f\n",IntegrationWave.size(),atoi(res[23].c_str()),float(IntegrationWave.size()/atoi(res[23].c_str()))); + string::size_type comper = param.mChannelId.find("Z"); + if (comper != string::npos && res[17]=="02"){ + jsBody["second"] = float((float)IntegrationWave.size()/(float)atoi(res[23].c_str())); + }else if(res[17]=="01"){ + jsBody["second"] = float((float)IntegrationWave.size()/(float)atoi(res[23].c_str())); + }else{ + jsBody["second"] = 1; + } + + jsBody["Data"] = strWaveData; + jsBody["timestamp"] = string(localtimestamp); + jsonVal["content"] = jsBody; + return showValue.write(jsonVal); +} + +std::string JsonData::JsonCmd_Cgi_56(Param_56 ¶m) +{ + Json::Value jsonVal; + Json::Value jsBody; + Json::Value SystemSetting; + jsonVal.clear(); + + jsonVal["cmd"] = "56"; + jsonVal["dataNodeGatewayNo"] = GlobalConfig::MacAddr_G; + jsonVal["success"] = true; + jsonVal["message"] = ""; + int i = 0; + std::string strWaveData; + std::string filename = "/opt/data/" + param.mChannelId + ".dat"; + char localtimestamp[32] = { 0 }; + std::vector vecWave; + std::vector hanningWave; + std::vector addhanningWave; + std::vector fftWave; + std::vector IntegrationWave; + int sampleRateReference = 0; + /* 新增代码 */ + char whereCon[64] = {}; + sprintf(whereCon, "dataNodeNo='%s'",param.mDataNodeNo.c_str()); + vec_t res = sql_ctl->GetDataSingleLine(T_SENSOR_INFO(TNAME)," * ",whereCon); + if (access(filename.c_str(), 0) >= 0) + { + std::ifstream inFile(filename.c_str(),ios::in|ios::binary); + if(!inFile) + { + print_error("read channel data error\n"); + jsonVal["success"] = "false"; + jsonVal["message"] = "error"; + }else{ + float fTemp = 0; + inFile.read((char *)localtimestamp,sizeof(localtimestamp)); + string::size_type comper = param.mChannelId.find("Z"); + if (comper != string::npos && res[17]=="02") { + while(inFile.read((char *)&fTemp,sizeof(fTemp))) + { + vecWave.push_back(fTemp); + } + //积分 + pCalculation->Integration(vecWave, IntegrationWave); + pCalculation->FFTSpec(IntegrationWave, fftWave); + sampleRateReference = 1000; + + }else{ + while(inFile.read((char *)&fTemp,sizeof(fTemp))) + { // 取8K进行计算 + if(i < 8192) + { + vecWave.push_back(fTemp); + }else{ + break; + } + i++; + } + //测试正弦波 + //pCalculation->GenerateSin(vecWave); + + if(vecWave.size() < 8192){ + for(int i = vecWave.size(); i < 8192;i++){ + vecWave.push_back(0); + } + } + // //添加汉宁窗 + // pCalculation->Hanning(vecWave, hanningWave); + // for(int i = 0; i < vecWave.size();i++){ + // addhanningWave.push_back(vecWave[i]*hanningWave[i]); + // } + + // //积分 + + pCalculation->Integration(vecWave, IntegrationWave); + pCalculation->FFTSpec(IntegrationWave, fftWave); + sampleRateReference = 1024; + } + /*for(int i = 0; i < fftWave.size();i++){ + fftWave[i] = fftWave[i]*2; + }*/ + printf("2---------------------------------------------->vecWave = %d,fftWave = %d\n",vecWave.size(),fftWave.size()); + + int flag = param.mPackageFlag; + flag = (flag + 1) * sampleRateReference; + int number = fftWave.size(); + printf("number---------------------------------------------->%d\n",number); + int start = param.mPackageFlag * sampleRateReference; + printf("param.mPackageFlag = %d\n",param.mPackageFlag); + printf("param.start = %d\n",start); + printf("param.flag = %d\n",flag); + if (number < sampleRateReference) { + flag = number; + start = 0; + } + char buf[32]; + for (int i = start; i < flag; i++) { + if ( i == start ) { + memset(buf, 0, 32); + sprintf(buf, "%.6f", fftWave[i]); + std::string waveTemp(buf); + strWaveData = waveTemp; + + } else { + memset(buf, 0, 32); + sprintf(buf, "%.6f", fftWave[i]); + std::string waveTemp(buf); + strWaveData = strWaveData + "," + waveTemp; + } + } + + int max = number / sampleRateReference; + if (max == 0 && number > 0) { + max = 1; + } + + jsBody["packageMax"] = max; + + + + } + } else { + jsonVal["success"] = false; + jsonVal["message"] = "没有数据文件"; + } + + jsBody["channelId"] = param.mChannelId; + jsBody["package"] = param.mPackageFlag; + jsBody["timestamp"] = string(localtimestamp); + jsBody["Data"] = strWaveData; + + double resolution = 0.0; + int SampleRate =0; + print_info("sensor type %s\n",res[17].c_str()); + if(res[17]=="01"){ + SampleRate = atoi(res[23].c_str()); + printf("@@@@@@@@@@@@@@@@@@@@sample_rate=%d\n",SampleRate); + resolution = (((double)SampleRate/1000)*1024)/ 8192; + + }else if(res[17]=="02"){ + string::size_type comper = param.mChannelId.find("Z"); + if (comper != string::npos) { + SampleRate = atoi(res[23].c_str()); + resolution = (double)SampleRate/vecWave.size(); + //resolution = (((double)vecWave.size()/1000)*1024)/ (SampleRate * ((vecWave.size()/SampleRate))); + printf("@@@@@@@@@@@@@@@@@@@@sample_rate=%d,resolution = %f\n",SampleRate,resolution); + }else{ + SampleRate = 8000; + printf("@@@@@@@@@@@@@@@@@@@@sample_rate=%d\n",SampleRate); + resolution = (((double)SampleRate/1024)*1024)/ 8192; + } + } + + print_info("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@the sample rate is %d,the resolution %f\n",SampleRate,resolution); + char buf[32]; + memset(buf, 0, 32); + sprintf(buf, "%f", resolution); + jsBody["resolution"] = std::string(buf); + + jsonVal["content"] = jsBody; + return showValue.write(jsonVal); +} + diff --git a/jsonparse/SH_JsonCmd.hpp b/jsonparse/SH_JsonCmd.hpp index 2033aa6..47d666c 100644 --- a/jsonparse/SH_JsonCmd.hpp +++ b/jsonparse/SH_JsonCmd.hpp @@ -70,6 +70,9 @@ public : std::string JsonCmd_Cgi_52(Param_52 ¶m); std::string JsonCmd_Cgi_53(std::vector ¶m); std::string JsonCmd_Cgi_54(Param_54 ¶m); + + std::string JsonCmd_Cgi_55(Param_55 ¶m); + std::string JsonCmd_Cgi_56(Param_56 ¶m); std::string JsonCmd_Cgi_default(); private : diff --git a/localserver/SH_LocalServer.cpp b/localserver/SH_LocalServer.cpp index c1bac87..ba91296 100644 --- a/localserver/SH_LocalServer.cpp +++ b/localserver/SH_LocalServer.cpp @@ -616,6 +616,26 @@ try{ return data; } break; + case 55:{ + JsonData jd; + Param_55 param; + param.mChannelId = recvBody["channelId"].asString(); + param.mPackageFlag = recvBody["package"].asInt(); + param.mDataNodeNo = recvBody["dataNodeNo"].asString(); + std::string data = jd.JsonCmd_Cgi_55(param); + return data; + } + break; + case 56:{ + JsonData jd; + Param_56 param; + param.mChannelId = recvBody["channelId"].asString(); + param.mPackageFlag = recvBody["package"].asInt(); + param.mDataNodeNo = recvBody["dataNodeNo"].asString(); + std::string data = jd.JsonCmd_Cgi_56(param); + return data; + } + break; default: JsonData jd; std::string data = jd.JsonCmd_Cgi_default(); diff --git a/main.cpp b/main.cpp index ba26fc9..1618a43 100644 --- a/main.cpp +++ b/main.cpp @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) sql_ctl->InintGateway(); //sql_ctl->CalculateDip(); - sql_ctl->CalculateBattery(); + //sql_ctl->CalculateBattery(); pUart->InitZigbee(); // UDP,接收客户端发来的组播消息,用于外接 QT 专家系统,屏蔽之 boost::thread searchT(SearchThread); diff --git a/mqttclient/SH_MqttClient.cpp b/mqttclient/SH_MqttClient.cpp index cd67b32..830d5d0 100644 --- a/mqttclient/SH_MqttClient.cpp +++ b/mqttclient/SH_MqttClient.cpp @@ -28,7 +28,6 @@ subscribe_callback my_subscribe_callback = NULL; log_callback my_log_callback = NULL; publish_callback my_publish_callback = NULL; - void register_collback(connect_callback connect_c, message_callback message_c, subscribe_callback subscribe_c, @@ -71,7 +70,7 @@ int data_publish(const char *str, const char *topic) } if(iRet != 0) { - reconnect(); + disconnect(); } return iRet; } diff --git a/mqttclient/mosquitto.h b/mqttclient/mosquitto.h index 7fa8241..5633b40 100644 --- a/mqttclient/mosquitto.h +++ b/mqttclient/mosquitto.h @@ -1,37 +1,55 @@ /* -Copyright (c) 2010-2014 Roger Light +Copyright (c) 2010-2020 Roger Light All rights reserved. This program and the accompanying materials -are made available under the terms of the Eclipse Public License v1.0 +are made available under the terms of the Eclipse Public License 2.0 and Eclipse Distribution License v1.0 which accompany this distribution. - + The Eclipse Public License is available at - http://www.eclipse.org/legal/epl-v10.html + https://www.eclipse.org/legal/epl-2.0/ and the Eclipse Distribution License is available at http://www.eclipse.org/org/documents/edl-v10.php. - + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + Contributors: Roger Light - initial implementation and documentation. */ -#ifndef _MOSQUITTO_H_ -#define _MOSQUITTO_H_ +#ifndef MOSQUITTO_H +#define MOSQUITTO_H +/* + * File: mosquitto.h + * + * This header contains functions and definitions for use with libmosquitto, the Mosquitto client library. + * + * The definitions are also used in Mosquitto broker plugins, and some functions are available to plugins. + */ #ifdef __cplusplus extern "C" { #endif -#if defined(WIN32) && !defined(WITH_BROKER) -# ifdef libmosquitto_EXPORTS -# define libmosq_EXPORT __declspec(dllexport) -# else -# define libmosq_EXPORT __declspec(dllimport) -# endif -#else -# define libmosq_EXPORT -#endif #ifdef WIN32 +# ifdef mosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# ifndef LIBMOSQUITTO_STATIC +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +# else +# define libmosq_EXPORT +# endif +# endif +#else +# define libmosq_EXPORT +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 && !defined(bool) # ifndef __cplusplus # define bool char # define true 1 @@ -43,26 +61,34 @@ extern "C" { # endif #endif -#define LIBMOSQUITTO_MAJOR 1 -#define LIBMOSQUITTO_MINOR 4 -#define LIBMOSQUITTO_REVISION 9 +#include +#include + +#define LIBMOSQUITTO_MAJOR 2 +#define LIBMOSQUITTO_MINOR 0 +#define LIBMOSQUITTO_REVISION 18 /* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) /* Log types */ -#define MOSQ_LOG_NONE 0x00 -#define MOSQ_LOG_INFO 0x01 -#define MOSQ_LOG_NOTICE 0x02 -#define MOSQ_LOG_WARNING 0x04 -#define MOSQ_LOG_ERR 0x08 -#define MOSQ_LOG_DEBUG 0x10 -#define MOSQ_LOG_SUBSCRIBE 0x20 -#define MOSQ_LOG_UNSUBSCRIBE 0x40 -#define MOSQ_LOG_WEBSOCKETS 0x80 -#define MOSQ_LOG_ALL 0xFFFF +#define MOSQ_LOG_NONE 0 +#define MOSQ_LOG_INFO (1<<0) +#define MOSQ_LOG_NOTICE (1<<1) +#define MOSQ_LOG_WARNING (1<<2) +#define MOSQ_LOG_ERR (1<<3) +#define MOSQ_LOG_DEBUG (1<<4) +#define MOSQ_LOG_SUBSCRIBE (1<<5) +#define MOSQ_LOG_UNSUBSCRIBE (1<<6) +#define MOSQ_LOG_WEBSOCKETS (1<<7) +#define MOSQ_LOG_INTERNAL 0x80000000U +#define MOSQ_LOG_ALL 0xFFFFFFFFU -/* Error values */ +/* Enum: mosq_err_t + * Integer values returned from many libmosquitto functions. */ enum mosq_err_t { + MOSQ_ERR_AUTH_CONTINUE = -4, + MOSQ_ERR_NO_SUBSCRIBERS = -3, + MOSQ_ERR_SUB_EXISTS = -2, MOSQ_ERR_CONN_PENDING = -1, MOSQ_ERR_SUCCESS = 0, MOSQ_ERR_NOMEM = 1, @@ -80,21 +106,72 @@ enum mosq_err_t { MOSQ_ERR_UNKNOWN = 13, MOSQ_ERR_ERRNO = 14, MOSQ_ERR_EAI = 15, - MOSQ_ERR_PROXY = 16 + MOSQ_ERR_PROXY = 16, + MOSQ_ERR_PLUGIN_DEFER = 17, + MOSQ_ERR_MALFORMED_UTF8 = 18, + MOSQ_ERR_KEEPALIVE = 19, + MOSQ_ERR_LOOKUP = 20, + MOSQ_ERR_MALFORMED_PACKET = 21, + MOSQ_ERR_DUPLICATE_PROPERTY = 22, + MOSQ_ERR_TLS_HANDSHAKE = 23, + MOSQ_ERR_QOS_NOT_SUPPORTED = 24, + MOSQ_ERR_OVERSIZE_PACKET = 25, + MOSQ_ERR_OCSP = 26, + MOSQ_ERR_TIMEOUT = 27, + MOSQ_ERR_RETAIN_NOT_SUPPORTED = 28, + MOSQ_ERR_TOPIC_ALIAS_INVALID = 29, + MOSQ_ERR_ADMINISTRATIVE_ACTION = 30, + MOSQ_ERR_ALREADY_EXISTS = 31, }; - -/* Error values */ +/* Enum: mosq_opt_t + * + * Client options. + * + * See , , and . + */ enum mosq_opt_t { MOSQ_OPT_PROTOCOL_VERSION = 1, + MOSQ_OPT_SSL_CTX = 2, + MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3, + MOSQ_OPT_RECEIVE_MAXIMUM = 4, + MOSQ_OPT_SEND_MAXIMUM = 5, + MOSQ_OPT_TLS_KEYFORM = 6, + MOSQ_OPT_TLS_ENGINE = 7, + MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8, + MOSQ_OPT_TLS_OCSP_REQUIRED = 9, + MOSQ_OPT_TLS_ALPN = 10, + MOSQ_OPT_TCP_NODELAY = 11, + MOSQ_OPT_BIND_ADDRESS = 12, + MOSQ_OPT_TLS_USE_OS_CERTS = 13, }; + /* MQTT specification restricts client ids to a maximum of 23 characters */ #define MOSQ_MQTT_ID_MAX_LENGTH 23 #define MQTT_PROTOCOL_V31 3 #define MQTT_PROTOCOL_V311 4 +#define MQTT_PROTOCOL_V5 5 +/* Struct: mosquitto_message + * + * Contains details of a PUBLISH message. + * + * int mid - the message/packet ID of the PUBLISH message, assuming this is a + * QoS 1 or 2 message. Will be set to 0 for QoS 0 messages. + * + * char *topic - the topic the message was delivered on. + * + * void *payload - the message payload. This will be payloadlen bytes long, and + * may be NULL if a zero length payload was sent. + * + * int payloadlen - the length of the payload, in bytes. + * + * int qos - the quality of service of the message, 0, 1, or 2. + * + * bool retain - set to true for stale retained messages. + */ struct mosquitto_message{ int mid; char *topic; @@ -105,12 +182,16 @@ struct mosquitto_message{ }; struct mosquitto; +typedef struct mqtt5__property mosquitto_property; /* * Topic: Threads * libmosquitto provides thread safe operation, with the exception of * which is not thread safe. * + * If the library has been compiled without thread support it is *not* + * guaranteed to be thread safe. + * * If your application uses threads you must use to * tell the library this is the case, otherwise it makes some optimisations * for the single threaded case that may result in unexpected behaviour for @@ -118,7 +199,7 @@ struct mosquitto; */ /*************************************************** * Important note - * + * * The following functions that deal with network operations will return * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has * taken place. An attempt will be made to write the network data, but if the @@ -136,6 +217,12 @@ struct mosquitto; * mosquitto_publish() ***************************************************/ + +/* ====================================================================== + * + * Section: Library version, init, and cleanup + * + * ====================================================================== */ /* * Function: mosquitto_lib_version * @@ -153,7 +240,7 @@ struct mosquitto; * be returned in this variable. * * Returns: - * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * LIBMOSQUITTO_VERSION_NUMBER - which is a unique number based on the major, * minor and revision values. * See Also: * , @@ -168,7 +255,8 @@ libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); * This function is *not* thread safe. * * Returns: - * MOSQ_ERR_SUCCESS - always + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. * * See Also: * , @@ -188,6 +276,12 @@ libmosq_EXPORT int mosquitto_lib_init(void); */ libmosq_EXPORT int mosquitto_lib_cleanup(void); + +/* ====================================================================== + * + * Section: Client creation, destruction, and reinitialisation + * + * ====================================================================== */ /* * Function: mosquitto_new * @@ -219,7 +313,7 @@ libmosq_EXPORT int mosquitto_lib_cleanup(void); */ libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); -/* +/* * Function: mosquitto_destroy * * Use to free memory associated with a mosquitto client instance. @@ -252,21 +346,31 @@ libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); * callbacks that are specified. * * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the client id is not valid UTF-8. * * See Also: * , */ libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); -/* + +/* ====================================================================== + * + * Section: Will + * + * ====================================================================== */ +/* * Function: mosquitto_will_set * * Configure will information for a mosquitto instance. By default, clients do * not have a will. This must be called before calling . * + * It is valid to use this function for clients using all MQTT protocol versions. + * If you need to set MQTT v5 Will properties, use instead. + * * Parameters: * mosq - a valid mosquitto instance. * topic - the topic on which to publish the will. @@ -280,13 +384,57 @@ libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - * MOSQ_ERR_NOMEM - if an out of memory condition occurred. - * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. */ libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); -/* +/* + * Function: mosquitto_will_set_v5 + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * If the mosquitto instance `mosq` is using MQTT v5, the `properties` argument + * will be applied to the Will. For MQTT v3.1.1 and below, the `properties` + * argument will be ignored. + * + * Set your client to use MQTT v5 immediately after it is created: + * + * mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5); + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + */ +libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + +/* * Function: mosquitto_will_clear * * Remove a previously configured will. This must be called before calling @@ -301,14 +449,18 @@ libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, */ libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + +/* ====================================================================== + * + * Section: Username and password + * + * ====================================================================== */ /* * Function: mosquitto_username_pw_set * - * Configure username and password for a mosquitton instance. This is only - * supported by brokers that implement the MQTT spec v3.1. By default, no - * username or password will be sent. - * If username is NULL, the password argument is ignored. - * This must be called before calling mosquitto_connect(). + * Configure username and password for a mosquitto instance. By default, no + * username or password will be sent. For v3.1 and v3.1.1 clients, if username + * is NULL, the password argument is ignored. * * This is must be called before calling . * @@ -326,22 +478,36 @@ libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); */ libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + +/* ====================================================================== + * + * Section: Connecting, reconnecting, disconnecting + * + * ====================================================================== */ /* * Function: mosquitto_connect * * Connect to an MQTT broker. * + * It is valid to use this function for clients using all MQTT protocol versions. + * If you need to set MQTT v5 CONNECT properties, use + * instead. + * * Parameters: * mosq - a valid mosquitto instance. * host - the hostname or ip address of the broker to connect to. * port - the network port to connect to. Usually 1883. - * keepalive - the number of seconds after which the broker should send a PING - * message to the client if no other messages have been exchanged + * keepalive - the number of seconds after which the client should send a PING + * message to the broker if no other messages have been exchanged * in that time. * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno * contains the error code, even on Windows. * Use strerror_r() where available or FormatMessage() on @@ -357,17 +523,18 @@ libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, i * * Connect to an MQTT broker. This extends the functionality of * by adding the bind_address parameter. Use this function - * if you need to restrict network communication over a particular interface. + * if you need to restrict network communication over a particular interface. * * Parameters: * mosq - a valid mosquitto instance. * host - the hostname or ip address of the broker to connect to. * port - the network port to connect to. Usually 1883. - * keepalive - the number of seconds after which the broker should send a PING - * message to the client if no other messages have been exchanged + * keepalive - the number of seconds after which the client should send a PING + * message to the broker if no other messages have been exchanged * in that time. * bind_address - the hostname or ip address of the local network interface to - * bind to. + * bind to. If you do not want to bind to a specific interface, + * set this to NULL. * * Returns: * MOSQ_ERR_SUCCESS - on success. @@ -382,6 +549,57 @@ libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, i */ libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); +/* + * Function: mosquitto_connect_bind_v5 + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter and MQTT v5 + * properties. Use this function if you need to restrict network communication + * over a particular interface. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * If the mosquitto instance `mosq` is using MQTT v5, the `properties` argument + * will be applied to the CONNECT message. For MQTT v3.1.1 and below, the + * `properties` argument will be ignored. + * + * Set your client to use MQTT v5 immediately after it is created: + * + * mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5); + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the client should send a PING + * message to the broker if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. If you do not want to bind to a specific interface, + * set this to NULL. + * properties - the MQTT 5 properties for the connect (not for the Will). + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties); + /* * Function: mosquitto_connect_async * @@ -396,8 +614,8 @@ libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *ho * mosq - a valid mosquitto instance. * host - the hostname or ip address of the broker to connect to. * port - the network port to connect to. Usually 1883. - * keepalive - the number of seconds after which the broker should send a PING - * message to the client if no other messages have been exchanged + * keepalive - the number of seconds after which the client should send a PING + * message to the broker if no other messages have been exchanged * in that time. * * Returns: @@ -423,7 +641,7 @@ libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *h * * This extends the functionality of by adding the * bind_address parameter. Use this function if you need to restrict network - * communication over a particular interface. + * communication over a particular interface. * * May be called before or after . * @@ -431,15 +649,20 @@ libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *h * mosq - a valid mosquitto instance. * host - the hostname or ip address of the broker to connect to. * port - the network port to connect to. Usually 1883. - * keepalive - the number of seconds after which the broker should send a PING - * message to the client if no other messages have been exchanged + * keepalive - the number of seconds after which the client should send a PING + * message to the broker if no other messages have been exchanged * in that time. * bind_address - the hostname or ip address of the local network interface to - * bind to. + * bind to. If you do not want to bind to a specific interface, + * set this to NULL. * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno * contains the error code, even on Windows. * Use strerror_r() where available or FormatMessage() on @@ -453,29 +676,32 @@ libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const ch /* * Function: mosquitto_connect_srv * - * Connect to an MQTT broker. This is a non-blocking call. If you use - * your client must use the threaded interface - * . If you need to use , you must use - * to connect the client. + * Connect to an MQTT broker. * - * This extends the functionality of by adding the - * bind_address parameter. Use this function if you need to restrict network - * communication over a particular interface. + * If you set `host` to `example.com`, then this call will attempt to retrieve + * the DNS SRV record for `_secure-mqtt._tcp.example.com` or + * `_mqtt._tcp.example.com` to discover which actual host to connect to. * - * May be called before or after . + * DNS SRV support is not usually compiled in to libmosquitto, use of this call + * is not recommended. * * Parameters: * mosq - a valid mosquitto instance. - * host - the hostname or ip address of the broker to connect to. - * keepalive - the number of seconds after which the broker should send a PING - * message to the client if no other messages have been exchanged + * host - the hostname to search for an SRV record. + * keepalive - the number of seconds after which the client should send a PING + * message to the broker if no other messages have been exchanged * in that time. * bind_address - the hostname or ip address of the local network interface to - * bind to. + * bind to. If you do not want to bind to a specific interface, + * set this to NULL. * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno * contains the error code, even on Windows. * Use strerror_r() where available or FormatMessage() on @@ -495,7 +721,7 @@ libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *hos * connection has been lost. It uses the values that were provided in the * call. It must not be called before * . - * + * * Parameters: * mosq - a valid mosquitto instance. * @@ -503,10 +729,6 @@ libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *hos * MOSQ_ERR_SUCCESS - on success. * MOSQ_ERR_INVAL - if the input parameters were invalid. * MOSQ_ERR_NOMEM - if an out of memory condition occurred. - * - * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno * contains the error code, even on Windows. * Use strerror_r() where available or FormatMessage() on @@ -526,7 +748,7 @@ libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); * connection has been lost. It uses the values that were provided in the * or calls. It must not be * called before . - * + * * Parameters: * mosq - a valid mosquitto instance. * @@ -534,10 +756,6 @@ libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); * MOSQ_ERR_SUCCESS - on success. * MOSQ_ERR_INVAL - if the input parameters were invalid. * MOSQ_ERR_NOMEM - if an out of memory condition occurred. - * - * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno * contains the error code, even on Windows. * Use strerror_r() where available or FormatMessage() on @@ -553,6 +771,10 @@ libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); * * Disconnect from the broker. * + * It is valid to use this function for clients using all MQTT protocol versions. + * If you need to set MQTT v5 DISCONNECT properties, use + * instead. + * * Parameters: * mosq - a valid mosquitto instance. * @@ -563,11 +785,52 @@ libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); */ libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); -/* +/* + * Function: mosquitto_disconnect_v5 + * + * Disconnect from the broker, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * If the mosquitto instance `mosq` is using MQTT v5, the `properties` argument + * will be applied to the DISCONNECT message. For MQTT v3.1.1 and below, the + * `properties` argument will be ignored. + * + * Set your client to use MQTT v5 immediately after it is created: + * + * mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5); + * + * Parameters: + * mosq - a valid mosquitto instance. + * reason_code - the disconnect reason code. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT. + */ +libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Publishing, subscribing, unsubscribing + * + * ====================================================================== */ +/* * Function: mosquitto_publish * * Publish a message on a given topic. - * + * + * It is valid to use this function for clients using all MQTT protocol versions. + * If you need to set MQTT v5 PUBLISH properties, use + * instead. + * * Parameters: * mosq - a valid mosquitto instance. * mid - pointer to an int. If not NULL, the function will set this @@ -587,24 +850,97 @@ libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); * retain - set to true to make the message retained. * * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - * MOSQ_ERR_NOMEM - if an out of memory condition occurred. - * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. - * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the - * broker. - * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. * - * See Also: + * See Also: * */ libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_publish_v5 + * + * Publish a message on a given topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * If the mosquitto instance `mosq` is using MQTT v5, the `properties` argument + * will be applied to the PUBLISH message. For MQTT v3.1.1 and below, the + * `properties` argument will be ignored. + * + * Set your client to use MQTT v5 immediately after it is created: + * + * mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5); + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH. + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_publish_v5( + struct mosquitto *mosq, + int *mid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + const mosquitto_property *properties); + + /* * Function: mosquitto_subscribe * * Subscribe to a topic. * + * It is valid to use this function for clients using all MQTT protocol versions. + * If you need to set MQTT v5 SUBSCRIBE properties, use + * instead. + * * Parameters: * mosq - a valid mosquitto instance. * mid - a pointer to an int. If not NULL, the function will set this to @@ -615,13 +951,93 @@ libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const cha * qos - the requested Quality of Service for this subscription. * * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - * MOSQ_ERR_NOMEM - if an out of memory condition occurred. - * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. */ libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); +/* + * Function: mosquitto_subscribe_v5 + * + * Subscribe to a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * If the mosquitto instance `mosq` is using MQTT v5, the `properties` argument + * will be applied to the PUBLISH message. For MQTT v3.1.1 and below, the + * `properties` argument will be ignored. + * + * Set your client to use MQTT v5 immediately after it is created: + * + * mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5); + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * options - options to apply to this subscription, OR'd together. Set to 0 to + * use the default options, otherwise choose from list of + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_subscribe_multiple + * + * Subscribe to multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of subscriptions to be made + * sub - array of sub_count pointers, each pointing to a subscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * qos - the requested Quality of Service for each subscription. + * options - options to apply to this subscription, OR'd together. This + * argument is not used for MQTT v3 susbcriptions. Set to 0 to use + * the default options, otherwise choose from list of + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties); + /* * Function: mosquitto_unsubscribe * @@ -636,13 +1052,97 @@ libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const c * sub - the unsubscription pattern. * * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - * MOSQ_ERR_NOMEM - if an out of memory condition occurred. - * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. */ libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); +/* + * Function: mosquitto_unsubscribe_v5 + * + * Unsubscribe from a topic, with attached MQTT properties. + * + * It is valid to use this function for clients using all MQTT protocol versions. + * If you need to set MQTT v5 UNSUBSCRIBE properties, use + * instead. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * If the mosquitto instance `mosq` is using MQTT v5, the `properties` argument + * will be applied to the PUBLISH message. For MQTT v3.1.1 and below, the + * `properties` argument will be ignored. + * + * Set your client to use MQTT v5 immediately after it is created: + * + * mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5); + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe_multiple + * + * Unsubscribe from multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of unsubscriptions to be made + * sub - array of sub_count pointers, each pointing to an unsubscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Struct mosquitto_message helper functions + * + * ====================================================================== */ /* * Function: mosquitto_message_copy * @@ -665,62 +1165,45 @@ libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const s /* * Function: mosquitto_message_free - * + * * Completely free a mosquitto_message struct. * * Parameters: * message - pointer to a mosquitto_message pointer to free. * * See Also: - * + * , */ libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); /* - * Function: mosquitto_loop + * Function: mosquitto_message_free_contents * - * The main network loop for the client. You must call this frequently in order - * to keep communications between the client and broker working. If incoming - * data is present it will then be processed. Outgoing commands, from e.g. - * , are normally sent immediately that their function is - * called, but this is not always possible. will also attempt - * to send any remaining outgoing messages, which also includes commands that - * are part of the flow for messages with QoS>0. + * Free a mosquitto_message struct contents, leaving the struct unaffected. * - * An alternative approach is to use to run the client - * loop in its own thread. - * - * This calls select() to monitor the client network socket. If you want to - * integrate mosquitto client operation with your own select() call, use - * , , and - * . - * - * Threads: - * * Parameters: - * mosq - a valid mosquitto instance. - * timeout - Maximum number of milliseconds to wait for network activity - * in the select() call before timing out. Set to 0 for instant - * return. Set negative to use the default of 1000ms. - * max_packets - this parameter is currently unused and should be set to 1 for - * future compatibility. - * - * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - * MOSQ_ERR_NOMEM - if an out of memory condition occurred. - * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. - * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. - * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the - * broker. - * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno - * contains the error code, even on Windows. - * Use strerror_r() where available or FormatMessage() on - * Windows. + * message - pointer to a mosquitto_message struct to free its contents. + * * See Also: - * , , + * , */ -libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); +libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message); + + +/* ====================================================================== + * + * Section: Network loop (managed by libmosquitto) + * + * The internal network loop must be called at a regular interval. The two + * recommended approaches are to use either or + * . is a blocking call and is + * suitable for the situation where you only want to handle incoming messages + * in callbacks. is a non-blocking call, it creates a + * separate thread to run the loop for you. Use this function when you have + * other tasks you need to run at the same time as the MQTT client, e.g. + * reading data from a sensor. + * + * ====================================================================== */ /* * Function: mosquitto_loop_forever @@ -803,19 +1286,57 @@ libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); /* - * Function: mosquitto_socket + * Function: mosquitto_loop * - * Return the socket handle for a mosquitto instance. Useful if you want to - * include a mosquitto client in your own select() calls. + * The main network loop for the client. This must be called frequently + * to keep communications between the client and broker working. This is + * carried out by and , which + * are the recommended ways of handling the network loop. You may also use this + * function if you wish. It must not be called inside a callback. + * + * If incoming data is present it will then be processed. Outgoing commands, + * from e.g. , are normally sent immediately that their + * function is called, but this is not always possible. will + * also attempt to send any remaining outgoing messages, which also includes + * commands that are part of the flow for messages with QoS>0. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: * * Parameters: - * mosq - a valid mosquitto instance. + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. * * Returns: - * The socket for the mosquitto client or -1 on failure. + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , */ -libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); +/* ====================================================================== + * + * Section: Network loop (for use in other event loops) + * + * ====================================================================== */ /* * Function: mosquitto_loop_read * @@ -884,7 +1405,8 @@ libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets) * monitoring the client network socket for activity yourself. * * This function deals with handling PINGs and checking whether messages need - * to be retried, so should be called fairly frequently. + * to be retried, so should be called fairly frequently, around once per second + * is sufficient. * * Parameters: * mosq - a valid mosquitto instance. @@ -899,6 +1421,26 @@ libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets) */ libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + +/* ====================================================================== + * + * Section: Network loop (helper functions) + * + * ====================================================================== */ +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + /* * Function: mosquitto_want_write * @@ -929,25 +1471,280 @@ libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); */ libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded); + +/* ====================================================================== + * + * Section: Client options + * + * ====================================================================== */ /* * Function: mosquitto_opts_set * * Used to set options for the client. * + * This function is deprecated, the replacement , + * and functions should + * be used instead. + * * Parameters: * mosq - a valid mosquitto instance. * option - the option to set. * value - the option specific value. * * Options: - * MOSQ_OPT_PROTOCOL_VERSION - value must be an int, set to either - * MQTT_PROTOCOL_V31 or MQTT_PROTOCOL_V311. Must - * be set before the client connects. Defaults to - * MQTT_PROTOCOL_V31. + * MOSQ_OPT_PROTOCOL_VERSION - Value must be an int, set to either + * MQTT_PROTOCOL_V31 or MQTT_PROTOCOL_V311. Must be set + * before the client connects. + * Defaults to MQTT_PROTOCOL_V31. + * + * MOSQ_OPT_SSL_CTX - Pass an openssl SSL_CTX to be used when creating + * TLS connections rather than libmosquitto creating its own. + * This must be called before connecting to have any effect. + * If you use this option, the onus is on you to ensure that + * you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - Value must be an int set to 1 or 0. + * If set to 1, then the user specified SSL_CTX passed in using + * MOSQ_OPT_SSL_CTX will have the default options applied to it. + * This means that you only need to change the values that are + * relevant to you. If you use this option then you must configure + * the TLS options as normal, i.e. you should use + * to configure the cafile/capath as a minimum. + * This option is only available for openssl 1.1.0 and higher. */ libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value); +/* + * Function: mosquitto_int_option + * + * Used to set integer options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TCP_NODELAY - Set to 1 to disable Nagle's algorithm on client + * sockets. This has the effect of reducing latency of individual + * messages at the potential cost of increasing the number of + * packets being sent. + * Defaults to 0, which means Nagle remains enabled. + * + * MOSQ_OPT_PROTOCOL_VERSION - Value must be set to either MQTT_PROTOCOL_V31, + * MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the + * client connects. Defaults to MQTT_PROTOCOL_V311. + * + * MOSQ_OPT_RECEIVE_MAXIMUM - Value can be set between 1 and 65535 inclusive, + * and represents the maximum number of incoming QoS 1 and QoS 2 + * messages that this client wants to process at once. Defaults to + * 20. This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the + * proplist passed to mosquitto_connect_v5(), then that property + * will override this option. Using this option is the recommended + * method however. + * + * MOSQ_OPT_SEND_MAXIMUM - Value can be set between 1 and 65535 inclusive, + * and represents the maximum number of outgoing QoS 1 and QoS 2 + * messages that this client will attempt to have "in flight" at + * once. Defaults to 20. + * This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the broker being connected to sends a + * MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than + * this option, then the broker provided value will be used. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - If value is set to a non zero value, + * then the user specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX + * will have the default options applied to it. This means that + * you only need to change the values that are relevant to you. + * If you use this option then you must configure the TLS options + * as normal, i.e. you should use to + * configure the cafile/capath as a minimum. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_TLS_OCSP_REQUIRED - Set whether OCSP checking on TLS + * connections is required. Set to 1 to enable checking, + * or 0 (the default) for no checking. + * + * MOSQ_OPT_TLS_USE_OS_CERTS - Set to 1 to instruct the client to load and + * trust OS provided CA certificates for use with TLS connections. + * Set to 0 (the default) to only use manually specified CA certs. + */ +libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value); + +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE - Configure the client for TLS Engine support. + * Pass a TLS Engine ID to be used when creating TLS + * connections. Must be set before . + * Must be a valid engine, and note that the string will not be used + * until a connection attempt is made so this function will return + * success even if an invalid engine string is passed. + * + * MOSQ_OPT_TLS_KEYFORM - Configure the client to treat the keyfile + * differently depending on its type. Must be set + * before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * + * MOSQ_OPT_TLS_KPASS_SHA1 - Where the TLS Engine requires the use of + * a password to be accessed, this option allows a hex encoded + * SHA1 hash of the private key password to be passed to the + * engine directly. Must be set before . + * + * MOSQ_OPT_TLS_ALPN - If the broker being connected to has multiple + * services available on a single TLS port, such as both MQTT + * and WebSockets, use this option to configure the ALPN + * option for the connection. + * + * MOSQ_OPT_BIND_ADDRESS - Set the hostname or ip address of the local network + * interface to bind to when connecting. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + + +/* + * Function: mosquitto_void_option + * + * Used to set void* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_SSL_CTX - Pass an openssl SSL_CTX to be used when creating TLS + * connections rather than libmosquitto creating its own. This must + * be called before connecting to have any effect. If you use this + * option, the onus is on you to ensure that you are using secure + * settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * This function is deprected. Use the function with the + * MOSQ_OPT_SEND_MAXIMUM option instead. + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * This function now has no effect. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + +/* Function: mosquitto_userdata + * + * Retrieve the "userdata" variable for a mosquitto client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * A pointer to the userdata member variable. + */ +libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: TLS support + * + * ====================================================================== */ /* * Function: mosquitto_tls_set * @@ -984,7 +1781,8 @@ libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t op * Your callback must write the password into "buf", which is * "size" bytes long. The return value must be the length of the * password. "userdata" will be set to the calling mosquitto - * instance. + * instance. The mosquitto userdata member variable can be + * retrieved using . * * Returns: * MOSQ_ERR_SUCCESS - on success. @@ -992,7 +1790,8 @@ libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t op * MOSQ_ERR_NOMEM - if an out of memory condition occurred. * * See Also: - * , , + * , , + * , */ libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *capath, @@ -1087,10 +1886,33 @@ libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, */ libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); -/* + +/* + * Function: mosquitto_ssl_get + * + * Retrieve a pointer to the SSL structure used for TLS connections in this + * client. This can be used in e.g. the connect callback to carry out + * additional verification steps. + * + * Parameters: + * mosq - a valid mosquitto instance + * + * Returns: + * A valid pointer to an openssl SSL structure - if the client is using TLS. + * NULL - if the client is not using TLS, or TLS support is not compiled in. + */ +libmosq_EXPORT void *mosquitto_ssl_get(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Callbacks + * + * ====================================================================== */ +/* * Function: mosquitto_connect_callback_set * - * Set the connect callback. This is called when the broker sends a CONNACK + * Set the connect callback. This is called when the library receives a CONNACK * message in response to a connection. * * Parameters: @@ -1101,22 +1923,69 @@ libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk * Callback Parameters: * mosq - the mosquitto instance making the callback. * obj - the user data provided in - * rc - the return code of the connection response, one of: - * - * * 0 - success - * * 1 - connection refused (unacceptable protocol version) - * * 2 - connection refused (identifier rejected) - * * 3 - connection refused (broker unavailable) - * * 4-255 - reserved for future use + * rc - the return code of the connection response. The values are defined by + * the MQTT protocol version in use. + * For MQTT v5.0, look at section 3.2.2.2 Connect Reason code: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html + * For MQTT v3.1.1, look at section 3.2.2.3 Connect Return code: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html */ libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); - + +/* + * Function: mosquitto_connect_with_flags_callback_set + * + * Set the connect callback. This is called when the library receives a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response. The values are defined by + * the MQTT protocol version in use. + * For MQTT v5.0, look at section 3.2.2.2 Connect Reason code: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html + * For MQTT v3.1.1, look at section 3.2.2.3 Connect Return code: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html + * flags - the connect flags. + */ +libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); + +/* + * Function: mosquitto_connect_v5_callback_set + * + * Set the connect callback. This is called when the library receives a CONNACK + * message in response to a connection. + * + * It is valid to set this callback for all MQTT protocol versions. If it is + * used with MQTT clients that use MQTT v3.1.1 or earlier, then the `props` + * argument will always be NULL. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response. The values are defined by + * the MQTT protocol version in use. + * For MQTT v5.0, look at section 3.2.2.2 Connect Reason code: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html + * For MQTT v3.1.1, look at section 3.2.2.3 Connect Return code: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html + * flags - the connect flags. + * props - list of MQTT 5 properties, or NULL + * + */ +libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + /* * Function: mosquitto_disconnect_callback_set * * Set the disconnect callback. This is called when the broker has received the * DISCONNECT command and has disconnected the client. - * + * * Parameters: * mosq - a valid mosquitto instance. * on_disconnect - a callback function in the following form: @@ -1130,13 +1999,46 @@ libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void * indicates that the disconnect is unexpected. */ libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); - + +/* + * Function: mosquitto_disconnect_v5_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * It is valid to set this callback for all MQTT protocol versions. If it is + * used with MQTT clients that use MQTT v3.1.1 or earlier, then the `props` + * argument will always be NULL. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *props)); + /* * Function: mosquitto_publish_callback_set * * Set the publish callback. This is called when a message initiated with - * has been sent to the broker successfully. - * + * has been sent to the broker. "Sent" means different + * things depending on the QoS of the message: + * + * QoS 0: The PUBLISH was passed to the local operating system for delivery, + * there is no guarantee that it was delivered to the remote broker. + * QoS 1: The PUBLISH was sent to the remote broker and the corresponding + * PUBACK was received by the library. + * QoS 2: The PUBLISH was sent to the remote broker and the corresponding + * PUBCOMP was received by the library. + * * Parameters: * mosq - a valid mosquitto instance. * on_publish - a callback function in the following form: @@ -1149,12 +2051,47 @@ libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, vo */ libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); +/* + * Function: mosquitto_publish_v5_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker. This callback will be + * called both if the message is sent successfully, or if the broker responded + * with an error, which will be reflected in the reason_code parameter. + * "Sent" means different things depending on the QoS of the message: + * + * QoS 0: The PUBLISH was passed to the local operating system for delivery, + * there is no guarantee that it was delivered to the remote broker. + * QoS 1: The PUBLISH was sent to the remote broker and the corresponding + * PUBACK was received by the library. + * QoS 2: The PUBLISH was sent to the remote broker and the corresponding + * PUBCOMP was received by the library. + * + * + * It is valid to set this callback for all MQTT protocol versions. If it is + * used with MQTT clients that use MQTT v3.1.1 or earlier, then the `props` + * argument will always be NULL. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + * reason_code - the MQTT 5 reason code + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + /* * Function: mosquitto_message_callback_set * * Set the message callback. This is called when a message is received from the - * broker. - * + * broker and the required QoS flow has completed. + * * Parameters: * mosq - a valid mosquitto instance. * on_message - a callback function in the following form: @@ -1172,12 +2109,40 @@ libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void */ libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); +/* + * Function: mosquitto_message_v5_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker and the required QoS flow has completed. + * + * It is valid to set this callback for all MQTT protocol versions. If it is + * used with MQTT clients that use MQTT v3.1.1 or earlier, then the `props` + * argument will always be NULL. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * props - list of MQTT 5 properties, or NULL + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *props)); + /* * Function: mosquitto_subscribe_callback_set * - * Set the subscribe callback. This is called when the broker responds to a - * subscription request. - * + * Set the subscribe callback. This is called when the library receives a + * SUBACK message in response to a SUBSCRIBE. + * * Parameters: * mosq - a valid mosquitto instance. * on_subscribe - a callback function in the following form: @@ -1193,12 +2158,38 @@ libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void */ libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); +/* + * Function: mosquitto_subscribe_v5_callback_set + * + * Set the subscribe callback. This is called when the library receives a + * SUBACK message in response to a SUBSCRIBE. + * + * It is valid to set this callback for all MQTT protocol versions. If it is + * used with MQTT clients that use MQTT v3.1.1 or earlier, then the `props` + * argument will always be NULL. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *props)); + /* * Function: mosquitto_unsubscribe_callback_set * - * Set the unsubscribe callback. This is called when the broker responds to a - * unsubscription request. - * + * Set the unsubscribe callback. This is called when the library receives a + * UNSUBACK message in response to an UNSUBSCRIBE. + * * Parameters: * mosq - a valid mosquitto instance. * on_unsubscribe - a callback function in the following form: @@ -1211,6 +2202,29 @@ libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, voi */ libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); +/* + * Function: mosquitto_unsubscribe_v5_callback_set + * + * Set the unsubscribe callback. This is called when the library receives a + * UNSUBACK message in response to an UNSUBSCRIBE. + * + * It is valid to set this callback for all MQTT protocol versions. If it is + * used with MQTT clients that use MQTT v3.1.1 or earlier, then the `props` + * argument will always be NULL. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *props)); + /* * Function: mosquitto_log_callback_set * @@ -1234,96 +2248,6 @@ libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, v */ libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); -/* - * Function: mosquitto_reconnect_delay_set - * - * Control the behaviour of the client when it has unexpectedly disconnected in - * or after . The default - * behaviour if this function is not used is to repeatedly attempt to reconnect - * with a delay of 1 second until the connection succeeds. - * - * Use reconnect_delay parameter to change the delay between successive - * reconnection attempts. You may also enable exponential backoff of the time - * between reconnections by setting reconnect_exponential_backoff to true and - * set an upper bound on the delay with reconnect_delay_max. - * - * Example 1: - * delay=2, delay_max=10, exponential_backoff=False - * Delays would be: 2, 4, 6, 8, 10, 10, ... - * - * Example 2: - * delay=3, delay_max=30, exponential_backoff=True - * Delays would be: 3, 6, 12, 24, 30, 30, ... - * - * Parameters: - * mosq - a valid mosquitto instance. - * reconnect_delay - the number of seconds to wait between - * reconnects. - * reconnect_delay_max - the maximum number of seconds to wait - * between reconnects. - * reconnect_exponential_backoff - use exponential backoff between - * reconnect attempts. Set to true to enable - * exponential backoff. - * - * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - */ -libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); - -/* - * Function: mosquitto_max_inflight_messages_set - * - * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. - * An in flight message is part way through its delivery flow. Attempts to send - * further messages with will result in the messages being - * queued until the number of in flight messages reduces. - * - * A higher number here results in greater message throughput, but if set - * higher than the maximum in flight messages on the broker may lead to - * delays in the messages being acknowledged. - * - * Set to 0 for no maximum. - * - * Parameters: - * mosq - a valid mosquitto instance. - * max_inflight_messages - the maximum number of inflight messages. Defaults - * to 20. - * - * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - */ -libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); - -/* - * Function: mosquitto_message_retry_set - * - * Set the number of seconds to wait before retrying messages. This applies to - * publish messages with QoS>0. May be called at any time. - * - * Parameters: - * mosq - a valid mosquitto instance. - * message_retry - the number of seconds to wait for a response before - * retrying. Defaults to 20. - */ -libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); - -/* - * Function: mosquitto_user_data_set - * - * When is called, the pointer given as the "obj" parameter - * will be passed to the callbacks as user data. The - * function allows this obj parameter to be updated at any time. This function - * will not modify the memory pointed to by the current user data pointer. If - * it is dynamically allocated memory you must free it yourself. - * - * Parameters: - * mosq - a valid mosquitto instance. - * obj - A user pointer that will be passed as an argument to any callbacks - * that are specified. - */ -libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); /* ============================================================================= * @@ -1349,6 +2273,7 @@ libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); */ libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password); + /* ============================================================================= * * Section: Utility functions @@ -1382,6 +2307,40 @@ libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); */ libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); +/* + * Function: mosquitto_reason_string + * + * Call to obtain a const string description of an MQTT reason code. + * + * Parameters: + * reason_code - an MQTT reason code. + * + * Returns: + * A constant string describing the reason. + */ +libmosq_EXPORT const char *mosquitto_reason_string(int reason_code); + +/* Function: mosquitto_string_to_command + * + * Take a string input representing an MQTT command and convert it to the + * libmosquitto integer representation. + * + * Parameters: + * str - the string to parse. + * cmd - pointer to an int, for the result. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - on an invalid input. + * + * Example: + * (start code) + * mosquitto_string_to_command("CONNECT", &cmd); + * // cmd == CMD_CONNECT + * (end) + */ +libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd); + /* * Function: mosquitto_sub_topic_tokenise * @@ -1390,26 +2349,26 @@ libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); * * For example: * - * subtopic: "a/deep/topic/hierarchy" + * subtopic: "a/deep/topic/hierarchy" * - * Would result in: + * Would result in: * - * topics[0] = "a" - * topics[1] = "deep" - * topics[2] = "topic" - * topics[3] = "hierarchy" + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" * - * and: + * and: * - * subtopic: "/a/deep/topic/hierarchy/" + * subtopic: "/a/deep/topic/hierarchy/" * - * Would result in: + * Would result in: * - * topics[0] = NULL - * topics[1] = "a" - * topics[2] = "deep" - * topics[3] = "topic" - * topics[4] = "hierarchy" + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" * * Parameters: * subtopic - the subscription/topic to tokenise @@ -1417,15 +2376,16 @@ libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); * count - an int pointer to store the number of items in the topics array. * * Returns: - * MOSQ_ERR_SUCCESS - on success - * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 * * Example: * * > char **topics; * > int topic_count; * > int i; - * > + * > * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); * > * > for(i=0; i */ libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); +/* + * Function: mosquitto_pub_topic_check2 + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - length of the topic in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen); + /* * Function: mosquitto_sub_topic_check * @@ -1520,15 +2533,737 @@ libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); * topic - the topic to check * * Returns: - * MOSQ_ERR_SUCCESS - for a valid topic - * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an invalid - * position, or if it is too long. + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 * * See Also: * */ libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic); +/* + * Function: mosquitto_sub_topic_check2 + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - the length in bytes of the topic + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen); + + +/* + * Function: mosquitto_validate_utf8 + * + * Helper function to validate whether a UTF-8 string is valid, according to + * the UTF-8 spec and the MQTT additions. + * + * Parameters: + * str - a string to check + * len - the length of the string in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536 + * MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8 + */ +libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len); + + +/* ============================================================================= + * + * Section: One line client helper functions + * + * ============================================================================= + */ + +struct libmosquitto_will { + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct libmosquitto_auth { + char *username; + char *password; +}; + +struct libmosquitto_tls { + char *cafile; + char *capath; + char *certfile; + char *keyfile; + char *ciphers; + char *tls_version; + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata); + int cert_reqs; +}; + +/* + * Function: mosquitto_subscribe_simple + * + * Helper function to make subscribing to a topic and retrieving some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, waits for msg_count + * messages to be received, then returns after disconnecting cleanly. + * + * Parameters: + * messages - pointer to a "struct mosquitto_message *". The received + * messages will be returned here. On error, this will be set to + * NULL. + * msg_count - the number of messages to retrieve. + * want_retained - if set to true, stale retained messages will be treated as + * normal messages with regards to msg_count. If set to + * false, they will be ignored. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * Greater than 0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool want_retained, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* + * Function: mosquitto_subscribe_callback + * + * Helper function to make subscribing to a topic and processing some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, then passes received + * messages to a user provided callback. If the callback returns a 1, it then + * disconnects cleanly and returns. + * + * Parameters: + * callback - a callback function in the following form: + * int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * Note that this is the same as the normal on_message callback, + * except that it returns an int. + * userdata - user provided pointer that will be passed to the callback. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * Greater than 0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* ============================================================================= + * + * Section: Properties + * + * ============================================================================= + */ + + +/* + * Function: mosquitto_property_add_byte + * + * Add a new byte property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * > mosquitto_property *proplist = NULL; + * > mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value); + +/* + * Function: mosquitto_property_add_int16 + * + * Add a new int16 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * > mosquitto_property *proplist = NULL; + * > mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000); + */ +libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value); + +/* + * Function: mosquitto_property_add_int32 + * + * Add a new int32 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * > mosquitto_property *proplist = NULL; + * > mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400); + */ +libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_varint + * + * Add a new varint property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * > mosquitto_property *proplist = NULL; + * > mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_binary + * + * Add a new binary property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to the property data + * len - length of property data in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * > mosquitto_property *proplist = NULL; + * > mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len); + */ +libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len); + +/* + * Function: mosquitto_property_add_string + * + * Add a new string property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE) + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8. + * + * Example: + * > mosquitto_property *proplist = NULL; + * > mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); + */ +libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value); + +/* + * Function: mosquitto_property_add_string_pair + * + * Add a new string pair property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY) + * name - string name for the new property, must be UTF-8 and zero terminated + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8. + * + * Example: + * > mosquitto_property *proplist = NULL; + * > mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub"); + */ +libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value); + + +/* + * Function: mosquitto_property_identifier + * + * Return the property identifier for a single property. + * + * Parameters: + * property - pointer to a valid mosquitto_property pointer. + * + * Returns: + * A valid property identifier on success + * 0 - on error + */ +libmosq_EXPORT int mosquitto_property_identifier(const mosquitto_property *property); + + +/* + * Function: mosquitto_property_next + * + * Return the next property in a property list. Use to iterate over a property + * list, e.g.: + * + * (start code) + * for(prop = proplist; prop != NULL; prop = mosquitto_property_next(prop)){ + * if(mosquitto_property_identifier(prop) == MQTT_PROP_CONTENT_TYPE){ + * ... + * } + * } + * (end) + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * + * Returns: + * Pointer to the next item in the list + * NULL, if proplist is NULL, or if there are no more items in the list. + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_next(const mosquitto_property *proplist); + + +/* + * Function: mosquitto_property_read_byte + * + * Attempt to read a byte property matching an identifier, from a property list + * or single property. This function can search for multiple entries of the + * same identifier by using the returned value and skip_first. Note however + * that it is forbidden for most properties to be duplicated. + * + * If the property is not found, *value will not be modified, so it is safe to + * pass a variable with a default value to be potentially overwritten: + * + * (start code) + * uint16_t keepalive = 60; // default value + * // Get value from property list, or keep default if not found. + * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false); + * (end) + * + * Parameters: + * proplist - mosquitto_property pointer, the list of properties or single property + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * (start code) + * // proplist is obtained from a callback + * mosquitto_property *prop; + * prop = mosquitto_property_read_byte(proplist, identifier, &value, false); + * while(prop){ + * printf("value: %s\n", value); + * prop = mosquitto_property_read_byte(prop, identifier, &value); + * } + * (end) + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte( + const mosquitto_property *proplist, + int identifier, + uint8_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int16 + * + * Read an int16 property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16( + const mosquitto_property *proplist, + int identifier, + uint16_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int32 + * + * Read an int32 property value from a property. + * + * Parameters: + * property - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_varint + * + * Read a varint property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_binary + * + * Read a binary property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary( + const mosquitto_property *proplist, + int identifier, + void **value, + uint16_t *len, + bool skip_first); + +/* + * Function: mosquitto_property_read_string + * + * Read a string property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string( + const mosquitto_property *proplist, + int identifier, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_read_string_pair + * + * Read a string pair property value pair from a property. + * + * On success, name and value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * name - pointer to char* for the name property data to be stored in, or NULL + * if the name is not required. + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair( + const mosquitto_property *proplist, + int identifier, + char **name, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_free_all + * + * Free all properties from a list of properties. Frees the list and sets *properties to NULL. + * + * Parameters: + * properties - list of properties to free + * + * Example: + * > mosquitto_properties *properties = NULL; + * > // Add properties + * > mosquitto_property_free_all(&properties); + */ +libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties); + +/* + * Function: mosquitto_property_copy_all + * + * Parameters: + * dest - pointer for new property list + * src - property list + * + * Returns: + * MOSQ_ERR_SUCCESS - on successful copy + * MOSQ_ERR_INVAL - if dest is NULL + * MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL) + */ +libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src); + +/* + * Function: mosquitto_property_check_command + * + * Check whether a property identifier is valid for the given command. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY) + * + * Returns: + * MOSQ_ERR_SUCCESS - if the identifier is valid for command + * MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command. + */ +libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier); + + +/* + * Function: mosquitto_property_check_all + * + * Check whether a list of properties are valid for a particular command, + * whether there are duplicates, and whether the values are valid where + * possible. + * + * Note that this function is used internally in the library whenever + * properties are passed to it, so in basic use this is not needed, but should + * be helpful to check property lists *before* the point of using them. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * properties - list of MQTT properties to check. + * + * Returns: + * MOSQ_ERR_SUCCESS - if all properties are valid + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid + */ +libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties); + +/* + * Function: mosquitto_property_identifier_to_string + * + * Return the property name as a string for a property identifier. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * identifier - valid MQTT property identifier integer + * + * Returns: + * A const string to the property name on success + * NULL on failure + */ +libmosq_EXPORT const char *mosquitto_property_identifier_to_string(int identifier); + + +/* Function: mosquitto_string_to_property_info + * + * Parse a property name string and convert to a property identifier and data type. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * propname - the string to parse + * identifier - pointer to an int to receive the property identifier + * type - pointer to an int to receive the property type + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the string does not match a property + * + * Example: + * (start code) + * mosquitto_string_to_property_info("response-topic", &id, &type); + * // id == MQTT_PROP_RESPONSE_TOPIC + * // type == MQTT_PROP_TYPE_STRING + * (end) + */ +libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); + + #ifdef __cplusplus } #endif diff --git a/mqttclient/mosquitto_broker.h b/mqttclient/mosquitto_broker.h new file mode 100644 index 0000000..9a6ba1e --- /dev/null +++ b/mqttclient/mosquitto_broker.h @@ -0,0 +1,561 @@ +/* +Copyright (c) 2009-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +/* + * File: mosquitto_broker.h + * + * This header contains functions for use by plugins. + */ +#ifndef MOSQUITTO_BROKER_H +#define MOSQUITTO_BROKER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && defined(mosquitto_EXPORTS) +# define mosq_EXPORT __declspec(dllexport) +#else +# define mosq_EXPORT +#endif + +#include +#include +#include +#include + +struct mosquitto; +typedef struct mqtt5__property mosquitto_property; + +enum mosquitto_protocol { + mp_mqtt, + mp_mqttsn, + mp_websockets +}; + +/* ========================================================================= + * + * Section: Register callbacks. + * + * ========================================================================= */ + +/* Callback events */ +enum mosquitto_plugin_event { + MOSQ_EVT_RELOAD = 1, + MOSQ_EVT_ACL_CHECK = 2, + MOSQ_EVT_BASIC_AUTH = 3, + MOSQ_EVT_EXT_AUTH_START = 4, + MOSQ_EVT_EXT_AUTH_CONTINUE = 5, + MOSQ_EVT_CONTROL = 6, + MOSQ_EVT_MESSAGE = 7, + MOSQ_EVT_PSK_KEY = 8, + MOSQ_EVT_TICK = 9, + MOSQ_EVT_DISCONNECT = 10, +}; + +/* Data for the MOSQ_EVT_RELOAD event */ +struct mosquitto_evt_reload { + void *future; + struct mosquitto_opt *options; + int option_count; + void *future2[4]; +}; + +/* Data for the MOSQ_EVT_ACL_CHECK event */ +struct mosquitto_evt_acl_check { + void *future; + struct mosquitto *client; + const char *topic; + const void *payload; + mosquitto_property *properties; + int access; + uint32_t payloadlen; + uint8_t qos; + bool retain; + void *future2[4]; +}; + +/* Data for the MOSQ_EVT_BASIC_AUTH event */ +struct mosquitto_evt_basic_auth { + void *future; + struct mosquitto *client; + char *username; + char *password; + void *future2[4]; +}; + +/* Data for the MOSQ_EVT_PSK_KEY event */ +struct mosquitto_evt_psk_key { + void *future; + struct mosquitto *client; + const char *hint; + const char *identity; + char *key; + int max_key_len; + void *future2[4]; +}; + +/* Data for the MOSQ_EVT_EXTENDED_AUTH event */ +struct mosquitto_evt_extended_auth { + void *future; + struct mosquitto *client; + const void *data_in; + void *data_out; + uint16_t data_in_len; + uint16_t data_out_len; + const char *auth_method; + void *future2[3]; +}; + +/* Data for the MOSQ_EVT_CONTROL event */ +struct mosquitto_evt_control { + void *future; + struct mosquitto *client; + const char *topic; + const void *payload; + const mosquitto_property *properties; + char *reason_string; + uint32_t payloadlen; + uint8_t qos; + uint8_t reason_code; + bool retain; + void *future2[4]; +}; + +/* Data for the MOSQ_EVT_MESSAGE event */ +struct mosquitto_evt_message { + void *future; + struct mosquitto *client; + char *topic; + void *payload; + mosquitto_property *properties; + char *reason_string; + uint32_t payloadlen; + uint8_t qos; + uint8_t reason_code; + bool retain; + void *future2[4]; +}; + + +/* Data for the MOSQ_EVT_TICK event */ +struct mosquitto_evt_tick { + void *future; + long now_ns; + long next_ns; + time_t now_s; + time_t next_s; + void *future2[4]; +}; + +/* Data for the MOSQ_EVT_DISCONNECT event */ +struct mosquitto_evt_disconnect { + void *future; + struct mosquitto *client; + int reason; + void *future2[4]; +}; + + +/* Callback definition */ +typedef int (*MOSQ_FUNC_generic_callback)(int, void *, void *); + +typedef struct mosquitto_plugin_id_t mosquitto_plugin_id_t; + +/* + * Function: mosquitto_callback_register + * + * Register a callback for an event. + * + * Parameters: + * identifier - the plugin identifier, as provided by . + * event - the event to register a callback for. Can be one of: + * * MOSQ_EVT_RELOAD + * * MOSQ_EVT_ACL_CHECK + * * MOSQ_EVT_BASIC_AUTH + * * MOSQ_EVT_EXT_AUTH_START + * * MOSQ_EVT_EXT_AUTH_CONTINUE + * * MOSQ_EVT_CONTROL + * * MOSQ_EVT_MESSAGE + * * MOSQ_EVT_PSK_KEY + * * MOSQ_EVT_TICK + * * MOSQ_EVT_DISCONNECT + * cb_func - the callback function + * event_data - event specific data + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if cb_func is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_ALREADY_EXISTS - if cb_func has already been registered for this event + * MOSQ_ERR_NOT_SUPPORTED - if the event is not supported + */ +mosq_EXPORT int mosquitto_callback_register( + mosquitto_plugin_id_t *identifier, + int event, + MOSQ_FUNC_generic_callback cb_func, + const void *event_data, + void *userdata); + +/* + * Function: mosquitto_callback_unregister + * + * Unregister a previously registered callback function. + * + * Parameters: + * identifier - the plugin identifier, as provided by . + * event - the event to register a callback for. Can be one of: + * * MOSQ_EVT_RELOAD + * * MOSQ_EVT_ACL_CHECK + * * MOSQ_EVT_BASIC_AUTH + * * MOSQ_EVT_EXT_AUTH_START + * * MOSQ_EVT_EXT_AUTH_CONTINUE + * * MOSQ_EVT_CONTROL + * * MOSQ_EVT_MESSAGE + * * MOSQ_EVT_PSK_KEY + * * MOSQ_EVT_TICK + * * MOSQ_EVT_DISCONNECT + * cb_func - the callback function + * event_data - event specific data + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if cb_func is NULL + * MOSQ_ERR_NOT_FOUND - if cb_func was not registered for this event + * MOSQ_ERR_NOT_SUPPORTED - if the event is not supported + */ +mosq_EXPORT int mosquitto_callback_unregister( + mosquitto_plugin_id_t *identifier, + int event, + MOSQ_FUNC_generic_callback cb_func, + const void *event_data); + + +/* ========================================================================= + * + * Section: Memory allocation. + * + * Use these functions when allocating or freeing memory to have your memory + * included in the memory tracking on the broker. + * + * ========================================================================= */ + +/* + * Function: mosquitto_calloc + */ +mosq_EXPORT void *mosquitto_calloc(size_t nmemb, size_t size); + +/* + * Function: mosquitto_free + */ +mosq_EXPORT void mosquitto_free(void *mem); + +/* + * Function: mosquitto_malloc + */ +mosq_EXPORT void *mosquitto_malloc(size_t size); + +/* + * Function: mosquitto_realloc + */ +mosq_EXPORT void *mosquitto_realloc(void *ptr, size_t size); + +/* + * Function: mosquitto_strdup + */ +mosq_EXPORT char *mosquitto_strdup(const char *s); + +/* ========================================================================= + * + * Section: Utility Functions + * + * Use these functions from within your plugin. + * + * ========================================================================= */ + + +/* + * Function: mosquitto_log_printf + * + * Write a log message using the broker configured logging. + * + * Parameters: + * level - Log message priority. Can currently be one of: + * + * * MOSQ_LOG_INFO + * * MOSQ_LOG_NOTICE + * * MOSQ_LOG_WARNING + * * MOSQ_LOG_ERR + * * MOSQ_LOG_DEBUG + * * MOSQ_LOG_SUBSCRIBE (not recommended for use by plugins) + * * MOSQ_LOG_UNSUBSCRIBE (not recommended for use by plugins) + * + * These values are defined in mosquitto.h. + * + * fmt, ... - printf style format and arguments. + */ +mosq_EXPORT void mosquitto_log_printf(int level, const char *fmt, ...); + + +/* ========================================================================= + * + * Client Functions + * + * Use these functions to access client information. + * + * ========================================================================= */ + +/* + * Function: mosquitto_client_address + * + * Retrieve the IP address of the client as a string. + */ +mosq_EXPORT const char *mosquitto_client_address(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_clean_session + * + * Retrieve the clean session flag value for a client. + */ +mosq_EXPORT bool mosquitto_client_clean_session(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_id + * + * Retrieve the client id associated with a client. + */ +mosq_EXPORT const char *mosquitto_client_id(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_keepalive + * + * Retrieve the keepalive value for a client. + */ +mosq_EXPORT int mosquitto_client_keepalive(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_certificate + * + * If TLS support is enabled, return the certificate provided by a client as an + * X509 pointer from openssl. If the client did not provide a certificate, then + * NULL will be returned. This function will only ever return a non-NULL value + * if the `require_certificate` option is set to true. + * + * When you have finished with the x509 pointer, it must be freed using + * X509_free(). + * + * If TLS is not supported, this function will always return NULL. + */ +mosq_EXPORT void *mosquitto_client_certificate(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_protocol + * + * Retrieve the protocol with which the client has connected. Can be one of: + * + * mp_mqtt (MQTT over TCP) + * mp_mqttsn (MQTT-SN) + * mp_websockets (MQTT over Websockets) + */ +mosq_EXPORT int mosquitto_client_protocol(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_protocol_version + * + * Retrieve the MQTT protocol version with which the client has connected. Can be one of: + * + * Returns: + * 3 - for MQTT v3 / v3.1 + * 4 - for MQTT v3.1.1 + * 5 - for MQTT v5 + */ +mosq_EXPORT int mosquitto_client_protocol_version(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_sub_count + * + * Retrieve the number of subscriptions that have been made by a client. + */ +mosq_EXPORT int mosquitto_client_sub_count(const struct mosquitto *client); + + +/* + * Function: mosquitto_client_username + * + * Retrieve the username associated with a client. + */ +mosq_EXPORT const char *mosquitto_client_username(const struct mosquitto *client); + + +/* Function: mosquitto_set_username + * + * Set the username for a client. + * + * This removes and replaces the current username for a client and hence + * updates its access. + * + * username can be NULL, in which case the client will become anonymous, but + * must not be zero length. + * + * In the case of error, the client will be left with its original username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if client is NULL, or if username is zero length + * MOSQ_ERR_NOMEM - on out of memory + */ +mosq_EXPORT int mosquitto_set_username(struct mosquitto *client, const char *username); + + +/* ========================================================================= + * + * Section: Client control + * + * ========================================================================= */ + +/* Function: mosquitto_kick_client_by_clientid + * + * Forcefully disconnect a client from the broker. + * + * If clientid != NULL, then the client with the matching client id is + * disconnected from the broker. + * If clientid == NULL, then all clients are disconnected from the broker. + * + * If with_will == true, then if the client has a Last Will and Testament + * defined then this will be sent. If false, the LWT will not be sent. + */ +mosq_EXPORT int mosquitto_kick_client_by_clientid(const char *clientid, bool with_will); + +/* Function: mosquitto_kick_client_by_username + * + * Forcefully disconnect a client from the broker. + * + * If username != NULL, then all clients with a matching username are kicked + * from the broker. + * If username == NULL, then all clients that do not have a username are + * kicked. + * + * If with_will == true, then if the client has a Last Will and Testament + * defined then this will be sent. If false, the LWT will not be sent. + */ +mosq_EXPORT int mosquitto_kick_client_by_username(const char *username, bool with_will); + + +/* ========================================================================= + * + * Section: Publishing functions + * + * ========================================================================= */ + +/* Function: mosquitto_broker_publish + * + * Publish a message from within a plugin. + * + * This function allows a plugin to publish a message. Messages published in + * this way are treated as coming from the broker and so will not be passed to + * `mosquitto_auth_acl_check(, MOSQ_ACL_WRITE, , )` for checking. Read access + * will be enforced as normal for individual clients when they are due to + * receive the message. + * + * It can be used to send messages to all clients that have a matching + * subscription, or to a single client whether or not it has a matching + * subscription. + * + * Parameters: + * clientid - optional string. If set to NULL, the message is delivered to all + * clients. If non-NULL, the message is delivered only to the + * client with the corresponding client id. If the client id + * specified is not connected, the message will be dropped. + * topic - message topic + * payloadlen - payload length in bytes. Can be 0 for an empty payload. + * payload - payload bytes. If payloadlen > 0 this must not be NULL. Must + * be allocated on the heap. Will be freed by mosquitto after use if the + * function returns success. + * qos - message QoS to use. + * retain - should retain be set on the message. This does not apply if + * clientid is non-NULL. + * properties - MQTT v5 properties to attach to the message. If the function + * returns success, then properties is owned by the broker and + * will be freed at a later point. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if topic is NULL, if payloadlen < 0, if payloadlen > 0 + * and payload is NULL, if qos is not 0, 1, or 2. + * MOSQ_ERR_NOMEM - on out of memory + */ +mosq_EXPORT int mosquitto_broker_publish( + const char *clientid, + const char *topic, + int payloadlen, + void *payload, + int qos, + bool retain, + mosquitto_property *properties); + + +/* Function: mosquitto_broker_publish_copy + * + * Publish a message from within a plugin. + * + * This function is identical to mosquitto_broker_publish, except that a copy + * of `payload` is taken. + * + * Parameters: + * clientid - optional string. If set to NULL, the message is delivered to all + * clients. If non-NULL, the message is delivered only to the + * client with the corresponding client id. If the client id + * specified is not connected, the message will be dropped. + * topic - message topic + * payloadlen - payload length in bytes. Can be 0 for an empty payload. + * payload - payload bytes. If payloadlen > 0 this must not be NULL. + * Memory remains the property of the calling function. + * qos - message QoS to use. + * retain - should retain be set on the message. This does not apply if + * clientid is non-NULL. + * properties - MQTT v5 properties to attach to the message. If the function + * returns success, then properties is owned by the broker and + * will be freed at a later point. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if topic is NULL, if payloadlen < 0, if payloadlen > 0 + * and payload is NULL, if qos is not 0, 1, or 2. + * MOSQ_ERR_NOMEM - on out of memory + */ +mosq_EXPORT int mosquitto_broker_publish_copy( + const char *clientid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + mosquitto_property *properties); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mqttclient/mosquitto_plugin.h b/mqttclient/mosquitto_plugin.h new file mode 100644 index 0000000..5b5974d --- /dev/null +++ b/mqttclient/mosquitto_plugin.h @@ -0,0 +1,420 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +/* + * File: mosquitto_plugin.h + * + * This header contains function declarations for use when writing a Mosquitto plugin. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* The generic plugin interface starts at version 5 */ +#define MOSQ_PLUGIN_VERSION 5 + +/* The old auth only interface stopped at version 4 */ +#define MOSQ_AUTH_PLUGIN_VERSION 4 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 +#define MOSQ_ACL_SUBSCRIBE 0x04 +#define MOSQ_ACL_UNSUBSCRIBE 0x08 + +#include +#include + +#include + +struct mosquitto; + +struct mosquitto_opt { + char *key; + char *value; +}; + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +struct mosquitto_acl_msg { + const char *topic; + const void *payload; + long payloadlen; + int qos; + bool retain; +}; + +#ifdef WIN32 +# define mosq_plugin_EXPORT __declspec(dllexport) +#else +# define mosq_plugin_EXPORT +#endif + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed in the "Plugin Functions" section below. The resulting + * code should then be compiled as a shared library. Using gcc this can be + * achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + * Authentication plugins can implement one or both of authentication and + * access control. If your plugin does not wish to handle either of + * authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In + * this case, the next plugin will handle it. If all plugins return + * MOSQ_ERR_PLUGIN_DEFER, the request will be denied. + * + * For each check, the following flow happens: + * + * * The default password file and/or acl file checks are made. If either one + * of these is not defined, then they are considered to be deferred. If either + * one accepts the check, no further checks are made. If an error occurs, the + * check is denied + * * The first plugin does the check, if it returns anything other than + * MOSQ_ERR_PLUGIN_DEFER, then the check returns immediately. If the plugin + * returns MOSQ_ERR_PLUGIN_DEFER then the next plugin runs its check. + * * If the final plugin returns MOSQ_ERR_PLUGIN_DEFER, then access will be + * denied. + */ + +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + + +/* ========================================================================= + * + * Section: Plugin Functions v5 + * + * This is the plugin version 5 interface, which covers authentication, access + * control, the $CONTROL topic space handling, and message inspection and + * modification. + * + * This interface is available from v2.0 onwards. + * + * There are just three functions to implement in your plugin. You should + * register callbacks to handle different events in your + * mosquitto_plugin_init() function. See mosquitto_broker.h for the events and + * callback registering functions. + * + * ========================================================================= */ + +/* + * Function: mosquitto_plugin_version + * + * The broker will attempt to call this function immediately after loading the + * plugin to check it is a supported plugin version. Your code must simply + * return the plugin interface version you support, i.e. 5. + * + * The supported_versions array tells you which plugin versions the broker supports. + * + * If the broker does not support the version that you require, return -1 to + * indicate failure. + */ +mosq_plugin_EXPORT int mosquitto_plugin_version(int supported_version_count, const int *supported_versions); + +/* + * Function: mosquitto_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * identifier - This is a pointer to an opaque structure which you must + * save and use when registering/unregistering callbacks. + * user_data - The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts - Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count - The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +mosq_plugin_EXPORT int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **userdata, struct mosquitto_opt *options, int option_count); + + +/* + * Function: mosquitto_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * + * Parameters: + * + * user_data - The pointer provided in . + * opts - Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count - The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +mosq_plugin_EXPORT int mosquitto_plugin_cleanup(void *userdata, struct mosquitto_opt *options, int option_count); + + + +/* ========================================================================= + * + * Section: Plugin Functions v4 + * + * This is the plugin version 4 interface, which is exclusively for + * authentication and access control, and which is still supported for existing + * plugins. If you are developing a new plugin, please use the v5 interface. + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * the version of the plugin interface you support, i.e. 4. + */ +mosq_plugin_EXPORT int mosquitto_auth_plugin_version(void); + + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data - The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts - Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count - The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +mosq_plugin_EXPORT int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data - The pointer provided in . + * opts - Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count - The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +mosq_plugin_EXPORT int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_security_init + * + * This function is called in two scenarios: + * + * 1. When the broker starts up. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, will be called first, then + * this function will be called. In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data - The pointer provided in . + * opts - Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count - The number of elements in the opts array. + * reload - If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +mosq_plugin_EXPORT int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_security_cleanup + * + * This function is called in two scenarios: + * + * 1. When the broker is shutting down. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, this function will be called, followed by + * . In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data - The pointer provided in . + * opts - Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count - The number of elements in the opts array. + * reload - If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +mosq_plugin_EXPORT int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). + * + * Return: + * MOSQ_ERR_SUCCESS if access was granted. + * MOSQ_ERR_ACL_DENIED if access was not granted. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +mosq_plugin_EXPORT int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg); + + +/* + * Function: mosquitto_auth_unpwd_check + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making basic username/password checks. + * + * Called by the broker when a username/password must be checked. + * + * Return: + * MOSQ_ERR_SUCCESS if the user is authenticated. + * MOSQ_ERR_AUTH if authentication failed. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +mosq_plugin_EXPORT int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password); + + +/* + * Function: mosquitto_psk_key_get + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making TLS-PSK checks. + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data - the pointer provided in . + * hint - the psk_hint for the listener the client is connecting to. + * identity - the identity string provided by the client + * key - a string where the hex PSK should be copied + * max_key_len - the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +mosq_plugin_EXPORT int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len); + +/* + * Function: mosquitto_auth_start + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making extended authentication checks. + * + * Parameters: + * user_data - the pointer provided in . + * method - the authentication method + * reauth - this is set to false if this is the first authentication attempt + * on a connection, set to true if the client is attempting to + * reauthenticate. + * data_in - pointer to authentication data, or NULL + * data_in_len - length of data_in, in bytes + * data_out - if your plugin wishes to send authentication data back to the + * client, allocate some memory using malloc or friends and set + * data_out. The broker will free the memory after use. + * data_out_len - Set the length of data_out in bytes. + * + * Return value: + * Return MOSQ_ERR_SUCCESS if authentication was successful. + * Return MOSQ_ERR_AUTH_CONTINUE if the authentication is a multi step process and can continue. + * Return MOSQ_ERR_AUTH if authentication was valid but did not succeed. + * Return any other relevant positive integer MOSQ_ERR_* to produce an error. + */ +mosq_plugin_EXPORT int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + +mosq_plugin_EXPORT int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mqttclient/mqtt_protocol.h b/mqttclient/mqtt_protocol.h new file mode 100644 index 0000000..15c4c3e --- /dev/null +++ b/mqttclient/mqtt_protocol.h @@ -0,0 +1,282 @@ +/* +Copyright (c) 2009-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MQTT_PROTOCOL_H +#define MQTT_PROTOCOL_H + +/* + * File: mqtt_protocol.h + * + * This header contains definitions of MQTT values as defined in the specifications. + */ +#define PROTOCOL_NAME_v31 "MQIsdp" +#define PROTOCOL_VERSION_v31 3 + +#define PROTOCOL_NAME "MQTT" + +#define PROTOCOL_VERSION_v311 4 +#define PROTOCOL_VERSION_v5 5 + + +/* Message types */ +#define CMD_CONNECT 0x10U +#define CMD_CONNACK 0x20U +#define CMD_PUBLISH 0x30U +#define CMD_PUBACK 0x40U +#define CMD_PUBREC 0x50U +#define CMD_PUBREL 0x60U +#define CMD_PUBCOMP 0x70U +#define CMD_SUBSCRIBE 0x80U +#define CMD_SUBACK 0x90U +#define CMD_UNSUBSCRIBE 0xA0U +#define CMD_UNSUBACK 0xB0U +#define CMD_PINGREQ 0xC0U +#define CMD_PINGRESP 0xD0U +#define CMD_DISCONNECT 0xE0U +#define CMD_AUTH 0xF0U + +/* Mosquitto only: for distinguishing CONNECT and WILL properties */ +#define CMD_WILL 0x100 + +/* Enum: mqtt311_connack_codes + * + * The CONNACK results for MQTT v3.1.1, and v3.1. + * + * Values: + * CONNACK_ACCEPTED - 0 + * CONNACK_REFUSED_PROTOCOL_VERSION - 1 + * CONNACK_REFUSED_IDENTIFIER_REJECTED - 2 + * CONNACK_REFUSED_SERVER_UNAVAILABLE - 3 + * CONNACK_REFUSED_BAD_USERNAME_PASSWORD - 4 + * CONNACK_REFUSED_NOT_AUTHORIZED - 5 + */ +enum mqtt311_connack_codes { + CONNACK_ACCEPTED = 0, + CONNACK_REFUSED_PROTOCOL_VERSION = 1, + CONNACK_REFUSED_IDENTIFIER_REJECTED = 2, + CONNACK_REFUSED_SERVER_UNAVAILABLE = 3, + CONNACK_REFUSED_BAD_USERNAME_PASSWORD = 4, + CONNACK_REFUSED_NOT_AUTHORIZED = 5, +}; + +/* Enum: mqtt5_return_codes + * The reason codes returned in various MQTT commands. + * + * Values: + * MQTT_RC_SUCCESS - 0 + * MQTT_RC_NORMAL_DISCONNECTION - 0 + * MQTT_RC_GRANTED_QOS0 - 0 + * MQTT_RC_GRANTED_QOS1 - 1 + * MQTT_RC_GRANTED_QOS2 - 2 + * MQTT_RC_DISCONNECT_WITH_WILL_MSG - 4 + * MQTT_RC_NO_MATCHING_SUBSCRIBERS - 16 + * MQTT_RC_NO_SUBSCRIPTION_EXISTED - 17 + * MQTT_RC_CONTINUE_AUTHENTICATION - 24 + * MQTT_RC_REAUTHENTICATE - 25 + * MQTT_RC_UNSPECIFIED - 128 + * MQTT_RC_MALFORMED_PACKET - 129 + * MQTT_RC_PROTOCOL_ERROR - 130 + * MQTT_RC_IMPLEMENTATION_SPECIFIC - 131 + * MQTT_RC_UNSUPPORTED_PROTOCOL_VERSION - 132 + * MQTT_RC_CLIENTID_NOT_VALID - 133 + * MQTT_RC_BAD_USERNAME_OR_PASSWORD - 134 + * MQTT_RC_NOT_AUTHORIZED - 135 + * MQTT_RC_SERVER_UNAVAILABLE - 136 + * MQTT_RC_SERVER_BUSY - 137 + * MQTT_RC_BANNED - 138 + * MQTT_RC_SERVER_SHUTTING_DOWN - 139 + * MQTT_RC_BAD_AUTHENTICATION_METHOD - 140 + * MQTT_RC_KEEP_ALIVE_TIMEOUT - 141 + * MQTT_RC_SESSION_TAKEN_OVER - 142 + * MQTT_RC_TOPIC_FILTER_INVALID - 143 + * MQTT_RC_TOPIC_NAME_INVALID - 144 + * MQTT_RC_PACKET_ID_IN_USE - 145 + * MQTT_RC_PACKET_ID_NOT_FOUND - 146 + * MQTT_RC_RECEIVE_MAXIMUM_EXCEEDED - 147 + * MQTT_RC_TOPIC_ALIAS_INVALID - 148 + * MQTT_RC_PACKET_TOO_LARGE - 149 + * MQTT_RC_MESSAGE_RATE_TOO_HIGH - 150 + * MQTT_RC_QUOTA_EXCEEDED - 151 + * MQTT_RC_ADMINISTRATIVE_ACTION - 152 + * MQTT_RC_PAYLOAD_FORMAT_INVALID - 153 + * MQTT_RC_RETAIN_NOT_SUPPORTED - 154 + * MQTT_RC_QOS_NOT_SUPPORTED - 155 + * MQTT_RC_USE_ANOTHER_SERVER - 156 + * MQTT_RC_SERVER_MOVED - 157 + * MQTT_RC_SHARED_SUBS_NOT_SUPPORTED - 158 + * MQTT_RC_CONNECTION_RATE_EXCEEDED - 159 + * MQTT_RC_MAXIMUM_CONNECT_TIME - 160 + * MQTT_RC_SUBSCRIPTION_IDS_NOT_SUPPORTED - 161 + * MQTT_RC_WILDCARD_SUBS_NOT_SUPPORTED - 162 + */ +enum mqtt5_return_codes { + MQTT_RC_SUCCESS = 0, /* CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH */ + MQTT_RC_NORMAL_DISCONNECTION = 0, /* DISCONNECT */ + MQTT_RC_GRANTED_QOS0 = 0, /* SUBACK */ + MQTT_RC_GRANTED_QOS1 = 1, /* SUBACK */ + MQTT_RC_GRANTED_QOS2 = 2, /* SUBACK */ + MQTT_RC_DISCONNECT_WITH_WILL_MSG = 4, /* DISCONNECT */ + MQTT_RC_NO_MATCHING_SUBSCRIBERS = 16, /* PUBACK, PUBREC */ + MQTT_RC_NO_SUBSCRIPTION_EXISTED = 17, /* UNSUBACK */ + MQTT_RC_CONTINUE_AUTHENTICATION = 24, /* AUTH */ + MQTT_RC_REAUTHENTICATE = 25, /* AUTH */ + + MQTT_RC_UNSPECIFIED = 128, /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */ + MQTT_RC_MALFORMED_PACKET = 129, /* CONNACK, DISCONNECT */ + MQTT_RC_PROTOCOL_ERROR = 130, /* DISCONNECT */ + MQTT_RC_IMPLEMENTATION_SPECIFIC = 131, /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */ + MQTT_RC_UNSUPPORTED_PROTOCOL_VERSION = 132, /* CONNACK */ + MQTT_RC_CLIENTID_NOT_VALID = 133, /* CONNACK */ + MQTT_RC_BAD_USERNAME_OR_PASSWORD = 134, /* CONNACK */ + MQTT_RC_NOT_AUTHORIZED = 135, /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */ + MQTT_RC_SERVER_UNAVAILABLE = 136, /* CONNACK */ + MQTT_RC_SERVER_BUSY = 137, /* CONNACK, DISCONNECT */ + MQTT_RC_BANNED = 138, /* CONNACK */ + MQTT_RC_SERVER_SHUTTING_DOWN = 139, /* DISCONNECT */ + MQTT_RC_BAD_AUTHENTICATION_METHOD = 140, /* CONNACK */ + MQTT_RC_KEEP_ALIVE_TIMEOUT = 141, /* DISCONNECT */ + MQTT_RC_SESSION_TAKEN_OVER = 142, /* DISCONNECT */ + MQTT_RC_TOPIC_FILTER_INVALID = 143, /* SUBACK, UNSUBACK, DISCONNECT */ + MQTT_RC_TOPIC_NAME_INVALID = 144, /* CONNACK, PUBACK, PUBREC, DISCONNECT */ + MQTT_RC_PACKET_ID_IN_USE = 145, /* PUBACK, SUBACK, UNSUBACK */ + MQTT_RC_PACKET_ID_NOT_FOUND = 146, /* PUBREL, PUBCOMP */ + MQTT_RC_RECEIVE_MAXIMUM_EXCEEDED = 147, /* DISCONNECT */ + MQTT_RC_TOPIC_ALIAS_INVALID = 148, /* DISCONNECT */ + MQTT_RC_PACKET_TOO_LARGE = 149, /* CONNACK, PUBACK, PUBREC, DISCONNECT */ + MQTT_RC_MESSAGE_RATE_TOO_HIGH = 150, /* DISCONNECT */ + MQTT_RC_QUOTA_EXCEEDED = 151, /* PUBACK, PUBREC, SUBACK, DISCONNECT */ + MQTT_RC_ADMINISTRATIVE_ACTION = 152, /* DISCONNECT */ + MQTT_RC_PAYLOAD_FORMAT_INVALID = 153, /* CONNACK, DISCONNECT */ + MQTT_RC_RETAIN_NOT_SUPPORTED = 154, /* CONNACK, DISCONNECT */ + MQTT_RC_QOS_NOT_SUPPORTED = 155, /* CONNACK, DISCONNECT */ + MQTT_RC_USE_ANOTHER_SERVER = 156, /* CONNACK, DISCONNECT */ + MQTT_RC_SERVER_MOVED = 157, /* CONNACK, DISCONNECT */ + MQTT_RC_SHARED_SUBS_NOT_SUPPORTED = 158, /* SUBACK, DISCONNECT */ + MQTT_RC_CONNECTION_RATE_EXCEEDED = 159, /* CONNACK, DISCONNECT */ + MQTT_RC_MAXIMUM_CONNECT_TIME = 160, /* DISCONNECT */ + MQTT_RC_SUBSCRIPTION_IDS_NOT_SUPPORTED = 161, /* SUBACK, DISCONNECT */ + MQTT_RC_WILDCARD_SUBS_NOT_SUPPORTED = 162, /* SUBACK, DISCONNECT */ +}; + +/* Enum: mqtt5_property + * Options for use with MQTTv5 properties. + * Options: + * + * MQTT_PROP_PAYLOAD_FORMAT_INDICATOR - property option. + * MQTT_PROP_MESSAGE_EXPIRY_INTERVAL - property option. + * MQTT_PROP_CONTENT_TYPE - property option. + * MQTT_PROP_RESPONSE_TOPIC - property option. + * MQTT_PROP_CORRELATION_DATA - property option. + * MQTT_PROP_SUBSCRIPTION_IDENTIFIER - property option. + * MQTT_PROP_SESSION_EXPIRY_INTERVAL - property option. + * MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER - property option. + * MQTT_PROP_SERVER_KEEP_ALIVE - property option. + * MQTT_PROP_AUTHENTICATION_METHOD - property option. + * MQTT_PROP_AUTHENTICATION_DATA - property option. + * MQTT_PROP_REQUEST_PROBLEM_INFORMATION - property option. + * MQTT_PROP_WILL_DELAY_INTERVAL - property option. + * MQTT_PROP_REQUEST_RESPONSE_INFORMATION - property option. + * MQTT_PROP_RESPONSE_INFORMATION - property option. + * MQTT_PROP_SERVER_REFERENCE - property option. + * MQTT_PROP_REASON_STRING - property option. + * MQTT_PROP_RECEIVE_MAXIMUM - property option. + * MQTT_PROP_TOPIC_ALIAS_MAXIMUM - property option. + * MQTT_PROP_TOPIC_ALIAS - property option. + * MQTT_PROP_MAXIMUM_QOS - property option. + * MQTT_PROP_RETAIN_AVAILABLE - property option. + * MQTT_PROP_USER_PROPERTY - property option. + * MQTT_PROP_MAXIMUM_PACKET_SIZE - property option. + * MQTT_PROP_WILDCARD_SUB_AVAILABLE - property option. + * MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE - property option. + * MQTT_PROP_SHARED_SUB_AVAILABLE - property option. + */ +enum mqtt5_property { + MQTT_PROP_PAYLOAD_FORMAT_INDICATOR = 1, /* Byte : PUBLISH, Will Properties */ + MQTT_PROP_MESSAGE_EXPIRY_INTERVAL = 2, /* 4 byte int : PUBLISH, Will Properties */ + MQTT_PROP_CONTENT_TYPE = 3, /* UTF-8 string : PUBLISH, Will Properties */ + MQTT_PROP_RESPONSE_TOPIC = 8, /* UTF-8 string : PUBLISH, Will Properties */ + MQTT_PROP_CORRELATION_DATA = 9, /* Binary Data : PUBLISH, Will Properties */ + MQTT_PROP_SUBSCRIPTION_IDENTIFIER = 11, /* Variable byte int : PUBLISH, SUBSCRIBE */ + MQTT_PROP_SESSION_EXPIRY_INTERVAL = 17, /* 4 byte int : CONNECT, CONNACK, DISCONNECT */ + MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER = 18, /* UTF-8 string : CONNACK */ + MQTT_PROP_SERVER_KEEP_ALIVE = 19, /* 2 byte int : CONNACK */ + MQTT_PROP_AUTHENTICATION_METHOD = 21, /* UTF-8 string : CONNECT, CONNACK, AUTH */ + MQTT_PROP_AUTHENTICATION_DATA = 22, /* Binary Data : CONNECT, CONNACK, AUTH */ + MQTT_PROP_REQUEST_PROBLEM_INFORMATION = 23, /* Byte : CONNECT */ + MQTT_PROP_WILL_DELAY_INTERVAL = 24, /* 4 byte int : Will properties */ + MQTT_PROP_REQUEST_RESPONSE_INFORMATION = 25,/* Byte : CONNECT */ + MQTT_PROP_RESPONSE_INFORMATION = 26, /* UTF-8 string : CONNACK */ + MQTT_PROP_SERVER_REFERENCE = 28, /* UTF-8 string : CONNACK, DISCONNECT */ + MQTT_PROP_REASON_STRING = 31, /* UTF-8 string : All except Will properties */ + MQTT_PROP_RECEIVE_MAXIMUM = 33, /* 2 byte int : CONNECT, CONNACK */ + MQTT_PROP_TOPIC_ALIAS_MAXIMUM = 34, /* 2 byte int : CONNECT, CONNACK */ + MQTT_PROP_TOPIC_ALIAS = 35, /* 2 byte int : PUBLISH */ + MQTT_PROP_MAXIMUM_QOS = 36, /* Byte : CONNACK */ + MQTT_PROP_RETAIN_AVAILABLE = 37, /* Byte : CONNACK */ + MQTT_PROP_USER_PROPERTY = 38, /* UTF-8 string pair : All */ + MQTT_PROP_MAXIMUM_PACKET_SIZE = 39, /* 4 byte int : CONNECT, CONNACK */ + MQTT_PROP_WILDCARD_SUB_AVAILABLE = 40, /* Byte : CONNACK */ + MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE = 41, /* Byte : CONNACK */ + MQTT_PROP_SHARED_SUB_AVAILABLE = 42, /* Byte : CONNACK */ +}; + +enum mqtt5_property_type { + MQTT_PROP_TYPE_BYTE = 1, + MQTT_PROP_TYPE_INT16 = 2, + MQTT_PROP_TYPE_INT32 = 3, + MQTT_PROP_TYPE_VARINT = 4, + MQTT_PROP_TYPE_BINARY = 5, + MQTT_PROP_TYPE_STRING = 6, + MQTT_PROP_TYPE_STRING_PAIR = 7 +}; + +/* Enum: mqtt5_sub_options + * Options for use with MQTTv5 subscriptions. + * + * MQTT_SUB_OPT_NO_LOCAL - with this option set, if this client publishes to + * a topic to which it is subscribed, the broker will not publish the + * message back to the client. + * + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED - with this option set, messages + * published for this subscription will keep the retain flag as was set by + * the publishing client. The default behaviour without this option set has + * the retain flag indicating whether a message is fresh/stale. + * + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS - with this option set, pre-existing + * retained messages are sent as soon as the subscription is made, even + * if the subscription already exists. This is the default behaviour, so + * it is not necessary to set this option. + * + * MQTT_SUB_OPT_SEND_RETAIN_NEW - with this option set, pre-existing retained + * messages for this subscription will be sent when the subscription is made, + * but only if the subscription does not already exist. + * + * MQTT_SUB_OPT_SEND_RETAIN_NEVER - with this option set, pre-existing + * retained messages will never be sent for this subscription. + */ +enum mqtt5_sub_options { + MQTT_SUB_OPT_NO_LOCAL = 0x04, + MQTT_SUB_OPT_RETAIN_AS_PUBLISHED = 0x08, + MQTT_SUB_OPT_SEND_RETAIN_ALWAYS = 0x00, + MQTT_SUB_OPT_SEND_RETAIN_NEW = 0x10, + MQTT_SUB_OPT_SEND_RETAIN_NEVER = 0x20, +}; + +#define MQTT_MAX_PAYLOAD 268435455U + +#endif diff --git a/threadfunc/SH_ThreadFunc.cpp b/threadfunc/SH_ThreadFunc.cpp index d013d02..f64b486 100644 --- a/threadfunc/SH_ThreadFunc.cpp +++ b/threadfunc/SH_ThreadFunc.cpp @@ -53,7 +53,10 @@ void CheckThread() if (10 == heart_count) { // StatusPub(); if (GlobalConfig::LinkCount > 30) { - //exit(0); +#ifdef IMX6UL_GATEWAY + LOG_ERROR("MQTT connect failed,reboot\n"); + exit(0); +#endif } std::string ipTemp = IpAddrInit(); GlobalConfig::IpAddr_G = ipTemp; @@ -453,7 +456,7 @@ void HeartRep() int iRet = data_publish(strJson.c_str(), GlobalConfig::Topic_G.mPubHeart.c_str()); print_info("heart = %s,iRet = %d\n",strJson.c_str(),iRet); if(iRet != 0){ - count ++; + //count ++; gpio_set(GlobalConfig::GPIO_G.errorLed,1); sleep(1); gpio_set(GlobalConfig::GPIO_G.errorLed,0); @@ -808,7 +811,7 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result) void my_disconnect_callback(struct mosquitto *mosq, void *obj, int result) { int ret = 0; - //ret = disconnect(); + ret = disconnect(); //LOG_ERROR("The MQTT connection lost:%d\n", ret); print_debug("The MQTT connection lost\n"); char gwTime[32] = { 0 }; @@ -913,7 +916,7 @@ void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *s if (level == MOSQ_LOG_ERR) { //LOG_ERROR("%s\n", str); } else if (level == MOSQ_LOG_WARNING) { - // LOG_WARN("%s\n", str); + //LOG_WARN("%s\n", str); } else if (level == MOSQ_LOG_NOTICE) { //LOG_INFO("%s\n", str); } diff --git a/uart/SH_Uart.cpp b/uart/SH_Uart.cpp index 1f16929..24567ff 100644 --- a/uart/SH_Uart.cpp +++ b/uart/SH_Uart.cpp @@ -1964,7 +1964,7 @@ void Uart::DealDataNodeFeature(const char *pData, int flag) char buf[20] = {0x00}; int nodeResend = 0; sprintf(buf, "%02x%02x", pRecvData->ShortAddr[0], pRecvData->ShortAddr[1]); - //LOG_INFO("DealDataNodeFeature %02x%02x\n",pRecvData->ShortAddr[0], pRecvData->ShortAddr[1]); + LOG_INFO("DealDataNodeFeature %02x%02x\n",pRecvData->ShortAddr[0], pRecvData->ShortAddr[1]); std::string strShortAddr = std::string(buf); print_info("zigbeeShortAddr='%s'\n", strShortAddr.c_str()); @@ -2144,7 +2144,6 @@ void Uart::DealDataNodeFeature(const char *pData, int flag) sprintf(whereCon,"StaticIndex = %d",staticIndex); int count = sql_ctl->GetTableRows(szTableNameStatic, whereCon);//避免重复数据 - sprintf(szTableNameData,"t_data_%s",strLongAddr.c_str()); int count2 = sql_ctl->GetTableRows(szTableNameData, whereCon); @@ -2155,7 +2154,6 @@ void Uart::DealDataNodeFeature(const char *pData, int flag) return; } memset(whereCon,0x00,sizeof(whereCon)); - ///////////////////////////////////////////////////////////// for V2.0.3 upgrade to V3.0 std::string strTmp = ""; char sztmp[100]={0x00}; @@ -3434,7 +3432,7 @@ void Uart::DealDataNodeFeature(const char *pData, int flag) } bZigbeeSinal = false; } - //LOG_INFO("DealDataNodeFeature end\n"); + LOG_INFO("DealDataNodeFeature end\n"); } void Uart::DealDataNodeWave(const char *pData)