Esempio n. 1
0
        public void Run()
        {
            //string serviceUUID="713d0000-503e-4c75-ba94-3148f18d941e";
            //string charVendorName = "713D0001-503E-4C75-BA94-3148F18D941E";
            //string charRead = "713D0002-503E-4C75-BA94-3148F18D941E";//rx
            //string charWrite = "713D0003-503E-4C75-BA94-3148F18D941E";//tx
            //string charAck = "713D0004-503E-4C75-BA94-3148F18D941E";
            //string charVersion = "713D0005-503E-4C75-BA94-3148F18D941E";
            //string clientCharacteristic = "00002902-0000-1000-8000-00805f9b34fb";

            System.Console.WriteLine("Starting Blend Micro Bootstrap");
            string Service = "org.bluez";
            //Important!: there is a flaw in dbus-sharp such that you can only register one interface
            //at each path, so we have to put these at 2 seperate paths, otherwise I'd probably just put them
            //both at root
            var agentPath       = new ObjectPath("/agent");
            var gattProfilePath = new ObjectPath("/gattprofiles");
            var blueZPath       = new ObjectPath("/org/bluez");

            //get a copy of the object manager so we can browse the "tree" of bluetooth items
            var manager = GetObject <org.freedesktop.DBus.ObjectManager> (Service, ObjectPath.Root);

            //register these events so we can tell when things are added/removed (eg: discovery)
            manager.InterfacesAdded += (p, i) => {
                System.Console.WriteLine(p + " Discovered");
            };
            manager.InterfacesRemoved += (p, i) => {
                System.Console.WriteLine(p + " Lost");
            };

            System.Console.WriteLine("Registring agent");
            //get the agent manager so we can register our agent
            var          agentManager = GetObject <AgentManager1> (Service, blueZPath);
            var          agent        = new DemoAgent();
            GattManager1 gattManager  = null;

            //register our agent and make it the default
            _system.Register(agentPath, agent);
            agentManager.RegisterAgent(agentPath, "KeyboardDisplay");
            agentManager.RequestDefaultAgent(agentPath);

            var devices = new List <Device1> ();

            try
            {
                System.Console.WriteLine("Fetching objects");
                //get the bluetooth object tree
                var managedObjects = manager.GetManagedObjects();
                //find our adapter
                ObjectPath adapterPath = null;
                foreach (var obj in managedObjects.Keys)
                {
                    System.Console.WriteLine("Checking " + obj);
                    if (managedObjects [obj].ContainsKey(typeof(LEAdvertisingManager1).DBusInterfaceName()))
                    {
                        System.Console.WriteLine("Adapter found at" + obj + " that supports LE");
                        adapterPath = obj;
                        break;
                    }
                }

                if (adapterPath == null)
                {
                    System.Console.WriteLine("Couldn't find adapter that supports LE");
                    return;
                }

                //get a dbus proxy to the adapter
                var adapter = GetObject <Adapter1> (Service, adapterPath);
                gattManager = GetObject <GattManager1>(Service, adapterPath);
                var gattProfile = new BlendGattProfile();
                _system.Register(gattProfilePath, gattProfile);
                gattManager.RegisterApplication(gattProfilePath, new Dictionary <string, object>());
                System.Console.WriteLine("Registered gatt profile");

                //assume discovery for ble
                //scan for any new devices
                System.Console.WriteLine("Starting LE Discovery...");
                var discoveryProperties = new Dictionary <string, object>();
                discoveryProperties["Transport"] = "le";
                adapter.SetDiscoveryFilter(discoveryProperties);
                adapter.StartDiscovery();
                Thread.Sleep(5000);                //totally arbitrary constant, the best kind
                //Thread.Sleep ((int)adapter.DiscoverableTimeout * 1000);

                //refresh the object graph to get any devices that were discovered
                //arguably we should do this in the objectmanager added/removed events and skip the full
                //refresh, but I'm lazy.
                System.Console.WriteLine("Discovery complete, refreshing");
                managedObjects = manager.GetManagedObjects();

                foreach (var obj in managedObjects.Keys)
                {
                    if (obj.ToString().StartsWith(adapterPath.ToString()))
                    {
                        if (managedObjects [obj].ContainsKey(typeof(Device1).DBusInterfaceName()))
                        {
                            var managedObject = managedObjects [obj];
                            if (managedObject[typeof(Device1).DBusInterfaceName()].ContainsKey("Name"))
                            {
                                var name = (string)managedObject[typeof(Device1).DBusInterfaceName()]["Name"];

                                if (name.StartsWith("MrGibbs"))
                                {
                                    System.Console.WriteLine("Device " + name + " at " + obj);
                                    var device = _system.GetObject <Device1> (Service, obj);

                                    var uuids = device.UUIDs;
                                    foreach (var uuid in device.UUIDs)
                                    {
                                        System.Console.WriteLine("\tUUID: " + uuid);
                                    }

                                    devices.Add(device);
                                }
                            }
                        }
                    }
                }

                var readCharPath = new ObjectPath("/org/bluez/hci0/dev_F6_58_7F_09_5D_E6/service000c/char000f");
                var readChar     = GetObject <GattCharacteristic1>(Service, readCharPath);
                var properties   = GetObject <Properties>(Service, readCharPath);

                properties.PropertiesChanged += new PropertiesChangedHandler(
                    new Action <string, IDictionary <string, object>, string[]>((@interface, changed, invalidated) => {
                    System.Console.WriteLine("Properties Changed on " + @interface);
                    if (changed != null)
                    {
                        foreach (var prop in changed.Keys)
                        {
                            if (changed[prop] is byte[])
                            {
                                foreach (var b in ((byte[])changed[prop]))
                                {
                                    System.Console.Write(b + ",");
                                }
                                System.Console.WriteLine("");
                            }
                            else
                            {
                                System.Console.WriteLine("{0}={1}", prop, changed[prop]);
                            }
                        }
                    }

                    if (invalidated != null)
                    {
                        foreach (var prop in invalidated)
                        {
                            System.Console.WriteLine(prop + " Invalidated");
                        }
                    }
                }));

                foreach (var device in devices)
                {
                    System.Console.WriteLine("Connecting to " + device.Name);
                    device.Connect();
                    System.Console.WriteLine("\tConnected");
                }

                readChar.StartNotify();

                System.Threading.Thread.Sleep(10000);

                readChar.StopNotify();
                System.Threading.Thread.Sleep(500);
            }
            finally
            {
                if (devices != null)
                {
                    foreach (var device in devices)
                    {
                        System.Console.WriteLine("Disconnecting " + device.Name);
                        device.Disconnect();
                        System.Console.WriteLine("\tDisconnected");
                    }
                }
                agentManager.UnregisterAgent(agentPath);
                gattManager.UnregisterApplication(gattProfilePath);
            }
        }
Esempio n. 2
0
        public void Run(bool doDiscovery, string adapterName)
        {
            var    devices = new List <Pebble> ();
            string Service = "org.bluez";
            //Important!: there is a flaw in dbus-sharp such that you can only register one interface
            //at each path, so we have to put these at 2 seperate paths, otherwise I'd probably just put them
            //both at root
            var agentPath   = new ObjectPath("/agent");
            var profilePath = new ObjectPath("/profiles");
            var blueZPath   = new ObjectPath("/org/bluez");

            //still don't really understand this.  The pebble advertises this uuid,
            //and this is what works, but all my reading tells me that the uuid for the
            //serial service should be the 2nd one
            string pebbleSerialUUID = "00000000-deca-fade-deca-deafdecacaff";
            //string serialServiceUUID = "00001101-0000-1000-8000-00805F9B34FB";

            //these properties are defined by bluez in /doc/profile-api.txt
            //but it turns out the defaults work just fine
            var properties = new Dictionary <string, object> ();
            //properties ["AutoConnect"] = true;
            //properties ["Name"] = "Serial Port";
            //properties ["Service"] = pebbleSerialUUID;
            //properties ["Role"] = "client";
            //properties ["PSM"] = (ushort)1;
            //properties ["RequireAuthentication"] = false;
            //properties ["RequireAuthorization"] = false;
            //properties ["Channel"] = (ushort)1;

            //get a proxy for the profile manager so we can register our profile
            var profileManager = GetObject <ProfileManager1> (Service, blueZPath);
            //create and register our profile
            var profile = new DemoProfile();

            _system.Register(profilePath, profile);
            profileManager.RegisterProfile(profilePath
                                           , pebbleSerialUUID
                                           , properties);
            System.Console.WriteLine("Registered profile with BlueZ");

            //get a copy of the object manager so we can browse the "tree" of bluetooth items
            var manager = GetObject <org.freedesktop.DBus.ObjectManager> (Service, ObjectPath.Root);

            //register these events so we can tell when things are added/removed (eg: discovery)
            manager.InterfacesAdded += (p, i) => {
                System.Console.WriteLine(p + " Discovered");
            };
            manager.InterfacesRemoved += (p, i) => {
                System.Console.WriteLine(p + " Lost");
            };

            //get the agent manager so we can register our agent
            var agentManager = GetObject <AgentManager1> (Service, blueZPath);
            var agent        = new DemoAgent();

            //register our agent and make it the default
            _system.Register(agentPath, agent);
            agentManager.RegisterAgent(agentPath, "KeyboardDisplay");
            agentManager.RequestDefaultAgent(agentPath);

            try
            {
                //get the bluetooth object tree
                var managedObjects = manager.GetManagedObjects();
                //find our adapter
                ObjectPath adapterPath = null;
                foreach (var obj in managedObjects.Keys)
                {
                    if (managedObjects [obj].ContainsKey(typeof(Adapter1).DBusInterfaceName()))
                    {
                        if (string.IsNullOrEmpty(adapterName) || obj.ToString().EndsWith(adapterName))
                        {
                            System.Console.WriteLine("Adapter found at" + obj);
                            adapterPath = obj;
                            break;
                        }
                    }
                }

                if (adapterPath == null)
                {
                    System.Console.WriteLine("Couldn't find adapter " + adapterName);
                    return;
                }

                //get a dbus proxy to the adapter
                var adapter = GetObject <Adapter1> (Service, adapterPath);

                if (doDiscovery)
                {
                    //scan for any new devices
                    System.Console.WriteLine("Starting Discovery...");
                    adapter.StartDiscovery();
                    Thread.Sleep(5000);                    //totally arbitrary constant, the best kind
                    //Thread.Sleep ((int)adapter.DiscoverableTimeout * 1000);

                    //refresh the object graph to get any devices that were discovered
                    //arguably we should do this in the objectmanager added/removed events and skip the full
                    //refresh, but I'm lazy.
                    managedObjects = manager.GetManagedObjects();
                }


                foreach (var obj in managedObjects.Keys)
                {
                    if (obj.ToString().StartsWith(adapterPath.ToString()))
                    {
                        if (managedObjects [obj].ContainsKey(typeof(Device1).DBusInterfaceName()))
                        {
                            var managedObject = managedObjects [obj];
                            var name          = (string)managedObject[typeof(Device1).DBusInterfaceName()]["Name"];

                            if (name.StartsWith("Pebble"))
                            {
                                System.Console.WriteLine("Device " + name + " at " + obj);
                                var device = _system.GetObject <Device1> (Service, obj);
                                devices.Add(new Pebble()
                                {
                                    Name = name, Device = device, Path = obj
                                });

                                if (!device.Paired)
                                {
                                    System.Console.WriteLine(name + " not paired, attempting to pair");
                                    device.Pair();
                                    System.Console.WriteLine("Paired");
                                }
                                if (!device.Trusted)
                                {
                                    System.Console.WriteLine(name + " not trust, attempting to trust");
                                    device.Trusted = true;
                                    System.Console.WriteLine("Trusted");
                                }
                            }
                        }
                    }
                }

                profile.NewConnectionAction = (path, fd, props) => {
                    var pebble = devices.Single(x => x.Path == path);
                    System.Console.WriteLine("Received FD " + fd + " for " + pebble.Name);
                    fd.SetBlocking();
                    System.Console.WriteLine(props.Count + " properties");
                    foreach (var k in props.Keys)
                    {
                        System.Console.WriteLine(k + ":" + props[k]);
                    }

                    pebble.FileDescriptor = fd;
                    pebble.Stream         = fd.OpenAsStream(true);

                    System.Console.WriteLine("Saying Hello...");
                    var pebbleHello = PebbleHello();

                    pebble.Stream.Write(pebbleHello, 0, pebbleHello.Length);
                    pebble.Stream.Flush();
                };

                foreach (var device in devices)
                {
                    try{
                        System.Console.WriteLine("Attempting Connection to " + device.Name);
                        System.Console.WriteLine("Paired:" + device.Device.Paired.ToString());
                        System.Console.WriteLine("Trusted:" + device.Device.Trusted.ToString());
                        System.Console.WriteLine("UUIDs:");
                        foreach (var uuid in device.Device.UUIDs)
                        {
                            System.Console.WriteLine(uuid);
                        }

                        System.Console.WriteLine("Connecting...");
                        device.Device.ConnectProfile(pebbleSerialUUID);
                        System.Console.WriteLine("Connected");
                    }
                    catch (Exception ex) {
                        System.Console.WriteLine("Bootstrap handler");
                        System.Console.WriteLine(ex.Message);
                        System.Console.WriteLine(ex.StackTrace);
                    }
                }

                while (true)
                {
                    byte[] buffer = new byte[72];
                    foreach (var pebble in devices)
                    {
                        int count = pebble.Stream.Read(buffer, 0, 72);
                        System.Console.WriteLine("Received data from " + pebble.Name);
                        string read = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
                        System.Console.WriteLine(read);
                    }
                }
            }
            finally
            {
                foreach (var pebble in devices)
                {
                    System.Console.WriteLine("Shutting down " + pebble.Name);
                    try{
                        System.Console.WriteLine("Closing FD");
                        pebble.FileDescriptor.Close();
                    }catch {}
                    try{
                        System.Console.WriteLine("Disconnecting");
                        pebble.Device.Disconnect();
                    }catch {}
                }

                agentManager.UnregisterAgent(agentPath);
                profileManager.UnregisterProfile(profilePath);
            }
        }