4
4
using Microsoft . Extensions . Logging ;
5
5
using TcHaxx . Snappy . Common . RPC ;
6
6
using TcHaxx . Snappy . Common . RPC . Attributes ;
7
- using TcHaxx . Snappy . Common . Verify ;
8
7
using TwinCAT . Ads ;
9
8
using TwinCAT . Ads . Server . TypeSystem ;
10
9
using TwinCAT . Ads . TypeSystem ;
@@ -17,7 +16,7 @@ internal class SymbolFactory : ISymbolFactory
17
16
private readonly IRpcMethodDescriptor _rpcMethodDescriptor ;
18
17
private readonly ILogger ? _logger ;
19
18
20
- private readonly Dictionary < IDataType , IVerifyMethod > _mappedStructTypeToRpcMethod = [ ] ;
19
+ private readonly Dictionary < IDataType , IRpcMethodMarker > _mappedStructTypeToRpcMethod = [ ] ;
21
20
22
21
internal SymbolFactory ( IRpcMethodDescriptor rpcMethodDescriptor , ILogger ? logger )
23
22
{
@@ -42,47 +41,57 @@ public void AddSymbols(ServerSymbolFactory? serverSymbolFactory)
42
41
var retValKvp = GetMethodReturnValue ( rpcMethodDescription . ReturnValue ) ;
43
42
AddToServerSymbolFactory ( serverSymbolFactory , [ retValKvp ] ) ;
44
43
45
- var fullName = rpcMethodDescription . Method . ReflectedType ? . FullName ?? rpcMethodDescription . Method . Name ;
44
+ var fullName = rpcMethodDescription . InstanceName ;
46
45
var dataArea = new DataArea ( $ "DATA::{ fullName } ", idxGrp , idxOffset ++ , 0x10000 ) ;
47
46
48
47
_ = serverSymbolFactory . AddDataArea ( dataArea ) ;
49
48
50
- var rpc = BuildRpcMethod ( rpcMethodDescription . Method , paramsKvp , retValKvp ) ;
49
+ var rpc = BuildRpcMethod ( rpcMethodDescription , paramsKvp , retValKvp ) ;
51
50
52
51
var dtStructRpc = new StructType ( $ "STRUCT::{ fullName } ") ;
53
52
_ = dtStructRpc . AddMethod ( rpc ) ;
54
53
_ = serverSymbolFactory . AddType ( dtStructRpc ) ;
55
54
_ = serverSymbolFactory . AddSymbol ( fullName , dtStructRpc , dataArea ) ;
56
55
56
+ _logger ? . LogInformation ( "Adding RPC method {MappedTypeFullName}#{MethodName}" , fullName , rpc . Name ) ;
57
57
_mappedStructTypeToRpcMethod . Add ( dtStructRpc , rpcMethodDescription . RpcInvocableMethod ) ;
58
58
}
59
59
}
60
60
61
- public AdsErrorCode InvokeRpcMethod ( IDataType mappedType , object [ ] values , out object ? returnValue )
61
+ public AdsErrorCode InvokeRpcMethod ( IInterfaceInstance structInstance , IRpcMethod method , object [ ] parameterValues , out object ? returnValue )
62
62
{
63
- returnValue = null ;
64
- if ( ! _mappedStructTypeToRpcMethod . TryGetValue ( mappedType , out var value ) )
63
+ returnValue = Activator . CreateInstance ( Type . GetType ( method . ReturnType , false ) ?? typeof ( int ) ) ;
64
+ var mappedType = structInstance . DataType ! ;
65
+
66
+ if ( ! _mappedStructTypeToRpcMethod . TryGetValue ( mappedType , out var rpcMethodType ) )
65
67
{
68
+ _logger ? . LogError ( "No matching type found ({MappedTypeFullName})" , mappedType . FullName ) ;
66
69
return AdsErrorCode . DeviceServiceNotSupported ;
67
70
}
68
71
69
- var rpcMethodToInvoke = value ;
72
+ var rpcMethodToInvoke = rpcMethodType . GetType ( )
73
+ . GetMethods ( )
74
+ . FirstOrDefault ( x => string . Equals ( x . Name , method . Name , StringComparison . OrdinalIgnoreCase ) ) ;
75
+ if ( rpcMethodToInvoke is null )
76
+ {
77
+ _logger ? . LogError ( "Method \" {MethodName}\" not found in type \" {MappedTypeFullName}\" " , method . Name , mappedType . FullName ) ;
78
+ return AdsErrorCode . DeviceServiceNotSupported ;
79
+ }
70
80
71
- if ( values . Length != rpcMethodToInvoke . GetType ( ) . GetMethod ( nameof ( IVerifyMethod . Verify ) ) ! . GetParameters ( ) . Length )
81
+ if ( parameterValues . Length != rpcMethodToInvoke . GetParameters ( ) . Length )
72
82
{
83
+ _logger ? . LogError ( "Different method parameter length: {ParameterValuesLength} != {RpcMethodParameterLength}" , parameterValues . Length , rpcMethodToInvoke . GetParameters ( ) . Length ) ;
73
84
return AdsErrorCode . DeviceInvalidParam ;
74
85
}
75
86
76
- // FIXME: This is ugly...
77
- // Find a better solution, e.g. reflection.
78
- returnValue = rpcMethodToInvoke . Verify ( ( string ) values [ 0 ] , ( string ) values [ 1 ] , ( string ) values [ 2 ] ) ;
87
+ returnValue = rpcMethodToInvoke . Invoke ( rpcMethodType , parameterValues ) ;
79
88
80
89
return AdsErrorCode . NoError ;
81
90
}
82
91
83
- private static RpcMethod BuildRpcMethod ( MethodInfo methodInfo , IEnumerable < KeyValuePair < ParameterInfo , IDataType > > paramsKvp , KeyValuePair < ParameterInfo , IDataType > retValKvp )
92
+ private static RpcMethod BuildRpcMethod ( RpcMethodDescription rpcMethodDescription , IEnumerable < KeyValuePair < ParameterInfo , IDataType > > paramsKvp , KeyValuePair < ParameterInfo , IDataType > retValKvp )
84
93
{
85
- var nameOrAlias = methodInfo . GetCustomAttribute < AliasAttribute > ( ) ? . AliasName ?? methodInfo . Name ;
94
+ var nameOrAlias = rpcMethodDescription . Alias ?? rpcMethodDescription . Method . Name ;
86
95
var rpc = new RpcMethod ( nameOrAlias ) ;
87
96
foreach ( var ( k , v ) in paramsKvp )
88
97
{
0 commit comments