mqtt/mqtt_client_gen.py
changeset 3986 98bd0bb33ce4
parent 3984 883a85b9ebcc
child 3987 cec48fc7ccd0
equal deleted inserted replaced
3985:d0c5d77a33af 3986:98bd0bb33ce4
   328 #include <pthread.h>
   328 #include <pthread.h>
   329 
   329 
   330 #include "MQTTClient.h"
   330 #include "MQTTClient.h"
   331 #include "MQTTClientPersistence.h"
   331 #include "MQTTClientPersistence.h"
   332 
   332 
   333 #define _Log(level, ...)                                                                           \\
   333 #define _Log(level, ...)                                                                          \\
   334     {{                                                                                             \\
   334     {{                                                                                            \\
   335         /* char mstr[256];                          */                                            \\
   335         /* char mstr[256];                          */                                            \\
   336         /* snprintf(mstr, 255, __VA_ARGS__);        */                                            \\
   336         /* snprintf(mstr, 255, __VA_ARGS__);        */                                            \\
   337         /* LogMessage(level, mstr, strlen(mstr));   */                                            \\
   337         /* LogMessage(level, mstr, strlen(mstr));   */                                            \\
   338         printf(__VA_ARGS__);                                                          \\
   338         printf(__VA_ARGS__);                                                                      \\
   339     }}
   339     }}
   340 
   340 
   341 #define LogInfo(...) _Log(LOG_INFO, __VA_ARGS__);
   341 #define LogInfo(...) _Log(LOG_INFO, __VA_ARGS__);
   342 #define LogError(...) _Log(LOG_CRITICAL, __VA_ARGS__);
   342 #define LogError(...) _Log(LOG_CRITICAL, __VA_ARGS__);
   343 #define LogWarning(...) _Log(LOG_WARNING, __VA_ARGS__);
   343 #define LogWarning(...) _Log(LOG_WARNING, __VA_ARGS__);
   344 
       
   345 static MQTTClient client;
       
   346 static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer5;
       
   347 static pthread_mutex_t clientMutex;  // mutex to keep PLC data consistent
       
   348 
   344 
   349 void trace_callback(enum MQTTCLIENT_TRACE_LEVELS level, char* message)
   345 void trace_callback(enum MQTTCLIENT_TRACE_LEVELS level, char* message)
   350 {{
   346 {{
   351     LogWarning("Paho MQTT Trace : %d, %s\\n", level, message);
   347     LogWarning("Paho MQTT Trace : %d, %s\\n", level, message);
   352 }}
   348 }}
   356 static C_type MQTT_##c_loc_name##_buf = 0;                                                         \\
   352 static C_type MQTT_##c_loc_name##_buf = 0;                                                         \\
   357 C_type *c_loc_name = &PLC_##c_loc_name##_buf;
   353 C_type *c_loc_name = &PLC_##c_loc_name##_buf;
   358 
   354 
   359 {decl}
   355 {decl}
   360 
   356 
   361 #define INIT_TOPIC(topic, iec_type, c_loc_name)                                            \\
   357 static MQTTClient client;
       
   358 #ifdef USE_MQTT_5
       
   359 static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer5;
       
   360 #else
       
   361 static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
       
   362 #endif
       
   363 static pthread_mutex_t clientMutex;  // mutex to keep PLC data consistent
       
   364 
       
   365 #define INIT_TOPIC(topic, iec_type, c_loc_name)                                                    \\
   362 {{#topic, &MQTT_##c_loc_name##_buf, iec_type##_ENUM}},
   366 {{#topic, &MQTT_##c_loc_name##_buf, iec_type##_ENUM}},
   363 
   367 
   364 static struct {{
   368 static struct {{
   365     const char *topic; //null terminated topic string
   369     const char *topic; //null terminated topic string
   366     void *mqtt_pdata; //data from/for MQTT stack
   370     void *mqtt_pdata; //data from/for MQTT stack
   370 }};
   374 }};
   371 
   375 
   372 static int _connect_mqtt(void)
   376 static int _connect_mqtt(void)
   373 {{
   377 {{
   374     int rc;
   378     int rc;
       
   379 
       
   380 #ifdef USE_MQTT_5
   375     MQTTProperties props = MQTTProperties_initializer;
   381     MQTTProperties props = MQTTProperties_initializer;
   376     MQTTProperties willProps = MQTTProperties_initializer;
   382     MQTTProperties willProps = MQTTProperties_initializer;
   377     MQTTResponse response = MQTTResponse_initializer;
   383     MQTTResponse response = MQTTResponse_initializer;
   378 
   384 
   379     response = MQTTClient_connect5(client, &conn_opts, &props, &willProps);
   385     response = MQTTClient_connect5(client, &conn_opts, &props, &willProps);
   380     rc = response.reasonCode;
   386     rc = response.reasonCode;
   381     MQTTResponse_free(response);
   387     MQTTResponse_free(response);
       
   388 #else
       
   389     rc = MQTTClient_connect(client, &conn_opts);
       
   390 #endif
   382 
   391 
   383 	return rc;
   392 	return rc;
   384 }}
   393 }}
   385 
   394 
   386 void __cleanup_{locstr}(void)
   395 void __cleanup_{locstr}(void)
   387 {{
   396 {{
   388     int rc;
   397     int rc;
   389 
   398 
   390     /* TODO stop publish thread */
   399     /* TODO stop publish thread */
   391 
   400 
       
   401 #ifdef USE_MQTT_5
   392     if (rc = MQTTClient_disconnect5(client, 5000, MQTTREASONCODE_SUCCESS, NULL) != MQTTCLIENT_SUCCESS)
   402     if (rc = MQTTClient_disconnect5(client, 5000, MQTTREASONCODE_SUCCESS, NULL) != MQTTCLIENT_SUCCESS)
       
   403 #else
       
   404     if (rc = MQTTClient_disconnect(client, 5000) != MQTTCLIENT_SUCCESS)
       
   405 #endif
   393     {{
   406     {{
   394         LogError("MQTT Failed to disconnect, return code %d\\n", rc);
   407         LogError("MQTT Failed to disconnect, return code %d\\n", rc);
   395     }}
   408     }}
   396     MQTTClient_destroy(&client);
   409     MQTTClient_destroy(&client);
   397 }}
   410 }}
   413     MQTTClient_free(topicName);
   426     MQTTClient_free(topicName);
   414     return 1;
   427     return 1;
   415 }}
   428 }}
   416 
   429 
   417 #define INIT_NoAuth()                                                                             \\
   430 #define INIT_NoAuth()                                                                             \\
   418     LogInfo("MQTT Init no auth");
   431     LogInfo("MQTT Init no auth\\n");
   419 
   432 
   420 #define INIT_x509(PrivateKey, Certificate)                                                        \\
   433 #define INIT_x509(PrivateKey, Certificate)                                                        \\
   421     LogInfo("MQTT Init x509 %s,%s", PrivateKey, Certificate);
   434     LogInfo("MQTT Init x509 %s,%s\\n", PrivateKey, Certificate);
   422     /* TODO */
   435     /* TODO */
   423 
   436 
   424 #define INIT_UserPassword(User, Password)                                                         \\
   437 #define INIT_UserPassword(User, Password)                                                         \\
   425     LogInfo("MQTT Init UserPassword %s,%s", User, Password);                                      \\
   438     LogInfo("MQTT Init UserPassword %s,%s\\n", User, Password);                                   \\
   426 	conn_opts.username = User;                                                                    \\
   439 	conn_opts.username = User;                                                                    \\
   427 	conn_opts.password = Password;
   440 	conn_opts.password = Password;
   428 
   441 
       
   442 #ifdef USE_MQTT_5
       
   443 #define MY_SUBSCRIBE(Topic, QoS)                                                                  \\
       
   444         MQTTResponse response = MQTTClient_subscribe5(client, #Topic, QoS, NULL, NULL);           \\
       
   445         rc = response.reasonCode;                                                                 \\
       
   446         MQTTResponse_free(response);
       
   447 #else
       
   448 #define MY_SUBSCRIBE(Topic, QoS)                                                                  \\
       
   449         rc = MQTTClient_subscribe(client, #Topic, QoS);
       
   450 #endif
       
   451 
   429 #define INIT_SUBSCRIPTION(Topic, QoS)                                                             \\
   452 #define INIT_SUBSCRIPTION(Topic, QoS)                                                             \\
   430     {{                                                                                            \\
   453     {{                                                                                            \\
   431         MQTTResponse response = MQTTClient_subscribe5(client, #Topic, QoS, NULL, NULL);            \\
   454         MY_SUBSCRIBE(Topic, QoS)                                                                  \\
   432         rc = response.reasonCode;                                                                 \\
       
   433         MQTTResponse_free(response);                                                              \\
       
   434         if (rc != MQTTCLIENT_SUCCESS)                                                             \\
   455         if (rc != MQTTCLIENT_SUCCESS)                                                             \\
   435         {{                                                                                        \\
   456         {{                                                                                        \\
   436             LogError("MQTT client failed to subscribe to '%s', return code %d\\n", #Topic, rc);\\
   457             LogError("MQTT client failed to subscribe to '%s', return code %d\\n", #Topic, rc);   \\
   437         }}                                                                                        \\
   458         }}                                                                                        \\
   438     }}
   459     }}
   439 
   460 
   440 int __init_{locstr}(int argc,char **argv)
   461 int __init_{locstr}(int argc,char **argv)
   441 {{
   462 {{
   443     char *clientID = "{clientID}";
   464     char *clientID = "{clientID}";
   444     int rc;
   465     int rc;
   445 
   466 
   446 	MQTTClient_createOptions createOpts = MQTTClient_createOptions_initializer;
   467 	MQTTClient_createOptions createOpts = MQTTClient_createOptions_initializer;
   447 
   468 
       
   469 #ifdef USE_MQTT_5
   448 	conn_opts.MQTTVersion = MQTTVERSION_5;
   470 	conn_opts.MQTTVersion = MQTTVERSION_5;
   449     conn_opts.cleanstart = 1;
   471     conn_opts.cleanstart = 1;
   450 
   472 
   451     createOpts.MQTTVersion = MQTTVERSION_5;
   473     createOpts.MQTTVersion = MQTTVERSION_5;
       
   474 #else
       
   475 	conn_opts.cleansession = 1;
       
   476 #endif
   452 
   477 
   453     MQTTClient_setTraceCallback(trace_callback);
   478     MQTTClient_setTraceCallback(trace_callback);
   454     MQTTClient_setTraceLevel(MQTTCLIENT_TRACE_ERROR);
   479     MQTTClient_setTraceLevel(MQTTCLIENT_TRACE_ERROR);
   455 
   480 
   456 
   481 
   463     }}
   488     }}
   464 
   489 
   465 	rc = MQTTClient_setCallbacks(client, NULL, connectionLost, messageArrived, NULL);
   490 	rc = MQTTClient_setCallbacks(client, NULL, connectionLost, messageArrived, NULL);
   466 	if (rc != MQTTCLIENT_SUCCESS)
   491 	if (rc != MQTTCLIENT_SUCCESS)
   467 	{{
   492 	{{
   468         LogError("MQTT Failed to set callbacks %d", rc);
   493         LogError("MQTT Failed to set callbacks, return code %d\\n", rc);
   469         return rc;
   494         return rc;
   470 	}}
   495 	}}
   471 
   496 
   472 {init}
       
   473 
       
   474 	rc = _connect_mqtt();
   497 	rc = _connect_mqtt();
   475 
   498 
   476 	if (rc != MQTTCLIENT_SUCCESS) {{
   499 	if (rc != MQTTCLIENT_SUCCESS) {{
   477         LogError("MQTT Init Failed %d", rc);
   500         LogError("MQTT Connect Failed, return code %d\\n", rc);
   478         return rc;
   501         return rc;
   479     }}
   502     }}
       
   503 
       
   504 {init}
       
   505 
   480     /* TODO start publish thread */
   506     /* TODO start publish thread */
   481 
   507 
   482     return 0;
   508     return 0;
   483 }}
   509 }}
   484 
   510 
   502     /* TODO free mutex */
   528     /* TODO free mutex */
   503     /* TODO unblock publish thread */
   529     /* TODO unblock publish thread */
   504 }}
   530 }}
   505 
   531 
   506 """
   532 """
   507         
   533 
   508         formatdict = dict(
   534         formatdict = dict(
   509             locstr   = locstr,
   535             locstr   = locstr,
   510             uri      = config["URI"],
   536             uri      = config["URI"],
   511             clientID = config["clientID"],
   537             clientID = config["clientID"],
   512             decl     = "",
   538             decl     = "",
   513             topics   = "",
   539             topics   = "",
   514             cleanup  = "",
   540             cleanup  = "",
   515             init     = "",
   541             init     = "",
   516             retrieve = "",
   542             retrieve = "",
   517             publish  = "" 
   543             publish  = ""
   518         )
   544         )
       
   545 
       
   546 
       
   547         # Use Config's "MQTTVersion" to switch between protocol version at build time
       
   548         if config["UseMQTT5"]:
       
   549             formatdict["decl"] += """
       
   550 #define USE_MQTT_5""".format(**config)
   519 
   551 
   520         AuthType = config["AuthType"]
   552         AuthType = config["AuthType"]
   521         if AuthType == "x509":
   553         if AuthType == "x509":
   522             formatdict["init"] += """
   554             formatdict["init"] += """
   523     INIT_x509("{PrivateKey}", "{Certificate}")""".format(**config)
   555     INIT_x509("{PrivateKey}", "{Certificate}")""".format(**config)
   547     INIT_SUBSCRIPTION({Topic}, {QoS})""".format(**locals())
   579     INIT_SUBSCRIPTION({Topic}, {QoS})""".format(**locals())
   548                     formatdict["retrieve"] += """
   580                     formatdict["retrieve"] += """
   549     READ_VALUE({c_loc_name}, {C_type})""".format(**locals())
   581     READ_VALUE({c_loc_name}, {C_type})""".format(**locals())
   550 
   582 
   551                 if direction == "output":
   583                 if direction == "output":
       
   584                     # TODO: publish at init
   552                     # formatdict["init"] += " NOTHING ! publish doesn't need init. "
   585                     # formatdict["init"] += " NOTHING ! publish doesn't need init. "
   553                     formatdict["publish"] += """
   586                     formatdict["publish"] += """
   554     WRITE_VALUE({c_loc_name}, {C_type})""".format(**locals())
   587     WRITE_VALUE({c_loc_name}, {C_type})""".format(**locals())
   555 
   588 
   556         Ccode = template.format(**formatdict)
   589         Ccode = template.format(**formatdict)
   557         
   590 
   558         return Ccode
   591         return Ccode
   559 
   592 
   560 if __name__ == "__main__":
   593 if __name__ == "__main__":
   561 
   594 
   562     import wx.lib.mixins.inspection as wit
   595     import wx.lib.mixins.inspection as wit
   570 
   603 
   571     config={}
   604     config={}
   572     config["URI"] = sys.argv[1] if argc>1 else "tcp://localhost:1883"
   605     config["URI"] = sys.argv[1] if argc>1 else "tcp://localhost:1883"
   573     config["clientID"] = sys.argv[2] if argc>2 else ""
   606     config["clientID"] = sys.argv[2] if argc>2 else ""
   574     config["AuthType"] = None
   607     config["AuthType"] = None
       
   608     config["UseMQTT5"] = True
   575 
   609 
   576     if argc > 3:
   610     if argc > 3:
   577         AuthType = sys.argv[3]
   611         AuthType = sys.argv[3]
   578         config["AuthType"] = AuthType
   612         config["AuthType"] = AuthType
   579         for (name, default), value in zip_longest(authParams[AuthType], sys.argv[4:]):
   613         for (name, default), value in zip_longest(authParams[AuthType], sys.argv[4:]):
   593     mqtttestpanel = MQTTClientPanel(test_panel, modeldata, print, lambda:config)
   627     mqtttestpanel = MQTTClientPanel(test_panel, modeldata, print, lambda:config)
   594 
   628 
   595     def OnGenerate(evt):
   629     def OnGenerate(evt):
   596         dlg = wx.FileDialog(
   630         dlg = wx.FileDialog(
   597             frame, message="Generate file as ...", defaultDir=os.getcwd(),
   631             frame, message="Generate file as ...", defaultDir=os.getcwd(),
   598             defaultFile="", 
   632             defaultFile="",
   599             wildcard="C (*.c)|*.c", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
   633             wildcard="C (*.c)|*.c", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
   600             )
   634             )
   601 
   635 
   602         if dlg.ShowModal() == wx.ID_OK:
   636         if dlg.ShowModal() == wx.ID_OK:
   603             path = dlg.GetPath()
   637             path = dlg.GetPath()
   618 };
   652 };
   619 
   653 
   620 int main(int argc, char *argv[]) {
   654 int main(int argc, char *argv[]) {
   621 
   655 
   622     __init_test(arc,argv);
   656     __init_test(arc,argv);
   623    
   657 
   624     __retrieve_test();
   658     __retrieve_test();
   625    
   659 
   626     __publish_test();
   660     __publish_test();
   627 
   661 
   628     __cleanup_test();
   662     __cleanup_test();
   629 
   663 
   630     return EXIT_SUCCESS;
   664     return EXIT_SUCCESS;
   653         dlg.Destroy()
   687         dlg.Destroy()
   654 
   688 
   655     def OnSave(evt):
   689     def OnSave(evt):
   656         dlg = wx.FileDialog(
   690         dlg = wx.FileDialog(
   657             frame, message="Save file as ...", defaultDir=os.getcwd(),
   691             frame, message="Save file as ...", defaultDir=os.getcwd(),
   658             defaultFile="", 
   692             defaultFile="",
   659             wildcard="CSV (*.csv)|*.csv", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
   693             wildcard="CSV (*.csv)|*.csv", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
   660             )
   694             )
   661 
   695 
   662         if dlg.ShowModal() == wx.ID_OK:
   696         if dlg.ShowModal() == wx.ID_OK:
   663             path = dlg.GetPath()
   697             path = dlg.GetPath()