diff -r 412090a6b3a7 -r a0b645a934c9 opc_ua/opcua_client_maker.py --- a/opc_ua/opcua_client_maker.py Tue Aug 23 08:39:08 2022 +0200 +++ b/opc_ua/opcua_client_maker.py Tue Sep 06 21:06:36 2022 +0200 @@ -38,6 +38,16 @@ directions = ["input", "output"] +authParams = { + "x509":[ + ("Certificate", "certificate.der"), + ("PrivateKey", "private_key.pem"), + ("Policy", "Basic256Sha256"), + ("Mode", "SignAndEncrypt")], + "UserPassword":[ + ("User", None), + ("Password", None)]} + class OPCUASubListModel(dv.DataViewIndexListModel): def __init__(self, data, log): dv.DataViewIndexListModel.__init__(self, len(data)) @@ -230,7 +240,7 @@ class OPCUAClientPanel(wx.SplitterWindow): - def __init__(self, parent, modeldata, log, uri_getter): + def __init__(self, parent, modeldata, log, config_getter): self.log = log wx.SplitterWindow.__init__(self, parent, -1) @@ -242,7 +252,7 @@ self.inout_sizer.AddGrowableRow(1) self.client = None - self.uri_getter = uri_getter + self.config_getter = config_getter self.connect_button = wx.ToggleButton(self.inout_panel, -1, "Browse Server") @@ -298,7 +308,12 @@ self.tree.SetMainColumn(0) - self.client = Client(self.uri_getter()) + config = self.config_getter() + self.client = Client(config["URI"]) + + # TODO: crypto stuff + # client.set_security_string("Basic256Sha256,SignAndEncrypt,certificate-example.der,private-key-example.pem") + self.client.connect() self.client.load_type_definitions() # load definition of server specific structures/extension objects rootnode = self.client.get_root_node() @@ -478,7 +493,7 @@ for row in data: writer.writerow([direction] + row) - def GenerateC(self, path, locstr, server_uri): + def GenerateC(self, path, locstr, config): template = """/* code generated by beremiz OPC-UA extension */ #include @@ -492,65 +507,66 @@ static C_type c_loc_name##_buf = 0; \\ C_type *c_loc_name = &c_loc_name##_buf; -%(decl)s - -void __cleanup_%(locstr)s(void) -{ +{decl} + +void __cleanup_{locstr}(void) +{{ UA_Client_disconnect(client); UA_Client_delete(client); -} +}} #define INIT_READ_VARIANT(ua_type, c_loc_name) \\ UA_Variant_init(&c_loc_name##_variant); -#define INIT_WRITE_VARIANT(ua_type, ua_type_enum, c_loc_name) \\ +#define INIT_WRITE_VARIANT(ua_type, ua_type_enum, c_loc_name) \\ UA_Variant_setScalar(&c_loc_name##_variant, (ua_type*)c_loc_name, &UA_TYPES[ua_type_enum]); -int __init_%(locstr)s(int argc,char **argv) -{ +int __init_{locstr}(int argc,char **argv) +{{ UA_StatusCode retval; client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); -%(init)s +{init} /* Connect to server */ - retval = UA_Client_connect(client, "%(uri)s"); - if(retval != UA_STATUSCODE_GOOD) { + retval = UA_Client_connect(client, "{uri}"); + if(retval != UA_STATUSCODE_GOOD) {{ UA_Client_delete(client); return EXIT_FAILURE; - } -} + }} +}} #define READ_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \\ retval = UA_Client_readValueAttribute( \\ client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant); \\ if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(&c_loc_name##_variant) && \\ - c_loc_name##_variant.type == &UA_TYPES[ua_type_enum]) { \\ + c_loc_name##_variant.type == &UA_TYPES[ua_type_enum]) {{ \\ c_loc_name##_buf = *(ua_type*)c_loc_name##_variant.data; \\ UA_Variant_clear(&c_loc_name##_variant); /* Unalloc requiered on each read ! */ \\ - } - -void __retrieve_%(locstr)s(void) -{ + }} + +void __retrieve_{locstr}(void) +{{ UA_StatusCode retval; -%(retrieve)s -} - -#define WRITE_VALUE(ua_type, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \\ +{retrieve} +}} + +#define WRITE_VALUE(ua_type, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \\ UA_Client_writeValueAttribute( \\ client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant); -void __publish_%(locstr)s(void) -{ -%(publish)s -} +void __publish_{locstr}(void) +{{ +{publish} +}} """ formatdict = dict( locstr = locstr, - uri = server_uri, + uri = config["URI"], + # TODO: pass authentication code. decl = "", cleanup = "", init = "", @@ -581,7 +597,7 @@ formatdict["publish"] += """ WRITE_VALUE({ua_type}, {c_loc_name}, {ua_nodeid_type}, {ua_nsidx}, {ua_node_id})""".format(**locals()) - Ccode = template%formatdict + Ccode = template.format(**formatdict) return Ccode @@ -594,7 +610,20 @@ frame = wx.Frame(None, -1, "OPCUA Client Test App", size=(800,600)) - uri = sys.argv[1] if len(sys.argv)>1 else "opc.tcp://localhost:4840" + argc = len(sys.argv) + + config={} + config["URI"] = sys.argv[1] if argc>1 else "opc.tcp://localhost:4840" + + if argc > 2: + AuthType = sys.argv[2] + config["AuthType"] = AuthType + for (name, default), value in izip_longest(authParams[AuthType], sys.argv[3:]): + if value is None: + if default is None: + raise Exception(name+" param expected") + value = default + config[name] = value test_panel = wx.Panel(frame) test_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) @@ -603,7 +632,7 @@ modeldata = OPCUAClientModel(print) - opcuatestpanel = OPCUAClientPanel(test_panel, modeldata, print, lambda:uri) + opcuatestpanel = OPCUAClientPanel(test_panel, modeldata, print, lambda:config) def OnGenerate(evt): dlg = wx.FileDialog( @@ -624,7 +653,7 @@ -I ../../open62541/arch/ ../../open62541/build/bin/libopen62541.a */ -"""%(path, path[:-2]) + modeldata.GenerateC(path, "test", uri) + """ +"""%(path, path[:-2]) + modeldata.GenerateC(path, "test", config) + """ int main(int argc, char *argv[]) {