aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungjae Yoo <seungjaeyoo@google.com>2023-04-18 05:07:00 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-04-18 05:07:00 +0000
commit14a365cb860ae87029c77e044b430b46f2caa454 (patch)
treebf147033c7996651571bc641b782aba0e4842b27
parenta361310ba2f23a11579b8b39dbb63157cb83ad63 (diff)
parentff489ad593805def05b444e65ada8f13baa61496 (diff)
downloadwmediumd-14a365cb860ae87029c77e044b430b46f2caa454.tar.gz
Add SetPosition into WmediumdService am: f0058e9439 am: ff489ad593
Original change: https://android-review.googlesource.com/c/platform/external/wmediumd/+/2530763 Change-Id: Ib70fb9353937c0c4cc4ac5a338e9e74d49fd9e76 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--main.cc11
-rw-r--r--wmediumd/grpc.h42
-rw-r--r--wmediumd/wmediumd.c48
-rw-r--r--wmediumd/wmediumd.h5
-rw-r--r--wmediumd_server/wmediumd.proto15
-rw-r--r--wmediumd_server/wmediumd_server.cc100
-rw-r--r--wmediumd_server/wmediumd_server.h2
7 files changed, 200 insertions, 23 deletions
diff --git a/main.cc b/main.cc
index 25f8298..ae62f53 100644
--- a/main.cc
+++ b/main.cc
@@ -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