Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux platform support #2098

Draft
wants to merge 185 commits into
base: main
Choose a base branch
from
Draft

Linux platform support #2098

wants to merge 185 commits into from

Conversation

vibhavp
Copy link

@vibhavp vibhavp commented Aug 29, 2023

Summary

This PR adds an implementation geared towards Desktop Linux systems in internal/platform/implementation/linux. The motivation behind the code is to rely on widely available interfaces to implement mediums, and to use D-Bus as the primary transport for talking to system services. The code is broadly untested (and undocumented!), and is currently missing an implementation for the Bluetooth Low Energy medium, as I still haven't gotten around to understanding BlueZ's LE interfaces, parts of which are currently marked as experimental.
The implementation tries to rely on as few external libraries as possible, and as such, pulls in sdbus-c++, libsystemd, and libcurl via pkg-config rules added to WORKSPACE.

Additionally, the branch also includes a prototype for connectionsd, a daemon that will expose a D-Bus interface for the connections v1 and v3 APIs, centralizing resource management and providing a portable API for app developers.

To help aid understanding, here's a list of the main ImplementationPlatform components and the services/APIs used to implement them:

Classic Bluetooth

  • api::BluetoothAdapter: Backed by the org.bluez.Adapter1 interface.
  • api::BluetoothDevice: Uses org.bluez.Device1.
  • Pairing is handled through org.bluez.Device1, with sockets implemented by registering org.bluez.Profile1 with org.bluez.ProfileManager1 (documented here). A ProfileManager is in charge of tracking registered services, and any connections/sockets created on the same per device.
  • Scanning and discovery is performed by calling StartDiscovery on the adapter, and monitoring the adapter object for new objects implementing org.bluez.Device1.

Networking

  • The only supported backend right now is NetworkManager as its status as the de-facto network configuration service on Linux desktops.
  • Scanning for WiFi APs, creating hotspots, connecting to WiFi networks, and fetching networking and connectivity information is done through the NetworkManager D-Bus APIs.
  • api::WifiLan uses the Avahi's D-Bus interfaces for performing service discovery and advertising.

api::DeviceInfo

  • Download and AppData paths are handled using the environment variables specified by the XDG Base Directory Spec.
  • Screen lock information and support for preventing device sleep is provided via org.freedesktop.login1 (implemented by systemd-logind).
  • Device type and name are looked up from org.freedesktop.hostname1 (implemented by systemd-hostnamed).

Miscellaneous

  • api::LogMessage: All LogMessages are sent to a glog LogSink that implements the org.freedesktop.LogControl1 D-Bus interface, to allow the log target and severity threshold to be externally controlled via the default bus connection (at the name com.google.nearby).
  • HTTP requests are executed using libcurl.

TODOs

  • Support persisting radio names through BluetoothAdapter::SetName
  • Add support for sending basic payloads over connectionsd.
  • Test implemented mediums with unit tests and through connectionsd
  • Move generated D-Bus client and server headers to a generated folder.
  • Implement api::CredentialStorage, preferably using org.freedesktop.Secret.Service
  • Sockets for all mediums currently share a simple unbuffered fd backed implementation. Does this need to be specialized further?

proatgram and others added 30 commits May 18, 2023 13:33
The build directories should not be commited and definitly not pushed to
remote. This will prevent that from accidentally happening, and will
declutter `git status`
This is the start of the implementing for the Linux platform.

I aim to make this as similar to the Windows platform as possible,
although due to the fundamental difference in the two OS's, there will
be things that need to be different.
As such, I will be using the Windows platform files as a base, and
reimplementing the functions with Linux equivalents.

I am sure this will have bugs, which by my best attempt will be fixed
when found.
There was no free after we were finished with the interface pointer
There are a couple of places where apps can store data in Linux, one is
in the HOME directory, which is being phased out, the second, is in
HOME/.config, and the other is HOME/.local/share. This uses
HOME/.local/share, and since there isn't a common appdata path on Linux
that function will just return the local appdata path.
This adds a Linux equivalent to file path operations done in the Windows
headers and source files. Some differences that will occur are the
invalid path names and contents, as there are no invalid path names, and
only one invalid path content (excluding non-printable characters) on
Linux.
The `http_loader` class takes a `WebRequest` with information to send a
web request, and sends it. This uses `libcurl`, which is present from
installation on most major Linux distrobutions (e.g. Fedora, Ubuntu,
PopOS...).

If libcurl is not present on the target system, it will need to be
installed.
A file was named wrong. It was changed.
The Windows implementation of the Timer class (in timer.h) used Timer
Queues. This brings in implementation for a mostly Windows complient
TimerQueue class to work with the Timer class.
This are unimplemented currently, but will be in the future.
I missed some implementation when I was looking over them. These are
them.
@vibhavp
Copy link
Author

vibhavp commented Sep 13, 2023

I have removed connectionsd, as the project should probably live outside the library, and the daemon's implementation presents a bunch of issues that are currently outside the scope of this PR.
Additionally, using the C++ core API, I've written a Linux implementation of Google's WalkieTalkie Automatic example app at https://github.com/vibhavp/nearby/tree/sample-walkietakie, which serves as a minimal enough test case to test the Linux code. While the app only supports playback for now, I have been able to successfully connect to and playback incoming audio payloads from an Android WalkieTalkie instance over WifiLan, Wifi Direct/Hotspot and Bluetooth Classic, both through discovery and advertising. The recently added BLEv2 code still hasn't been tested yet, though I hope to find enough time to be able to do so soon.

@Cattn
Copy link

Cattn commented Feb 2, 2024

This looks promising!

@anayw2001
Copy link
Collaborator

Hi! I was wondering if it would be possible to split up this PR into the following:

  • A base PR implementing a Linux base platform with the common utilities (though I think most of that can be done via Abseil)
  • And a PR for adding each medium/bit of functionality

This would make this much easier to review (if you still would like to get this code merged), thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants