DBus 上第二个 class 的方法不可调用

Methods of second class on DBus not callable

我用 Vala 语言创建了 Dbus 服务。它创建接口以添加具有不同路径的设备。设备必须扫描子路径上的目录和绑定方法。

然后我调用 su.example.Phone.AddBySyspath(/sys/bus/usb/devices/2-2.4),它 returns “/su/example/phone/2_2d4” 如预期的那样。但是在这条路径上调用 Reset 会导致 "Unable to find method Reset on path /su/example/phone/2_2d4 in interface su.example.Phone".

我有代码:

using Gee;

[DBus (name = "su.example.Phone")]
public class Phone : Object {

    Regex ttyregex;
    string path;
    string manufacturer;

    public Phone(string path){
        this.path = path;
        this.ttyregex = new Regex ("tty[A-Z0-9]+");
        this.manufacturer = "Unknown";
        load();
    }

    private async void load(){
        string[3] ttys = {"", "", ""};
        var dir = File.new_for_path (path);
        stderr.printf ("path %s\n", path);

        FindTTY(dir,0,ttys);
        stdout.printf ("done\n");
    }


    private void FindTTY(File dir, int sub, string[] ttys){
        sub++;
        FileEnumerator enumerator = dir.enumerate_children(
            "standard::*",
            FileQueryInfoFlags.NONE
        );

        FileInfo info = null;
        while
            ((info = enumerator.next_file ()) != null)
        {
            var name = info.get_name ();

            if (name == "manufacturer") {
                File f = dir.resolve_relative_path (info.get_name ());
                var dis = new DataInputStream (f.read ());
                manufacturer = dis.read_line (null);
            }

            stdout.printf ("%s\n", info.get_name ());
            stdout.printf ("%d\n", info.get_file_type ());
        }
    }

    public string reset() throws Error {

        stdout.printf ("ATZ\n");
        return "OK";

    }



}



[DBus (name = "su.example.Phone")]
public class PhoneServer : Object {

    Regex dotregex;
    Regex nonalpharegex;

    private DBusConnection conn;
    private HashMap<string, Phone> map;

    public PhoneServer(DBusConnection conn) {
        this.conn = conn;
        this.map = new HashMap<string, Phone> ();

        this.dotregex = new Regex ("[.]+");
        this.nonalpharegex = new Regex ("\W+");

    }



    public string add_by_syspath(string path, GLib.BusName sender) throws Error {
        // path = /sys/bus/usb/devices/2-2.4

        var pathv = path.split("/");
        string name = pathv[pathv.length-1];

        name = dotregex.replace(name,name.length,0, "d");
        name = nonalpharegex.replace(name,name.length,0, "_");

        stderr.printf ("name %s\n", name);

        var buspath = "/su/example/phone/%s".printf(name);

        if (map.has_key(name)) {

        } else {

            var phone = new Phone (path);
            map.set(name,phone);

            try {
                conn.register_object ("/su/example/phone/%s".printf(name), phone);
            } catch (IOError e) {
                stderr.printf ("Could not register service\n");
            }

        }

        return buspath;
    }
}

[DBus (name = "su.example.PhoneError")]
public errordomain PhoneError
{
    SOME_ERROR
}


void on_bus_aquired (DBusConnection conn) {
    try {
        conn.register_object ("/su/example/phone", new PhoneServer (conn));
    } catch (IOError e) {
        stderr.printf ("Could not register service\n");
    }
}

void main (string[] args) {

    Bus.own_name (BusType.SYSTEM, "su.example.Phone", BusNameOwnerFlags.NONE,
                  on_bus_aquired,
                  () => {},
                  () => stderr.printf ("Could not aquire name\n"));

    new MainLoop ().run ();
}

在写问题的时候我解决了这个问题。

我需要为处理程序使用不同的 DBus 名称 类:

[DBus (name = "su.eerie.PhoneManager.Phone")]
public class Phone : Object {

...


[DBus (name = "su.eerie.PhoneManager")]
public class PhoneServer : Object {

...