ads/
errors.rs

1//! Defines ADS error types.
2
3/// Result alias for `ads::Error`.
4pub type Result<T> = std::result::Result<T, Error>;
5
6/// A collection of different errors that can happen with ADS requests.
7#[derive(Debug, thiserror::Error)]
8pub enum Error {
9    /// An IO error occurred.
10    #[error("{0}: {1}")]
11    Io(&'static str, std::io::Error),
12
13    /// The ADS server responded with an error code.
14    #[error("{0}: {1} ({2:#x})")]
15    Ads(&'static str, &'static str, u32),
16
17    /// An unexpected or inconsistent reply was received.
18    #[error("{0}: {1} ({2})")]
19    Reply(&'static str, &'static str, u32),
20
21    /// A value exceeds the allowed 32 bits for ADS.
22    #[error("data length or duration exceeds 32 bits")]
23    Overflow(#[from] std::num::TryFromIntError),
24}
25
26pub(crate) trait ErrContext {
27    type Success;
28    fn ctx(self, context: &'static str) -> Result<Self::Success>;
29}
30
31impl<T> ErrContext for std::result::Result<T, std::io::Error> {
32    type Success = T;
33    fn ctx(self, context: &'static str) -> Result<Self::Success> {
34        self.map_err(|e| Error::Io(context, e))
35    }
36}
37
38/// The list of known ADS error codes from
39/// [here](https://infosys.beckhoff.com/content/1033/tc3_ads_intro_howto/374277003.html?id=2736996179007627436).
40pub const ADS_ERRORS: &[(u32, &str)] = &[
41    (0x001, "Internal error"),
42    (0x002, "No real-time"),
43    (0x003, "Allocation locked - memory error"),
44    (0x004, "Mailbox full - ADS message could not be sent"),
45    (0x005, "Wrong receive HMSG"),
46    (0x006, "Target port not found, possibly ADS server not started"),
47    (0x007, "Target machine not found, possibly missing ADS routes"),
48    (0x008, "Unknown command ID"),
49    (0x009, "Invalid task ID"),
50    (0x00A, "No IO"),
51    (0x00B, "Unknown AMS command"),
52    (0x00C, "Win32 error"),
53    (0x00D, "Port not connected"),
54    (0x00E, "Invalid AMS length"),
55    (0x00F, "Invalid AMS NetID"),
56    (0x010, "Low installation level"),
57    (0x011, "No debugging available"),
58    (0x012, "Port disabled - system service not started"),
59    (0x013, "Port already connected"),
60    (0x014, "AMS Sync Win32 error"),
61    (0x015, "AMS Sync timeout"),
62    (0x016, "AMS Sync error"),
63    (0x017, "AMS Sync no index map"),
64    (0x018, "Invalid AMS port"),
65    (0x019, "No memory"),
66    (0x01A, "TCP send error"),
67    (0x01B, "Host unreachable"),
68    (0x01C, "Invalid AMS fragment"),
69    (0x01D, "TLS send error - secure ADS connection failed"),
70    (0x01E, "Access denied - secure ADS access denied"),
71
72    (0x500, "Router: no locked memory"),
73    (0x501, "Router: memory size could not be changed"),
74    (0x502, "Router: mailbox full"),
75    (0x503, "Router: debug mailbox full"),
76    (0x504, "Router: port type is unknown"),
77    (0x505, "Router is not initialized"),
78    (0x506, "Router: desired port number is already assigned"),
79    (0x507, "Router: port not registered"),
80    (0x508, "Router: maximum number of ports reached"),
81    (0x509, "Router: port is invalid"),
82    (0x50A, "Router is not active"),
83    (0x50B, "Router: mailbox full for fragmented messages"),
84    (0x50C, "Router: fragment timeout occurred"),
85    (0x50D, "Router: port removed"),
86
87    (0x700, "General device error"),
88    (0x701, "Service is not supported by server"),
89    (0x702, "Invalid index group"),
90    (0x703, "Invalid index offset"),
91    (0x704, "Reading/writing not permitted"),
92    (0x705, "Parameter size not correct"),
93    (0x706, "Invalid parameter value(s)"),
94    (0x707, "Device is not in a ready state"),
95    (0x708, "Device is busy"),
96    (0x709, "Invalid OS context -> use multi-task data access"),
97    (0x70A, "Out of memory"),
98    (0x70B, "Invalid parameter value(s)"),
99    (0x70C, "Not found (files, ...)"),
100    (0x70D, "Syntax error in command or file"),
101    (0x70E, "Objects do not match"),
102    (0x70F, "Object already exists"),
103    (0x710, "Symbol not found"),
104    (0x711, "Symbol version invalid -> create a new handle"),
105    (0x712, "Server is in an invalid state"),
106    (0x713, "AdsTransMode not supported"),
107    (0x714, "Notification handle is invalid"),
108    (0x715, "Notification client not registered"),
109    (0x716, "No more notification handles"),
110    (0x717, "Notification size too large"),
111    (0x718, "Device not initialized"),
112    (0x719, "Device has a timeout"),
113    (0x71A, "Query interface failed"),
114    (0x71B, "Wrong interface required"),
115    (0x71C, "Class ID is invalid"),
116    (0x71D, "Object ID is invalid"),
117    (0x71E, "Request is pending"),
118    (0x71F, "Request is aborted"),
119    (0x720, "Signal warning"),
120    (0x721, "Invalid array index"),
121    (0x722, "Symbol not active -> release handle and try again"),
122    (0x723, "Access denied"),
123    (0x724, "No license found -> activate license"),
124    (0x725, "License expired"),
125    (0x726, "License exceeded"),
126    (0x727, "License invalid"),
127    (0x728, "Invalid system ID in license"),
128    (0x729, "License not time limited"),
129    (0x72A, "License issue time in the future"),
130    (0x72B, "License time period too long"),
131    (0x72C, "Exception in device specific code -> check each device"),
132    (0x72D, "License file read twice"),
133    (0x72E, "Invalid signature"),
134    (0x72F, "Invalid public key certificate"),
135    (0x730, "Public key not known from OEM"),
136    (0x731, "License not valid for this system ID"),
137    (0x732, "Demo license prohibited"),
138    (0x733, "Invalid function ID"),
139    (0x734, "Outside the valid range"),
140    (0x735, "Invalid alignment"),
141    (0x736, "Invalid platform level"),
142    (0x737, "Context - forward to passive level"),
143    (0x738, "Content - forward to dispatch level"),
144    (0x739, "Context - forward to real-time"),
145
146    (0x740, "General client error"),
147    (0x741, "Invalid parameter at service"),
148    (0x742, "Polling list is empty"),
149    (0x743, "Var connection already in use"),
150    (0x744, "Invoke ID in use"),
151    (0x745, "Timeout elapsed -> check route setting"),
152    (0x746, "Error in Win32 subsystem"),
153    (0x747, "Invalid client timeout value"),
154    (0x748, "ADS port not opened"),
155    (0x749, "No AMS address"),
156    (0x750, "Internal error in ADS sync"),
157    (0x751, "Hash table overflow"),
158    (0x752, "Key not found in hash"),
159    (0x753, "No more symbols in cache"),
160    (0x754, "Invalid response received"),
161    (0x755, "Sync port is locked"),
162
163    (0x1000, "Internal error in real-time system"),
164    (0x1001, "Timer value not valid"),
165    (0x1002, "Task pointer has invalid value 0"),
166    (0x1003, "Stack pointer has invalid value 0"),
167    (0x1004, "Requested task priority already assigned"),
168    (0x1005, "No free Task Control Block"),
169    (0x1006, "No free semaphores"),
170    (0x1007, "No free space in the queue"),
171    (0x100D, "External sync interrupt already applied"),
172    (0x100E, "No external sync interrupt applied"),
173    (0x100F, "External sync interrupt application failed"),
174    (0x1010, "Call of service function in wrong context"),
175    (0x1017, "Intel VT-x not supported"),
176    (0x1018, "Intel VT-x not enabled in BIOS"),
177    (0x1019, "Missing function in Intel VT-x"),
178    (0x101A, "Activation of Intel VT-x failed"),
179];
180
181/// Return an `Error` corresponding to the given ADS result code.
182pub fn ads_error<T>(action: &'static str, err: u32) -> Result<T> {
183    match ADS_ERRORS.binary_search_by_key(&err, |e| e.0) {
184        Ok(idx) => Err(Error::Ads(action, ADS_ERRORS[idx].1, err)),
185        Err(_) => Err(Error::Ads(action, "Unknown error code", err)),
186    }
187}