aboutsummaryrefslogtreecommitdiff
path: root/wmediumd_server
diff options
context:
space:
mode:
authorSeungjae Yoo <seungjaeyoo@google.com>2023-04-11 14:43:41 +0900
committerSeungjae Yoo <seungjaeyoo@google.com>2023-04-17 15:37:35 +0900
commitf0058e9439a3206ed5f61b6864044abd96d539f7 (patch)
treebf147033c7996651571bc641b782aba0e4842b27 /wmediumd_server
parentbc21ed09e5f19133942a5812fb2adddda55bfce4 (diff)
downloadwmediumd-f0058e9439a3206ed5f61b6864044abd96d539f7.tar.gz
Add SetPosition into WmediumdService
Bug: 273384914 Test: cvd env cvd-1 call WmediumdService SetPosition "mac_address:'42:00:00:00:01:00' x_pos:100.0 y_pos:100.0" && wmediumd_control list_stations Change-Id: I4229047e125191a051a7fbd629530a0beac224c1
Diffstat (limited to 'wmediumd_server')
-rw-r--r--wmediumd_server/wmediumd.proto15
-rw-r--r--wmediumd_server/wmediumd_server.cc100
-rw-r--r--wmediumd_server/wmediumd_server.h2
3 files changed, 99 insertions, 18 deletions
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