Loading automotive/can/1.0/default/libnetdevice/can.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { } nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } } // namespace android::netdevice::can automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ bool add(std::string dev, std::string type) { } nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } bool del(std::string dev) { Loading @@ -80,7 +80,7 @@ bool del(std::string dev) { req.addattr(IFLA_IFNAME, dev); nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } std::optional<hwaddr_t> getHwAddr(const std::string& ifname) { Loading automotive/can/1.0/default/libnetdevice/vlan.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { } nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } } // namespace android::netdevice::vlan automotive/can/1.0/default/libnl++/Socket.cpp +27 −42 Original line number Diff line number Diff line Loading @@ -103,60 +103,45 @@ std::pair<std::optional<Buffer<nlmsghdr>>, sockaddr_nl> Socket::receiveFrom(size return {msg, sa}; } /* TODO(161389935): Migrate receiveAck to use nlmsg<> internally. Possibly reuse * Socket::receive(). */ bool Socket::receiveAck() { if (mFailed) return false; char buf[8192]; sockaddr_nl sa; iovec iov = {buf, sizeof(buf)}; msghdr msg = {}; msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); msg.msg_iov = &iov; msg.msg_iovlen = 1; bool Socket::receiveAck(uint32_t seq) { const auto nlerr = receive<nlmsgerr>({NLMSG_ERROR}); if (!nlerr.has_value()) return false; const ssize_t status = recvmsg(mFd.get(), &msg, 0); if (status < 0) { PLOG(ERROR) << "Failed to receive Netlink message"; if (nlerr->data.msg.nlmsg_seq != seq) { LOG(ERROR) << "Received ACK for a different message (" << nlerr->data.msg.nlmsg_seq << ", expected " << seq << "). Multi-message tracking is not implemented."; return false; } size_t remainingLen = status; if (msg.msg_flags & MSG_TRUNC) { LOG(ERROR) << "Failed to receive Netlink message: truncated"; if (nlerr->data.error == 0) return true; LOG(WARNING) << "Received Netlink error message: " << strerror(-nlerr->data.error); return false; } for (auto nlmsg = reinterpret_cast<nlmsghdr*>(buf); NLMSG_OK(nlmsg, remainingLen); nlmsg = NLMSG_NEXT(nlmsg, remainingLen)) { if constexpr (kSuperVerbose) { LOG(VERBOSE) << "received Netlink response: " << toString({nlmsg, nlmsg->nlmsg_len}, mProtocol); } std::optional<Buffer<nlmsghdr>> Socket::receive(const std::set<nlmsgtype_t>& msgtypes, size_t maxSize) { while (!mFailed) { const auto msgBuf = receive(maxSize); if (!msgBuf.has_value()) return std::nullopt; // We're looking for error/ack message only, ignoring others. if (nlmsg->nlmsg_type != NLMSG_ERROR) { LOG(WARNING) << "Received unexpected Netlink message (ignored): " << nlmsg->nlmsg_type; for (const auto rawMsg : *msgBuf) { if (msgtypes.count(rawMsg->nlmsg_type) == 0) { LOG(WARNING) << "Received (and ignored) unexpected Netlink message of type " << rawMsg->nlmsg_type; continue; } // Found error/ack message, return status. const auto nlerr = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(nlmsg)); if (nlerr->error != 0) { LOG(ERROR) << "Received Netlink error message: " << strerror(-nlerr->error); return false; return rawMsg; } return true; } // Couldn't find any error/ack messages. return false; return std::nullopt; } std::optional<unsigned> Socket::getPid() { if (mFailed) return std::nullopt; sockaddr_nl sa = {}; socklen_t sasize = sizeof(sa); if (getsockname(mFd.get(), reinterpret_cast<sockaddr*>(&sa), &sasize) < 0) { Loading automotive/can/1.0/default/libnl++/include/libnl++/Message.h +4 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <libnl++/Attributes.h> #include <libnl++/Buffer.h> #include <set> namespace android::nl { /** Loading Loading @@ -60,7 +62,8 @@ class Message { * \return Parsed message or nullopt, if the buffer data is invalid or message type * doesn't match. */ static std::optional<Message<T>> parse(Buffer<nlmsghdr> buf, std::set<nlmsgtype_t> msgtypes) { static std::optional<Message<T>> parse(Buffer<nlmsghdr> buf, const std::set<nlmsgtype_t>& msgtypes) { const auto& [nlOk, nlHeader] = buf.getFirst(); // we're doing it twice, but it's fine if (!nlOk) return std::nullopt; Loading Loading
automotive/can/1.0/default/libnetdevice/can.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { } nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } } // namespace android::netdevice::can
automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ bool add(std::string dev, std::string type) { } nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } bool del(std::string dev) { Loading @@ -80,7 +80,7 @@ bool del(std::string dev) { req.addattr(IFLA_IFNAME, dev); nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } std::optional<hwaddr_t> getHwAddr(const std::string& ifname) { Loading
automotive/can/1.0/default/libnetdevice/vlan.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { } nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); return sock.send(req) && sock.receiveAck(req); } } // namespace android::netdevice::vlan
automotive/can/1.0/default/libnl++/Socket.cpp +27 −42 Original line number Diff line number Diff line Loading @@ -103,60 +103,45 @@ std::pair<std::optional<Buffer<nlmsghdr>>, sockaddr_nl> Socket::receiveFrom(size return {msg, sa}; } /* TODO(161389935): Migrate receiveAck to use nlmsg<> internally. Possibly reuse * Socket::receive(). */ bool Socket::receiveAck() { if (mFailed) return false; char buf[8192]; sockaddr_nl sa; iovec iov = {buf, sizeof(buf)}; msghdr msg = {}; msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); msg.msg_iov = &iov; msg.msg_iovlen = 1; bool Socket::receiveAck(uint32_t seq) { const auto nlerr = receive<nlmsgerr>({NLMSG_ERROR}); if (!nlerr.has_value()) return false; const ssize_t status = recvmsg(mFd.get(), &msg, 0); if (status < 0) { PLOG(ERROR) << "Failed to receive Netlink message"; if (nlerr->data.msg.nlmsg_seq != seq) { LOG(ERROR) << "Received ACK for a different message (" << nlerr->data.msg.nlmsg_seq << ", expected " << seq << "). Multi-message tracking is not implemented."; return false; } size_t remainingLen = status; if (msg.msg_flags & MSG_TRUNC) { LOG(ERROR) << "Failed to receive Netlink message: truncated"; if (nlerr->data.error == 0) return true; LOG(WARNING) << "Received Netlink error message: " << strerror(-nlerr->data.error); return false; } for (auto nlmsg = reinterpret_cast<nlmsghdr*>(buf); NLMSG_OK(nlmsg, remainingLen); nlmsg = NLMSG_NEXT(nlmsg, remainingLen)) { if constexpr (kSuperVerbose) { LOG(VERBOSE) << "received Netlink response: " << toString({nlmsg, nlmsg->nlmsg_len}, mProtocol); } std::optional<Buffer<nlmsghdr>> Socket::receive(const std::set<nlmsgtype_t>& msgtypes, size_t maxSize) { while (!mFailed) { const auto msgBuf = receive(maxSize); if (!msgBuf.has_value()) return std::nullopt; // We're looking for error/ack message only, ignoring others. if (nlmsg->nlmsg_type != NLMSG_ERROR) { LOG(WARNING) << "Received unexpected Netlink message (ignored): " << nlmsg->nlmsg_type; for (const auto rawMsg : *msgBuf) { if (msgtypes.count(rawMsg->nlmsg_type) == 0) { LOG(WARNING) << "Received (and ignored) unexpected Netlink message of type " << rawMsg->nlmsg_type; continue; } // Found error/ack message, return status. const auto nlerr = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(nlmsg)); if (nlerr->error != 0) { LOG(ERROR) << "Received Netlink error message: " << strerror(-nlerr->error); return false; return rawMsg; } return true; } // Couldn't find any error/ack messages. return false; return std::nullopt; } std::optional<unsigned> Socket::getPid() { if (mFailed) return std::nullopt; sockaddr_nl sa = {}; socklen_t sasize = sizeof(sa); if (getsockname(mFd.get(), reinterpret_cast<sockaddr*>(&sa), &sasize) < 0) { Loading
automotive/can/1.0/default/libnl++/include/libnl++/Message.h +4 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <libnl++/Attributes.h> #include <libnl++/Buffer.h> #include <set> namespace android::nl { /** Loading Loading @@ -60,7 +62,8 @@ class Message { * \return Parsed message or nullopt, if the buffer data is invalid or message type * doesn't match. */ static std::optional<Message<T>> parse(Buffer<nlmsghdr> buf, std::set<nlmsgtype_t> msgtypes) { static std::optional<Message<T>> parse(Buffer<nlmsghdr> buf, const std::set<nlmsgtype_t>& msgtypes) { const auto& [nlOk, nlHeader] = buf.getFirst(); // we're doing it twice, but it's fine if (!nlOk) return std::nullopt; Loading