Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | minor update in topcua subtree |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3461a2287ee6bbc198035f41678880ff |
User & Date: | chw 2018-09-13 08:45:04.636 |
Context
2018-09-13
| ||
16:44 | some fixes in tkpath for MacOSX (observed on high sierra) check-in: 745a6479d3 user: chw tags: trunk | |
08:45 | minor update in topcua subtree check-in: 3461a2287e user: chw tags: trunk | |
2018-09-12
| ||
08:43 | add selected tcllib upstream changes check-in: 898ffc44fd user: chw tags: trunk | |
Changes
Changes to jni/topcua/doc/opcua.n.
︙ | ︙ | |||
479 480 481 482 483 484 485 | \fIOutputArguments\fR child nodes are retrieved and stub procedures are written using the browse path and argument information. .TP \fBopcua gentypes\fR \fIhandle\fR . Generates custom data type mappings using information obtained from analyzing the address space derived from the client or server object \fIhandle\fR. | | | | | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | \fIOutputArguments\fR child nodes are retrieved and stub procedures are written using the browse path and argument information. .TP \fBopcua gentypes\fR \fIhandle\fR . Generates custom data type mappings using information obtained from analyzing the address space derived from the client or server object \fIhandle\fR. This feature is highly experimental and requires the tDOM package for parsing XML. It can create encoders/decoders for simple structure data types defined in the address space which perform a mapping from/to tcl dictionaries. For further information, see the server_types.tcl and client_types.tcl scripts in the examples directory. If this command is used, it should be invoked prior to creating method stubs, since methods may require custom data types in their arguments. .TP \fBopcua info\fR ?\fIhandle\fR? . |
︙ | ︙ | |||
553 554 555 556 557 558 559 560 561 562 563 564 565 566 | method stub procedures and other information. That namespace is tied to the life time of the client or server object. .TP \fBopcua parent\fR \fIhandle nodeid\fR . Returns the parent node identifier of the given node identifier \fInodeid\fR on the client or server object \fIhandle\fR. .TP \fBopcua read\fR \fIhandle nodeid\fR ?\fIattr\fR? . Performs a read operation on the client or server object \fIhandle\fR and returns the value of attribute \fIattr\fR of the node identifier \fInodeid\fR. If \fIattr\fR is omitted, it defaults to the \fIValue\fR attribute. | > > > > > > > > > > > > > > > > > | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | method stub procedures and other information. That namespace is tied to the life time of the client or server object. .TP \fBopcua parent\fR \fIhandle nodeid\fR . Returns the parent node identifier of the given node identifier \fInodeid\fR on the client or server object \fIhandle\fR. .TP \fBopcua ptree\fR \fIhandle\fR ?\fInodeid\fR? . Returns information similar to \fBopcua tree\fR using the client or server object \fIhandle\fR. The address space is traversed starting at the node identifier \fInodeid\fR (the root node if omitted). The result list is made up of browse path name, node identifier, node class path, reference node identier, and type node identifier. The browse path name is a path name like notation made up of the browse names pointing to the final node as seen from the starting node. Browse names are written as qualified names, i.e. including the numeric namespace index if not in root namespace. Similarly, the node class path is a path name like notation made up of the node classes of all nodes along the path. The \fBopcua ptree\fR command is used internally by the \fBopcua genstubs\fR command in order to filter out objects and methods when creating stub Tcl commands to invoke methods on objects. .TP \fBopcua read\fR \fIhandle nodeid\fR ?\fIattr\fR? . Performs a read operation on the client or server object \fIhandle\fR and returns the value of attribute \fIattr\fR of the node identifier \fInodeid\fR. If \fIattr\fR is omitted, it defaults to the \fIValue\fR attribute. |
︙ | ︙ | |||
645 646 647 648 649 650 651 | their direction. A reference may be abbreviated as slash for \fIHierarchicalReferences\fR or as dot for \fIAggregates\fR. .TP \fBopcua tree\fR \fIhandle\fR ?\fInodeid\fR? . Returns information similar to \fBopcua browse\fR using the client or server object \fIhandle\fR. The address space is traversed starting | | | 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | their direction. A reference may be abbreviated as slash for \fIHierarchicalReferences\fR or as dot for \fIAggregates\fR. .TP \fBopcua tree\fR \fIhandle\fR ?\fInodeid\fR? . Returns information similar to \fBopcua browse\fR using the client or server object \fIhandle\fR. The address space is traversed starting at the node identifier \fInodeid\fR (the root node if omitted). The result list is made up of tree level (0-based), node identifier, browse name (qualified name), display name (locale and text), node class, reference node identifier, and type node identifier. .TP \fBopcua type\fR \fIhandle nodeid\fR ?\fIattr\fR? . Performs a read operation on the client or server object \fIhandle\fR |
︙ | ︙ |
Changes to jni/topcua/topcua.c.
1 2 3 4 | /* * topcua.c -- * * This file contains a proof of concept Tcl binding to the | | | 1 2 3 4 5 6 7 8 9 10 11 12 | /* * topcua.c -- * * This file contains a proof of concept Tcl binding to the * open62541 OPC/UA library (client and server). * * Copyright (c) 2018 Christian Werner <chw at ch minus werner dot de> * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ |
︙ | ︙ | |||
71 72 73 74 75 76 77 | int nCmdObjs; /* For the Tcl callback. */ Tcl_Obj **cmdObjs; /* Ditto. */ int nSavedCmdObjs; /* Ditto. */ Tcl_Obj **savedCmdObjs; /* Ditto. */ } UAQ; /* | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | int nCmdObjs; /* For the Tcl callback. */ Tcl_Obj **cmdObjs; /* Ditto. */ int nSavedCmdObjs; /* Ditto. */ Tcl_Obj **savedCmdObjs; /* Ditto. */ } UAQ; /* * Structure representing an OPC/UA client or server. */ typedef struct UAH { struct UAI *uai; /* Pointer to per-interp data. */ Tcl_Interp *interp; /* Interpreter for the client. */ UA_Client *client; /* Client connection handle. */ UA_Server *server; /* Server handle. */ |
︙ | ︙ | |||
1069 1070 1071 1072 1073 1074 1075 | g->data4[4] = d[7]; g->data4[5] = d[8]; g->data4[6] = d[9]; g->data4[7] = d[10]; break; } case UA_NODEIDTYPE_BYTESTRING: | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 | g->data4[4] = d[7]; g->data4[5] = d[8]; g->data4[6] = d[9]; g->data4[7] = d[10]; break; } case UA_NODEIDTYPE_BYTESTRING: if ((string[0] == '0') && (string[1] == 'x')) { UA_ByteString *bs = &nodein->identifier.byteString; char buffer[3]; int v; Tcl_DString ds; Tcl_DStringInit(&ds); string += 2; while (1) { buffer[0] = string[0]; if (string[0] == '\0') { break; } buffer[1] = string[1]; if (string[1] == '\0') { break; } buffer[2] = '\0'; if (sscanf(buffer, "%x", &v) != 1) { break; } buffer[0] = v; Tcl_DStringAppend(&ds, buffer, 1); string += 2; } bs->length = Tcl_DStringLength(&ds); if (bs->length > 0) { bs->data = (UA_Byte *) UA_malloc(bs->length); if (bs->data == NULL) { bs->length = 0; bs->data = (UA_Byte *) UA_EMPTY_ARRAY_SENTINEL; } else { memcpy(bs->data, Tcl_DStringValue(&ds), bs->length); } } else { bs->data = (UA_Byte *) UA_EMPTY_ARRAY_SENTINEL; } Tcl_DStringFree(&ds); } else { UA_ByteString *bs = &nodein->identifier.byteString; bs->length = strlen(string); if (bs->length > 0) { bs->data = (UA_Byte *) UA_malloc(bs->length); if (bs->data == NULL) { bs->length = 0; bs->data = (UA_Byte *) UA_EMPTY_ARRAY_SENTINEL; } else { memcpy(bs->data, string, bs->length); } } else { bs->data = (UA_Byte *) UA_EMPTY_ARRAY_SENTINEL; } } goto error; } return nodein; error: if (interp != NULL) { Tcl_Obj *list[4]; UA_StatusCode uaret = UA_STATUSCODE_BADINTERNALERROR; |
︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 | * *------------------------------------------------------------------------- */ static char * PrintNodeId(const UA_NodeId *nodein, Tcl_DString *dsPtr) { char buffer[64]; Tcl_DStringInit(dsPtr); if (nodein->namespaceIndex) { sprintf(buffer, "ns=%d;", nodein->namespaceIndex); Tcl_DStringAppend(dsPtr, buffer, -1); } | > | 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 | * *------------------------------------------------------------------------- */ static char * PrintNodeId(const UA_NodeId *nodein, Tcl_DString *dsPtr) { size_t i; char buffer[64]; Tcl_DStringInit(dsPtr); if (nodein->namespaceIndex) { sprintf(buffer, "ns=%d;", nodein->namespaceIndex); Tcl_DStringAppend(dsPtr, buffer, -1); } |
︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | nodein->identifier.guid.data4[4], nodein->identifier.guid.data4[5], nodein->identifier.guid.data4[6], nodein->identifier.guid.data4[7]); Tcl_DStringAppend(dsPtr, buffer, -1); break; case UA_NODEIDTYPE_BYTESTRING: | < | | | > > | 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 | nodein->identifier.guid.data4[4], nodein->identifier.guid.data4[5], nodein->identifier.guid.data4[6], nodein->identifier.guid.data4[7]); Tcl_DStringAppend(dsPtr, buffer, -1); break; case UA_NODEIDTYPE_BYTESTRING: Tcl_DStringAppend(dsPtr, "b=0x", 2); for (i = 0; i < nodein->identifier.byteString.length; i++) { sprintf(buffer, "%02x", nodein->identifier.byteString.data[i]); Tcl_DStringAppend(dsPtr, buffer, 2); } break; } return Tcl_DStringValue(dsPtr); } /* *------------------------------------------------------------------------- |
︙ | ︙ | |||
2092 2093 2094 2095 2096 2097 2098 | } /* *------------------------------------------------------------------------- * * DecodeToObj -- * | | | 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 | } /* *------------------------------------------------------------------------- * * DecodeToObj -- * * Decode a OPC/UA type to a Tcl_Obj. * * Results: * A pointer to a Tcl_Obj (which is empty when decoding is not * possible due to data type). * * Side effects: * None. |
︙ | ︙ | |||
2125 2126 2127 2128 2129 2130 2131 | switch (ext->encoding) { case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING: p = PrintNodeId(&ext->content.encoded.typeId, &ds); list[0] = Tcl_NewStringObj(p, -1); Tcl_DStringFree(&ds); if (ext->content.encoded.body.data != NULL) { | < | 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 | switch (ext->encoding) { case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING: p = PrintNodeId(&ext->content.encoded.typeId, &ds); list[0] = Tcl_NewStringObj(p, -1); Tcl_DStringFree(&ds); if (ext->content.encoded.body.data != NULL) { list[1] = Tcl_NewByteArrayObj(ext->content.encoded.body.data, ext->content.encoded.body.length); } else { list[1] = Tcl_NewObj(); } return Tcl_NewListObj(2, list); |
︙ | ︙ | |||
2249 2250 2251 2252 2253 2254 2255 | v->data4[6], v->data4[7]); return Tcl_NewStringObj(buffer, -1); } if (type == &UA_TYPES[UA_TYPES_BYTESTRING]) { UA_ByteString *v = (UA_ByteString *) data; if (v->data != NULL) { | < | 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 | v->data4[6], v->data4[7]); return Tcl_NewStringObj(buffer, -1); } if (type == &UA_TYPES[UA_TYPES_BYTESTRING]) { UA_ByteString *v = (UA_ByteString *) data; if (v->data != NULL) { return Tcl_NewByteArrayObj(v->data, v->length); } return Tcl_NewObj(); } if (type == &UA_TYPES[UA_TYPES_XMLELEMENT]) { UA_String *v = (UA_String *) data; |
︙ | ︙ | |||
2488 2489 2490 2491 2492 2493 2494 | } /* *------------------------------------------------------------------------- * * EncodeFromObj -- * | | | | 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 | } /* *------------------------------------------------------------------------- * * EncodeFromObj -- * * Encode a Tcl_Obj to an OPC/UA type. * * Results: * A pointer to an allocated OPC/UA value. * * Side effects: * None. * *------------------------------------------------------------------------- */ |
︙ | ︙ | |||
3005 3006 3007 3008 3009 3010 3011 | } /* *------------------------------------------------------------------------- * * MethodInvoke -- * | | | 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 | } /* *------------------------------------------------------------------------- * * MethodInvoke -- * * Method invocation callback from OPC/UA server. * * Results: * UA_StatusCode. * * Side effects: * Many, since Tcl code gets evaluated. * |
︙ | ︙ |