Check-in [38747b01a0]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:various fixes in topcua
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 38747b01a0630b779e5b9104cdf007c3b4cd139f
User & Date: chw 2023-12-17 11:28:03
Context
2023-12-20
04:25
add tklib upstream changes check-in: ea4eb0dad6 user: chw tags: trunk
2023-12-17
11:28
various fixes in topcua check-in: 38747b01a0 user: chw tags: trunk
11:24
tweak android build of tclepeg check-in: 26be3d4858 user: chw tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to jni/topcua/library/ns0.db.gz.

cannot compute difference between binary files

Changes to jni/topcua/library/sqlmodel.tcl.

672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
	if {![catch {mbrowse $handle \
		[list $rootid Forward] [list $rootid Inverse]} brlist]} {
	    foreach {nodeid brname dname ncls refid typeid} [join $brlist] {
		if {![::info exists exists($nodeid)]} {
		    lassign [_db_getparent $handle $nodeid] parent invref
		    if {($ncls eq "Method") && ($parent eq {})} {
			# Method without parent Object is bogus
			set exits($nodeid) 1
			continue
		    }
		    _db_addnode $handle $db $map nc $nodeid $ncls \
			$parent $invref $typeid
		    set exists($nodeid) 1
		    lappend refsfor $nodeid
		    _db_treewalk $handle $db $map exists nc $nodeid







|







672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
	if {![catch {mbrowse $handle \
		[list $rootid Forward] [list $rootid Inverse]} brlist]} {
	    foreach {nodeid brname dname ncls refid typeid} [join $brlist] {
		if {![::info exists exists($nodeid)]} {
		    lassign [_db_getparent $handle $nodeid] parent invref
		    if {($ncls eq "Method") && ($parent eq {})} {
			# Method without parent Object is bogus
			set exists($nodeid) 1
			continue
		    }
		    _db_addnode $handle $db $map nc $nodeid $ncls \
			$parent $invref $typeid
		    set exists($nodeid) 1
		    lappend refsfor $nodeid
		    _db_treewalk $handle $db $map exists nc $nodeid
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
	    { Objects / Server / PublishSubscribe /
		1:DeletePubSubConfiguration }
	    { Objects / Server / ServerDiagnostics }
	    { Objects / Server / VendorServerInfo }
	} {
	    if {![catch {translate $handle [root] / {*}$path} n]} {
		set n [lindex $n 0]
		set exits($n) -1
		foreach {_ n _ _ _ _ _ _} [tree $handle $n] {
		    set exists($n) -1
		}
	    }
	}
	if {$schema ne {}} {
	    append schema "."







|







901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
	    { Objects / Server / PublishSubscribe /
		1:DeletePubSubConfiguration }
	    { Objects / Server / ServerDiagnostics }
	    { Objects / Server / VendorServerInfo }
	} {
	    if {![catch {translate $handle [root] / {*}$path} n]} {
		set n [lindex $n 0]
		set exists($n) -1
		foreach {_ n _ _ _ _ _ _} [tree $handle $n] {
		    set exists($n) -1
		}
	    }
	}
	if {$schema ne {}} {
	    append schema "."
1714
1715
1716
1717
1718
1719
1720
1721







1722

1723



1724
1725
1726
1727
1728
1729
1730
	    }
	    if {![string match "{*}" $jval]} {
		set jval " $jval "
	    }
	    if {[catch {
		writejson $handle $wr(NodeId) Value ${vr}$wr(DataType) $jval
		# TODO: fixup for ExtensionObjects required?
		write $handle $wr(NodeId) Value ${vr}$wr(DataType) \







		    [read $handle $wr(NodeId)]

	    }] && [catch {



		write $handle $wr(NodeId) Value ${vr}$wr(DataType) $wr(Value)
	    }]} {
		# only retry later when not an abstract type
		if {![read $handle $wr(DataType) IsAbstract]} {
		    set wretry($wr(NodeId)) \
			[list $wr(DataType) $vr $wr(Value) $jval]
		}







|
>
>
>
>
>
>
>
|
>

>
>
>







1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
	    }
	    if {![string match "{*}" $jval]} {
		set jval " $jval "
	    }
	    if {[catch {
		writejson $handle $wr(NodeId) Value ${vr}$wr(DataType) $jval
		# TODO: fixup for ExtensionObjects required?
		set dv [read $handle $wr(NodeId) Value {}]
		set dims [dict get $dv arrayDimensions]
		if {[llength $dims]} {
		    set vr ([join $dims ,])
		    if {$vr eq "(0)"} {
			set vr ([llength [dict get $dv value]])
		    }
		}
		write $handle $wr(NodeId) Value ${vr}$wr(DataType) \
		    [dict get $dv value]
	    }] && [catch {
		if {$vr eq "(0)"} {
		    set vr ([llength $wr(Value)])
		}
		write $handle $wr(NodeId) Value ${vr}$wr(DataType) $wr(Value)
	    }]} {
		# only retry later when not an abstract type
		if {![read $handle $wr(DataType) IsAbstract]} {
		    set wretry($wr(NodeId)) \
			[list $wr(DataType) $vr $wr(Value) $jval]
		}
1749
1750
1751
1752
1753
1754
1755
1756







1757

1758



1759
1760
1761
1762
1763
1764
1765
	# failed write operations are left in the "wretry" array
	foreach nodeid [array names wretry] {
	    set wr(NodeId) $nodeid
	    lassign $wretry($nodeid) wr(DataType) vr wr(Value) jval
	    if {[catch {
		writejson $handle $wr(NodeId) Value ${vr}$wr(DataType) $jval
		# TODO: fixup for ExtensionObjects required?
		write $handle $wr(NodeId) Value ${vr}$wr(DataType) \







		    [read $handle $wr(NodeId)]

	    } err] && [catch {



		write $handle $wr(NodeId) Value ${vr}$wr(DataType) $wr(Value)
	    } err]} {
		lappend wretry($nodeid) $err
	    } else {
		unset wretry($nodeid)
	    }
	}







|
>
>
>
>
>
>
>
|
>

>
>
>







1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
	# failed write operations are left in the "wretry" array
	foreach nodeid [array names wretry] {
	    set wr(NodeId) $nodeid
	    lassign $wretry($nodeid) wr(DataType) vr wr(Value) jval
	    if {[catch {
		writejson $handle $wr(NodeId) Value ${vr}$wr(DataType) $jval
		# TODO: fixup for ExtensionObjects required?
		set dv [read $handle $wr(NodeId) Value {}]
		set dims [dict get $dv arrayDimensions]
		if {[llength $dims]} {
		    set vr ([join $dims ,])
		    if {$vr eq "(0)"} {
			set vr ([llength [dict get $dv value]])
		    }
		}
		write $handle $wr(NodeId) Value ${vr}$wr(DataType) \
		    [dict get $dv value]
	    } err] && [catch {
		if {$vr eq "(0)"} {
		    set vr ([llength $wr(Value)])
		}
		write $handle $wr(NodeId) Value ${vr}$wr(DataType) $wr(Value)
	    } err]} {
		lappend wretry($nodeid) $err
	    } else {
		unset wretry($nodeid)
	    }
	}

Changes to jni/topcua/topcua.c.

11208
11209
11210
11211
11212
11213
11214











11215
11216
11217
11218
11219



11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235



11236
11237
11238
11239
11240
11241
11242
error:
	ReportError(interp, uai, NULL, 0);
	UA_NodeId_clear(&nodeid);
	if (arrDim != NULL) {
	    UA_free(arrDim);
	}
	return TCL_ERROR;











    }
    if (uah->client != NULL) {
	if ((type == &UA_TYPES[UA_TYPES_VARIANT]) && (arrDim != NULL)) {
	    UA_Variant *v = (UA_Variant *) value;




	    v->arrayDimensionsSize = arrDimSize;
	    v->arrayDimensions = arrDim;
	    arrDimSize = 0;
	    arrDim = NULL;
	}
	uaret = __UA_Client_writeAttribute(uah->client, &nodeid,
					   (UA_AttributeId) attr,
					   value, type);
    } else {
	UA_WriteValue_init(&wv);
	wv.nodeId = nodeid;
	wv.attributeId = (UA_AttributeId) attr;
	wv.value.hasValue = true;
	if (vr >= UA_VALUERANK_ONE_OR_MORE_DIMENSIONS) {
	    wv.value.value = *((UA_Variant *) value);
	    if (arrDim != NULL) {



		wv.value.value.arrayDimensionsSize = arrDimSize;
		wv.value.value.arrayDimensions = arrDim;
		arrDimSize = 0;
		arrDim = NULL;
	    }
	} else if (type == &UA_TYPES[UA_TYPES_VARIANT]) {
	    if (UA_Variant_isEmpty(value)) {







>
>
>
>
>
>
>
>
>
>
>





>
>
>
















>
>
>







11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
error:
	ReportError(interp, uai, NULL, 0);
	UA_NodeId_clear(&nodeid);
	if (arrDim != NULL) {
	    UA_free(arrDim);
	}
	return TCL_ERROR;
    }
    if ((type == &UA_TYPES[UA_TYPES_VARIANT]) && (arrDim != NULL)) {
	UA_Variant *v = (UA_Variant *) value;

	/* If JSON has dimension information, keep it. */
	if (v->arrayDimensions != NULL) {
	    vr = v->arrayDimensionsSize;
	    UA_free(arrDim);
	    arrDimSize = 0;
	    arrDim = NULL;
	}
    }
    if (uah->client != NULL) {
	if ((type == &UA_TYPES[UA_TYPES_VARIANT]) && (arrDim != NULL)) {
	    UA_Variant *v = (UA_Variant *) value;

	    if (v->arrayDimensions != NULL) {
		UA_free(v->arrayDimensions);
	    }
	    v->arrayDimensionsSize = arrDimSize;
	    v->arrayDimensions = arrDim;
	    arrDimSize = 0;
	    arrDim = NULL;
	}
	uaret = __UA_Client_writeAttribute(uah->client, &nodeid,
					   (UA_AttributeId) attr,
					   value, type);
    } else {
	UA_WriteValue_init(&wv);
	wv.nodeId = nodeid;
	wv.attributeId = (UA_AttributeId) attr;
	wv.value.hasValue = true;
	if (vr >= UA_VALUERANK_ONE_OR_MORE_DIMENSIONS) {
	    wv.value.value = *((UA_Variant *) value);
	    if (arrDim != NULL) {
		if (wv.value.value.arrayDimensions != NULL) {
		    UA_free(wv.value.value.arrayDimensions);
		}
		wv.value.value.arrayDimensionsSize = arrDimSize;
		wv.value.value.arrayDimensions = arrDim;
		arrDimSize = 0;
		arrDim = NULL;
	    }
	} else if (type == &UA_TYPES[UA_TYPES_VARIANT]) {
	    if (UA_Variant_isEmpty(value)) {
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
 */

static UA_StatusCode
MakeMappedVars(UAI *uai, UAH *uah, UA_NodeId *nodeid,
	       const UA_DataType *type, UAF *topfm, int isVT)
{
    Tcl_HashEntry *hPtr;
    UA_StatusCode uaret;
    char *p;
    Tcl_DString ds;
    static const UA_DataSource fmsrc = { StructFieldMapper, NULL };
    size_t i, k;
    int isNew, addSize = (topfm == NULL) ? 0 : topfm->nMembers;
    void *ctx;








|







17053
17054
17055
17056
17057
17058
17059
17060
17061
17062
17063
17064
17065
17066
17067
 */

static UA_StatusCode
MakeMappedVars(UAI *uai, UAH *uah, UA_NodeId *nodeid,
	       const UA_DataType *type, UAF *topfm, int isVT)
{
    Tcl_HashEntry *hPtr;
    UA_StatusCode uaret = UA_STATUSCODE_BADINTERNALERROR;
    char *p;
    Tcl_DString ds;
    static const UA_DataSource fmsrc = { StructFieldMapper, NULL };
    size_t i, k;
    int isNew, addSize = (topfm == NULL) ? 0 : topfm->nMembers;
    void *ctx;