From 0177331e9e7ad8ade0c6de111661cdb05633639b Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Tue, 19 Apr 2016 16:45:12 +0200 Subject: [PATCH 1/9] Media Media Interfaces for sink --- Mono.BlueZ.DBus/MediaEndpoint1.cs | 16 ++++++++++++++ Mono.BlueZ.DBus/MediaTransport1.cs | 29 ++++++++++++++++++++++++++ Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj | 6 ++++-- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 Mono.BlueZ.DBus/MediaEndpoint1.cs create mode 100644 Mono.BlueZ.DBus/MediaTransport1.cs diff --git a/Mono.BlueZ.DBus/MediaEndpoint1.cs b/Mono.BlueZ.DBus/MediaEndpoint1.cs new file mode 100644 index 0000000..8677cc3 --- /dev/null +++ b/Mono.BlueZ.DBus/MediaEndpoint1.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using DBus; + +namespace Mono.BlueZ.DBus +{ + // on /org/bluez/hciX + [Interface("org.bluez.MediaEndpoint1")] + public interface MediaEndpoint1 + { + void SetConfiguration(ObjectPath transport, IDictionary properties); + byte[] SelectConfiguration(byte[] capabilities); + void ClearConfiguration(ObjectPath transport); + void Release(); + } +} \ No newline at end of file diff --git a/Mono.BlueZ.DBus/MediaTransport1.cs b/Mono.BlueZ.DBus/MediaTransport1.cs new file mode 100644 index 0000000..c97c17d --- /dev/null +++ b/Mono.BlueZ.DBus/MediaTransport1.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using DBus; + +namespace Mono.BlueZ.DBus +{ + // on /org/bluez/hciX + [Interface("org.bluez.MediaEndpoint1")] + public interface MediaEndpoint1 + { + FileDescriptor Acquire(); + FileDescriptor TryAcquire(); + void Release(); + readonly ObjectPath Device; + readonly string UUID; + readonly byte Codec ; + readonly byte[] Configuration; + readonly State State; + ushort Delay {get;set;} + ushort Volume {get;set;} + } + + public enum State + { + Idle = "idle", + Pending = "pending", + Active = "active" + } +} \ No newline at end of file diff --git a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj index 205033c..e06d0af 100644 --- a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj +++ b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj @@ -1,4 +1,4 @@ - + Debug @@ -31,6 +31,8 @@ + + @@ -64,4 +66,4 @@ dbus-sharp - + \ No newline at end of file From 231a072b20e067eac2d18bb6afa9e40c315c50ec Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Tue, 19 Apr 2016 16:57:22 +0200 Subject: [PATCH 2/9] A2DP Add A2DP properties --- Mono.BlueZ.DBus/A2DP.cs | 96 ++++++++++++++++++++++++++ Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj | 1 + 2 files changed, 97 insertions(+) create mode 100644 Mono.BlueZ.DBus/A2DP.cs diff --git a/Mono.BlueZ.DBus/A2DP.cs b/Mono.BlueZ.DBus/A2DP.cs new file mode 100644 index 0000000..595737e --- /dev/null +++ b/Mono.BlueZ.DBus/A2DP.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; + +namespace Mono.BlueZ.DBus +{ + public static class A2DP + { + #region const + public static const string A2DP_SOURCE_UUID = "0000110A-0000-1000-8000-00805F9B34FB"; + public static const string A2DP_SINK_UUID = "0000110B-0000-1000-8000-00805F9B34FB"; + public static const string HFP_AG_UUID = "0000111F-0000-1000-8000-00805F9B34FB"; + public static const string HFP_HF_UUID = "0000111E-0000-1000-8000-00805F9B34FB"; + public static const string HSP_AG_UUID = "00001112-0000-1000-8000-00805F9B34FB"; + + + public static const byte SBC_CODEC = 0;//dbus.Byte(0x00) + //Channel Modes: Mono DualChannel Stereo JointStereo + //Frequencies: 16Khz 32Khz 44.1Khz 48Khz + //Subbands: 4 8 + //Blocks: 4 8 12 16 + //Bitpool Range: 2-64 + public static const byte[] SBC_CAPABILITIES = new byte[] { 0xff, 0xff, 2, 64 };//dbus.Array([dbus.Byte(0xff), dbus.Byte(0xff), dbus.Byte(2), dbus.Byte(64)]) + //JointStereo 44.1Khz Subbands: Blocks: 16 Bitpool Range: 2-32 + public static const byte[] SBC_CONFIGURATION = new byte[] { 0x21, 0x15, 2, 32 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x15), dbus.Byte(2), dbus.Byte(32)]) + + + + public static const byte MP3_CODEC = 1;//dbus.Byte(0x01) + //Channel Modes: Mono DualChannel Stereo JointStereo + //Frequencies: 32Khz 44.1Khz 48Khz + //CRC: YES + //Layer: 3 + //Bit Rate: All except Free format + //VBR: Yes + //Payload Format: RFC-2250 + public static const byte[] MP3_CAPABILITIES = new byte[] { 0x3f, 0x07, 0xff, 0xfe };//dbus.Array([dbus.Byte(0x3f), dbus.Byte(0x07), dbus.Byte(0xff), dbus.Byte(0xfe)]) + //JointStereo 44.1Khz Layer: 3 Bit Rate: VBR Format: RFC-2250 + public static const byte[] MP3_CONFIGURATION = new byte[] { 0x21, 0x02, 0x00, 0x80 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x02), dbus.Byte(0x00), dbus.Byte(0x80)]) + + + + public static const byte PCM_CODEC = 0;//dbus.Byte(0x00) + //public static const PCM_CONFIGURATION = dbus.Array([], signature="ay") + //TODO pcm config + + public static const byte CVSD_CODEC = 1;//dbus.Byte(0x01) + #endregion + + #region Propterties + public static IDictionary SBC_SOURCE_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SOURCE_UUID}, + {"Codec" , SBC_CODEC}, + {"DelayReporting" , true}, + {"Capabilities" , SBC_CAPABILITIES} + }; + + public static IDictionary SBC_SINK_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SINK_UUID}, + {"Codec" , SBC_CODEC}, + {"DelayReporting" , true}, + {"Capabilities" , SBC_CAPABILITIES} + }; + + public static IDictionary MP3_SOURCE_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SOURCE_UUID}, + {"Codec" , MP3_CODEC}, + {"Capabilities" , MP3_CAPABILITIES} + }; + + public static IDictionary MP3_SINK_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SINK_UUID}, + {"Codec" , MP3_CODEC}, + {"Capabilities" , MP3_CAPABILITIES} + }; + + //TODO based on PCM_CONF + /*public static IDictionary HFP_AG_PROPERTIES = new Dictionary + { + {"UUID" , HFP_AG_UUID}, + {"Codec" , PCM_CODEC}, + {"Capabilities" , PCM_CONFIGURATION} + }; + + public static IDictionary HFP_HF_PROPERTIES = new Dictionary + { + {"UUID" , HFP_HF_UUID}, + {"Codec" , CVSD_CODEC}, + {"Capabilities" , PCM_CONFIGURATION} + };*/ + #endregion + } +} diff --git a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj index e06d0af..3a54a09 100644 --- a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj +++ b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj @@ -31,6 +31,7 @@ + From 3b2e17448689ad8a7d851a65032f17bbeb11251b Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Tue, 19 Apr 2016 18:27:30 +0200 Subject: [PATCH 3/9] Fix A2DP --- Mono.BlueZ.DBus/A2DP.cs | 26 +++++++++++++------------- Mono.BlueZ.DBus/MediaTransport1.cs | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Mono.BlueZ.DBus/A2DP.cs b/Mono.BlueZ.DBus/A2DP.cs index 595737e..e931bf3 100644 --- a/Mono.BlueZ.DBus/A2DP.cs +++ b/Mono.BlueZ.DBus/A2DP.cs @@ -6,26 +6,26 @@ namespace Mono.BlueZ.DBus public static class A2DP { #region const - public static const string A2DP_SOURCE_UUID = "0000110A-0000-1000-8000-00805F9B34FB"; - public static const string A2DP_SINK_UUID = "0000110B-0000-1000-8000-00805F9B34FB"; - public static const string HFP_AG_UUID = "0000111F-0000-1000-8000-00805F9B34FB"; - public static const string HFP_HF_UUID = "0000111E-0000-1000-8000-00805F9B34FB"; - public static const string HSP_AG_UUID = "00001112-0000-1000-8000-00805F9B34FB"; + public const string A2DP_SOURCE_UUID = "0000110A-0000-1000-8000-00805F9B34FB"; + public const string A2DP_SINK_UUID = "0000110B-0000-1000-8000-00805F9B34FB"; + public const string HFP_AG_UUID = "0000111F-0000-1000-8000-00805F9B34FB"; + public const string HFP_HF_UUID = "0000111E-0000-1000-8000-00805F9B34FB"; + public const string HSP_AG_UUID = "00001112-0000-1000-8000-00805F9B34FB"; - public static const byte SBC_CODEC = 0;//dbus.Byte(0x00) + public const byte SBC_CODEC = 0;//dbus.Byte(0x00) //Channel Modes: Mono DualChannel Stereo JointStereo //Frequencies: 16Khz 32Khz 44.1Khz 48Khz //Subbands: 4 8 //Blocks: 4 8 12 16 //Bitpool Range: 2-64 - public static const byte[] SBC_CAPABILITIES = new byte[] { 0xff, 0xff, 2, 64 };//dbus.Array([dbus.Byte(0xff), dbus.Byte(0xff), dbus.Byte(2), dbus.Byte(64)]) + public static byte[] SBC_CAPABILITIES = new byte[] { 0xff, 0xff, 2, 64 };//dbus.Array([dbus.Byte(0xff), dbus.Byte(0xff), dbus.Byte(2), dbus.Byte(64)]) //JointStereo 44.1Khz Subbands: Blocks: 16 Bitpool Range: 2-32 - public static const byte[] SBC_CONFIGURATION = new byte[] { 0x21, 0x15, 2, 32 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x15), dbus.Byte(2), dbus.Byte(32)]) + public static byte[] SBC_CONFIGURATION = new byte[] { 0x21, 0x15, 2, 32 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x15), dbus.Byte(2), dbus.Byte(32)]) - public static const byte MP3_CODEC = 1;//dbus.Byte(0x01) + public const byte MP3_CODEC = 1;//dbus.Byte(0x01) //Channel Modes: Mono DualChannel Stereo JointStereo //Frequencies: 32Khz 44.1Khz 48Khz //CRC: YES @@ -33,17 +33,17 @@ public static class A2DP //Bit Rate: All except Free format //VBR: Yes //Payload Format: RFC-2250 - public static const byte[] MP3_CAPABILITIES = new byte[] { 0x3f, 0x07, 0xff, 0xfe };//dbus.Array([dbus.Byte(0x3f), dbus.Byte(0x07), dbus.Byte(0xff), dbus.Byte(0xfe)]) + public static byte[] MP3_CAPABILITIES = new byte[] { 0x3f, 0x07, 0xff, 0xfe };//dbus.Array([dbus.Byte(0x3f), dbus.Byte(0x07), dbus.Byte(0xff), dbus.Byte(0xfe)]) //JointStereo 44.1Khz Layer: 3 Bit Rate: VBR Format: RFC-2250 - public static const byte[] MP3_CONFIGURATION = new byte[] { 0x21, 0x02, 0x00, 0x80 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x02), dbus.Byte(0x00), dbus.Byte(0x80)]) + public static byte[] MP3_CONFIGURATION = new byte[] { 0x21, 0x02, 0x00, 0x80 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x02), dbus.Byte(0x00), dbus.Byte(0x80)]) - public static const byte PCM_CODEC = 0;//dbus.Byte(0x00) + public const byte PCM_CODEC = 0;//dbus.Byte(0x00) //public static const PCM_CONFIGURATION = dbus.Array([], signature="ay") //TODO pcm config - public static const byte CVSD_CODEC = 1;//dbus.Byte(0x01) + public const byte CVSD_CODEC = 1;//dbus.Byte(0x01) #endregion #region Propterties diff --git a/Mono.BlueZ.DBus/MediaTransport1.cs b/Mono.BlueZ.DBus/MediaTransport1.cs index c97c17d..40e9326 100644 --- a/Mono.BlueZ.DBus/MediaTransport1.cs +++ b/Mono.BlueZ.DBus/MediaTransport1.cs @@ -5,25 +5,25 @@ namespace Mono.BlueZ.DBus { // on /org/bluez/hciX - [Interface("org.bluez.MediaEndpoint1")] - public interface MediaEndpoint1 + [Interface("org.bluez.MediaTransport1")] + public interface MediaTransport1 { FileDescriptor Acquire(); FileDescriptor TryAcquire(); void Release(); - readonly ObjectPath Device; - readonly string UUID; - readonly byte Codec ; - readonly byte[] Configuration; - readonly State State; + ObjectPath Device {get;} + string UUID {get;} + byte Codec {get;} + byte[] Configuration {get;} + State State {get;} ushort Delay {get;set;} ushort Volume {get;set;} } public enum State { - Idle = "idle", - Pending = "pending", - Active = "active" + Idle, + Pending, + Active } -} \ No newline at end of file +} From f9fde227cc427d04279c685bb49d9e52ddf786d9 Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Wed, 20 Apr 2016 14:05:54 +0200 Subject: [PATCH 4/9] Fix MediaTransport1 enum -> static class with --- Mono.BlueZ.DBus/MediaTransport1.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Mono.BlueZ.DBus/MediaTransport1.cs b/Mono.BlueZ.DBus/MediaTransport1.cs index 40e9326..b1b9ac8 100644 --- a/Mono.BlueZ.DBus/MediaTransport1.cs +++ b/Mono.BlueZ.DBus/MediaTransport1.cs @@ -15,15 +15,12 @@ public interface MediaTransport1 string UUID {get;} byte Codec {get;} byte[] Configuration {get;} - State State {get;} + string State {get;} ushort Delay {get;set;} ushort Volume {get;set;} } - public enum State + public static class State { - Idle, - Pending, - Active } } From 9412cfa86649c4afd4fdfe35ecc7fddedb6cbe2c Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Wed, 20 Apr 2016 14:39:51 +0200 Subject: [PATCH 5/9] Bluezutils Added Bluezutils -> converted from Python example Fixes --- Mono.BlueZ.DBus/MediaTransport1.cs | 7 ++- Mono.BlueZ/A2DP.cs | 96 ++++++++++++++++++++++++++++++ Mono.BlueZ/BluezUtils.cs | 66 ++++++++++++++++++++ Mono.BlueZ/Mono.BlueZ.csproj | 4 +- 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 Mono.BlueZ/A2DP.cs create mode 100644 Mono.BlueZ/BluezUtils.cs diff --git a/Mono.BlueZ.DBus/MediaTransport1.cs b/Mono.BlueZ.DBus/MediaTransport1.cs index b1b9ac8..1164661 100644 --- a/Mono.BlueZ.DBus/MediaTransport1.cs +++ b/Mono.BlueZ.DBus/MediaTransport1.cs @@ -9,7 +9,9 @@ namespace Mono.BlueZ.DBus public interface MediaTransport1 { FileDescriptor Acquire(); - FileDescriptor TryAcquire(); + //TODO fd, uint16, uint16 Acquire() "Acquire transport file descriptor and the MTU for readand write respectively." + FileDescriptor TryAcquire(); + //TODO fd, uint16, uint16 TryAcquire() void Release(); ObjectPath Device {get;} string UUID {get;} @@ -22,5 +24,8 @@ public interface MediaTransport1 public static class State { + public const string Idle = "idle"; + public const string Pending = "pending"; + public const string Active = "active"; } } diff --git a/Mono.BlueZ/A2DP.cs b/Mono.BlueZ/A2DP.cs new file mode 100644 index 0000000..be1bc57 --- /dev/null +++ b/Mono.BlueZ/A2DP.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; + +namespace Mono.BlueZ +{ + public static class A2DP + { + #region const + public const string A2DP_SOURCE_UUID = "0000110A-0000-1000-8000-00805F9B34FB"; + public const string A2DP_SINK_UUID = "0000110B-0000-1000-8000-00805F9B34FB"; + public const string HFP_AG_UUID = "0000111F-0000-1000-8000-00805F9B34FB"; + public const string HFP_HF_UUID = "0000111E-0000-1000-8000-00805F9B34FB"; + public const string HSP_AG_UUID = "00001112-0000-1000-8000-00805F9B34FB"; + + + public const byte SBC_CODEC = 0;//dbus.Byte(0x00) + //Channel Modes: Mono DualChannel Stereo JointStereo + //Frequencies: 16Khz 32Khz 44.1Khz 48Khz + //Subbands: 4 8 + //Blocks: 4 8 12 16 + //Bitpool Range: 2-64 + public static byte[] SBC_CAPABILITIES = new byte[] { 0xff, 0xff, 2, 64 };//dbus.Array([dbus.Byte(0xff), dbus.Byte(0xff), dbus.Byte(2), dbus.Byte(64)]) + //JointStereo 44.1Khz Subbands: Blocks: 16 Bitpool Range: 2-32 + public static byte[] SBC_CONFIGURATION = new byte[] { 0x21, 0x15, 2, 32 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x15), dbus.Byte(2), dbus.Byte(32)]) + + + + public const byte MP3_CODEC = 1;//dbus.Byte(0x01) + //Channel Modes: Mono DualChannel Stereo JointStereo + //Frequencies: 32Khz 44.1Khz 48Khz + //CRC: YES + //Layer: 3 + //Bit Rate: All except Free format + //VBR: Yes + //Payload Format: RFC-2250 + public static byte[] MP3_CAPABILITIES = new byte[] { 0x3f, 0x07, 0xff, 0xfe };//dbus.Array([dbus.Byte(0x3f), dbus.Byte(0x07), dbus.Byte(0xff), dbus.Byte(0xfe)]) + //JointStereo 44.1Khz Layer: 3 Bit Rate: VBR Format: RFC-2250 + public static byte[] MP3_CONFIGURATION = new byte[] { 0x21, 0x02, 0x00, 0x80 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x02), dbus.Byte(0x00), dbus.Byte(0x80)]) + + + + public const byte PCM_CODEC = 0;//dbus.Byte(0x00) + //public static const PCM_CONFIGURATION = dbus.Array([], signature="ay") + //TODO pcm config + + public const byte CVSD_CODEC = 1;//dbus.Byte(0x01) + #endregion + + #region Propterties + public static IDictionary SBC_SOURCE_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SOURCE_UUID}, + {"Codec" , SBC_CODEC}, + {"DelayReporting" , true}, + {"Capabilities" , SBC_CAPABILITIES} + }; + + public static IDictionary SBC_SINK_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SINK_UUID}, + {"Codec" , SBC_CODEC}, + {"DelayReporting" , true}, + {"Capabilities" , SBC_CAPABILITIES} + }; + + public static IDictionary MP3_SOURCE_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SOURCE_UUID}, + {"Codec" , MP3_CODEC}, + {"Capabilities" , MP3_CAPABILITIES} + }; + + public static IDictionary MP3_SINK_PROPERTIES = new Dictionary + { + {"UUID" , A2DP_SINK_UUID}, + {"Codec" , MP3_CODEC}, + {"Capabilities" , MP3_CAPABILITIES} + }; + + //TODO based on PCM_CONF + /*public static IDictionary HFP_AG_PROPERTIES = new Dictionary + { + {"UUID" , HFP_AG_UUID}, + {"Codec" , PCM_CODEC}, + {"Capabilities" , PCM_CONFIGURATION} + }; + + public static IDictionary HFP_HF_PROPERTIES = new Dictionary + { + {"UUID" , HFP_HF_UUID}, + {"Codec" , CVSD_CODEC}, + {"Capabilities" , PCM_CONFIGURATION} + };*/ + #endregion + } +} diff --git a/Mono.BlueZ/BluezUtils.cs b/Mono.BlueZ/BluezUtils.cs new file mode 100644 index 0000000..cc00e2c --- /dev/null +++ b/Mono.BlueZ/BluezUtils.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using DBus; +using Mono.BlueZ.DBus; + +namespace Mono.Bluez +{ + //https://git.kernel.org/cgit/bluetooth/bluez.git/tree/test/bluezutils.py + public static class BluezUtils//TODO Address pattern + { + private const string ServiceName = "org.bluez"; + + public static IDictionary>> get_managed_objects() + { + var bus = Bus.System; + var manager = bus.GetObject(ServiceName, ObjectPath.Root); + return manager.GetManagedObjects(); + } + + public static Adapter1 find_adapter() + { + return find_adapter_in_objects(get_managed_objects()); + } + + public static Adapter1 find_adapter_in_objects(IDictionary>> managedObjects) + { + var bus = Bus.System; + ObjectPath adapterPath = null; + foreach (var obj in managedObjects.Keys) + { + if (managedObjects[obj].ContainsKey(typeof(Adapter1).DBusInterfaceName())) + { + adapterPath = obj; + break; + } + } + + var adapter = bus.GetObject(ServiceName, adapterPath); + + return adapter; + } + + public static Device1 find_device(string device_address) + { + return find_device_in_objects(get_managed_objects(), device_address); + } + + public static Device1 find_device_in_objects(IDictionary>> managedObjects, string device_adress) + { + var bus = Bus.System; + ObjectPath devicePath = null; + foreach (var obj in managedObjects.Keys) + { + if (managedObjects[obj].ContainsKey(typeof(Device1).DBusInterfaceName())) + { + devicePath = obj; + break; + } + } + + var device = bus.GetObject(ServiceName, devicePath); + + return device; + } + } +} diff --git a/Mono.BlueZ/Mono.BlueZ.csproj b/Mono.BlueZ/Mono.BlueZ.csproj index 047227d..94df856 100644 --- a/Mono.BlueZ/Mono.BlueZ.csproj +++ b/Mono.BlueZ/Mono.BlueZ.csproj @@ -31,7 +31,9 @@ + + @@ -45,4 +47,4 @@ - + \ No newline at end of file From 281e041c8479a4b588a8d1e989d85dd1804d582f Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Wed, 20 Apr 2016 14:41:55 +0200 Subject: [PATCH 6/9] Fix A2DP.cs location Delete A2Dp.cs from Mono.DBus (duplicate) --- Mono.BlueZ.DBus/A2DP.cs | 96 ----------------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 Mono.BlueZ.DBus/A2DP.cs diff --git a/Mono.BlueZ.DBus/A2DP.cs b/Mono.BlueZ.DBus/A2DP.cs deleted file mode 100644 index e931bf3..0000000 --- a/Mono.BlueZ.DBus/A2DP.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Mono.BlueZ.DBus -{ - public static class A2DP - { - #region const - public const string A2DP_SOURCE_UUID = "0000110A-0000-1000-8000-00805F9B34FB"; - public const string A2DP_SINK_UUID = "0000110B-0000-1000-8000-00805F9B34FB"; - public const string HFP_AG_UUID = "0000111F-0000-1000-8000-00805F9B34FB"; - public const string HFP_HF_UUID = "0000111E-0000-1000-8000-00805F9B34FB"; - public const string HSP_AG_UUID = "00001112-0000-1000-8000-00805F9B34FB"; - - - public const byte SBC_CODEC = 0;//dbus.Byte(0x00) - //Channel Modes: Mono DualChannel Stereo JointStereo - //Frequencies: 16Khz 32Khz 44.1Khz 48Khz - //Subbands: 4 8 - //Blocks: 4 8 12 16 - //Bitpool Range: 2-64 - public static byte[] SBC_CAPABILITIES = new byte[] { 0xff, 0xff, 2, 64 };//dbus.Array([dbus.Byte(0xff), dbus.Byte(0xff), dbus.Byte(2), dbus.Byte(64)]) - //JointStereo 44.1Khz Subbands: Blocks: 16 Bitpool Range: 2-32 - public static byte[] SBC_CONFIGURATION = new byte[] { 0x21, 0x15, 2, 32 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x15), dbus.Byte(2), dbus.Byte(32)]) - - - - public const byte MP3_CODEC = 1;//dbus.Byte(0x01) - //Channel Modes: Mono DualChannel Stereo JointStereo - //Frequencies: 32Khz 44.1Khz 48Khz - //CRC: YES - //Layer: 3 - //Bit Rate: All except Free format - //VBR: Yes - //Payload Format: RFC-2250 - public static byte[] MP3_CAPABILITIES = new byte[] { 0x3f, 0x07, 0xff, 0xfe };//dbus.Array([dbus.Byte(0x3f), dbus.Byte(0x07), dbus.Byte(0xff), dbus.Byte(0xfe)]) - //JointStereo 44.1Khz Layer: 3 Bit Rate: VBR Format: RFC-2250 - public static byte[] MP3_CONFIGURATION = new byte[] { 0x21, 0x02, 0x00, 0x80 };//dbus.Array([dbus.Byte(0x21), dbus.Byte(0x02), dbus.Byte(0x00), dbus.Byte(0x80)]) - - - - public const byte PCM_CODEC = 0;//dbus.Byte(0x00) - //public static const PCM_CONFIGURATION = dbus.Array([], signature="ay") - //TODO pcm config - - public const byte CVSD_CODEC = 1;//dbus.Byte(0x01) - #endregion - - #region Propterties - public static IDictionary SBC_SOURCE_PROPERTIES = new Dictionary - { - {"UUID" , A2DP_SOURCE_UUID}, - {"Codec" , SBC_CODEC}, - {"DelayReporting" , true}, - {"Capabilities" , SBC_CAPABILITIES} - }; - - public static IDictionary SBC_SINK_PROPERTIES = new Dictionary - { - {"UUID" , A2DP_SINK_UUID}, - {"Codec" , SBC_CODEC}, - {"DelayReporting" , true}, - {"Capabilities" , SBC_CAPABILITIES} - }; - - public static IDictionary MP3_SOURCE_PROPERTIES = new Dictionary - { - {"UUID" , A2DP_SOURCE_UUID}, - {"Codec" , MP3_CODEC}, - {"Capabilities" , MP3_CAPABILITIES} - }; - - public static IDictionary MP3_SINK_PROPERTIES = new Dictionary - { - {"UUID" , A2DP_SINK_UUID}, - {"Codec" , MP3_CODEC}, - {"Capabilities" , MP3_CAPABILITIES} - }; - - //TODO based on PCM_CONF - /*public static IDictionary HFP_AG_PROPERTIES = new Dictionary - { - {"UUID" , HFP_AG_UUID}, - {"Codec" , PCM_CODEC}, - {"Capabilities" , PCM_CONFIGURATION} - }; - - public static IDictionary HFP_HF_PROPERTIES = new Dictionary - { - {"UUID" , HFP_HF_UUID}, - {"Codec" , CVSD_CODEC}, - {"Capabilities" , PCM_CONFIGURATION} - };*/ - #endregion - } -} From 3af46205d6d1fe4f4f9bdb53119d1066ee8577a3 Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Wed, 20 Apr 2016 14:45:04 +0200 Subject: [PATCH 7/9] Fix Namespaces --- Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj | 1 - Mono.BlueZ/BluezUtils.cs | 4 ++-- Mono.BlueZ/Mono.BlueZ.csproj | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj index 3a54a09..e06d0af 100644 --- a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj +++ b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj @@ -31,7 +31,6 @@ - diff --git a/Mono.BlueZ/BluezUtils.cs b/Mono.BlueZ/BluezUtils.cs index cc00e2c..330fab5 100644 --- a/Mono.BlueZ/BluezUtils.cs +++ b/Mono.BlueZ/BluezUtils.cs @@ -3,10 +3,10 @@ using DBus; using Mono.BlueZ.DBus; -namespace Mono.Bluez +namespace Mono.BlueZ { //https://git.kernel.org/cgit/bluetooth/bluez.git/tree/test/bluezutils.py - public static class BluezUtils//TODO Address pattern + public static class BlueZtils//TODO Address pattern { private const string ServiceName = "org.bluez"; diff --git a/Mono.BlueZ/Mono.BlueZ.csproj b/Mono.BlueZ/Mono.BlueZ.csproj index 94df856..c188fe6 100644 --- a/Mono.BlueZ/Mono.BlueZ.csproj +++ b/Mono.BlueZ/Mono.BlueZ.csproj @@ -33,7 +33,7 @@ - + From 4b7fa90156ffee133b9c903a0cd6d6809c25e580 Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Wed, 20 Apr 2016 14:53:16 +0200 Subject: [PATCH 8/9] Fixes --- Mono.BlueZ/BluezUtils.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mono.BlueZ/BluezUtils.cs b/Mono.BlueZ/BluezUtils.cs index 330fab5..f19f04a 100644 --- a/Mono.BlueZ/BluezUtils.cs +++ b/Mono.BlueZ/BluezUtils.cs @@ -6,7 +6,7 @@ namespace Mono.BlueZ { //https://git.kernel.org/cgit/bluetooth/bluez.git/tree/test/bluezutils.py - public static class BlueZtils//TODO Address pattern + public static class BlueZUtils//TODO Address pattern { private const string ServiceName = "org.bluez"; @@ -17,12 +17,12 @@ public static IDictionary find_adapter() { return find_adapter_in_objects(get_managed_objects()); } - public static Adapter1 find_adapter_in_objects(IDictionary>> managedObjects) + public static KeyValuePair find_adapter_in_objects(IDictionary>> managedObjects) { var bus = Bus.System; ObjectPath adapterPath = null; @@ -37,15 +37,15 @@ public static Adapter1 find_adapter_in_objects(IDictionary(ServiceName, adapterPath); - return adapter; + return new KeyValuePair(adapterPath, adapter); } - public static Device1 find_device(string device_address) + public static KeyValuePair find_device(string device_address) { return find_device_in_objects(get_managed_objects(), device_address); } - public static Device1 find_device_in_objects(IDictionary>> managedObjects, string device_adress) + public static KeyValuePair find_device_in_objects(IDictionary>> managedObjects, string device_adress) { var bus = Bus.System; ObjectPath devicePath = null; @@ -60,7 +60,7 @@ public static Device1 find_device_in_objects(IDictionary(ServiceName, devicePath); - return device; + return new KeyValuePair(devicePath, device); } } } From bbac58f29c07908a4afaf5b89270647b373c9a4c Mon Sep 17 00:00:00 2001 From: Ch4rg3r Date: Thu, 21 Apr 2016 13:08:42 +0200 Subject: [PATCH 9/9] A2Dp Test Project Added testproject (not yet tested) Added AudioSink & AudioSource interfaces Fixes --- Mono.BlueZ.Console/A2DP_Test/BlueZA2DP.cs | 143 +++++++++++++++++++ Mono.BlueZ.Console/A2DP_Test/Endpoint.cs | 51 +++++++ Mono.BlueZ.Console/Mono.BlueZ.Console.csproj | 6 +- Mono.BlueZ.Console/Program.cs | 14 +- Mono.BlueZ.DBus/Audio.cs | 16 +++ Mono.BlueZ.DBus/AudioSink.cs | 17 +++ Mono.BlueZ.DBus/AudioSource.cs | 16 +++ Mono.BlueZ.DBus/MediaTransport1.cs | 2 +- Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj | 3 + 9 files changed, 260 insertions(+), 8 deletions(-) create mode 100644 Mono.BlueZ.Console/A2DP_Test/BlueZA2DP.cs create mode 100644 Mono.BlueZ.Console/A2DP_Test/Endpoint.cs create mode 100644 Mono.BlueZ.DBus/Audio.cs create mode 100644 Mono.BlueZ.DBus/AudioSink.cs create mode 100644 Mono.BlueZ.DBus/AudioSource.cs diff --git a/Mono.BlueZ.Console/A2DP_Test/BlueZA2DP.cs b/Mono.BlueZ.Console/A2DP_Test/BlueZA2DP.cs new file mode 100644 index 0000000..4ff1311 --- /dev/null +++ b/Mono.BlueZ.Console/A2DP_Test/BlueZA2DP.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DBus; +using org.freedesktop.DBus; +using Mono.BlueZ; +using Mono.BlueZ.DBus; +using System.Threading; + +namespace Mono.BlueZ.Console +{ + public class BlueZA2DP + { + private Bus _system; + public Exception _startupException { get; private set; } + private ManualResetEvent _started = new ManualResetEvent(false); + + private const string BlueZRootPath = "/org/bluez"; + private const string BlueZService = "org.bluez"; + + private ObjectPath ProfilePath = new ObjectPath("/profiles"); + private ObjectPath EndpointPath = new ObjectPath("/led_web/endpoint"); + private ObjectPath BlueZPath = new ObjectPath("/org/bluez"); + + private ObjectManager _objectManager; + private AgentManager1 _agentManager; + private ProfileManager1 _profileManager; + + private Endpoint _endpoint; + private FileDescriptor _filedescriptor; + + public BlueZA2DP() + { + var t = new Thread(DBusLoop); + t.IsBackground = true; + t.Start(); + _started.WaitOne(60 * 1000); + _started.Close(); + if (_startupException != null) + { + throw _startupException; + } + else + { + _objectManager = _system.GetObject(BlueZService, ObjectPath.Root); + _objectManager.InterfacesAdded += _objectManager_InterfacesAdded; + _objectManager.InterfacesRemoved += _objectManager_InterfacesRemoved; + } + } + + public void RegisterEndpoint()//A1. Application Startup + { + var adapter = BlueZUtils.find_adapter(); + var path = adapter.Key; + + var media = _system.GetObject(BlueZService, path); + //_endpoint = _system.GetObject(BlueZService, ObjectPath.Root); + _endpoint = new Endpoint(); + + _system.Register(EndpointPath, _endpoint); + media.RegisterEndpoint(EndpointPath, A2DP.MP3_SINK_PROPERTIES); + + var audiosource = _system.GetObject(BlueZService, ObjectPath.Root); + audiosource.PropertyChanged += AudioSourcePropertyChanged; + } + + private void GetTransportStream() + { + ObjectPath transportPath = _endpoint.TransportPath; + var transport = _system.GetObject(BlueZService, transportPath); + + _filedescriptor = transport.Acquire(); + } + + public FileDescriptor AudioStream + { + get { return _filedescriptor; } + } + + private void _objectManager_InterfacesRemoved(ObjectPath path, string[] interfaces) + { + } + + private void _objectManager_InterfacesAdded(ObjectPath path, IDictionary> interfaces) + { + } + + private void AudioSourcePropertyChanged(string name, object value)//C1. Start streaming event. + { + if (name == "State") + { + switch (value as string) + { + case AudioState.Playing: + GetTransportStream(); + break; + //TODO implement changes to stop stream + } + } + } + + private void DBusLoop() + { + try + { + _system = Bus.System; + } + catch (Exception ex) + { + _startupException = ex; + return; + } + finally + { + _started.Set(); + } + + while (true) + { + _system.Iterate(); + } + } + + private ProfileManager1 ProfileManager + { + get + { + if (_profileManager == null) + { + _profileManager = _system.GetObject(BlueZService, new ObjectPath(BlueZRootPath)); + } + return _profileManager; + } + } + + private ObjectPath GetObjectPathForLocalObject(object obj) + { + return new ObjectPath("/" + obj.GetHashCode()); + } + } +} diff --git a/Mono.BlueZ.Console/A2DP_Test/Endpoint.cs b/Mono.BlueZ.Console/A2DP_Test/Endpoint.cs new file mode 100644 index 0000000..0a4c91d --- /dev/null +++ b/Mono.BlueZ.Console/A2DP_Test/Endpoint.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.BlueZ.DBus; +using Mono.BlueZ; +using DBus; + +namespace Mono.BlueZ.Console +{ + public class Endpoint : MediaEndpoint1 + { + private ObjectPath transportPath; + + public void ClearConfiguration(ObjectPath transport)//B2. Device Disconnection Events + { + transportPath = null; + return; + } + + public void Release() + { + return; + } + + public byte[] SelectConfiguration(byte[] capabilities)//B1. Device Connection Events + { + if(capabilities == A2DP.MP3_CAPABILITIES) + { + return A2DP.MP3_CONFIGURATION; + } + if(capabilities == A2DP.SBC_CAPABILITIES) + { + return A2DP.SBC_CONFIGURATION; + } + return null; + } + + public void SetConfiguration(ObjectPath transport, IDictionary properties)//B1. Device Connection Events + { + transportPath = transport; + return; + } + + public ObjectPath TransportPath + { + get { return transportPath; } + } + } +} diff --git a/Mono.BlueZ.Console/Mono.BlueZ.Console.csproj b/Mono.BlueZ.Console/Mono.BlueZ.Console.csproj index 3176ab3..637c8f9 100644 --- a/Mono.BlueZ.Console/Mono.BlueZ.Console.csproj +++ b/Mono.BlueZ.Console/Mono.BlueZ.Console.csproj @@ -1,4 +1,4 @@ - + Debug @@ -31,6 +31,8 @@ + + PreserveNewest @@ -55,4 +57,4 @@ dbus-sharp - + \ No newline at end of file diff --git a/Mono.BlueZ.Console/Program.cs b/Mono.BlueZ.Console/Program.cs index c735946..e1c0fea 100644 --- a/Mono.BlueZ.Console/Program.cs +++ b/Mono.BlueZ.Console/Program.cs @@ -8,12 +8,16 @@ class MainClass public static void Main (string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler (GlobalHandler); - var bootstrap = new BlendMicroBootstrap (); - bootstrap.Run (); - //var bootstrap = new PebbleBootstrap (); - //bootstrap.Run (true, null); - } + //var bootstrap = new BlendMicroBootstrap (); + //bootstrap.Run (); + + //var bootstrap = new PebbleBootstrap (); + //bootstrap.Run (true, null); + + var a2dp = new BlueZA2DP(); + a2dp.RegisterEndpoint(); + } static void GlobalHandler(object sender, UnhandledExceptionEventArgs args) { diff --git a/Mono.BlueZ.DBus/Audio.cs b/Mono.BlueZ.DBus/Audio.cs new file mode 100644 index 0000000..6d2a11c --- /dev/null +++ b/Mono.BlueZ.DBus/Audio.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using DBus; + +namespace Mono.BlueZ.DBus +{ + public delegate void PropertyChangedHandler(string name, object value); + + public static class AudioState + { + public const string Disconnected = "disconnected"; + public const string Connected = "connected"; + public const string Connecting = "connecting"; + public const string Playing = "playing"; + } +} diff --git a/Mono.BlueZ.DBus/AudioSink.cs b/Mono.BlueZ.DBus/AudioSink.cs new file mode 100644 index 0000000..b4e07b2 --- /dev/null +++ b/Mono.BlueZ.DBus/AudioSink.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using DBus; + +namespace Mono.BlueZ.DBus +{ + [Interface("org.bluez.AudioSink")] + public interface AudioSink + { + void Connect(); + void Disconnect(); + IDictionary GetProperties(); + event PropertyChangedHandler PropertyChanged; + string State { get; } + bool Playing { get; } + } +} diff --git a/Mono.BlueZ.DBus/AudioSource.cs b/Mono.BlueZ.DBus/AudioSource.cs new file mode 100644 index 0000000..1b34187 --- /dev/null +++ b/Mono.BlueZ.DBus/AudioSource.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using DBus; + +namespace Mono.BlueZ.DBus +{ + [Interface("org.bluez.AudioSource")] + public interface AudioSource + { + void Connect(); + void Disconnect(); + IDictionary GetProperties(); + event PropertyChangedHandler PropertyChanged; + string State { get; } + } +} diff --git a/Mono.BlueZ.DBus/MediaTransport1.cs b/Mono.BlueZ.DBus/MediaTransport1.cs index 1164661..e6ef645 100644 --- a/Mono.BlueZ.DBus/MediaTransport1.cs +++ b/Mono.BlueZ.DBus/MediaTransport1.cs @@ -22,7 +22,7 @@ public interface MediaTransport1 ushort Volume {get;set;} } - public static class State + public static class TransportState { public const string Idle = "idle"; public const string Pending = "pending"; diff --git a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj index e06d0af..eb6ab8f 100644 --- a/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj +++ b/Mono.BlueZ.DBus/Mono.BlueZ.DBus.csproj @@ -31,6 +31,9 @@ + + +