# HG changeset patch # User Edouard Tisserant # Date 1718373372 -7200 # Node ID 96acfee19caf4d4fed2be675fbaa472cb50be3c7 # Parent 76295adcf94034f0326da2153e9a8728462a3ac0 MQTT WIP: intermediate state, implementing MQTT client C code generator. diff -r 76295adcf940 -r 96acfee19caf mqtt/client.py --- a/mqtt/client.py Wed Jun 12 11:45:09 2024 +0200 +++ b/mqtt/client.py Fri Jun 14 15:56:12 2024 +0200 @@ -50,6 +50,7 @@ + @@ -79,7 +80,7 @@ return attr["value"] AuthType = cfg("AuthType") - res = dict(URI=cfg("Broker_URI"), AuthType=AuthType) + res = dict(URI=cfg("Broker_URI"), AuthType=AuthType, clientID=cfg("Client_ID")) paramList = authParams.get(AuthType, None) if paramList: diff -r 76295adcf940 -r 96acfee19caf mqtt/mqtt_client_gen.py --- a/mqtt/mqtt_client_gen.py Wed Jun 12 11:45:09 2024 +0200 +++ b/mqtt/mqtt_client_gen.py Fri Jun 14 15:56:12 2024 +0200 @@ -32,10 +32,16 @@ """ QoS_values = [0, 1, 2] -lstcolnames = [ "Topic", "QoS", "Type", "Location"] -lstcolwidths = [ 100, 50, 100, 50] -lstcoltypess = [ str, int, str, int] -lstcoldeflts = [ "a/b/c", "1", "DINT", "0"] +def boolean(v): + if v in ["False","0"]: + return False + else: + return bool(v) + +lstcolnames = [ "Topic", "QoS", "Retain", "Type", "Location"] +lstcolwidths = [ 100, 50, 100, 100, 50] +lstcoltypess = [ str, int, boolean, str, int] +lstcoldeflts = [ "a/b/c", "1", False, "DINT", "0"] Location_column = lstcolnames.index("Location") directions = ["input", "output"] @@ -48,7 +54,7 @@ ("User", None), ("Password", None)]} -class MQTTSubListModel(dv.PyDataViewIndexListModel): +class MQTTTopicListModel(dv.PyDataViewIndexListModel): def __init__(self, data, log): dv.PyDataViewIndexListModel.__init__(self, len(data)) self.data = data @@ -121,7 +127,7 @@ def ResetData(self): self.Reset(len(self.data)) -class MQTTSubListPanel(wx.Panel): +class MQTTTopicListPanel(wx.Panel): def __init__(self, parent, log, model, direction): self.log = log wx.Panel.__init__(self, parent, -1) @@ -188,8 +194,8 @@ self.selected_splitter = wx.SplitterWindow(self, style=wx.SUNKEN_BORDER | wx.SP_3D) self.selected_datas = modeldata - self.selected_models = { direction:MQTTSubListModel(self.selected_datas[direction], log) for direction in directions } - self.selected_lists = { direction:MQTTSubListPanel( + self.selected_models = { direction:MQTTTopicListModel(self.selected_datas[direction], log) for direction in directions } + self.selected_lists = { direction:MQTTTopicListPanel( self.selected_splitter, log, self.selected_models[direction], direction) for direction in directions } @@ -283,14 +289,8 @@ def GenerateC(self, path, locstr, config): template = """/* code generated by beremiz MQTT extension */ -#include -#include -#include -#include -#include - -#include -#include +#include "MQTTAsync.h" +#include "MQTTClientPersistence.h" #define _Log(level, ...) \\ {{ \\ @@ -303,38 +303,40 @@ #define LogError(...) _Log(LOG_CRITICAL, __VA_ARGS__); #define LogWarning(...) _Log(LOG_WARNING, __VA_ARGS__); -static MQTT_INLINE MQTT_ByteString -loadFile(const char *const path) {{ - MQTT_ByteString fileContents = MQTT_STRING_NULL; +static inline void* loadFile(const char *const path) {{ FILE *fp = fopen(path, "rb"); if(!fp) {{ errno = 0; - LogError("OPC-MQTT could not open %s", path); - return fileContents; + LogError("MQTT could not open %s", path); + return NULL; }} fseek(fp, 0, SEEK_END); - fileContents.length = (size_t)ftell(fp); - fileContents.data = (MQTT_Byte *)MQTT_malloc(fileContents.length * sizeof(MQTT_Byte)); - if(fileContents.data) {{ + size_t length = (size_t)ftell(fp); + void* data = malloc(length); + if(data) {{ fseek(fp, 0, SEEK_SET); - size_t read = fread(fileContents.data, sizeof(MQTT_Byte), fileContents.length, fp); - if(read != fileContents.length){{ - MQTT_ByteString_clear(&fileContents); - LogError("OPC-MQTT could not read %s", path); + size_t read = fread(data, 1, fileContents.length, fp); + if(read != length){{ + free(data); + LogError("MQTT could not read %s", path); }} }} else {{ - fileContents.length = 0; - LogError("OPC-MQTT Not enough memoty to load %s", path); + LogError("MQTT Not enough memoty to load %s", path); }} fclose(fp); - return fileContents; + return data; }} -static MQTT_Client *client; -static MQTT_ClientConfig *cc; +static MQTTClient client; +static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; + +void trace_callback(enum MQTTASYNC_TRACE_LEVELS level, char* message) +{ + LogWarning("Paho MQTT Trace : %d, %s\n", level, message); +} #define DECL_VAR(ua_type, C_type, c_loc_name) \\ static MQTT_Variant c_loc_name##_variant; \\ @@ -350,13 +352,13 @@ }} #define INIT_NoAuth() \\ - LogInfo("OPC-MQTT Init no auth"); \\ + LogInfo("MQTT Init no auth"); \\ MQTT_ClientConfig_setDefault(cc); \\ retval = MQTT_Client_connect(client, uri); /* Note : Single policy is enforced here, by default open62541 client supports all policies */ #define INIT_x509(Policy, UpperCaseMode, PrivateKey, Certificate) \\ - LogInfo("OPC-MQTT Init x509 %s,%s,%s,%s", #Policy, #UpperCaseMode, PrivateKey, Certificate); \\ + LogInfo("MQTT Init x509 %s,%s,%s,%s", #Policy, #UpperCaseMode, PrivateKey, Certificate); \\ \\ MQTT_ByteString certificate = loadFile(Certificate); \\ MQTT_ByteString privateKey = loadFile(PrivateKey); \\ @@ -398,7 +400,7 @@ MQTT_ByteString_clear(&privateKey); #define INIT_UserPassword(User, Password) \\ - LogInfo("OPC-MQTT Init UserPassword %s,%s", User, Password); \\ + LogInfo("MQTT Init UserPassword %s,%s", User, Password); \\ MQTT_ClientConfig_setDefault(cc); \\ retval = MQTT_Client_connectUsername(client, uri, User, Password); @@ -410,14 +412,23 @@ int __init_{locstr}(int argc,char **argv) {{ - MQTT_StatusCode retval; - client = MQTT_Client_new(); - cc = MQTT_Client_getConfig(client); char *uri = "{uri}"; + char *clientID = "{clientID}"; + int rc; + conn_opts = MQTTClient_connectOptions_initializer; + + if ((rc = MQTTClient_create(&client, uri, clientID, + MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) + { + printf("Failed to create client, return code %d\n", rc); + rc = EXIT_FAILURE; + goto exit; + } + {init} if(retval != MQTT_STATUSCODE_GOOD) {{ - LogError("OPC-MQTT Init Failed %d", retval); + LogError("MQTT Init Failed %d", retval); MQTT_Client_delete(client); return EXIT_FAILURE; }} @@ -453,6 +464,7 @@ formatdict = dict( locstr = locstr, uri = config["URI"], + clientID = config["clientID"], decl = "", cleanup = "", init = "", @@ -511,13 +523,14 @@ argc = len(sys.argv) config={} - config["URI"] = sys.argv[1] if argc>1 else "opc.tcp://localhost:4840" + config["URI"] = sys.argv[1] if argc>1 else "tcp://localhost:1883" + config["clientID"] = sys.argv[2] if argc>2 else "" config["AuthType"] = None - if argc > 2: - AuthType = sys.argv[2] + if argc > 3: + AuthType = sys.argv[3] config["AuthType"] = AuthType - for (name, default), value in zip_longest(authParams[AuthType], sys.argv[3:]): + for (name, default), value in zip_longest(authParams[AuthType], sys.argv[4:]): if value is None: if default is None: raise Exception(name+" param expected")