diff options
author | Seungjae Yoo <seungjaeyoo@google.com> | 2023-04-18 05:25:38 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-18 05:25:38 +0000 |
commit | 9a7825e01db61d2fffcb286cd5d11e9781e904af (patch) | |
tree | bf147033c7996651571bc641b782aba0e4842b27 | |
parent | 853665dc3f07a51e1100732f7fa637503d6fe0f6 (diff) | |
parent | 14a365cb860ae87029c77e044b430b46f2caa454 (diff) | |
download | wmediumd-9a7825e01db61d2fffcb286cd5d11e9781e904af.tar.gz |
Add SetPosition into WmediumdService am: f0058e9439 am: ff489ad593 am: 14a365cb86
Original change: https://android-review.googlesource.com/c/platform/external/wmediumd/+/2530763
Change-Id: I3a564dc435d727b477c05dd918f07590e7d78cc6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | main.cc | 11 | ||||
-rw-r--r-- | wmediumd/grpc.h | 42 | ||||
-rw-r--r-- | wmediumd/wmediumd.c | 48 | ||||
-rw-r--r-- | wmediumd/wmediumd.h | 5 | ||||
-rw-r--r-- | wmediumd_server/wmediumd.proto | 15 | ||||
-rw-r--r-- | wmediumd_server/wmediumd_server.cc | 100 | ||||
-rw-r--r-- | wmediumd_server/wmediumd_server.h | 2 |
7 files changed, 200 insertions, 23 deletions
@@ -22,6 +22,8 @@ #include <android-base/logging.h> #include <android-base/strings.h> +#include <sys/eventfd.h> +#include <sys/msg.h> #include <wmediumd/wmediumd.h> #include <wmediumd_server/wmediumd_server.h> @@ -40,16 +42,21 @@ int main(int argc, char* argv[]) { } } + int fd = eventfd(0, 0); + int msq_id = msgget(IPC_PRIVATE, IPC_CREAT | 0666); + std::thread wmediumd_server_thread; if (!grpc_uds_path.empty()) { - wmediumd_server_thread = std::thread(RunWmediumdServer, grpc_uds_path); + wmediumd_server_thread = std::thread(RunWmediumdServer, grpc_uds_path, fd, msq_id); } - wmediumd_main(wmediumd_args.size(), wmediumd_args.data()); + wmediumd_main(wmediumd_args.size(), wmediumd_args.data(), fd, msq_id); if (!grpc_uds_path.empty()) { wmediumd_server_thread.join(); } + msgctl(msq_id, IPC_RMID, 0); + close(fd); return 0; }
\ No newline at end of file diff --git a/wmediumd/grpc.h b/wmediumd/grpc.h new file mode 100644 index 0000000..69084f2 --- /dev/null +++ b/wmediumd/grpc.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#define GRPC_MSG_BUF_MAX 1024 + +// Do not use_zero, the type of the message queue should be positive value. +enum wmediumd_grpc_type { + GRPC_REQUEST = 1, + GRPC_RESPONSE, +}; + +// Do not use zero, writing zero to eventfd doesn't throw an event. +enum wmediumd_grpc_request_type { + REQUEST_SET_POSITION = 1, +}; + +// Do not use zero, writing zero to eventfd doesn't throw an event. +enum wmediumd_grpc_response_type { + RESPONSE_INVALID = 1, + RESPONSE_ACK, +}; + +struct wmediumd_grpc_message { + long type; + char data[GRPC_MSG_BUF_MAX]; +};
\ No newline at end of file diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c index 2b1e9a4..0f4f050 100644 --- a/wmediumd/wmediumd.c +++ b/wmediumd/wmediumd.c @@ -39,6 +39,7 @@ #include <unistd.h> #include <stdarg.h> #include <endian.h> +#include <sys/msg.h> #include <usfstl/loop.h> #include <usfstl/sched.h> #include <usfstl/schedctrl.h> @@ -50,6 +51,7 @@ #include "config.h" #include "api.h" #include "pmsr.h" +#include "grpc.h" USFSTL_SCHEDULER(scheduler); @@ -1518,6 +1520,43 @@ static void close_pcapng(struct wmediumd *ctx) { static void init_pcapng(struct wmediumd *ctx, const char *filename); +static void wmediumd_grpc_service_handler(struct usfstl_loop_entry *entry) { + struct wmediumd *ctx = entry->data; + + // Receive request type from WmediumdService + uint64_t request_type; + read(entry->fd, &request_type, sizeof(uint64_t)); + + struct wmediumd_grpc_message request_body; + uint64_t response_type; + + // Receive request body from WmediumdService and do the task. + // TODO(273384914): Support more request types. + switch (request_type) { + case REQUEST_SET_POSITION: + if (msgrcv(ctx->msq_id, &request_body, sizeof(struct wmediumd_set_position), GRPC_REQUEST, 0) != sizeof(struct wmediumd_set_position)) { + w_logf(ctx, LOG_ERR, "%s: failed to get set_position request body\n", __func__); + } + + if (process_set_position_message(ctx, (struct wmediumd_set_position *)(request_body.data)) < 0) { + w_logf(ctx, LOG_ERR, "%s: failed to execute set_position\n", __func__); + response_type = RESPONSE_INVALID; + } + response_type = RESPONSE_ACK; + break; + default: + w_logf(ctx, LOG_ERR, "%s: unknown request type\n", __func__); + response_type = RESPONSE_INVALID; + break; + } + + // TODO(273384914): Send response with response_type + return; +} + +// TODO(273384914): Deprecate messages used in wmediumd_control after +// implementing in wmediumd_grpc_service_handler to be used in the command +// 'cvd env'. static void wmediumd_api_handler(struct usfstl_loop_entry *entry) { struct client *client = container_of(entry, struct client, loop); @@ -1871,7 +1910,7 @@ static void init_pcapng(struct wmediumd *ctx, const char *filename) #define VIRTIO_F_VERSION_1 32 #endif -int wmediumd_main(int argc, char *argv[]) +int wmediumd_main(int argc, char *argv[], int event_fd, int msq_id) { int opt; struct wmediumd ctx = {}; @@ -2022,6 +2061,13 @@ int wmediumd_main(int argc, char *argv[]) usfstl_sched_wallclock_init(&scheduler, 1000); } + // Control event_fd to communicate WmediumdService. + ctx.grpc_loop.handler = wmediumd_grpc_service_handler; + ctx.grpc_loop.data = &ctx; + ctx.grpc_loop.fd = event_fd; + usfstl_loop_register(&ctx.grpc_loop); + ctx.msq_id = msq_id; + while (1) { if (time_socket) { usfstl_sched_next(&scheduler); diff --git a/wmediumd/wmediumd.h b/wmediumd/wmediumd.h index c40f111..695f871 100644 --- a/wmediumd/wmediumd.h +++ b/wmediumd/wmediumd.h @@ -214,9 +214,10 @@ struct client { struct wmediumd { int timerfd; + int msq_id; struct nl_sock *sock; - struct usfstl_loop_entry nl_loop; + struct usfstl_loop_entry nl_loop, grpc_loop; struct usfstl_sched_ctrl *ctrl; @@ -310,7 +311,7 @@ int get_max_index(void); extern "C" { #endif -int wmediumd_main(int argc, char *argv[]); +int wmediumd_main(int argc, char *argv[], int event_fd, int msq_id); #ifdef __cplusplus } diff --git a/wmediumd_server/wmediumd.proto b/wmediumd_server/wmediumd.proto index c25b8c8..6939f7f 100644 --- a/wmediumd_server/wmediumd.proto +++ b/wmediumd_server/wmediumd.proto @@ -16,14 +16,15 @@ syntax = "proto3"; package wmediumdserver; +import "google/protobuf/empty.proto"; + service WmediumdService { - rpc Wmediumd (WmediumdRequest) returns (WmediumdReply) {} + // TODO(273384914): Define a response type. + rpc SetPosition (SetPositionRequest) returns (google.protobuf.Empty) {} } -message WmediumdRequest { - string message = 1; +message SetPositionRequest { + string mac_address = 1; + double x_pos = 2; + double y_pos = 3; } - -message WmediumdReply { - string message = 1; -}
\ No newline at end of file diff --git a/wmediumd_server/wmediumd_server.cc b/wmediumd_server/wmediumd_server.cc index 48388d5..09b3283 100644 --- a/wmediumd_server/wmediumd_server.cc +++ b/wmediumd_server/wmediumd_server.cc @@ -16,36 +16,116 @@ * */ +#include <algorithm> +#include <array> #include <iostream> #include <memory> #include <string> +#include <unistd.h> +#include <android-base/strings.h> #include <gflags/gflags.h> #include <grpcpp/ext/proto_server_reflection_plugin.h> #include <grpcpp/grpcpp.h> #include <grpcpp/health_check_service_interface.h> +#include <sys/msg.h> +#include "wmediumd/api.h" +#include "wmediumd/grpc.h" #include "wmediumd.grpc.pb.h" -using wmediumdserver::WmediumdReply; -using wmediumdserver::WmediumdRequest; -using wmediumdserver::WmediumdService; +using google::protobuf::Empty; using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; +using grpc::StatusCode; +using wmediumdserver::SetPositionRequest; +using wmediumdserver::WmediumdService; -class WmediumdServiceImpl final : public WmediumdService::Service { - Status Wmediumd(ServerContext* context, const WmediumdRequest* request, - WmediumdReply* reply) override { - reply->set_message(request->message()); - return Status::OK; +#define MAC_ADDR_LEN 6 +#define STR_MAC_ADDR_LEN 17 + +template <class T> +static void AppendBinaryRepresentation(std::string& buf, const T& data) { + std::copy(reinterpret_cast<const char*>(&data), + reinterpret_cast<const char*>(&data) + sizeof(T), + std::back_inserter(buf)); +} + +bool IsValidMacAddr(const std::string& mac_address) { + if (mac_address.size() != STR_MAC_ADDR_LEN) { + return false; } + + if (mac_address[2] != ':' || mac_address[5] != ':' || mac_address[8] != ':' || + mac_address[11] != ':' || mac_address[14] != ':') { + return false; + } + + for (int i = 0; i < STR_MAC_ADDR_LEN; ++i) { + if ((i - 2) % 3 == 0) continue; + char c = mac_address[i]; + + if (isupper(c)) { + c = tolower(c); + } + + if ((c < '0' || c > '9') && (c < 'a' || c > 'f')) return false; + } + + return true; +} + +static std::array<uint8_t, 6> ParseMacAddress(const std::string& mac_address) { + auto split_mac = android::base::Split(mac_address, ":"); + std::array<uint8_t, 6> mac; + for (int i = 0; i < 6; i++) { + char* end_ptr; + mac[i] = (uint8_t)strtol(split_mac[i].c_str(), &end_ptr, 16); + } + + return mac; +} + +class WmediumdServiceImpl final : public WmediumdService::Service { + public: + WmediumdServiceImpl(int event_fd, int msq_id) : event_fd_(event_fd), msq_id_(msq_id) {} + + Status SetPosition(ServerContext* context, const SetPositionRequest* request, + Empty* reply) override { + // Validate parameters + if (!IsValidMacAddr(request->mac_address())) { + return Status(StatusCode::INVALID_ARGUMENT, "Got invalid mac address"); + } + auto mac = ParseMacAddress(request->mac_address()); + + // Construct request data + struct wmediumd_set_position data; + memcpy(data.mac, &mac, sizeof(mac)); + data.x = request->x_pos(); + data.y = request->y_pos(); + + // Fill data in the message queue + struct wmediumd_grpc_message msg; + msg.type = GRPC_REQUEST; + memcpy(msg.data, &data, sizeof(data)); + msgsnd(msq_id_, &msg, sizeof(data), 0); + + // Throw an event to wmediumd + uint64_t value = REQUEST_SET_POSITION; + write(event_fd_, &value, sizeof(uint64_t)); + + return Status::OK; + } + private: + int event_fd_; + int msq_id_; }; -void RunWmediumdServer(std::string grpc_uds_path) { +void RunWmediumdServer(std::string grpc_uds_path, int event_fd, int msq_id) { std::string server_address("unix:" + grpc_uds_path); - WmediumdServiceImpl service; + WmediumdServiceImpl service(event_fd, msq_id); grpc::EnableDefaultHealthCheckService(true); grpc::reflection::InitProtoReflectionServerBuilderPlugin(); diff --git a/wmediumd_server/wmediumd_server.h b/wmediumd_server/wmediumd_server.h index 21e3c84..31761ac 100644 --- a/wmediumd_server/wmediumd_server.h +++ b/wmediumd_server/wmediumd_server.h @@ -16,4 +16,4 @@ * */ -void RunWmediumdServer(std::string grpc_uds_path);
\ No newline at end of file +void RunWmediumdServer(std::string grpc_uds_path, int event_fd, int msq_id);
\ No newline at end of file |