Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method call with arguments #29

Closed
maveyx opened this issue Jul 30, 2020 · 3 comments
Closed

Method call with arguments #29

maveyx opened this issue Jul 30, 2020 · 3 comments

Comments

@maveyx
Copy link

maveyx commented Jul 30, 2020

Dear @nauful,

Thank you again for your freely available code!

Regarding the server implementation:
I'm currently trying to support InputArguments/OutputArguments for a NodeMethod, which I added successfully according to #23.

I was able to add the reference nodes to my NodeMethod "method":

// argument nodes
method.References.Add(new ReferenceNode(new NodeId(UAConst.HasProperty), new NodeId(UAConst.InputArguments), false));
method.References.Add(new ReferenceNode(new NodeId(UAConst.HasProperty), new NodeId(UAConst.OutputArguments), false));

However, I don't know how to add, for example, a string InputArgument to "method".
I just found the "Argument = 296" definition in Types.cs but I think I lack understanding how to add InputArguments here.

Any advice is very much appreciated.

Thank you very much!

@nauful
Copy link
Owner

nauful commented Jul 30, 2020

Hello,

Always glad to see that my work has been useful.

Perhaps the OPC UA documentation on method call modelling in the UA namespace has more information for semantic correctness but I've never needed it.

On the client side, you have:
public StatusCode Call(CallMethodRequest[] requests, out CallMethodResult[] results)

On the server side, look at:
protected int DispatchMessage_CallRequest(SLChannel config, RequestHeader reqHeader, MemoryBuffer recvBuf, uint messageSize)

I haven't implemented a standard way of handling these on the server side, but look at #23 as one way to do it.

CallMethodRequest is defined as

public class CallMethodRequest
{
	public CallMethodRequest(NodeId ObjectId, NodeId MethodId, object[] InputArguments) ...
}

So the parameters are just an array of objects encoded as UA variant types. You don't need to define them yourself. As a client, just populate them as you wish (i.e. array of integers boxed as objects), and as a server, decode them as an array of variant types.

@maveyx
Copy link
Author

maveyx commented Aug 4, 2020

Dear @nauful,
Thank you very much for your advice!

How would you return OutputArguments in this case?

@nauful
Copy link
Owner

nauful commented Aug 4, 2020

OutputArguments can be returned to the caller in this way (last part): #23 (comment)

Off the top of my head, it should be similar to this:

for (uint i = 0; i < NoofMethodsToCall; i++)
{
	var resp = app.HandleMethodCall(reqs[i]);
	succeeded &= respBuf.Encode((UInt32)StatusCode.Good);
	// InputArgumentResults: Array of StatusCode
	succeeded &= respBuf.Encode((UInt32)resps.NumStatusCodes);
	... Encode each status code, then 0, then the number of result variants, then each result variant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants