xref: /aosp_15_r20/hardware/interfaces/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Error.h"
18 
19 #include "../MessageDefinition.h"
20 
21 #include <libnl++/printer.h>
22 
23 #include <map>
24 
25 #include <linux/netlink.h>
26 #ifndef _UAPI__LINUX_NETLINK_H
27 // linux_glibc (host) includes source headers instead of uapi headers
28 enum nlmsgerr_attrs {
29     NLMSGERR_ATTR_UNUSED,
30     NLMSGERR_ATTR_MSG,
31     NLMSGERR_ATTR_OFFS,
32     NLMSGERR_ATTR_COOKIE,
33 };
34 #endif
35 
36 namespace android::nl::protocols::base {
37 
38 using DataType = AttributeDefinition::DataType;
39 
40 // clang-format off
Error(int protocol)41 Error::Error(int protocol) : MessageDefinition<nlmsgerr>("nlmsg", {
42     {NLMSG_ERROR, {"ERROR", MessageGenre::Ack}},
43 }, {
44     {NLMSGERR_ATTR_MSG, {"MSG", DataType::String}},
45     {NLMSGERR_ATTR_OFFS, {"OFFS", DataType::Uint}},
46     {NLMSGERR_ATTR_COOKIE, {"COOKIE", DataType::Raw}},
47 }), mProtocol(protocol) {}
48 // clang-format on
49 
50 std::map<int, std::string> errnoNames{
51         {EPERM, "EPERM"},                      // Operation not permitted
52         {ENOENT, "ENOENT"},                    // No such file or directory
53         {ESRCH, "ESRCH"},                      // No such process
54         {EINTR, "EINTR"},                      // Interrupted system call
55         {EIO, "EIO"},                          // I/O error
56         {ENXIO, "ENXIO"},                      // No such device or address
57         {E2BIG, "E2BIG"},                      // Argument list too long
58         {ENOEXEC, "ENOEXEC"},                  // Exec format error
59         {EBADF, "EBADF"},                      // Bad file number
60         {ECHILD, "ECHILD"},                    // No child processes
61         {EAGAIN, "EAGAIN"},                    // Try again
62         {ENOMEM, "ENOMEM"},                    // Out of memory
63         {EACCES, "EACCES"},                    // Permission denied
64         {EFAULT, "EFAULT"},                    // Bad address
65         {ENOTBLK, "ENOTBLK"},                  // Block device required
66         {EBUSY, "EBUSY"},                      // Device or resource busy
67         {EEXIST, "EEXIST"},                    // File exists
68         {EXDEV, "EXDEV"},                      // Cross-device link
69         {ENODEV, "ENODEV"},                    // No such device
70         {ENOTDIR, "ENOTDIR"},                  // Not a directory
71         {EISDIR, "EISDIR"},                    // Is a directory
72         {EINVAL, "EINVAL"},                    // Invalid argument
73         {ENFILE, "ENFILE"},                    // File table overflow
74         {EMFILE, "EMFILE"},                    // Too many open files
75         {ENOTTY, "ENOTTY"},                    // Not a typewriter
76         {ETXTBSY, "ETXTBSY"},                  // Text file busy
77         {EFBIG, "EFBIG"},                      // File too large
78         {ENOSPC, "ENOSPC"},                    // No space left on device
79         {ESPIPE, "ESPIPE"},                    // Illegal seek
80         {EROFS, "EROFS"},                      // Read-only file system
81         {EMLINK, "EMLINK"},                    // Too many links
82         {EPIPE, "EPIPE"},                      // Broken pipe
83         {EDOM, "EDOM"},                        // Math argument out of domain of func
84         {ERANGE, "ERANGE"},                    // Math result not representable
85         {EDEADLK, "EDEADLK"},                  // Resource deadlock would occur
86         {ENAMETOOLONG, "ENAMETOOLONG"},        // File name too long
87         {ENOLCK, "ENOLCK"},                    // No record locks available
88         {ENOSYS, "ENOSYS"},                    // Invalid system call number
89         {ENOTEMPTY, "ENOTEMPTY"},              // Directory not empty
90         {ELOOP, "ELOOP"},                      // Too many symbolic links encountered
91         {ENOMSG, "ENOMSG"},                    // No message of desired type
92         {EIDRM, "EIDRM"},                      // Identifier removed
93         {ECHRNG, "ECHRNG"},                    // Channel number out of range
94         {EL2NSYNC, "EL2NSYNC"},                // Level 2 not synchronized
95         {EL3HLT, "EL3HLT"},                    // Level 3 halted
96         {EL3RST, "EL3RST"},                    // Level 3 reset
97         {ELNRNG, "ELNRNG"},                    // Link number out of range
98         {EUNATCH, "EUNATCH"},                  // Protocol driver not attached
99         {ENOCSI, "ENOCSI"},                    // No CSI structure available
100         {EL2HLT, "EL2HLT"},                    // Level 2 halted
101         {EBADE, "EBADE"},                      // Invalid exchange
102         {EBADR, "EBADR"},                      // Invalid request descriptor
103         {EXFULL, "EXFULL"},                    // Exchange full
104         {ENOANO, "ENOANO"},                    // No anode
105         {EBADRQC, "EBADRQC"},                  // Invalid request code
106         {EBADSLT, "EBADSLT"},                  // Invalid slot
107         {EBFONT, "EBFONT"},                    // Bad font file format
108         {ENOSTR, "ENOSTR"},                    // Device not a stream
109         {ENODATA, "ENODATA"},                  // No data available
110         {ETIME, "ETIME"},                      // Timer expired
111         {ENOSR, "ENOSR"},                      // Out of streams resources
112         {ENONET, "ENONET"},                    // Machine is not on the network
113         {ENOPKG, "ENOPKG"},                    // Package not installed
114         {EREMOTE, "EREMOTE"},                  // Object is remote
115         {ENOLINK, "ENOLINK"},                  // Link has been severed
116         {EADV, "EADV"},                        // Advertise error
117         {ESRMNT, "ESRMNT"},                    // Srmount error
118         {ECOMM, "ECOMM"},                      // Communication error on send
119         {EPROTO, "EPROTO"},                    // Protocol error
120         {EMULTIHOP, "EMULTIHOP"},              // Multihop attempted
121         {EDOTDOT, "EDOTDOT"},                  // RFS specific error
122         {EBADMSG, "EBADMSG"},                  // Not a data message
123         {EOVERFLOW, "EOVERFLOW"},              // Value too large for defined data type
124         {ENOTUNIQ, "ENOTUNIQ"},                // Name not unique on network
125         {EBADFD, "EBADFD"},                    // File descriptor in bad state
126         {EREMCHG, "EREMCHG"},                  // Remote address changed
127         {ELIBACC, "ELIBACC"},                  // Can not access a needed shared library
128         {ELIBBAD, "ELIBBAD"},                  // Accessing a corrupted shared library
129         {ELIBSCN, "ELIBSCN"},                  // .lib section in a.out corrupted
130         {ELIBMAX, "ELIBMAX"},                  // Attempting to link in too many shared libraries
131         {ELIBEXEC, "ELIBEXEC"},                // Cannot exec a shared library directly
132         {EILSEQ, "EILSEQ"},                    // Illegal byte sequence
133         {ERESTART, "ERESTART"},                // Interrupted system call should be restarted
134         {ESTRPIPE, "ESTRPIPE"},                // Streams pipe error
135         {EUSERS, "EUSERS"},                    // Too many users
136         {ENOTSOCK, "ENOTSOCK"},                // Socket operation on non-socket
137         {EDESTADDRREQ, "EDESTADDRREQ"},        // Destination address required
138         {EMSGSIZE, "EMSGSIZE"},                // Message too long
139         {EPROTOTYPE, "EPROTOTYPE"},            // Protocol wrong type for socket
140         {ENOPROTOOPT, "ENOPROTOOPT"},          // Protocol not available
141         {EPROTONOSUPPORT, "EPROTONOSUPPORT"},  // Protocol not supported
142         {ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT"},  // Socket type not supported
143         {EOPNOTSUPP, "EOPNOTSUPP"},            // Operation not supported on transport endpoint
144         {EPFNOSUPPORT, "EPFNOSUPPORT"},        // Protocol family not supported
145         {EAFNOSUPPORT, "EAFNOSUPPORT"},        // Address family not supported by protocol
146         {EADDRINUSE, "EADDRINUSE"},            // Address already in use
147         {EADDRNOTAVAIL, "EADDRNOTAVAIL"},      // Cannot assign requested address
148         {ENETDOWN, "ENETDOWN"},                // Network is down
149         {ENETUNREACH, "ENETUNREACH"},          // Network is unreachable
150         {ENETRESET, "ENETRESET"},              // Network dropped connection because of reset
151         {ECONNABORTED, "ECONNABORTED"},        // Software caused connection abort
152         {ECONNRESET, "ECONNRESET"},            // Connection reset by peer
153         {ENOBUFS, "ENOBUFS"},                  // No buffer space available
154         {EISCONN, "EISCONN"},                  // Transport endpoint is already connected
155         {ENOTCONN, "ENOTCONN"},                // Transport endpoint is not connected
156         {ESHUTDOWN, "ESHUTDOWN"},              // Cannot send after transport endpoint shutdown
157         {ETOOMANYREFS, "ETOOMANYREFS"},        // Too many references: cannot splice
158         {ETIMEDOUT, "ETIMEDOUT"},              // Connection timed out
159         {ECONNREFUSED, "ECONNREFUSED"},        // Connection refused
160         {EHOSTDOWN, "EHOSTDOWN"},              // Host is down
161         {EHOSTUNREACH, "EHOSTUNREACH"},        // No route to host
162         {EALREADY, "EALREADY"},                // Operation already in progress
163         {EINPROGRESS, "EINPROGRESS"},          // Operation now in progress
164         {ESTALE, "ESTALE"},                    // Stale file handle
165         {EUCLEAN, "EUCLEAN"},                  // Structure needs cleaning
166         {ENOTNAM, "ENOTNAM"},                  // Not a XENIX named type file
167         {ENAVAIL, "ENAVAIL"},                  // No XENIX semaphores available
168         {EISNAM, "EISNAM"},                    // Is a named type file
169         {EREMOTEIO, "EREMOTEIO"},              // Remote I/O error
170         {EDQUOT, "EDQUOT"},                    // Quota exceeded
171         {ENOMEDIUM, "ENOMEDIUM"},              // No medium found
172         {EMEDIUMTYPE, "EMEDIUMTYPE"},          // Wrong medium type
173         {ECANCELED, "ECANCELED"},              // Operation Canceled
174         {ENOKEY, "ENOKEY"},                    // Required key not available
175         {EKEYEXPIRED, "EKEYEXPIRED"},          // Key has expired
176         {EKEYREVOKED, "EKEYREVOKED"},          // Key has been revoked
177         {EKEYREJECTED, "EKEYREJECTED"},        // Key was rejected by service
178         {EOWNERDEAD, "EOWNERDEAD"},            // Owner died
179         {ENOTRECOVERABLE, "ENOTRECOVERABLE"},  // State not recoverable
180         {ERFKILL, "ERFKILL"},                  // Operation not possible due to RF-kill
181         {EHWPOISON, "EHWPOISON"},              // Memory page has hardware error
182 
183         // Duplicates: EWOULDBLOCK (Operation would block), EDEADLOCK
184 };
185 
toStream(std::stringstream & ss,const nlmsgerr & data) const186 void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const {
187     ss << "nlmsgerr{";
188     if (data.error == 0) {
189         ss << "ACK";
190     } else {
191         ss << "error=";
192         const auto nameIt = errnoNames.find(-data.error);
193         if (nameIt == errnoNames.end()) {
194             ss << data.error;
195         } else {
196             ss << nameIt->second;
197         }
198     }
199     ss << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol, false) << "}";
200 }
201 
202 }  // namespace android::nl::protocols::base
203