Code Monkey home page Code Monkey logo

dbux's Introduction

DBux

Build Status Coverage Status Hex.pm Hex.pm

DBux provides bindings for D-Bus IPC protocol for the Elixir programming language.

Project aims

DBux's aim is to provide low-level GenServer-like pattern to handle interaction with D-Bus daemon.

It is not going to provide high-level proxy that will magically map objects/interfaces exported over D-Bus to data structures used in your application. In my opinion it's a task for an another abstraction layer (read: another project built on top of DBux).

At the beginning it's going to provide only functionality needed to act as a client. Acting as a server may be added later.

Versioning

Project follows Semantic Versioning.

Status

Project in production use in at least one big app :) However, some things are still not implemented:

  • Marshalling variants that contain container types
  • Handling message timeouts
  • Handling introspection calls and other generic D-Bus methods
  • Other transports than TCP
  • Other authentication methods than anonymous

Installation

Add dependency to your mix.exs:

defp deps do
  [{:dbux, "~> 1.0.0"}]
end

Sample Usage

An example DBux.PeerConnection process:

defmodule MyApp.Bus do
  require Logger
  use DBux.PeerConnection

  @request_name_message_id :request_name
  @add_match_message_id    :add_match

  @introspection """
  <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
   "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
  <node name="/com/example/sample_object">
    <interface name="com.example.SampleInterface">
      <method name="Frobate">
        <arg name="foo" type="i" direction="in"/>
        <arg name="bar" type="s" direction="out"/>
        <arg name="baz" type="a{us}" direction="out"/>
        <annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
      </method>
      <method name="Bazify">
        <arg name="bar" type="(iiu)" direction="in"/>
        <arg name="bar" type="v" direction="out"/>
      </method>
      <method name="Mogrify">
        <arg name="bar" type="(iiav)" direction="in"/>
      </method>
      <signal name="Changed">
        <arg name="new_value" type="b"/>
      </signal>
      <property name="Bar" type="y" access="readwrite"/>
    </interface>
    <node name="child_of_sample_object"/>
    <node name="another_child_of_sample_object"/>
  </node>
  """

  def start_link(hostname, options \\ []) do
    DBux.PeerConnection.start_link(__MODULE__, hostname, options)
  end

  def init(hostname) do
    initial_state = %{hostname: hostname}

    {:ok, "tcp:host=" <> hostname <> ",port=8888", [:anonymous], initial_state}
  end

  def handle_up(state) do
    Logger.info("Up")

    {:send, [
      DBux.Message.build_signal("/", "org.example.dbux.MyApp", "Connected", []),
      {@add_match_message_id,    DBux.MessageTemplate.add_match(:signal, nil, "org.example.dbux.OtherIface")},
      {@request_name_message_id, DBux.MessageTemplate.request_name("org.example.dbux.MyApp", 0x4)}
    ], state}
  end

  def handle_down(state) do
    Logger.warn("Down")
    {:backoff, 1000, state}
  end

  def handle_method_call(serial, sender, "/", "Introspect", "org.freedesktop.DBus.Introspectable", _body, _flags, state) do
    Logger.debug("Got Introspect call")

    {:send, [
      DBux.Message.build_method_return(serial, sender, [%DBux.Value{type: :string, value: @introspection}])
    ], state}
  end

  def handle_method_return(_serial, _sender, _reply_serial, _body, @request_name_message_id, state) do
    Logger.info("Name acquired")
    {:noreply, state}
  end

  def handle_method_return(_serial, _sender, _reply_serial, _body, @add_match_message_id, state) do
    Logger.info("Match added")
    {:noreply, state}
  end

  def handle_error(_serial, _sender, _reply_serial, error_name, _body, @request_name_message_id, state) do
    Logger.warn("Failed to acquire name: " <> error_name)
    {:noreply, state}
  end

  def handle_error(_serial, _sender, _reply_serial, error_name, _body, @add_match_message_id, state) do
    Logger.warn("Failed to add match: " <> error_name)
    {:noreply, state}
  end

  def handle_signal(_serial, _sender, _path, _member, "org.example.dbux.OtherIface", _body, state) do
    Logger.info("Got signal from OtherIface")
    {:noreply, state}
  end

  def handle_signal(_serial, _sender, _path, _member, _member, _body, state) do
    Logger.info("Got other signal")
    {:noreply, state}
  end
end

And of the accompanying process that can control the connection:

defmodule MyApp.Core do
  def do_the_stuff do
    {:ok, connection} = MyApp.Bus.start_link("dbusserver.example.com")
  end
end

Authors

Marcin Lewandowski [email protected]

Debugging

If you encounter bugs, you may want to compile (not run, compile) the code with DBUX_DEBUG environment variable set to any value.

Contributing

You are welcome to open pull requests. Tests are mandatory.

Credits

Project is heavily inspired by Connection.

License

MIT

dbux's People

Contributors

khamilowicz avatar mspanc avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.