simple-endpoint 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #!/usr/bin/python
  2. # SPDX-License-Identifier: LGPL-2.1-or-later
  3. from __future__ import absolute_import, print_function, unicode_literals
  4. import sys
  5. import dbus
  6. import dbus.service
  7. import dbus.mainloop.glib
  8. try:
  9. from gi.repository import GObject
  10. except ImportError:
  11. import gobject as GObject
  12. import bluezutils
  13. A2DP_SOURCE_UUID = "0000110A-0000-1000-8000-00805F9B34FB"
  14. A2DP_SINK_UUID = "0000110B-0000-1000-8000-00805F9B34FB"
  15. HFP_AG_UUID = "0000111F-0000-1000-8000-00805F9B34FB"
  16. HFP_HF_UUID = "0000111E-0000-1000-8000-00805F9B34FB"
  17. HSP_AG_UUID = "00001112-0000-1000-8000-00805F9B34FB"
  18. SBC_CODEC = dbus.Byte(0x00)
  19. #Channel Modes: Mono DualChannel Stereo JointStereo
  20. #Frequencies: 16Khz 32Khz 44.1Khz 48Khz
  21. #Subbands: 4 8
  22. #Blocks: 4 8 12 16
  23. #Bitpool Range: 2-64
  24. SBC_CAPABILITIES = dbus.Array([dbus.Byte(0xff), dbus.Byte(0xff), dbus.Byte(2), dbus.Byte(64)])
  25. # JointStereo 44.1Khz Subbands: Blocks: 16 Bitpool Range: 2-32
  26. SBC_CONFIGURATION = dbus.Array([dbus.Byte(0x21), dbus.Byte(0x15), dbus.Byte(2), dbus.Byte(32)])
  27. MP3_CODEC = dbus.Byte(0x01)
  28. #Channel Modes: Mono DualChannel Stereo JointStereo
  29. #Frequencies: 32Khz 44.1Khz 48Khz
  30. #CRC: YES
  31. #Layer: 3
  32. #Bit Rate: All except Free format
  33. #VBR: Yes
  34. #Payload Format: RFC-2250
  35. MP3_CAPABILITIES = dbus.Array([dbus.Byte(0x3f), dbus.Byte(0x07), dbus.Byte(0xff), dbus.Byte(0xfe)])
  36. # JointStereo 44.1Khz Layer: 3 Bit Rate: VBR Format: RFC-2250
  37. MP3_CONFIGURATION = dbus.Array([dbus.Byte(0x21), dbus.Byte(0x02), dbus.Byte(0x00), dbus.Byte(0x80)])
  38. PCM_CODEC = dbus.Byte(0x00)
  39. PCM_CONFIGURATION = dbus.Array([], signature="ay")
  40. CVSD_CODEC = dbus.Byte(0x01)
  41. class Rejected(dbus.DBusException):
  42. _dbus_error_name = "org.bluez.Error.Rejected"
  43. class Endpoint(dbus.service.Object):
  44. exit_on_release = True
  45. configuration = SBC_CONFIGURATION
  46. def set_exit_on_release(self, exit_on_release):
  47. self.exit_on_release = exit_on_release
  48. def default_configuration(self, configuration):
  49. self.configuration = configuration
  50. @dbus.service.method("org.bluez.MediaEndpoint1",
  51. in_signature="", out_signature="")
  52. def Release(self):
  53. print("Release")
  54. if self.exit_on_release:
  55. mainloop.quit()
  56. @dbus.service.method("org.bluez.MediaEndpoint1",
  57. in_signature="o", out_signature="")
  58. def ClearConfiguration(self, transport):
  59. print("ClearConfiguration (%s)" % (transport))
  60. @dbus.service.method("org.bluez.MediaEndpoint1",
  61. in_signature="oay", out_signature="")
  62. def SetConfiguration(self, transport, config):
  63. print("SetConfiguration (%s, %s)" % (transport, config))
  64. return
  65. @dbus.service.method("org.bluez.MediaEndpoint1",
  66. in_signature="ay", out_signature="ay")
  67. def SelectConfiguration(self, caps):
  68. print("SelectConfiguration (%s)" % (caps))
  69. return self.configuration
  70. if __name__ == '__main__':
  71. dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
  72. bus = dbus.SystemBus()
  73. if len(sys.argv) > 1:
  74. path = bluezutils.find_adapter(sys.argv[1]).object_path
  75. else:
  76. path = bluezutils.find_adapter().object_path
  77. media = dbus.Interface(bus.get_object("org.bluez", path),
  78. "org.bluez.Media1")
  79. path = "/test/endpoint"
  80. endpoint = Endpoint(bus, path)
  81. mainloop = GObject.MainLoop()
  82. properties = dbus.Dictionary({ "UUID" : A2DP_SOURCE_UUID,
  83. "Codec" : SBC_CODEC,
  84. "DelayReporting" : True,
  85. "Capabilities" : SBC_CAPABILITIES })
  86. if len(sys.argv) > 2:
  87. if sys.argv[2] == "sbcsink":
  88. properties = dbus.Dictionary({ "UUID" : A2DP_SINK_UUID,
  89. "Codec" : SBC_CODEC,
  90. "DelayReporting" : True,
  91. "Capabilities" : SBC_CAPABILITIES })
  92. if sys.argv[2] == "mp3source":
  93. properties = dbus.Dictionary({ "UUID" : A2DP_SOURCE_UUID,
  94. "Codec" : MP3_CODEC,
  95. "Capabilities" : MP3_CAPABILITIES })
  96. endpoint.default_configuration(MP3_CONFIGURATION)
  97. if sys.argv[2] == "mp3sink":
  98. properties = dbus.Dictionary({ "UUID" : A2DP_SINK_UUID,
  99. "Codec" : MP3_CODEC,
  100. "Capabilities" : MP3_CAPABILITIES })
  101. endpoint.default_configuration(MP3_CONFIGURATION)
  102. if sys.argv[2] == "hfpag" or sys.argv[2] == "hspag":
  103. properties = dbus.Dictionary({ "UUID" : HFP_AG_UUID,
  104. "Codec" : PCM_CODEC,
  105. "Capabilities" : PCM_CONFIGURATION })
  106. endpoint.default_configuration(dbus.Array([]))
  107. if sys.argv[2] == "hfphf":
  108. properties = dbus.Dictionary({ "UUID" : HFP_HF_UUID,
  109. "Codec" : CVSD_CODEC,
  110. "Capabilities" : PCM_CONFIGURATION })
  111. endpoint.default_configuration(dbus.Array([]))
  112. print(properties)
  113. media.RegisterEndpoint(path, properties)
  114. mainloop.run()