diff --git a/api/api_helper.h b/api/api_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..0e48ccc303864881bc65fc7e3e83ba3554991488 --- /dev/null +++ b/api/api_helper.h @@ -0,0 +1,39 @@ +#ifndef API_HELPER_H +#define API_HELPER_H + +#include "api.h" + +#include <errno.h> +#include <sys/socket.h> + +#include <msgpack.hpp> + +namespace blue +{ + +template<class T> +bool send_reply(int fd, T msg) +{ + msgpack::sbuffer sbuf; + msghdr hdr{}; + + msgpack::pack(sbuf, msg); + if (sbuf.size() > blue::MAX_RPC_MSG_SIZE) + { + errno = EMSGSIZE; + return false; + } + + iovec vec = { sbuf.data(), sbuf.size() }; + hdr.msg_iov = &vec; + hdr.msg_iovlen = 1; + + if (sendmsg(fd, &hdr, 0) == -1) + return false; + + return true; +} + +} + +#endif // API_HELPER_H diff --git a/daemon/src/blue_daemon.cpp b/daemon/src/blue_daemon.cpp index c5a03a887f48fe96dee4c0ca5bb6a439dbd10162..58835b014bbbc8b012902e7cfb99d6e4510828d1 100644 --- a/daemon/src/blue_daemon.cpp +++ b/daemon/src/blue_daemon.cpp @@ -17,42 +17,15 @@ #include <sstream> #include "api.h" +#include "api_helper.h" using path = std::filesystem::path; -template<class T> -bool send_reply(int fd, T msg) -{ - msgpack::sbuffer sbuf; - msghdr hdr{}; - - msgpack::pack(sbuf, msg); - if (sbuf.size() > blue::MAX_RPC_MSG_SIZE) - { - syslog(LOG_ERR, "RPC message too large, not sending."); - return false; - } - - iovec vec = { sbuf.data(), sbuf.size() }; - hdr.msg_iov = &vec; - hdr.msg_iovlen = 1; - - if (sendmsg(fd, &hdr, 0) == -1) - { - syslog(LOG_ERR, "Failed to send message: %s", - strerror(errno)); - return false; - } - - return true; -} - -static void send_empty_reply(rpc_client &client, uint32_t op, - const char *error_msg) +static void send_empty_reply(int fd, uint32_t op, const char *error_msg) { blue::rpc_msg reply{}; reply.op = op; - if (!send_reply(client.get_fd(), reply)) + if (!send_reply(fd, reply)) syslog(LOG_WARNING, "%s: %s", error_msg, strerror(errno)); } @@ -125,7 +98,7 @@ void blue_daemon::query_complete(blue::hci_socket &s, bool success, std::stringstream ss; ss << d; msg.name = ss.str(); - if (!send_reply(client.get_fd(), msg)) + if (!blue::send_reply(client.get_fd(), msg)) { syslog(LOG_ERR, "Failed to send device to client: %s", strerror(errno)); @@ -135,7 +108,7 @@ void blue_daemon::query_complete(blue::hci_socket &s, bool success, blue::rpc_msg done_msg{}; done_msg.op = blue::OP_SCAN_DONE; - if (!send_reply(client.get_fd(), done_msg)) + if (!blue::send_reply(client.get_fd(), done_msg)) syslog(LOG_ERR, "Failed to send scan done to client: %s", strerror(errno)); } @@ -300,7 +273,7 @@ void blue_daemon::process_client_data(rpc_client &client) blue::msg_scan_reply reply{}; reply.result = scan() ? blue::OP_SUCCESS : blue::OP_BUSY; - if (!send_reply(client.get_fd(), reply)) + if (!blue::send_reply(client.get_fd(), reply)) { syslog(LOG_WARNING, "Could not send scan request reply: %s", strerror(errno)); @@ -352,7 +325,7 @@ void blue_daemon::pair_request(rpc_client &client, syslog(LOG_ERR, "Could not pair device: %s", e.what()); } - if (!send_reply(client.get_fd(), reply)) + if (!blue::send_reply(client.get_fd(), reply)) { syslog(LOG_WARNING, "Could not send pair request reply: %s", strerror(errno)); @@ -360,7 +333,7 @@ void blue_daemon::pair_request(rpc_client &client, } else { - send_empty_reply(client, blue::OP_PAIR_UNKNOWN, + send_empty_reply(client.get_fd(), blue::OP_PAIR_UNKNOWN, "Could not send pair request reply"); } } @@ -368,7 +341,7 @@ void blue_daemon::pair_request(rpc_client &client, { syslog(LOG_WARNING, "Pairing error: %s", e.what()); - send_empty_reply(client, blue::OP_PAIR_ERROR, + send_empty_reply(client.get_fd(), blue::OP_PAIR_ERROR, "Could not send pair request reply"); } } @@ -384,18 +357,18 @@ void blue_daemon::set_pin_request(rpc_client &client, { d->second.set_pin(p_msg.pin); - send_empty_reply(client, blue::OP_SUCCESS, + send_empty_reply(client.get_fd(), blue::OP_SUCCESS, "Could not send PIN success reply"); } catch (const std::length_error &e) { - send_empty_reply(client, blue::OP_SET_DEVICE_PIN_TOO_LONG, + send_empty_reply(client.get_fd(), blue::OP_SET_DEVICE_PIN_TOO_LONG, "Could not send PIN too long reply"); } } else { - send_empty_reply(client, blue::OP_SET_DEVICE_PIN_UNKNOWN, + send_empty_reply(client.get_fd(), blue::OP_SET_DEVICE_PIN_UNKNOWN, "Could not send PIN device unknown reply"); } }