Add headers.

This commit is contained in:
Vibhav Pant
2023-09-26 18:35:48 +05:30
parent 97af86a414
commit 71f54ac820
2 changed files with 238 additions and 0 deletions
@@ -0,0 +1,65 @@
// Copyright 2023 Google LLC
//
// 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
//
// https://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.
#ifndef PLATFORM_IMPL_LINUX_BLUEZ_DEVICE_H_
#define PLATFORM_IMPL_LINUX_BLUEZ_DEVICE_H_
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/ProxyInterfaces.h>
#include <sdbus-c++/Types.h>
#include "absl/functional/any_invocable.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/generated/dbus/bluez/device_client.h"
namespace nearby {
namespace linux {
namespace bluez {
class Device : public sdbus::ProxyInterfaces<org::bluez::Device1_proxy> {
public:
Device(std::shared_ptr<sdbus::IConnection> system_bus,
const sdbus::ObjectPath &device_path)
: ProxyInterfaces(*system_bus, "org.bluez", device_path),
system_bus(std::move(system_bus)) {
registerProxy();
}
~Device() { unregisterProxy(); }
void SetPairReplyCallback(absl::AnyInvocable<void(const sdbus::Error *)> cb)
ABSL_LOCKS_EXCLUDED(pair_callback_lock_) {
absl::MutexLock l(&pair_callback_lock_);
on_pair_reply_cb_ = std::move(cb);
}
void ResetPairReplyCallback() ABSL_LOCKS_EXCLUDED(pair_callback_lock_) {
absl::MutexLock l(&pair_callback_lock_);
on_pair_reply_cb_ = nullptr;
}
protected:
void onPairReply(const sdbus::Error *error) override
ABSL_LOCKS_EXCLUDED(pair_callback_lock_) {
absl::ReaderMutexLock l(&pair_callback_lock_);
if (on_pair_reply_cb_ != nullptr) on_pair_reply_cb_(error);
};
private:
std::shared_ptr<sdbus::IConnection> system_bus;
absl::Mutex pair_callback_lock_;
absl::AnyInvocable<void(const sdbus::Error *)> on_pair_reply_cb_
ABSL_GUARDED_BY(pair_callback_lock_) = nullptr;
};
} // namespace bluez
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,173 @@
// Copyright 2023 Google LLC
//
// 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
//
// https://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.
#ifndef PLATFORM_IMPL_LINUX_TCP_SERVER_SOCKET_H_
#define PLATFORM_IMPL_LINUX_TCP_SERVER_SOCKET_H_
#include <arpa/inet.h>
#include <netinet/in.h>
#include <atomic>
#include <functional>
#include <sdbus-c++/Types.h>
#include "internal/platform/exception.h"
#include "internal/platform/implementation/linux/stream.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
class TCPSocket {
public:
explicit TCPSocket(const sdbus::UnixFd& fd)
: closed_(false), output_stream_(fd), input_stream_(fd) {}
static std::optional<TCPSocket> Connect(const std::string& ip_address,
int port) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error opening socket: " << std::strerror(errno);
return std::nullopt;
}
NEARBY_LOGS(VERBOSE) << __func__ << ": Connecting to " << ip_address << ":"
<< port;
struct sockaddr_in addr;
addr.sin_addr.s_addr = inet_addr(ip_address.c_str());
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
auto ret =
connect(sock, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error connecting to socket: "
<< std::strerror(errno);
return std::nullopt;
}
return TCPSocket(sdbus::UnixFd(sock));
}
InputStream& GetInputStream() { return input_stream_; }
OutputStream& GetOutputStream() { return output_stream_; }
Exception Close() {
if (closed_) return {Exception::kFailed};
closed_ = true;
input_stream_.Close();
output_stream_.Close();
return {Exception::kSuccess};
};
private:
bool closed_;
OutputStream output_stream_;
InputStream input_stream_;
};
class TCPServerSocket {
public:
explicit TCPServerSocket(int fd) : fd_(fd) {}
static std::optional<TCPServerSocket> Listen(
std::optional<const std::reference_wrapper<std::string>> ip_address,
int port) {
auto sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error opening socket: " << std::strerror(errno);
return std::nullopt;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (ip_address.has_value())
addr.sin_addr.s_addr = inet_addr(ip_address->get().c_str());
else
addr.sin_addr.s_addr = htonl(INADDR_ANY);
auto ret =
bind(sock, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error binding to socket: "
<< std::strerror(errno);
return std::nullopt;
}
ret = listen(sock, 0);
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error listening on socket: "
<< std::strerror(errno);
return std::nullopt;
}
return TCPServerSocket(sock);
}
std::optional<TCPSocket> Accept() {
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
auto conn =
accept(fd_.get(), reinterpret_cast<struct sockaddr*>(&addr), &len);
if (conn < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error accepting incoming connections on socket "
<< fd_.get() << ": " << std::strerror(errno);
return std::nullopt;
}
return TCPSocket(sdbus::UnixFd(conn));
};
Exception Close() {
int fd = fd_.release();
shutdown(fd, SHUT_RDWR);
auto ret = close(fd);
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error closing socket " << fd << ": "
<< std::strerror(errno);
return {Exception::kFailed};
}
return {Exception::kSuccess};
};
int GetPort() const {
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
auto ret =
getsockname(fd_.get(), reinterpret_cast<struct sockaddr*>(&sin), &len);
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error getting information for socket "
<< fd_.get() << ": " << std::strerror(errno);
return 0;
}
return ntohs(sin.sin_port);
}
private:
sdbus::UnixFd fd_;
};
} // namespace linux
} // namespace nearby
#endif