1
|
using System.Runtime.InteropServices;
|
2
|
|
3
|
namespace LDClient.detection;
|
4
|
|
5
|
public class T32ApiFetcher : AInfoFetcher, IT32Utils {
|
6
|
#if _WINDOWS
|
7
|
/// <summary>
|
8
|
/// Path to the Trace32 API library
|
9
|
/// </summary>
|
10
|
private const string T32DllLibrary = "./lib/t32api64.dll";
|
11
|
#else
|
12
|
private const string T32DllLibrary = "./lib/t32api64.so";
|
13
|
#endif
|
14
|
/// <summary>
|
15
|
/// Address of the listening t32 application
|
16
|
/// </summary>
|
17
|
private readonly string _t32Address;
|
18
|
|
19
|
/// <summary>
|
20
|
/// Port of the listening t32 application
|
21
|
/// </summary>
|
22
|
private readonly string _t32Port;
|
23
|
|
24
|
/// <summary>
|
25
|
/// Size of the packets send/received from t32 application
|
26
|
/// </summary>
|
27
|
private readonly string _t32PacketLength;
|
28
|
|
29
|
/// <summary>
|
30
|
/// List of commands to be executed by though the t32 api
|
31
|
/// </summary>
|
32
|
private readonly string[] _commands;
|
33
|
|
34
|
/// <summary>
|
35
|
///
|
36
|
/// </summary>
|
37
|
/// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
|
38
|
/// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
|
39
|
/// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
|
40
|
/// <param name="t32Address">Address of the listening t32 application</param>
|
41
|
/// <param name="t32Port">Port of the listening t32 application</param>
|
42
|
/// <param name="t32PacketLength"> Size of the packets send/received from t32 application </param>
|
43
|
/// <param name="commands"> List of commands to be executed by though the t32 api</param>
|
44
|
public T32ApiFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string t32Address,
|
45
|
string t32Port, string t32PacketLength, string[] commands) : base(maxAttempts, waitPeriodMs, infoFilePath) {
|
46
|
this._t32Address = t32Address;
|
47
|
this._t32Port = t32Port;
|
48
|
this._t32PacketLength = t32PacketLength;
|
49
|
this._commands = commands;
|
50
|
}
|
51
|
|
52
|
|
53
|
/// <summary>
|
54
|
/// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
|
55
|
/// </summary>
|
56
|
/// <param name="s1"></param>
|
57
|
/// <param name="s2"></param>
|
58
|
/// <returns>return code</returns>
|
59
|
[DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
|
60
|
private static extern int T32_Config(string s1, string s2);
|
61
|
|
62
|
/// <summary>
|
63
|
/// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
|
64
|
/// </summary>
|
65
|
/// <returns>Return code</returns>
|
66
|
[DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
|
67
|
private static extern int T32_Init();
|
68
|
|
69
|
/// <summary>
|
70
|
/// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
|
71
|
/// </summary>
|
72
|
/// <param name="dev"></param>
|
73
|
/// <returns>Return code</returns>
|
74
|
[DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
|
75
|
private static extern int T32_Attach(int dev);
|
76
|
|
77
|
/// <summary>
|
78
|
/// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
|
79
|
/// </summary>
|
80
|
/// <param name="command"></param>
|
81
|
/// <returns>Return code</returns>
|
82
|
[DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
|
83
|
private static extern int T32_Cmd(string command);
|
84
|
|
85
|
/// <summary>
|
86
|
/// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
|
87
|
/// </summary>
|
88
|
/// <returns>Return code</returns>
|
89
|
[DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
|
90
|
private static extern int T32_Exit();
|
91
|
|
92
|
|
93
|
/// <summary>
|
94
|
/// This method initialized the connection with the trace32 application API.
|
95
|
/// It setups the standard connection configuration a tries to connect to the API
|
96
|
/// </summary>
|
97
|
/// <returns>true on success</returns>
|
98
|
public bool InitConnection() {
|
99
|
Program.DefaultLogger.Debug("Trace32 connection initialization");
|
100
|
var config1 = T32_Config("NODE=", _t32Address);
|
101
|
var config2 = T32_Config("PORT=", _t32Port);
|
102
|
var config3 = T32_Config("PACKLEN=", _t32PacketLength);
|
103
|
|
104
|
if (config1 != 0 || config2 != 0 || config3 != 0) {
|
105
|
Program.DefaultLogger.Error("Trace32 API connection configuration failed.");
|
106
|
return false;
|
107
|
}
|
108
|
var init = T32_Init();
|
109
|
if (init != 0) {
|
110
|
Program.DefaultLogger.Error("Trace32 API connection init failed.");
|
111
|
return false;
|
112
|
}
|
113
|
|
114
|
var attach = T32_Attach(1);
|
115
|
if (attach != 0) {
|
116
|
Program.DefaultLogger.Error("Trace32 API connection attach failed.");
|
117
|
}
|
118
|
|
119
|
Program.DefaultLogger.Info("Trace32 connection established");
|
120
|
return true;
|
121
|
}
|
122
|
|
123
|
/// <summary>
|
124
|
/// Method executes all passed commands though the trace32 API
|
125
|
/// </summary>
|
126
|
/// <returns>true on success</returns>
|
127
|
public bool ExecuteCommands() {
|
128
|
Program.DefaultLogger.Info("Trace32 API commands execution.");
|
129
|
foreach (var command in _commands) {
|
130
|
Program.DefaultLogger.Debug($"Executing Trace32 command '{command}'.");
|
131
|
var ret = T32_Cmd(command);
|
132
|
if (ret != 0) {
|
133
|
Program.DefaultLogger.Error($"Execution of command '{command}' failed. Return code {ret}.");
|
134
|
return false;
|
135
|
}
|
136
|
}
|
137
|
Program.DefaultLogger.Info("All Trace32 commands executed successfully.");
|
138
|
return true;
|
139
|
}
|
140
|
|
141
|
/// <summary>
|
142
|
/// This method closes the connection with the trace32 application api
|
143
|
/// </summary>
|
144
|
/// <returns>true on success</returns>
|
145
|
public bool CloseConnection() {
|
146
|
Program.DefaultLogger.Debug("Trace32 connection exit");
|
147
|
return T32_Exit() == 0;
|
148
|
}
|
149
|
|
150
|
/// <summary>
|
151
|
/// Method tries to fetch the data from the trace32 application.
|
152
|
/// Upon connection fail it tries again for specified number of times
|
153
|
/// </summary>
|
154
|
/// <returns>true on success</returns>
|
155
|
protected override bool FetchData() {
|
156
|
var connected = false;
|
157
|
for (var i = 0; i < _maxAttempts; i++) {
|
158
|
connected = InitConnection();
|
159
|
if (connected) {
|
160
|
break;
|
161
|
}
|
162
|
Thread.Sleep((int)_waitPeriodMs);
|
163
|
|
164
|
}
|
165
|
return connected && ExecuteCommands() && CloseConnection();
|
166
|
}
|
167
|
}
|