pax_global_header00006660000000000000000000000064142040760140014510gustar00rootroot0000000000000052 comment=a5391561599a7f35eecd533906db37b3413f7131 go-bluetooth-bluez-5.60/000077500000000000000000000000001420407601400151715ustar00rootroot00000000000000go-bluetooth-bluez-5.60/.github/000077500000000000000000000000001420407601400165315ustar00rootroot00000000000000go-bluetooth-bluez-5.60/.github/FUNDING.yml000066400000000000000000000012441420407601400203470ustar00rootroot00000000000000# These are supported funding model platforms github: muka # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] go-bluetooth-bluez-5.60/.gitignore000066400000000000000000000006161420407601400171640ustar00rootroot00000000000000*.code-workspace .vscode # /bluez/profile/*/gen_* # /bluez/profile/gen_* /go-bluetooth logs/*.log debug /vendor /test /src/gen* # Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe *.test *.prof go-bluetooth-bluez-5.60/.gitmodules000066400000000000000000000001441420407601400173450ustar00rootroot00000000000000[submodule "src/bluez"] path = src/bluez url = https://git.kernel.org/pub/scm/bluetooth/bluez.git go-bluetooth-bluez-5.60/CODE_OF_CONDUCT.md000066400000000000000000000064371420407601400200020ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at luca.capra+github@gmail.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq go-bluetooth-bluez-5.60/LICENSE000066400000000000000000000261151420407601400162030ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 20** luca capra Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. go-bluetooth-bluez-5.60/Makefile000066400000000000000000000036021420407601400166320ustar00rootroot00000000000000 .PHONY: gen BLUEZ_VERSION ?= 5.60 FILTER ?= DOCKER_PARAMS := --privileged -it --rm \ --net=host \ -v /dev:/dev \ -v /var/run/dbus:/var/run/dbus \ -v /sys/class/bluetooth:/sys/class/bluetooth \ -v /var/lib/bluetooth:/var/lib/bluetooth \ opny/bluez-${BLUEZ_VERSION} all: bluez/checkout gen/clean gen/run bluez/init: git submodule init git submodule update bluez/checkout: cd src/bluez && git fetch && git checkout ${BLUEZ_VERSION} service/bluetoothd/logs: journalctl -u bluetooth -f service/bluetoothd/start: service/bluetoothd/stop sudo bluetoothd -E -d -n -P hostname service/bluetoothd/stop: sudo killall bluetoothd || true gen/clean: rm -f `ls bluez/profile/*/gen_* -1` || true rm -f `ls bluez/profile/gen_* -1` || true gen/run: bluez/checkout BLUEZ_VERSION=${BLUEZ_VERSION} FILTER=${FILTER} go run gen/srcgen/main.go full gen: gen/run build: gen CGO_ENABLED=0 go build -o go-bluetooth ./main.go dev/kill: ssh ${DEV_HOST} "killall go-bluetooth" || true docker/bluetoothd/init: sudo addgroup bluetooth || true sudo adduser `id -nu` bluetooth || true sudo ln -s `pwd`/src/bluetooth.conf /etc/dbus-1/system.d/ docker/service/setup: ./bin/btmgmt power off ./bin/btmgmt le on ./bin/btmgmt bredr off ./bin/btmgmt power on docker/btmgmt: ./bin/btmgmt docker/bluetoothd/build: docker build ./env/bluez --build-arg BLUEZ_VERSION=${BLUEZ_VERSION} -t opny/bluez-${BLUEZ_VERSION} docker/bluetoothd/push: docker push opny/bluez-${BLUEZ_VERSION} docker/bluetoothd/run: service/bluetoothd/stop docker run --name bluez_bluetoothd \ ${DOCKER_PARAMS} bluez-5.50/gen: BLUEZ_VERSION=5.50 make gen/clean gen bluez-5.53/gen: BLUEZ_VERSION=5.53 make gen/clean gen bluez-5.54/gen: BLUEZ_VERSION=5.54 make gen/clean gen bluez-5.55/gen: BLUEZ_VERSION=5.55 make gen/clean gen bluez-5.62/gen: BLUEZ_VERSION=5.62 make gen/clean gen bluez-5.60/gen: BLUEZ_VERSION=5.60 make gen/clean gen go-bluetooth-bluez-5.60/README.md000066400000000000000000000116341420407601400164550ustar00rootroot00000000000000 # go-bluetooth Go bluetooth API for Linux-based Bluez DBus interface. [![GoDoc](https://godoc.org/github.com/muka/go-bluetooth?status.svg)](https://godoc.org/github.com/muka/go-bluetooth) ## Bluez API versioning The version on master tracks Ubuntu bluetoothd version. There are dedicated branches with various version - [bluez 5.50](https://github.com/muka/go-bluetooth/tree/bluez/5.50) - [bluez 5.53](https://github.com/muka/go-bluetooth/tree/bluez/5.53) - [bluez 5.54](https://github.com/muka/go-bluetooth/tree/bluez/5.54) - [bluez 5.55](https://github.com/muka/go-bluetooth/tree/bluez/5.55) - [bluez 5.60](https://github.com/muka/go-bluetooth/tree/bluez/5.60) - [bluez 5.62](https://github.com/muka/go-bluetooth/tree/bluez/5.62) - [bluez 5.63](https://github.com/muka/go-bluetooth/tree/bluez/5.63) ## Features The library is a wrapper to the Bluez DBus API and some high level API to ease the interaction. High level features supported: - [x] Client code generation from bluez documentation - [x] Shell wrappers for `rfkill`, `btmgmt`, `hciconfig`, `hcitool` - [x] An `hci` socket basic API (inspired by [go-ble/ble](https://github.com/go-ble/ble)) - [x] Expose bluetooth service from go code [*unstable*] - [x] Pairing and authentication support (via agent) - [x] Beaconing send & receive (iBeacon and Eddystone) - [x] Mesh API support (since v5.53) ## Todo - [ ] Generate dbus-compatible XML from documentation - [ ] Generate mock service to test the library against ## Using this library - [TinyGo bluetooth](https://github.com/tinygo-org/bluetooth) - [pi-wifi](https://github.com/muka/pi-wifi) Want to add your project? Please, add it to the [README.md](https://github.com/muka/go-bluetooth/edit/master/README.md) and open a PR! ## Running examples Examples are available in `_examples` folder. ```sh cd _examples go run main.go # print available example commands # Example discovery go run main.go discovery ``` ## Development setup 1. Clone the repository `git clone https://github.com/muka/go-bluetooth.git` 1. Retrieve the bluetooth API and generate GO code ```sh make bluez/init bluez/checkout gen/clean gen/run ``` ## Code generation The code structure follow this pattern: - `./api` contains wrappers for the DBus Api - `./bluez` contains the actual implementation, generated from the `bluez` documentation Use `make gen` to re-generate go sources. There is also a commodity bluez JSON file available in the root folder for reference. Generated code has `gen_` prefix. If an API file exists with the same filename but _without_ the prefix, generation will be skipped for that API. ## Requirements The library is tested with - golang `1.17.5` - bluez bluetooth `v5.50`, `v5.54`, `v5.60` ### Development notes - Inspect a service ObjectManager ```shell dbus-send --system --print-reply --dest=go.bluetooth /hci0/apps/0 org.freedesktop.DBus.ObjectManager.GetManagedObjects ``` - Retrieve char properties ``` dbus-send --system --print-reply --dest=go.bluetooth /hci0/apps/0/service000003e8/char0 org.freedesktop.DBus.Properties.GetAll string:org.bluez.GattCharacteristic1 ``` - Give access to `hciconfig` to any user and avoid `sudo` (may have [security implications](https://www.insecure.ws/linux/getcap_setcap.html)) ``` sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hciconfig` ``` - Monitor Bluetooth activity `sudo btmon` - Monitor DBus activity `sudo dbus-monitor --system "type=error"` - Start `bluetoothd` with experimental features and verbose debug messages `make bluetoothd` - Enable LE advertisement (on a single pc ensure to use at least 2x bluetooth adapter) ```bash sudo btmgmt -i 0 power off sudo btmgmt -i 0 name "my go app" sudo btmgmt -i 0 le on sudo btmgmt -i 0 connectable on sudo btmgmt -i 0 advertising on sudo btmgmt -i 0 power on ``` ## References - [Standard GATT characteristics descriptions](https://www.bluetooth.com/specifications/gatt/) - [bluez git](https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc) - [GATT services specs](https://www.bluetooth.com/specifications/gatt/services) - [A C++ implementation](https://github.com/nettlep/gobbledegook) - [DBus specifications](https://dbus.freedesktop.org/doc/dbus-specification.html#type-system) - [SensorTag specs](http://processors.wiki.ti.com/images/a/a8/BLE_SensorTag_GATT_Server.pdf) ## License Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. go-bluetooth-bluez-5.60/_examples/000077500000000000000000000000001420407601400171465ustar00rootroot00000000000000go-bluetooth-bluez-5.60/_examples/cmd/000077500000000000000000000000001420407601400177115ustar00rootroot00000000000000go-bluetooth-bluez-5.60/_examples/cmd/agent.go000066400000000000000000000025201420407601400213350ustar00rootroot00000000000000// Copyright © 2019 luca capra // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( agent_example "github.com/muka/go-bluetooth/examples/agent" "github.com/spf13/cobra" ) // agentCmd represents the agent command var agentCmd = &cobra.Command{ Use: "agent", Short: "A bluez Agent1 example", Long: `An example of agent interaction to exchange a passkey during pairing`, Run: func(cmd *cobra.Command, args []string) { // id, err := cmd.Flags().GetString("id") // if err != nil { // fail(err) // } adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } if len(args) == 0 { failArg("Device mac") } id := args[0] fail(agent_example.Run(id, adapterID)) }, } func init() { rootCmd.AddCommand(agentCmd) agentCmd.Flags().String("id", "", "Help message for toggle") } go-bluetooth-bluez-5.60/_examples/cmd/beacon.go000066400000000000000000000022761420407601400214760ustar00rootroot00000000000000// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( beacon_example "github.com/muka/go-bluetooth/examples/beacon" "github.com/spf13/cobra" ) // beaconCmd represents the beacon command var beaconCmd = &cobra.Command{ Use: "beacon", Short: "Advertising example", Long: ``, Run: func(cmd *cobra.Command, args []string) { adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } if len(args) == 0 { failArg("type: ibeacon or eddystone") } var beaconType string = "URL" if len(args) == 2 { beaconType = args[1] } fail(beacon_example.Run(args[0], beaconType, adapterID)) }, } func init() { rootCmd.AddCommand(beaconCmd) } go-bluetooth-bluez-5.60/_examples/cmd/btmgmt.go000066400000000000000000000016721420407601400215400ustar00rootroot00000000000000// Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( btmgmt_example "github.com/muka/go-bluetooth/examples/btmgmt" "github.com/spf13/cobra" ) // btmgmtCmd represents the btmgmt command var btmgmtCmd = &cobra.Command{ Use: "btmgmt", Short: "btmgmt shell command wrapper example", Long: ``, Run: func(cmd *cobra.Command, args []string) { fail(btmgmt_example.Run()) }, } func init() { rootCmd.AddCommand(btmgmtCmd) } go-bluetooth-bluez-5.60/_examples/cmd/discovery.go000066400000000000000000000023351420407601400222520ustar00rootroot00000000000000// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( discovery_example "github.com/muka/go-bluetooth/examples/discovery" "github.com/spf13/cobra" ) // discoveryCmd represents the discovery command var discoveryCmd = &cobra.Command{ Use: "discovery", Short: "bluetooth discovery example", Long: ``, Run: func(cmd *cobra.Command, args []string) { adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } onlyBeacon, err := cmd.Flags().GetBool("beacon") if err != nil { fail(err) } fail(discovery_example.Run(adapterID, onlyBeacon)) }, } func init() { rootCmd.AddCommand(discoveryCmd) discoveryCmd.Flags().BoolP("beacon", "b", false, "Only report beacons") } go-bluetooth-bluez-5.60/_examples/cmd/err.go000066400000000000000000000004701420407601400210310ustar00rootroot00000000000000package cmd import ( "fmt" "os" log "github.com/sirupsen/logrus" ) func failArg(arg string) { failArgs([]string{arg}) } func failArgs(args []string) { fail(fmt.Errorf("Missing arguments: %s", args)) } func fail(err error) { if err != nil { log.Errorf("Error: %s", err) os.Exit(1) } os.Exit(0) } go-bluetooth-bluez-5.60/_examples/cmd/hci.go000066400000000000000000000020331420407601400210010ustar00rootroot00000000000000// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( hci_updown_example "github.com/muka/go-bluetooth/examples/hci_updown" "github.com/spf13/cobra" ) // hciCmd represents the hci command var hciCmd = &cobra.Command{ Use: "hci", Short: "Example usage of the HCI interface", Long: ``, Run: func(cmd *cobra.Command, args []string) { adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } fail(hci_updown_example.Run(adapterID)) }, } func init() { rootCmd.AddCommand(hciCmd) } go-bluetooth-bluez-5.60/_examples/cmd/obexPush.go000066400000000000000000000022041420407601400220330ustar00rootroot00000000000000// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( obex_push_example "github.com/muka/go-bluetooth/examples/obex_push" "github.com/spf13/cobra" ) // obexPushCmd represents the obexPush command var obexPushCmd = &cobra.Command{ Use: "obex-push", Short: "Obex push example", Long: ``, Run: func(cmd *cobra.Command, args []string) { adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } if len(args) < 2 { failArgs([]string{"target_address", "file_path"}) } fail(obex_push_example.Run(args[0], args[1], adapterID)) }, } func init() { rootCmd.AddCommand(obexPushCmd) } go-bluetooth-bluez-5.60/_examples/cmd/root.go000066400000000000000000000037311420407601400212270ustar00rootroot00000000000000// Copyright © 2019 NAME HERE // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( "fmt" "os" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "go-bluetooth", Short: "Usage examples for the go-bluetooth library", Long: ``, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, } // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } func init() { cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().String("adapterID", "hci0", "Set the adapterID to use") } // initConfig reads in config file and ENV variables if set. func initConfig() { viper.SetConfigName("config") viper.AutomaticEnv() // read in environment variables that match // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { fmt.Println("Using config file:", viper.ConfigFileUsed()) } logLevel := log.DebugLevel if viper.IsSet("LOG_LEVEL") { lvl, err := log.ParseLevel(viper.GetString("LOG_LEVEL")) if err != nil { panic(err) } logLevel = lvl } log.SetLevel(logLevel) } go-bluetooth-bluez-5.60/_examples/cmd/sensortagInfo.go000066400000000000000000000031331420407601400230610ustar00rootroot00000000000000// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( sensortag_info_example "github.com/muka/go-bluetooth/examples/sensortag_info" "github.com/spf13/cobra" ) // sensortagInfoCmd represents the sensortagInfo command var sensortagInfoCmd = &cobra.Command{ Use: "sensortag-info", Short: "Retrieve TI SensorTag sensors informations", Long: ``, Run: func(cmd *cobra.Command, args []string) { adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } if len(args) < 1 { failArgs([]string{"sensortag_address"}) } fail(sensortag_info_example.Run(args[0], adapterID)) }, } func init() { rootCmd.AddCommand(sensortagInfoCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // sensortagInfoCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command // is called directly, e.g.: // sensortagInfoCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } go-bluetooth-bluez-5.60/_examples/cmd/sensortagTemperature.go000066400000000000000000000032351420407601400244660ustar00rootroot00000000000000// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( sensortag_temperature_example "github.com/muka/go-bluetooth/examples/sensortag_temperature" "github.com/spf13/cobra" ) // sensortagTemperatureCmd represents the sensortagTemperature command var sensortagTemperatureCmd = &cobra.Command{ Use: "sensortag-temperature", Short: "Receives SensorTag temperature updates", Long: ``, Run: func(cmd *cobra.Command, args []string) { adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } if len(args) < 1 { failArgs([]string{"sensortag_address"}) } fail(sensortag_temperature_example.Run(args[0], adapterID)) }, } func init() { rootCmd.AddCommand(sensortagTemperatureCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // sensortagTemperatureCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command // is called directly, e.g.: // sensortagTemperatureCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } go-bluetooth-bluez-5.60/_examples/cmd/service.go000066400000000000000000000025261420407601400217050ustar00rootroot00000000000000// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( service_example "github.com/muka/go-bluetooth/examples/service" "github.com/spf13/cobra" ) // serviceCmd represents the service command var serviceCmd = &cobra.Command{ Use: "service", Short: "A service / client example", Long: ``, Run: func(cmd *cobra.Command, args []string) { adapterID, err := cmd.Flags().GetString("adapterID") if err != nil { fail(err) } if len(args) < 1 { failArgs([]string{"mode [server|client]"}) } if args[0] == "client" { if len(args) < 2 { failArgs([]string{ "please specify the adapter HW address that expose the service (eg. using hciconfig)", }) } } else { args = append(args, "") } fail(service_example.Run(adapterID, args[0], args[1])) }, } func init() { rootCmd.AddCommand(serviceCmd) } go-bluetooth-bluez-5.60/_examples/go.mod000066400000000000000000000003761420407601400202620ustar00rootroot00000000000000module github.com/muka/go-bluetooth/_examples go 1.14 replace github.com/muka/go-bluetooth v0.0.0 => ../ require ( github.com/muka/go-bluetooth v0.0.0 github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v0.0.7 github.com/spf13/viper v1.6.2 ) go-bluetooth-bluez-5.60/_examples/go.sum000066400000000000000000000464611420407601400203140ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf/go.mod h1:+AwQL2mK3Pd3S+TUwg0tYQjid0q1txyNUJuuSmz8Kdk= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.7 h1:FfTH+vuMXOas8jmfb5/M7dzEYx7LpcLb7a0LPe34uOU= github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/suapapa/go_eddystone v1.3.1 h1:mfW3eNoRPpaZ0iARRZtEyudFfNFtytqeCexwXg1wIKE= github.com/suapapa/go_eddystone v1.3.1/go.mod h1:bXC11TfJOS+3g3q/Uzd7FKd5g62STQEfeEIhcKe4Qy8= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= go-bluetooth-bluez-5.60/_examples/main.go000066400000000000000000000013211420407601400204160ustar00rootroot00000000000000//go:generate go run ./gen/srcgen/main.go // Copyright © 2020 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import "github.com/muka/go-bluetooth/_examples/cmd" func main() { cmd.Execute() } go-bluetooth-bluez-5.60/api/000077500000000000000000000000001420407601400157425ustar00rootroot00000000000000go-bluetooth-bluez-5.60/api/advertisement.go000066400000000000000000000061151420407601400211460ustar00rootroot00000000000000package api import ( "fmt" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/advertising" log "github.com/sirupsen/logrus" ) // const baseAdvertismentPath = "/org/bluez/%s/apps/advertisement%d" const BaseAdvertismentPath = "/go_bluetooth/%s/advertisement/%d" var advertisingCount int = -1 func nextAdvertismentPath(adapterID string) dbus.ObjectPath { advertisingCount++ return dbus.ObjectPath(fmt.Sprintf(BaseAdvertismentPath, adapterID, advertisingCount)) } func decreaseAdvertismentCounter() { advertisingCount-- if advertisingCount < -1 { advertisingCount = -1 } } type Advertisement struct { path dbus.ObjectPath objectManager *DBusObjectManager iprops *DBusProperties conn *dbus.Conn props *advertising.LEAdvertisement1Properties } func (a *Advertisement) DBusConn() *dbus.Conn { return a.conn } func (a *Advertisement) DBusObjectManager() *DBusObjectManager { return a.objectManager } func (a *Advertisement) DBusProperties() *DBusProperties { return a.iprops } func (a *Advertisement) GetProperties() bluez.Properties { return a.props } func (a *Advertisement) Path() dbus.ObjectPath { return a.path } func (a *Advertisement) Interface() string { return advertising.LEAdvertisement1Interface } func NewAdvertisement(adapterID string, props *advertising.LEAdvertisement1Properties) (*Advertisement, error) { adv := new(Advertisement) adv.props = props adv.path = nextAdvertismentPath(adapterID) conn, err := dbus.SystemBus() if err != nil { return nil, err } adv.conn = conn om, err := NewDBusObjectManager(conn) if err != nil { return nil, err } adv.objectManager = om iprops, err := NewDBusProperties(conn) if err != nil { return nil, err } adv.iprops = iprops return adv, nil } // Expose to bluez an advertisment instance via the adapter advertisement manager func ExposeAdvertisement(adapterID string, props *advertising.LEAdvertisement1Properties, discoverableTimeout uint32) (func(), error) { log.Tracef("Retrieving adapter instance %s", adapterID) a, err := GetAdapter(adapterID) if err != nil { return nil, err } adv, err := NewAdvertisement(adapterID, props) if err != nil { return nil, err } err = ExposeDBusService(adv) if err != nil { return nil, err } log.Debug("Setup adapter") err = a.SetDiscoverable(true) if err != nil { return nil, err } err = a.SetDiscoverableTimeout(discoverableTimeout) if err != nil { return nil, err } err = a.SetPowered(true) if err != nil { return nil, err } log.Trace("Registering LEAdvertisement1 instance") advManager, err := advertising.NewLEAdvertisingManager1FromAdapterID(adapterID) if err != nil { return nil, err } err = advManager.RegisterAdvertisement(adv.Path(), map[string]interface{}{}) if err != nil { return nil, err } cancel := func() { decreaseAdvertismentCounter() err := advManager.UnregisterAdvertisement(adv.Path()) if err != nil { log.Warn(err) } err = a.SetProperty("Discoverable", false) if err != nil { log.Warn(err) } } return cancel, nil } go-bluetooth-bluez-5.60/api/api.go000066400000000000000000000015131420407601400170420ustar00rootroot00000000000000// package api wraps an high level API to simplify interaction package api import ( "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/adapter" ) var adapters = map[string]*adapter.Adapter1{} //Exit performs a clean exit func Exit() error { for _, a := range adapters { a.Close() } adapters = map[string]*adapter.Adapter1{} return bluez.CloseConnections() } func GetAdapter(adapterID string) (*adapter.Adapter1, error) { if _, ok := adapters[adapterID]; ok { return adapters[adapterID], nil } a, err := adapter.GetAdapter(adapterID) if err != nil { return nil, err } adapters[adapterID] = a return a, nil } func GetDefaultAdapter() (*adapter.Adapter1, error) { return GetAdapter(GetDefaultAdapterID()) } func GetDefaultAdapterID() string { return adapter.GetDefaultAdapterID() } go-bluetooth-bluez-5.60/api/api_test.go000066400000000000000000000015251420407601400201040ustar00rootroot00000000000000package api import ( "testing" "github.com/muka/go-bluetooth/bluez/profile/adapter" "github.com/stretchr/testify/assert" ) func TestGetAdapterID(t *testing.T) { defaultAdapterID := adapter.GetDefaultAdapterID() adapter.SetDefaultAdapterID("foo") adapterID := GetDefaultAdapterID() if adapterID != "foo" { t.Fatalf("Wrong adapter ID: %s", adapterID) } adapter.SetDefaultAdapterID(defaultAdapterID) adapterID = GetDefaultAdapterID() if adapterID != defaultAdapterID { t.Fatalf("Wrong adapter ID: %s", adapterID) } } func TestGetAdapter(t *testing.T) { a1, err := GetDefaultAdapter() if err != nil { t.Fatal(err) } id := GetDefaultAdapterID() a2, err := GetAdapter(id) if err != nil { t.Fatal(err) } assert.Equal(t, a1.Properties.Address, a2.Properties.Address) err = Exit() if err != nil { t.Fatal(err) } } go-bluetooth-bluez-5.60/api/beacon/000077500000000000000000000000001420407601400171715ustar00rootroot00000000000000go-bluetooth-bluez-5.60/api/beacon/beacon.go000066400000000000000000000072551420407601400207600ustar00rootroot00000000000000package beacon import ( "context" "strings" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez/profile/advertising" "github.com/muka/go-bluetooth/bluez/profile/device" ) const appleBit = 0x004C type BeaconType string const ( BeaconTypeEddystone = "eddystone" BeaconTypeIBeacon = "ibeacon" ) type Beacon struct { Name string iBeacon BeaconIBeacon eddystone BeaconEddystone props *advertising.LEAdvertisement1Properties Type BeaconType Device *device.Device1 } func NewBeacon(dev *device.Device1) (Beacon, error) { b := Beacon{ Name: "gobluetooth", Device: dev, } return b, nil } // IsEddystone return if the type of beacon is eddystone func (b *Beacon) IsEddystone() bool { return b.Type == BeaconTypeEddystone } // IsIBeacon return if the type of beacon is ibeacon func (b *Beacon) IsIBeacon() bool { return b.Type == BeaconTypeIBeacon } // WatchDeviceChanges watch for properties changes func (b *Beacon) WatchDeviceChanges(ctx context.Context) (chan bool, error) { propchanged, err := b.Device.WatchProperties() if err != nil { return nil, err } ch := make(chan bool) go func() { for { select { case changed := <-propchanged: if changed == nil { ctx.Done() return } if changed.Name == "ManufacturerData" || changed.Name == "ServiceData" { ch <- b.Parse() } break case <-ctx.Done(): propchanged <- nil close(ch) break } } }() return ch, nil } // GetEddystone return eddystone beacon information func (b *Beacon) GetEddystone() BeaconEddystone { return b.eddystone } // GetIBeacon return if the type of beacon is ibeacon func (b *Beacon) GetIBeacon() BeaconIBeacon { return b.iBeacon } // GetFrames return the bytes content func (b *Beacon) GetFrames() []byte { var data interface{} if b.IsIBeacon() { data = b.props.ManufacturerData[appleBit].([]byte) } else { data = b.props.ServiceData[eddystoneSrvcUid].([]byte) } if dataBytes, ok := b.getBytesFromData(data); ok { return dataBytes } return nil } // Load beacon information if available func (b *Beacon) Parse() bool { if b.Device != nil { props := b.Device.Properties if b.parserEddystone(props.UUIDs, props.ServiceData) { return true } if b.parserIBeacon(props.ManufacturerData) { return true } } if b.props != nil { props := b.props if b.parserEddystone(props.ServiceUUIDs, props.ServiceData) { return true } if b.parserIBeacon(props.ManufacturerData) { return true } } return false } func (b *Beacon) parserIBeacon(manufacturerData map[uint16]interface{}) bool { if len(manufacturerData) == 0 { return false } if frames, ok := manufacturerData[appleBit]; ok { if frameBytes, ok := b.getBytesFromData(frames); ok { if len(frameBytes) < 22 { return false } b.Type = BeaconTypeIBeacon b.iBeacon = b.ParseIBeacon(frameBytes) return true } } return false } func (b *Beacon) parserEddystone(UUIDs []string, serviceData map[string]interface{}) bool { for _, uuid := range UUIDs { // 0000feaa- srcUUID := uuid if len(uuid) > 8 { uuid = uuid[4:8] } if strings.ToUpper(uuid) == eddystoneSrvcUid { if data, ok := serviceData[srcUUID]; ok { // log.Debug("Found Eddystone") b.Type = BeaconTypeEddystone // log.Debugf("Eddystone data: %d", data) b.eddystone = b.ParseEddystone(data.([]byte)) return true } } } return false } func (b *Beacon) getBytesFromData(data interface{}) ([]byte, bool) { if variant, ok := data.(dbus.Variant); ok { if variantBytes, ok := variant.Value().([]byte); ok { return variantBytes, true } } else if dataBytes, ok := data.([]byte); ok { return dataBytes, true } return nil, false } go-bluetooth-bluez-5.60/api/beacon/beacon_cast.go000066400000000000000000000006351420407601400217650ustar00rootroot00000000000000package beacon // source https://github.com/suapapa/go_eddystone/blob/master/cast.go func fixTofloat32(a uint16) float32 { if a&0x8000 == 0 { return float32(a) / 256.0 } return -(float32(^a) + 1) / 256.0 } func bytesToUint16(a []byte) (v uint16) { _ = a[1] v = uint16(a[0])<<8 | uint16(a[1]) return } func byteToInt(a byte) (v int) { v = int(a) if v&0x80 != 0 { v = -((^v + 1) & 0xff) } return } go-bluetooth-bluez-5.60/api/beacon/beacon_create.go000066400000000000000000000063621420407601400223010ustar00rootroot00000000000000package beacon import ( "encoding/binary" "encoding/hex" "strings" "github.com/muka/go-bluetooth/bluez/profile/advertising" eddystone "github.com/suapapa/go_eddystone" ) func initBeacon() (*Beacon, error) { b := new(Beacon) b.props = new(advertising.LEAdvertisement1Properties) return b, nil } // CreateIBeacon Create a beacon in the IBeacon format func CreateIBeacon(uuid string, major uint16, minor uint16, measuredPower uint16) (*Beacon, error) { frames := []byte{ 0x02, 0x15, } // uuid 2-17 uuidBytes, err := hex.DecodeString(strings.Replace(uuid, "-", "", -1)) if err != nil { return nil, err } frames = append(frames, uuidBytes...) // major 18,19 mayorb := make([]byte, 2) binary.BigEndian.PutUint16(mayorb, major) frames = append(frames, mayorb...) // minor 20,21 minorb := make([]byte, 2) binary.BigEndian.PutUint16(minorb, minor) frames = append(frames, minorb...) // pwr 22 mpwr := make([]byte, 2) binary.BigEndian.PutUint16(mpwr, measuredPower) frames = append(frames, mpwr[1]) b, err := initBeacon() if err != nil { return nil, err } b.Type = BeaconTypeIBeacon b.iBeacon = BeaconIBeacon{ ProximityUUID: uuid, Major: major, Minor: minor, MeasuredPower: measuredPower, Type: "proximity", } b.props.AddManifacturerData(appleBit, frames) return b, nil } func appendEddystoneService(UUIDs []string) []string { found := false for _, uuid := range UUIDs { if uuid == eddystoneSrvcUid { found = true } } if !found { return append(UUIDs, eddystoneSrvcUid) } return UUIDs } // CreateEddystoneURL create an eddystone beacon frame with url func CreateEddystoneURL(url string, txPower int) (*Beacon, error) { frames, err := eddystone.MakeURLFrame(url, txPower) if err != nil { return nil, err } b, err := initBeacon() if err != nil { return nil, err } b.props.AddServiceUUID(eddystoneSrvcUid) b.props.AddServiceData(eddystoneSrvcUid, []byte(frames)) b.Type = BeaconTypeEddystone b.eddystone = BeaconEddystone{ URL: url, CalibratedTxPower: txPower, } return b, nil } // CreateEddystoneTLM create an eddystone beacon frame with tlm func CreateEddystoneTLM(batt uint16, temp float32, advCnt, secCnt uint32) (*Beacon, error) { frames, err := eddystone.MakeTLMFrame(batt, temp, advCnt, secCnt) if err != nil { return nil, err } b, err := initBeacon() if err != nil { return nil, err } b.props.AddServiceUUID(eddystoneSrvcUid) b.props.AddServiceData(eddystoneSrvcUid, []byte(frames)) b.Type = BeaconTypeEddystone b.eddystone = BeaconEddystone{ TLMVersion: 0, TLMTemperature: temp, TLMAdvertisingPDU: advCnt, TLMBatteryVoltage: batt, TLMLastRebootedTime: secCnt, } return b, nil } // CreateEddystoneUID create an eddystone beacon frame with uid func CreateEddystoneUID(namespace, instance string, txPwr int) (*Beacon, error) { frames, err := eddystone.MakeUIDFrame(namespace, instance, txPwr) if err != nil { return nil, err } b, err := initBeacon() if err != nil { return nil, err } b.props.AddServiceData(eddystoneSrvcUid, []byte(frames)) b.Type = BeaconTypeEddystone b.eddystone = BeaconEddystone{ UID: namespace, InstanceUID: instance, CalibratedTxPower: txPwr, } return b, nil } go-bluetooth-bluez-5.60/api/beacon/beacon_create_test.go000066400000000000000000000050571420407601400233400ustar00rootroot00000000000000package beacon import ( "testing" "github.com/muka/go-bluetooth/bluez/profile/device" "github.com/stretchr/testify/assert" ) func TestCreateIBeacon(t *testing.T) { uuid := "AAAABBBBCCCCDDDDAAAABBBBCCCCDDDD" maj := uint16(32000) min := uint16(11000) txPwr := uint16(0xB3) b, err := CreateIBeacon(uuid, maj, min, txPwr) if err != nil { t.Fatal(err) } b.Device = &device.Device1{ Properties: &device.Device1Properties{}, } b.Device.Properties.ServiceData = b.props.ServiceData isBeacon := b.Parse() assert.True(t, isBeacon) assert.Equal(t, BeaconTypeIBeacon, string(b.Type)) assert.Equal(t, uuid, b.GetIBeacon().ProximityUUID) assert.Equal(t, maj, b.GetIBeacon().Major) assert.Equal(t, min, b.GetIBeacon().Minor) assert.Equal(t, txPwr, b.GetIBeacon().MeasuredPower) } func TestCreateEddystoneURL(t *testing.T) { url := "http://example.com" b, err := CreateEddystoneURL(url, 99) if err != nil { t.Fatal(err) } b.Device = &device.Device1{ Properties: &device.Device1Properties{}, } b.Device.Properties.ManufacturerData = b.props.ManufacturerData b.Device.Properties.UUIDs = b.props.ServiceUUIDs isBeacon := b.Parse() assert.True(t, isBeacon) assert.True(t, b.IsEddystone()) assert.Equal(t, string(b.Type), string(BeaconTypeEddystone)) assert.IsType(t, BeaconEddystone{}, b.GetEddystone()) assert.Equal(t, url, b.GetEddystone().URL) } func TestCreateEddystoneTLM(t *testing.T) { batt := uint16(89) b, err := CreateEddystoneTLM(batt, 10.0, 10, 10) if err != nil { t.Fatal(err) } b.Device = &device.Device1{ Properties: &device.Device1Properties{}, } b.Device.Properties.ManufacturerData = b.props.ManufacturerData b.Device.Properties.UUIDs = b.props.ServiceUUIDs isBeacon := b.Parse() assert.True(t, isBeacon) assert.True(t, b.IsEddystone()) assert.Equal(t, string(b.Type), string(BeaconTypeEddystone)) assert.IsType(t, BeaconEddystone{}, b.GetEddystone()) assert.Equal(t, batt, b.GetEddystone().TLMBatteryVoltage) } func TestCreateEddystoneUID(t *testing.T) { nsUID := "AAAAAAAAAABBBBBBBBBB" b, err := CreateEddystoneUID(nsUID, "123456123456", 99) if err != nil { t.Fatal(err) } b.Device = &device.Device1{ Properties: &device.Device1Properties{}, } b.Device.Properties.ManufacturerData = b.props.ManufacturerData b.Device.Properties.UUIDs = b.props.ServiceUUIDs isBeacon := b.Parse() assert.True(t, isBeacon) assert.True(t, b.IsEddystone()) assert.Equal(t, string(b.Type), string(BeaconTypeEddystone)) assert.IsType(t, BeaconEddystone{}, b.GetEddystone()) assert.Equal(t, nsUID, b.GetEddystone().UID) } go-bluetooth-bluez-5.60/api/beacon/beacon_eddystone.go000066400000000000000000000077631420407601400230420ustar00rootroot00000000000000package beacon import ( "strings" log "github.com/sirupsen/logrus" eddystone "github.com/suapapa/go_eddystone" ) const eddystoneSrvcUid = "FEAA" type BeaconEddystone struct { Frame eddystone.Header CalibratedTxPower int // eddystone-uid UID string InstanceUID string URL string // eddystone-tlm plain TLMVersion int TLMBatteryVoltage uint16 TLMTemperature float32 TLMAdvertisingPDU uint32 TLMLastRebootedTime uint32 } func (b *Beacon) ParseEddystone(frames []byte) BeaconEddystone { info := BeaconEddystone{} frameHeader := eddystone.Header(frames[0]) switch frameHeader { case eddystone.UID: info.Frame = frameHeader parseEddystoneUID(&info, frames) case eddystone.TLM: info.Frame = frameHeader parseEddystoneTLM(&info, frames) case eddystone.URL: info.Frame = frameHeader err := parseEddystoneURL(&info, frames) if err != nil { log.Warn(err) } case eddystone.EID: // TODO } return info } // eddystone-uid // https://github.com/google/eddystone/tree/master/eddystone-uid // Byte offset Field Description // 0 Frame Type Value = 0x00 // 1 Ranging Data Calibrated Tx power at 0 m // 2 NID[0] 10-byte Namespace // 3 NID[1] // 4 NID[2] // 5 NID[3] // 6 NID[4] // 7 NID[5] // 8 NID[6] // 9 NID[7] // 10 NID[8] // 11 NID[9] // 12 BID[0] 6-byte Instance // 13 BID[1] // 14 BID[2] // 15 BID[3] // 16 BID[4] // 17 BID[5] // 18 RFU Reserved for future use, must be0x00 // 19 RFU Reserved for future use, must be0x00 func parseEddystoneUID(info *BeaconEddystone, frames []byte) { ns, instance, tx := eddystone.ParseUIDFrame(frames) info.CalibratedTxPower = tx info.UID = strings.ToUpper(ns) info.InstanceUID = strings.ToUpper(instance) } // eddystone-tlm (plain) // https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md // Byte offset Field Description // 0 Frame Type Value = 0x20 // 1 Version TLM version, value = 0x00 // 2 VBATT[0] Battery voltage, 1 mV/bit // 3 VBATT[1] // 4 TEMP[0] Beacon temperature // 5 TEMP[1] // 6 ADV_CNT[0] Advertising PDU count // 7 ADV_CNT[1] // 8 ADV_CNT[2] // 9 ADV_CNT[3] // 10 SEC_CNT[0] Time since power-on or reboot // 11 SEC_CNT[1] // 12 SEC_CNT[2] // 13 SEC_CNT[3] func parseEddystoneTLM(info *BeaconEddystone, frames []byte) { batt, temp, advCnt, secCnt := eddystone.ParseTLMFrame(frames) info.TLMVersion = int(frames[1] & 0xff) info.TLMBatteryVoltage = batt info.TLMTemperature = temp info.TLMAdvertisingPDU = advCnt info.TLMLastRebootedTime = secCnt } // Byte offset Field Description // 0 Frame Type Value = 0x10 // 1 TX Power Calibrated Tx power at 0 m // 2 URL Scheme Encoded Scheme Prefix // 3+ Encoded URL Length 1-17 // // URL Scheme Prefix // Decimal Hex Expansion // 0 0x00 http://www. // 1 0x01 https://www. // 2 0x02 http:// // 3 0x03 https:// // // Eddystone-URL HTTP URL encoding // Decimal Hex Expansion // 0 0x00 .com/ // 1 0x01 .org/ // 2 0x02 .edu/ // 3 0x03 .net/ // 4 0x04 .info/ // 5 0x05 .biz/ // 6 0x06 .gov/ // 7 0x07 .com // 8 0x08 .org // 9 0x09 .edu // 10 0x0a .net // 11 0x0b .info // 12 0x0c .biz // 13 0x0d .gov // 14..32 0x0e..0x20 Reserved for Future Use // 127..255 0x7F..0xFF Reserved for Future Use func parseEddystoneURL(info *BeaconEddystone, frames []byte) error { url, tx, err := eddystone.ParseURLFrame(frames) if err != nil { return err } info.CalibratedTxPower = tx info.URL = url return nil } go-bluetooth-bluez-5.60/api/beacon/beacon_eddystone_test.go000066400000000000000000000044661420407601400240760ustar00rootroot00000000000000package beacon import ( "strings" "testing" "github.com/muka/go-bluetooth/bluez/profile/device" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" eddystone "github.com/suapapa/go_eddystone" ) func testNewBeacon(t *testing.T, frame eddystone.Frame) Beacon { dev := &device.Device1{ Properties: &device.Device1Properties{ Name: "test_eddystone", // FEAA, full UUID UUIDs: []string{"0000feaa-0000-1000-8000-00805f9b34fb"}, ServiceData: map[string]interface{}{ "0000feaa-0000-1000-8000-00805f9b34fb": []byte(frame), }, }, } beacon, err := NewBeacon(dev) if err != nil { t.Fatal(err) } if frame == nil { return beacon } isBeacon := beacon.Parse() assert.True(t, isBeacon) assert.True(t, beacon.IsEddystone()) assert.Equal(t, string(beacon.Type), string(BeaconTypeEddystone)) assert.IsType(t, BeaconEddystone{}, beacon.GetEddystone()) return beacon } func TestParseEddystoneUID(t *testing.T) { log.SetLevel(log.DebugLevel) uid := "EDD1EBEAC04E5DEFA017" instanceUid := "0BDB87539B67" txpower := 120 frame, err := eddystone.MakeUIDFrame( strings.Replace(uid, "-", "", -1), strings.Replace(instanceUid, "-", "", -1), txpower, ) if err != nil { t.Fatal(err) } beacon := testNewBeacon(t, frame) assert.Equal(t, uid, beacon.GetEddystone().UID) assert.Equal(t, instanceUid, beacon.GetEddystone().InstanceUID) assert.Equal(t, txpower, beacon.GetEddystone().CalibratedTxPower) } func TestParseEddystoneTLM(t *testing.T) { log.SetLevel(log.DebugLevel) var batt uint16 = 1000 var temp float32 = 25 var advCnt uint32 = 10 var secCnt uint32 = 50 frame, err := eddystone.MakeTLMFrame(batt, temp, advCnt, secCnt) if err != nil { t.Fatal(err) } beacon := testNewBeacon(t, frame) e := beacon.GetEddystone() assert.Equal(t, batt, e.TLMBatteryVoltage) assert.Equal(t, temp, e.TLMTemperature) assert.Equal(t, advCnt, e.TLMAdvertisingPDU) assert.Equal(t, secCnt, e.TLMLastRebootedTime) // log.Debugf("%+v", e) } func TestParseEddystoneURL(t *testing.T) { log.SetLevel(log.DebugLevel) url := "https://bit.ly/2OCrFK2" txPwr := 89 frame, err := eddystone.MakeURLFrame(url, txPwr) if err != nil { t.Fatal(err) } beacon := testNewBeacon(t, frame) e := beacon.GetEddystone() assert.Equal(t, url, e.URL) assert.Equal(t, txPwr, e.CalibratedTxPower) } go-bluetooth-bluez-5.60/api/beacon/beacon_expose.go000066400000000000000000000011751420407601400223360ustar00rootroot00000000000000package beacon import ( "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/advertising" ) // Expose the beacon func (b *Beacon) Expose(adapterID string, timeout uint16) (func(), error) { props := b.props props.Type = advertising.AdvertisementTypeBroadcast if b.Name != "" { props.LocalName = b.Name } b.props.Includes = nil b.props.ManufacturerData = nil // Duration is set to 2sec by default // Not sure if duration can be mapped to interval. // props.Duration = 1 props.Timeout = timeout cancel, err := api.ExposeAdvertisement(adapterID, props, uint32(timeout)) return cancel, err } go-bluetooth-bluez-5.60/api/beacon/beacon_ibeacon.go000066400000000000000000000036531420407601400224360ustar00rootroot00000000000000package beacon import ( "encoding/binary" "encoding/hex" "strings" ) type BeaconIBeacon struct { Type string ProximityUUID string Major uint16 Minor uint16 MeasuredPower uint16 } // From Apple specifications // Byte(s) Name Value Notes // 0 Flags[0] 0x02 See Bluetooth 4.0 Core Specification , Volume 3, Appendix C, 18.1. // 1 Flags[1] 0x01 See Bluetooth 4.0 Core Specification , Volume 3, Appendix C, 18.1. // 2 Flags[2] 0x06 See Bluetooth 4.0 Core Specification , Volume 3, Appendix C, 18.1. // 3 Length 0x1A See Bluetooth 4.0 Core Specification // 4 Type 0xFF See Bluetooth 4.0 Core Specification // 5 Company ID[0] 0x4C Must not be used for any purposes not specified by Apple. // 6 Company ID[1] 0x00 Must not be used for any purposes not specified by Apple. // ---- Bluez data starts here ---- // 7 Beacon Type[0] 0x02 Must be set to 0x02 for all Proximity Beacons // 8 Beacon Type[1] 0x15 Must be set to 0x15 for all Proximity Beacons // 9-24 Proximity UUID 0xnn..nn See CLBeaconRegion class in iOS Developer Library. Must not be set to all 0s. // 25-26 Major 0xnnnn See CLBeaconRegion class in iOS Developer Library. 0x0000 = unset. // 27-28 Minor 0xnnnn See CLBeaconRegion class in iOS Developer Library. 0x0000 = unset. // 29 Measured Power 0xnn See Measured Power (page 7) func (b *Beacon) ParseIBeacon(frames []uint8) BeaconIBeacon { info := BeaconIBeacon{} if frames[7-7] == 0x02 && frames[8-7] == 0x15 { info.Type = "proximity" } uuid := strings.ToUpper(hex.EncodeToString(frames[9-7 : 25-7])) info.ProximityUUID = strings.ToUpper(uuid) info.Major = binary.BigEndian.Uint16(frames[25-7 : 27-7]) info.Minor = binary.BigEndian.Uint16(frames[27-7 : 29-7]) if len(frames) < 23 { frames = append(frames, 0xb3) } info.MeasuredPower = uint16(frames[29-7]) return info } go-bluetooth-bluez-5.60/api/beacon/beacon_ibeacon_test.go000066400000000000000000000026451420407601400234750ustar00rootroot00000000000000package beacon import ( "testing" "github.com/muka/go-bluetooth/bluez/profile/device" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) func TestParseIBeacon(t *testing.T) { log.SetLevel(log.DebugLevel) uuid := "010203040506070809101112131415" major := uint16(999) minor := uint16(111) measuredPower := uint16(80) b1, err := CreateIBeacon(uuid, major, minor, measuredPower) if err != nil { t.Fatal(err) } frames := b1.GetFrames() dev := &device.Device1{ Properties: &device.Device1Properties{ Name: "test_ibeacon", ManufacturerData: map[uint16]interface{}{ appleBit: frames, }, }, } beacon, err := NewBeacon(dev) if err != nil { t.Fatal(err) } isBeacon := beacon.Parse() assert.True(t, isBeacon) assert.True(t, beacon.IsIBeacon()) assert.Equal(t, string(beacon.Type), string(BeaconTypeIBeacon)) assert.IsType(t, BeaconIBeacon{}, beacon.GetIBeacon()) } func TestParseInvalidIBeacon(t *testing.T) { log.SetLevel(log.DebugLevel) dev := &device.Device1{ Properties: &device.Device1Properties{ Name: "test_ibeacon", ManufacturerData: map[uint16]interface{}{ // this is an invalid package appleBit: []byte{16, 5, 1, 24, 128, 123, 77}, }, }, } beacon, err := NewBeacon(dev) if err != nil { t.Fatal(err) } isBeacon := beacon.Parse() assert.False(t, isBeacon) assert.False(t, beacon.IsIBeacon()) assert.Equal(t, string(beacon.Type), "") } go-bluetooth-bluez-5.60/api/discover.go000066400000000000000000000017551420407601400201170ustar00rootroot00000000000000package api import ( "github.com/muka/go-bluetooth/bluez/profile/adapter" log "github.com/sirupsen/logrus" ) // Discover start device discovery func Discover( a *adapter.Adapter1, filter *adapter.DiscoveryFilter, ) ( chan *adapter.DeviceDiscovered, func(), error, ) { err := a.SetPairable(false) if err != nil { return nil, nil, err } err = a.SetDiscoverable(false) if err != nil { return nil, nil, err } err = a.SetPowered(true) if err != nil { return nil, nil, err } filterMap := make(map[string]interface{}) if filter != nil { filterMap = filter.ToMap() } err = a.SetDiscoveryFilter(filterMap) if err != nil { return nil, nil, err } err = a.StartDiscovery() if err != nil { return nil, nil, err } ch, discoveryCancel, err := a.OnDeviceDiscovered() if err != nil { return nil, nil, err } cancel := func() { err := a.StopDiscovery() if err != nil { log.Warnf("Error stopping discovery: %s", err) } discoveryCancel() } return ch, cancel, nil } go-bluetooth-bluez-5.60/api/discover_test.go000066400000000000000000000012251420407601400211460ustar00rootroot00000000000000package api // // func TestDiscoverDevice(t *testing.T) { // // a, err := GetDefaultAdapter() // if err != nil { // t.Fatal(err) // } // // discovery, cancel, err := Discover(a, nil) // if err != nil { // t.Fatal(err) // } // // defer cancel() // // wait := make(chan error) // // go func() { // for dev := range discovery { // if dev == nil { // return // } // wait <- nil // } // }() // // go func() { // sleep := 5 // time.Sleep(time.Duration(sleep) * time.Second) // log.Debugf("Discovery timeout exceeded (%ds)", sleep) // wait <- nil // }() // // err = <-wait // if err != nil { // t.Fatal(err) // } // // } go-bluetooth-bluez-5.60/api/object_manager_service.go000066400000000000000000000055541420407601400227620ustar00rootroot00000000000000package api import ( "errors" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile" log "github.com/sirupsen/logrus" ) // NewDBusObjectManager create a new instance func NewDBusObjectManager(conn *dbus.Conn) (*DBusObjectManager, error) { o := &DBusObjectManager{ conn: conn, objects: make(map[dbus.ObjectPath]map[string]bluez.Properties), } return o, nil } // DBusObjectManager interface implementation type DBusObjectManager struct { conn *dbus.Conn objects map[dbus.ObjectPath]map[string]bluez.Properties } // SignalAdded notify of interfaces being added func (o *DBusObjectManager) SignalAdded(path dbus.ObjectPath) error { props, err := o.GetManagedObject(path) if err != nil { return err } return o.conn.Emit(path, bluez.InterfacesAdded, props) } // SignalRemoved notify of interfaces being removed func (o *DBusObjectManager) SignalRemoved(path dbus.ObjectPath, ifaces []string) error { if ifaces == nil { ifaces = make([]string, 0) } return o.conn.Emit(path, bluez.InterfacesRemoved, ifaces) } // GetManagedObject return an up to date view of a single object state func (o *DBusObjectManager) GetManagedObject(objpath dbus.ObjectPath) (map[string]map[string]dbus.Variant, error) { props, err := o.GetManagedObjects() if err != nil { return nil, err } if p, ok := props[objpath]; ok { return p, nil } return nil, errors.New("Object not found") } // GetManagedObjects return an up to date view of the object state func (o *DBusObjectManager) GetManagedObjects() (map[dbus.ObjectPath]map[string]map[string]dbus.Variant, *dbus.Error) { props := make(map[dbus.ObjectPath]map[string]map[string]dbus.Variant) for path, ifs := range o.objects { if _, ok := props[path]; !ok { props[path] = make(map[string]map[string]dbus.Variant) } for i, m := range ifs { if _, ok := props[path][i]; !ok { props[path][i] = make(map[string]dbus.Variant) } l, err := m.ToMap() if err != nil { log.Errorf("Failed to serialize properties: %s", err.Error()) return nil, &profile.ErrInvalidArguments } for k, v := range l { vrt := dbus.MakeVariant(v) props[path][i][k] = vrt } } } log.Tracef("ObjectManager.GetManagedObjects \n %v", props) return props, nil } //AddObject add an object to the list func (o *DBusObjectManager) AddObject(path dbus.ObjectPath, val map[string]bluez.Properties) error { log.Tracef("ObjectManager.AddObject: %s", path) o.objects[path] = val return o.SignalAdded(path) } //RemoveObject remove an object from the list func (o *DBusObjectManager) RemoveObject(path dbus.ObjectPath) error { log.Tracef("ObjectManager.RemoveObject: %s", path) if s, ok := o.objects[path]; ok { delete(o.objects, path) ifaces := make([]string, len(s)) for i := range s { ifaces = append(ifaces, i) } return o.SignalRemoved(path, ifaces) } return nil } go-bluetooth-bluez-5.60/api/properties_service.go000066400000000000000000000051601420407601400222070ustar00rootroot00000000000000package api import ( "github.com/fatih/structs" "github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5/introspect" "github.com/godbus/dbus/v5/prop" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile" "github.com/muka/go-bluetooth/props" log "github.com/sirupsen/logrus" ) // NewDBusProperties create a new instance func NewDBusProperties(conn *dbus.Conn) (*DBusProperties, error) { o := &DBusProperties{ conn: conn, props: make(map[string]bluez.Properties), propsConfig: make(map[string]map[string]*props.PropInfo), } err := o.parseProperties() return o, err } // DBus Properties interface implementation type DBusProperties struct { conn *dbus.Conn props map[string]bluez.Properties propsConfig map[string]map[string]*props.PropInfo instance *prop.Properties } func (p *DBusProperties) parseProperties() error { for iface, ifaceVal := range p.props { if _, ok := p.propsConfig[iface]; !ok { p.propsConfig[iface] = make(map[string]*props.PropInfo) } p.propsConfig[iface] = props.ParseProperties(ifaceVal) } return nil } func (p *DBusProperties) onChange(ev *prop.Change) *dbus.Error { if _, ok := p.propsConfig[ev.Iface]; ok { if conf, ok := p.propsConfig[ev.Iface][ev.Name]; ok { if conf.Writable { log.Debugf("Set %s.%s", ev.Iface, ev.Name) prop := p.props[ev.Iface] s := structs.New(prop) err := s.Field(ev.Name).Set(ev.Value) if err != nil { log.Errorf("Failed to set %s.%s: %s", ev.Iface, ev.Name, err.Error()) return &profile.ErrRejected } } } } return nil } //Instance return the props instance func (p *DBusProperties) Instance() *prop.Properties { return p.instance } //Introspection return the props instance func (p *DBusProperties) Introspection(iface string) []introspect.Property { res := p.instance.Introspection(iface) // log.Debug("Introspect", res) return res } //Expose expose the properties interface func (p *DBusProperties) Expose(path dbus.ObjectPath) { propsConfig := make(map[string]map[string]*prop.Prop) for iface1, props1 := range p.propsConfig { propsConfig[iface1] = make(map[string]*prop.Prop) for k, v := range props1 { if v.Skip { continue } propsConfig[iface1][k] = &v.Prop } } p.instance = prop.New(p.conn, path, propsConfig) } //AddProperties add a property set func (p *DBusProperties) AddProperties(iface string, props bluez.Properties) error { p.props[iface] = props return p.parseProperties() } //RemoveProperties remove a property set func (p *DBusProperties) RemoveProperties(iface string) { delete(p.props, iface) delete(p.propsConfig, iface) } go-bluetooth-bluez-5.60/api/properties_service_test.go000066400000000000000000000027051420407601400232500ustar00rootroot00000000000000package api import ( "fmt" "testing" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" "github.com/stretchr/testify/assert" ) type testStruct struct { IgnoreFlag bool `dbus:"ignore"` ToOmit map[string]interface{} `dbus:"omitEmpty,writable"` Ignored string `dbus:"ignore"` IgnoredByProperty []string `dbus:"ignore=IgnoreFlag"` Avail string } func (s testStruct) ToMap() (map[string]interface{}, error) { m := map[string]interface{}{} util.StructToMap(s, m) return m, nil } func (s testStruct) Lock() {} func (s testStruct) Unlock() {} func TestParseTag(t *testing.T) { s := testStruct{ IgnoreFlag: true, Ignored: "foo", IgnoredByProperty: []string{"bar"}, Avail: "foo", } prop := &DBusProperties{ props: make(map[string]bluez.Properties), propsConfig: make(map[string]map[string]*props.PropInfo), } err := prop.AddProperties("test", s) if err != nil { t.Fatal(err) } err = prop.parseProperties() if err != nil { t.Fatal(err) } cfg := prop.propsConfig["test"] for field, cfg := range cfg { fmt.Printf("%s: %++v\n", field, cfg) } assert.True(t, cfg["ToOmit"].Skip) assert.True(t, cfg["ToOmit"].Writable) assert.True(t, cfg["Ignored"].Skip) assert.True(t, cfg["IgnoredByProperty"].Skip) assert.Equal(t, "foo", cfg["Avail"].Value) } go-bluetooth-bluez-5.60/api/service/000077500000000000000000000000001420407601400174025ustar00rootroot00000000000000go-bluetooth-bluez-5.60/api/service/agent.go000066400000000000000000000005631420407601400210330ustar00rootroot00000000000000package service import "github.com/muka/go-bluetooth/bluez/profile/agent" func (app *App) createAgent() (agent.Agent1Client, error) { a := agent.NewDefaultSimpleAgent() return a, nil } // Expose app agent on DBus func (app *App) ExposeAgent(caps string, setAsDefaultAgent bool) error { return agent.ExposeAgent(app.DBusConn(), app.agent, caps, setAsDefaultAgent) } go-bluetooth-bluez-5.60/api/service/agent_test.go000066400000000000000000000005261420407601400220710ustar00rootroot00000000000000package service // // func TestAppAgent(t *testing.T) { // a := createTestApp(t) // defer a.Close() // // ag, err := agent.NewAgent1("org.bluez", "/org/bluez/agent/simple0") // if err != nil { // t.Fatal(err) // } // // err = ag.RequestConfirmation("/org/bluez/hci0/app0", 123456) // if err != nil { // t.Fatal(err) // } // // } go-bluetooth-bluez-5.60/api/service/app.go000066400000000000000000000120141420407601400205070ustar00rootroot00000000000000package service import ( "errors" "fmt" "strings" "github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5/introspect" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/adapter" "github.com/muka/go-bluetooth/bluez/profile/advertising" "github.com/muka/go-bluetooth/bluez/profile/agent" "github.com/muka/go-bluetooth/bluez/profile/gatt" log "github.com/sirupsen/logrus" ) // AppPath default app path var AppPath = "/%s/apps/%d" var appCounter = 0 // AppOptions contains App options type AppOptions struct { AdapterID string AgentCaps string AgentSetAsDefault bool UUIDSuffix string UUID string } // NewApp initialize a new bluetooth service (app) func NewApp(options AppOptions) (*App, error) { app := new(App) if options.AdapterID == "" { return nil, errors.New("options.AdapterID is required") } app.Options = options if app.Options.UUIDSuffix == "" { app.Options.UUIDSuffix = "-0000-1000-8000-00805F9B34FB" } if app.Options.UUID == "" { app.Options.UUID = "1234" } app.adapterID = app.Options.AdapterID app.services = make(map[dbus.ObjectPath]*Service) app.path = dbus.ObjectPath( fmt.Sprintf( AppPath, app.adapterID, appCounter, ), ) app.advertisement = &advertising.LEAdvertisement1Properties{ Type: advertising.AdvertisementTypePeripheral, } if app.Options.AgentCaps == "" { app.Options.AgentCaps = agent.CapKeyboardDisplay } appCounter++ return app, app.init() } // App wraps a bluetooth application exposing services type App struct { path dbus.ObjectPath Options AppOptions adapterID string adapter *adapter.Adapter1 agent agent.Agent1Client conn *dbus.Conn objectManager *api.DBusObjectManager services map[dbus.ObjectPath]*Service advertisement *advertising.LEAdvertisement1Properties gm *gatt.GattManager1 } func (app *App) init() error { // log.Tracef("Exposing %s", app.Path()) // log.Trace("Load adapter") a, err := adapter.NewAdapter1FromAdapterID(app.adapterID) if err != nil { return err } app.adapter = a agent1, err := app.createAgent() if err != nil { return err } app.agent = agent1 conn, err := dbus.SystemBus() if err != nil { return err } app.conn = conn om, err := api.NewDBusObjectManager(app.DBusConn()) if err != nil { return err } app.objectManager = om return err } // GenerateUUID generate a 128bit UUID func (app *App) GenerateUUID(uuidVal string) string { base := app.Options.UUID if len(uuidVal) == 8 { base = "" } return base + uuidVal + app.Options.UUIDSuffix } // GetAdapter return the adapter in use func (app *App) GetAdapter() *adapter.Adapter1 { return app.adapter } // Expose children services, chars and descriptors func (app *App) extractChildren() (children []introspect.Node) { for _, service := range app.GetServices() { childPath := strings.ReplaceAll(string(service.Path()), string(app.Path())+"/", "") children = append(children, introspect.Node{ Name: childPath, }) // chars for _, char := range service.GetChars() { childPath := strings.ReplaceAll(string(char.Path()), string(app.Path())+"/", "") children = append(children, introspect.Node{ Name: childPath, }) // descrs for _, descr := range char.GetDescr() { childPath := strings.ReplaceAll(string(descr.Path()), string(app.Path())+"/", "") children = append(children, introspect.Node{ Name: childPath, }) } } } return children } // ExportTree update introspection data func (app *App) ExportTree() (err error) { node := &introspect.Node{ Interfaces: []introspect.Interface{ //Introspect introspect.IntrospectData, //ObjectManager bluez.ObjectManagerIntrospectData, }, Children: app.extractChildren(), } introspectable := introspect.NewIntrospectable(node) err = app.conn.Export( introspectable, app.Path(), "org.freedesktop.DBus.Introspectable", ) return err } // Run initialize the application func (app *App) Run() (err error) { log.Tracef("Expose %s (%s)", app.Path(), bluez.ObjectManagerInterface) err = app.conn.Export(app.objectManager, app.Path(), bluez.ObjectManagerInterface) if err != nil { return err } err = app.ExportTree() if err != nil { return err } err = app.ExposeAgent(app.Options.AgentCaps, app.Options.AgentSetAsDefault) if err != nil { return fmt.Errorf("ExposeAgent: %s", err) } gm, err := gatt.NewGattManager1FromAdapterID(app.adapterID) if err != nil { return err } app.gm = gm options := map[string]interface{}{} err = gm.RegisterApplication(app.Path(), options) return err } // Close close the app func (app *App) Close() { if app.agent != nil { err := agent.RemoveAgent(app.agent) if err != nil { log.Warnf("RemoveAgent: %s", err) } // err = app.agent.Release() // if err != nil { // log.Warnf("Agent1.Release: %s", err) // } } if app.gm != nil { err1 := app.gm.UnregisterApplication(app.Path()) if err1 != nil { log.Warnf("GattManager1.UnregisterApplication: %s", err1) } } } go-bluetooth-bluez-5.60/api/service/app_advertise.go000066400000000000000000000010021420407601400225500ustar00rootroot00000000000000package service import ( "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/advertising" ) func (app *App) GetAdvertisement() *advertising.LEAdvertisement1Properties { return app.advertisement } func (app *App) Advertise(timeout uint32) (func(), error) { adv := app.GetAdvertisement() for _, svc := range app.GetServices() { adv.ServiceUUIDs = append(adv.ServiceUUIDs, svc.UUID) } cancel, err := api.ExposeAdvertisement(app.adapterID, adv, timeout) return cancel, err } go-bluetooth-bluez-5.60/api/service/app_char.go000066400000000000000000000063271420407601400215160ustar00rootroot00000000000000package service import ( "fmt" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/gatt" log "github.com/sirupsen/logrus" ) type CharReadCallback func(c *Char, options map[string]interface{}) ([]byte, error) type CharWriteCallback func(c *Char, value []byte) ([]byte, error) type Char struct { UUID string app *App service *Service path dbus.ObjectPath descr map[dbus.ObjectPath]*Descr Properties *gatt.GattCharacteristic1Properties iprops *api.DBusProperties readCallback CharReadCallback writeCallback CharWriteCallback } func (s *Char) Path() dbus.ObjectPath { return s.path } func (s *Char) DBusProperties() *api.DBusProperties { return s.iprops } func (s *Char) Interface() string { return gatt.GattCharacteristic1Interface } func (s *Char) GetProperties() bluez.Properties { descr := []dbus.ObjectPath{} for dpath := range s.descr { descr = append(descr, dpath) } s.Properties.Descriptors = descr s.Properties.Service = s.Service().Path() return s.Properties } func (c *Char) GetDescr() map[dbus.ObjectPath]*Descr { return c.descr } func (c *Char) App() *App { return c.app } func (c *Char) Service() *Service { return c.service } func (s *Char) DBusObjectManager() *api.DBusObjectManager { return s.App().DBusObjectManager() } func (s *Char) DBusConn() *dbus.Conn { return s.App().DBusConn() } func (s *Char) RemoveDescr(descr *Descr) error { if _, ok := s.descr[descr.Path()]; !ok { return nil } err := descr.Remove() if err != nil { return err } delete(s.descr, descr.Path()) return nil } // Expose char to dbus func (s *Char) Expose() error { return api.ExposeDBusService(s) } // Remove char from dbus func (s *Char) Remove() error { return api.RemoveDBusService(s) } // NewDescr Init new descr func (s *Char) NewDescr(uuid string) (*Descr, error) { descr := new(Descr) descr.UUID = s.App().GenerateUUID(uuid) descr.app = s.App() descr.char = s descr.Properties = NewGattDescriptor1Properties(descr.UUID) descr.path = dbus.ObjectPath( fmt.Sprintf("%s/descriptor%d", s.Path(), len(s.GetDescr())), ) iprops, err := api.NewDBusProperties(s.App().DBusConn()) if err != nil { return nil, err } descr.iprops = iprops return descr, nil } // AddDescr Add descr to dbus func (s *Char) AddDescr(descr *Descr) error { err := api.ExposeDBusService(descr) if err != nil { return err } s.descr[descr.Path()] = descr err = s.DBusObjectManager().AddObject(descr.Path(), map[string]bluez.Properties{ descr.Interface(): descr.GetProperties(), }) if err != nil { return err } // update OM char too err = s.DBusObjectManager().AddObject(s.Path(), map[string]bluez.Properties{ s.Interface(): s.GetProperties(), }) if err != nil { return err } log.Tracef("Added GATT Descriptor UUID=%s %s", descr.UUID, descr.Path()) err = s.App().ExportTree() return err } // OnRead Set the Read callback, called when a client attempt to read func (s *Char) OnRead(fx CharReadCallback) *Char { s.readCallback = fx return s } // OnWrite Set the Write callback, called when a client attempt to write func (s *Char) OnWrite(fx CharWriteCallback) *Char { s.writeCallback = fx return s } go-bluetooth-bluez-5.60/api/service/app_char_rw.go000066400000000000000000000054301420407601400222200ustar00rootroot00000000000000package service import ( "github.com/godbus/dbus/v5" log "github.com/sirupsen/logrus" ) // Confirm This method doesn't expect a reply so it is just a // confirmation that value was received. // // Possible Errors: org.bluez.Error.Failed func (s *Char) Confirm() *dbus.Error { log.Debug("Char.Confirm") return nil } // StartNotify Starts a notification session from this characteristic // if it supports value notifications or indications. // // Possible Errors: org.bluez.Error.Failed // org.bluez.Error.NotPermitted // org.bluez.Error.InProgress // org.bluez.Error.NotSupported func (s *Char) StartNotify() *dbus.Error { log.Debug("Char.StartNotify") return nil } // StopNotify This method will cancel any previous StartNotify // transaction. Note that notifications from a // characteristic are shared between sessions thus // calling StopNotify will release a single session. // // Possible Errors: org.bluez.Error.Failed func (s *Char) StopNotify() *dbus.Error { log.Debug("Char.StopNotify") return nil } // ReadValue Issues a request to read the value of the // characteristic and returns the value if the // operation was successful. // // Possible options: "offset": uint16 offset // "device": Object Device (Server only) // // Possible Errors: org.bluez.Error.Failed // org.bluez.Error.InProgress // org.bluez.Error.NotPermitted // org.bluez.Error.NotAuthorized // org.bluez.Error.InvalidOffset // org.bluez.Error.NotSupported func (s *Char) ReadValue(options map[string]interface{}) ([]byte, *dbus.Error) { log.Debug("Characteristic.ReadValue") if s.readCallback != nil { b, err := s.readCallback(s, options) if err != nil { return nil, dbus.MakeFailedError(err) } return b, nil } return s.Properties.Value, nil } //WriteValue Issues a request to write the value of the // characteristic. // // Possible options: "offset": Start offset // "device": Device path (Server only) // "link": Link type (Server only) // "prepare-authorize": boolean Is prepare // authorization // request // // Possible Errors: org.bluez.Error.Failed // org.bluez.Error.InProgress // org.bluez.Error.NotPermitted // org.bluez.Error.InvalidValueLength // org.bluez.Error.NotAuthorized // org.bluez.Error.NotSupported func (s *Char) WriteValue(value []byte, options map[string]interface{}) *dbus.Error { log.Trace("Characteristic.WriteValue") val := value if s.writeCallback != nil { log.Trace("Used write callback") b, err := s.writeCallback(s, value) val = b if err != nil { return dbus.MakeFailedError(err) } } else { log.Trace("Store directly to value (no callback)") } // TODO update on Properties interface s.Properties.Value = val err := s.iprops.Instance().Set(s.Interface(), "Value", dbus.MakeVariant(value)) return err } go-bluetooth-bluez-5.60/api/service/app_descr.go000066400000000000000000000025061420407601400216740ustar00rootroot00000000000000package service import ( "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) type DescrReadCallback func(c *Descr, options map[string]interface{}) ([]byte, error) type DescrWriteCallback func(c *Descr, value []byte) ([]byte, error) type Descr struct { UUID string app *App char *Char path dbus.ObjectPath Properties *gatt.GattDescriptor1Properties iprops *api.DBusProperties readCallback DescrReadCallback writeCallback DescrWriteCallback } func (s *Descr) DBusProperties() *api.DBusProperties { return s.iprops } func (s *Descr) DBusObjectManager() *api.DBusObjectManager { return s.App().DBusObjectManager() } func (s *Descr) DBusConn() *dbus.Conn { return s.App().DBusConn() } func (s *Descr) Path() dbus.ObjectPath { return s.path } func (s *Descr) Char() *Char { return s.char } func (s *Descr) Interface() string { return gatt.GattDescriptor1Interface } func (s *Descr) GetProperties() bluez.Properties { s.Properties.Characteristic = s.char.Path() return s.Properties } func (s *Descr) App() *App { return s.app } // Expose descr to dbus func (s *Descr) Expose() error { return api.ExposeDBusService(s) } // Remove descr from dbus func (s *Descr) Remove() error { return api.RemoveDBusService(s) } go-bluetooth-bluez-5.60/api/service/app_descr_rw.go000066400000000000000000000024031420407601400224000ustar00rootroot00000000000000package service import ( "github.com/godbus/dbus/v5" log "github.com/sirupsen/logrus" ) // Set the Read callback, called when a client attempt to read func (s *Descr) OnRead(fx DescrReadCallback) *Descr { s.readCallback = fx return s } // Set the Write callback, called when a client attempt to write func (s *Descr) OnWrite(fx DescrWriteCallback) *Descr { s.writeCallback = fx return s } //ReadValue read a value func (s *Descr) ReadValue(options map[string]interface{}) ([]byte, *dbus.Error) { log.Trace("Descr.ReadValue") if s.readCallback != nil { b, err := s.readCallback(s, options) if err != nil { return nil, dbus.MakeFailedError(err) } return b, nil } return s.Properties.Value, nil } //WriteValue write a value func (s *Descr) WriteValue(value []byte, options map[string]interface{}) *dbus.Error { log.Trace("Descr.WriteValue") val := value if s.writeCallback != nil { log.Trace("Used write callback") b, err := s.writeCallback(s, value) val = b if err != nil { return dbus.MakeFailedError(err) } } else { log.Trace("Store directly to value (no callback)") } // TODO update on Properties interface s.Properties.Value = val err := s.iprops.Instance().Set(s.Interface(), "Value", dbus.MakeVariant(value)) return err } go-bluetooth-bluez-5.60/api/service/app_getter.go000066400000000000000000000013471420407601400220700ustar00rootroot00000000000000package service import ( "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/adapter" "github.com/muka/go-bluetooth/bluez/profile/agent" ) func (app *App) AdapterID() string { return app.adapterID } func (app *App) Adapter() *adapter.Adapter1 { return app.adapter } func (app *App) Agent() agent.Agent1Client { return app.agent } // return the app dbus path func (app *App) Path() dbus.ObjectPath { return app.path } // return the dbus connection func (app *App) DBusConn() *dbus.Conn { return app.conn } func (app *App) DBusObjectManager() *api.DBusObjectManager { return app.objectManager } func (app *App) SetName(name string) { app.advertisement.LocalName = name } go-bluetooth-bluez-5.60/api/service/app_service.go000066400000000000000000000062461420407601400222410ustar00rootroot00000000000000package service import ( "fmt" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/gatt" log "github.com/sirupsen/logrus" ) type Service struct { UUID string app *App path dbus.ObjectPath Properties *gatt.GattService1Properties chars map[dbus.ObjectPath]*Char iprops *api.DBusProperties } func (s *Service) DBusProperties() *api.DBusProperties { return s.iprops } func (s *Service) Path() dbus.ObjectPath { return s.path } func (s *Service) Interface() string { return gatt.GattService1Interface } func (s *Service) GetProperties() bluez.Properties { chars := []dbus.ObjectPath{} for cpath := range s.chars { chars = append(chars, cpath) } s.Properties.Characteristics = chars return s.Properties } func (s *Service) App() *App { return s.app } func (s *Service) DBusObjectManager() *api.DBusObjectManager { return s.App().DBusObjectManager() } func (s *Service) DBusConn() *dbus.Conn { return s.App().DBusConn() } // Expose service to dbus func (s *Service) Expose() error { return api.ExposeDBusService(s) } // Remove service from dbus func (s *Service) Remove() error { return api.RemoveDBusService(s) } func (s *Service) GetChars() map[dbus.ObjectPath]*Char { return s.chars } // NewChar Create a new characteristic func (s *Service) NewChar(uuid string) (*Char, error) { char := new(Char) char.UUID = s.App().GenerateUUID(uuid) char.path = dbus.ObjectPath( fmt.Sprintf("%s/char%d", s.Path(), len(s.GetChars())), ) char.app = s.App() char.service = s char.descr = make(map[dbus.ObjectPath]*Descr) char.Properties = NewGattCharacteristic1Properties(char.UUID) iprops, err := api.NewDBusProperties(s.App().DBusConn()) if err != nil { return nil, err } char.iprops = iprops return char, nil } func (s *Service) AddChar(char *Char) error { s.chars[char.Path()] = char err := api.ExposeDBusService(char) if err != nil { return err } err = s.DBusObjectManager().AddObject(char.Path(), map[string]bluez.Properties{ char.Interface(): char.GetProperties(), }) if err != nil { return err } // update OM service rapresentation also err = s.DBusObjectManager().AddObject(s.Path(), map[string]bluez.Properties{ s.Interface(): s.GetProperties(), }) if err != nil { return err } log.Tracef("Added GATT Characteristic UUID=%s %s", char.UUID, char.Path()) err = s.App().ExportTree() return err } // RemoveChar remove a characteristic from the service func (s *Service) RemoveChar(char *Char) error { // todo unregister properties if _, ok := s.chars[char.Path()]; !ok { return nil } for _, descr := range char.GetDescr() { err := char.RemoveDescr(descr) if err != nil { return err } } // remove the char from the three err := s.DBusObjectManager().RemoveObject(s.Path()) if err != nil { return err } // update OM service rapresentation also err = s.DBusObjectManager().AddObject(s.Path(), map[string]bluez.Properties{ s.Interface(): s.GetProperties(), }) if err != nil { return err } // err = s.ExportTree() // if err != nil { // return err // } delete(s.chars, char.Path()) return nil } go-bluetooth-bluez-5.60/api/service/app_service_mgm.go000066400000000000000000000027411420407601400230750ustar00rootroot00000000000000package service import ( "fmt" "strings" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez" log "github.com/sirupsen/logrus" ) func (app *App) GetServices() map[dbus.ObjectPath]*Service { return app.services } func (app *App) NewService(uuid string) (*Service, error) { s := new(Service) s.UUID = app.GenerateUUID(uuid) s.app = app s.chars = make(map[dbus.ObjectPath]*Char) s.path = dbus.ObjectPath(fmt.Sprintf("%s/service%s", app.Path(), strings.Replace(s.UUID, "-", "_", -1)[:8])) s.Properties = NewGattService1Properties(s.UUID) iprops, err := api.NewDBusProperties(s.App().DBusConn()) if err != nil { return nil, err } s.iprops = iprops return s, nil } func (app *App) AddService(s *Service) error { app.services[s.Path()] = s err := s.Expose() if err != nil { return err } err = app.DBusObjectManager().AddObject(s.Path(), map[string]bluez.Properties{ s.Interface(): s.GetProperties(), }) if err != nil { return err } log.Tracef("Added GATT Service UUID=%s %s", s.UUID, s.Path()) return nil } //RemoveService remove an exposed service func (app *App) RemoveService(service *Service) error { if _, ok := app.services[service.Path()]; !ok { return nil } for _, char := range service.GetChars() { err := service.RemoveChar(char) if err != nil { return err } } err := api.RemoveDBusService(service) if err != nil { return err } delete(app.services, service.Path()) return nil } go-bluetooth-bluez-5.60/api/service/app_test.go000066400000000000000000000020061420407601400215460ustar00rootroot00000000000000package service import ( "testing" "github.com/muka/go-bluetooth/api" log "github.com/sirupsen/logrus" ) func createTestApp(t *testing.T) *App { log.SetLevel(log.TraceLevel) a, err := NewApp(AppOptions{ AdapterID: api.GetDefaultAdapterID(), }) if err != nil { t.Fatal(err) } s1, err := a.NewService("2233") if err != nil { t.Fatal(err) } c1, err := s1.NewChar("3344") if err != nil { t.Fatal(err) } c1. OnRead(CharReadCallback(func(c *Char, options map[string]interface{}) ([]byte, error) { return nil, nil })). OnWrite(CharWriteCallback(func(c *Char, value []byte) ([]byte, error) { return nil, nil })) d1, err := c1.NewDescr("4455") if err != nil { t.Fatal(err) } err = c1.AddDescr(d1) if err != nil { t.Fatal(err) } err = s1.AddChar(c1) if err != nil { t.Fatal(err) } err = a.AddService(s1) if err != nil { t.Fatal(err) } err = a.Run() if err != nil { t.Fatal(err) } return a } func TestApp(t *testing.T) { a := createTestApp(t) defer a.Close() } go-bluetooth-bluez-5.60/api/service/gatt.go000066400000000000000000000014151420407601400206710ustar00rootroot00000000000000package service import ( "github.com/muka/go-bluetooth/bluez/profile/gatt" ) // Create a new GattService1Properties func NewGattService1Properties(uuid string) *gatt.GattService1Properties { return &gatt.GattService1Properties{ IsService: true, Primary: true, UUID: uuid, } } // Create a new GattCharacteristic1Properties func NewGattCharacteristic1Properties(uuid string) *gatt.GattCharacteristic1Properties { return &gatt.GattCharacteristic1Properties{ UUID: uuid, Flags: []string{}, } } // Create a new GattDescriptor1Properties func NewGattDescriptor1Properties(uuid string) *gatt.GattDescriptor1Properties { return &gatt.GattDescriptor1Properties{ UUID: uuid, Flags: []string{ gatt.FlagDescriptorRead, gatt.FlagDescriptorWrite, }, } } go-bluetooth-bluez-5.60/api/service_expose.go000066400000000000000000000033731420407601400213220ustar00rootroot00000000000000package api import ( "github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5/introspect" "github.com/godbus/dbus/v5/prop" "github.com/muka/go-bluetooth/bluez" log "github.com/sirupsen/logrus" ) type ExposedDBusService interface { Path() dbus.ObjectPath Interface() string GetProperties() bluez.Properties // App() *App DBusProperties() *DBusProperties DBusObjectManager() *DBusObjectManager DBusConn() *dbus.Conn // ExportTree() error } func RemoveDBusService(s ExposedDBusService) error { err := s.DBusObjectManager().RemoveObject(s.Path()) if err != nil { return err } return nil } // Expose // - Interface() (Service, Char or Descr) // - Properties interface func ExposeDBusService(s ExposedDBusService) (err error) { conn := s.DBusConn() if conn == nil { conn, err = dbus.SystemBus() if err != nil { return err } } log.Tracef("Expose %s (%s)", s.Path(), s.Interface()) err = conn.Export(s, s.Path(), s.Interface()) if err != nil { return err } err = s.DBusProperties().AddProperties(s.Interface(), s.GetProperties()) if err != nil { return err } log.Tracef("Expose Properties interface (%s)", s.Path()) s.DBusProperties().Expose(s.Path()) node := &introspect.Node{ Interfaces: []introspect.Interface{ //Introspect introspect.IntrospectData, //Properties prop.IntrospectData, // Exposed service introspectable { Name: s.Interface(), Methods: introspect.Methods(s), Properties: s.DBusProperties().Introspection(s.Interface()), }, }, } err = conn.Export( introspect.NewIntrospectable(node), s.Path(), "org.freedesktop.DBus.Introspectable", ) if err != nil { return err } // v, _ := intrsp.Introspect() // fmt.Println("service_expose introspection", v) return nil } go-bluetooth-bluez-5.60/bin/000077500000000000000000000000001420407601400157415ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bin/docker-btmgmt000077500000000000000000000003641420407601400204310ustar00rootroot00000000000000#!/bin/sh docker run -it --name bluez_btmgmt --privileged --rm --net=host -v /dev:/dev -v /var/run/dbus:/var/run/dbus -v /sys/class/bluetooth:/sys/class/bluetooth -v /var/lib/bluetooth:/var/lib/bluetooth opny/bluez-5.54 /bluez/tools/btmgmt $@ go-bluetooth-bluez-5.60/bluez-5.50.json000077500000000000000000003431451420407601400176070ustar00rootroot00000000000000{"Version":"5.50","Api":[{"FileName":"adapter-api.txt","Name":"BlueZ D-Bus Adapter API description","Description":"\n","Api":[{"Title":"Adapter hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Adapter1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"StartDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method starts the device discovery session. This\n\t\t\tincludes an inquiry procedure and remote device name\n\t\t\tresolving. Use StopDiscovery to release the sessions\n\t\t\tacquired.\n\t\t\tThis process will start creating Device objects as\n\t\t\tnew devices are discovered.\n\t\t\tDuring discovery RSSI delta-threshold is imposed.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"StopDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method will cancel any previous StartDiscovery\n\t\t\ttransaction.\n\t\t\tNote that a discovery procedure is shared between all\n\t\t\tdiscovery sessions thus calling StopDiscovery will only\n\t\t\trelease a single session.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n"},{"Name":"RemoveDevice","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis removes the remote device object at the given\n\t\t\tpath. It will remove also the pairing information.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"SetDiscoveryFilter","ReturnType":"void","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method sets the device discovery filter for the\n\t\t\tcaller. When this method is called with no filter\n\t\t\tparameter, filter is removed.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tarray{string} UUIDs\n\t\t\t\tFilter by service UUIDs, empty means match\n\t\t\t\t_any_ UUID.\n\t\t\t\tWhen a remote device is found that advertises\n\t\t\t\tany UUID from UUIDs, it will be reported if:\n\t\t\t\t- Pathloss and RSSI are both empty.\n\t\t\t\t- only Pathloss param is set, device advertise\n\t\t\t\t TX pwer, and computed pathloss is less than\n\t\t\t\t Pathloss param.\n\t\t\t\t- only RSSI param is set, and received RSSI is\n\t\t\t\t higher than RSSI param.\n\t\t\tint16 RSSI\n\t\t\t\tRSSI threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated RSSI value. If one or more discovery\n\t\t\t\tfilters have been set, the RSSI delta-threshold,\n\t\t\t\tthat is imposed by StartDiscovery by default,\n\t\t\t\twill not be applied.\n\t\t\tuint16 Pathloss\n\t\t\t\tPathloss threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated Pathloss value.\n\t\t\tstring Transport (Default \"auto\")\n\t\t\t\tTransport parameter determines the type of\n\t\t\t\tscan.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"auto\"\t- interleaved scan\n\t\t\t\t\t\"bredr\"\t- BR/EDR inquiry\n\t\t\t\t\t\"le\"\t- LE scan only\n\t\t\t\tIf \"le\" or \"bredr\" Transport is requested,\n\t\t\t\tand the controller doesn't support it,\n\t\t\t\torg.bluez.Error.Failed error will be returned.\n\t\t\t\tIf \"auto\" transport is requested, scan will use\n\t\t\t\tLE, BREDR, or both, depending on what's\n\t\t\t\tcurrently enabled on the controller.\n\t\t\tbool DuplicateData (Default: true)\n\t\t\t\tDisables duplicate detection of advertisement\n\t\t\t\tdata.\n\t\t\t\tWhen enabled PropertiesChanged signals will be\n\t\t\t\tgenerated for either ManufacturerData and\n\t\t\t\tServiceData everytime they are discovered.\n\t\t\tWhen discovery filter is set, Device objects will be\n\t\t\tcreated as new devices with matching criteria are\n\t\t\tdiscovered regardless of they are connectable or\n\t\t\tdiscoverable which enables listening to\n\t\t\tnon-connectable and non-discoverable devices.\n\t\t\tWhen multiple clients call SetDiscoveryFilter, their\n\t\t\tfilters are internally merged, and notifications about\n\t\t\tnew devices are sent to all clients. Therefore, each\n\t\t\tclient must check that device updates actually match\n\t\t\tits filter.\n\t\t\tWhen SetDiscoveryFilter is called multiple times by the\n\t\t\tsame client, last filter passed will be active for\n\t\t\tgiven client.\n\t\t\tSetDiscoveryFilter can be called before StartDiscovery.\n\t\t\tIt is useful when client will create first discovery\n\t\t\tsession, to ensure that proper scan will be started\n\t\t\tright after call to StartDiscovery.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"GetDiscoveryFilters","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn available filters that can be given to\n\t\t\tSetDiscoveryFilter.\n\t\t\tPossible errors: None\n"},{"Name":"ConnectDevice","ReturnType":"object","Args":[{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method connects to device without need of\n\t\t\tperforming General Discovery. Connection mechanism is\n\t\t\tsimilar to Connect method from Device1 interface with\n\t\t\texception that this method returns success when physical\n\t\t\tconnection is established. After this method returns,\n\t\t\tservices discovery will continue and any supported\n\t\t\tprofile will be connected. There is no need for calling\n\t\t\tConnect on Device1 after this call. If connection was\n\t\t\tsuccessful this method returns object path to created\n\t\t\tdevice object.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tstring Address\n\t\t\t\tThe Bluetooth device address of the remote\n\t\t\t\tdevice. This parameter is mandatory.\n\t\t\tstring AddressType\n\t\t\t\tThe Bluetooth device Address Type. This is\n\t\t\t\taddress type that should be used for initial\n\t\t\t\tconnection. If this parameter is not present\n\t\t\t\tBR/EDR device is created.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"public\" - Public address\n\t\t\t\t\t\"random\" - Random address\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth Address Type. For dual-mode and BR/EDR\n\t\t\tonly adapter this defaults to \"public\". Single mode LE\n\t\t\tadapters may have either value. With privacy enabled\n\t\t\tthis contains type of Identity Address and not type of\n\t\t\taddress used for connection.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth system name (pretty hostname).\n\n\t\t\tThis property is either a static system default\n\t\t\tor controlled by an external daemon providing\n\t\t\taccess to the pretty hostname configuration.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The Bluetooth friendly name. This value can be\n\t\t\tchanged.\n\n\t\t\tIn case no alias is set, it will return the system\n\t\t\tprovided name. Setting an empty string as alias will\n\t\t\tconvert it back to the system provided name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to system name.\n\n\t\t\tOn a well configured system, this property never\n\t\t\tneeds to be changed since it defaults to the system\n\t\t\tname and provides the pretty hostname. Only if the\n\t\t\tlocal name needs to be different from the pretty\n\t\t\thostname, this property should be used as last\n\t\t\tresort.","Flags":[]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device.\n\n\t\t\tThis property represents the value that is either\n\t\t\tautomatically configured by DMI/ACPI information\n\t\t\tor provided as static configuration.","Flags":[]},{"Name":"Powered","Type":"boolean","Docs":"Switch an adapter on or off. This will also set the\n\t\t\tappropriate connectable state of the controller.\n\n\t\t\tThe value of this property is not persistent. After\n\t\t\trestart or unplugging of the adapter it will reset\n\t\t\tback to false.","Flags":[]},{"Name":"Discoverable","Type":"boolean","Docs":"Switch an adapter to discoverable or non-discoverable\n\t\t\tto either make it visible or hide it. This is a global\n\t\t\tsetting and should only be used by the settings\n\t\t\tapplication.\n\n\t\t\tIf the DiscoverableTimeout is set to a non-zero\n\t\t\tvalue then the system will set this value back to\n\t\t\tfalse after the timer expired.\n\n\t\t\tIn case the adapter is switched off, setting this\n\t\t\tvalue will fail.\n\n\t\t\tWhen changing the Powered property the new state of\n\t\t\tthis property will be updated via a PropertiesChanged\n\t\t\tsignal.\n\n\t\t\tFor any new adapter this settings defaults to false.","Flags":[]},{"Name":"Pairable","Type":"boolean","Docs":"Switch an adapter to pairable or non-pairable. This is\n\t\t\ta global setting and should only be used by the\n\t\t\tsettings application.\n\n\t\t\tNote that this property only affects incoming pairing\n\t\t\trequests.\n\n\t\t\tFor any new adapter this settings defaults to true.","Flags":[]},{"Name":"PairableTimeout","Type":"uint32","Docs":"The pairable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tpairable mode forever.\n\n\t\t\tThe default value for pairable timeout should be\n\t\t\tdisabled (value 0).","Flags":[]},{"Name":"DiscoverableTimeout","Type":"uint32","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tThe default value for the discoverable timeout should\n\t\t\tbe 180 seconds (3 minutes).","Flags":[]},{"Name":"Discovering","Type":"boolean","Docs":"Indicates that a device discovery procedure is active.","Flags":[]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tlocal services.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Local Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]}]}]},{"FileName":"advertising-api.txt","Name":"BlueZ D-Bus LE Advertising API Description","Description":"Advertising packets are structured data which is broadcast on the LE Advertising\nchannels and available for all devices in range. Because of the limited space\navailable in LE Advertising packets (31 bytes), each packet's contents must be\ncarefully controlled.\n\nBlueZ acts as a store for the Advertisement Data which is meant to be sent.\nIt constructs the correct Advertisement Data from the structured\ndata and configured the kernel to send the correct advertisement.\n\nAdvertisement Data objects are registered freely and then referenced by BlueZ\nwhen constructing the data sent to the kernel.\n\n","Api":[{"Title":"LE Advertisement Data hierarchy","Description":"\nSpecifies the Advertisement Data to be broadcast and some advertising\nparameters. Properties which are not present will not be included in the\ndata. Required advertisement data types will always be included.\nAll UUIDs are 128-bit versions in the API, and 16 or 32-bit\nversions of the same UUID will be used in the advertising data as appropriate.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisement1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tremoves the Advertisement. A client can use it to do\n\t\t\tcleanup tasks. There is no need to call\n\t\t\tUnregisterAdvertisement because when this method gets\n\t\t\tcalled it has already been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"Determines the type of advertising packet requested.\n\n\t\t\tPossible values: \"broadcast\" or \"peripheral\"","Flags":[]},{"Name":"ServiceUUIDs","Type":"array{string}","Docs":"List of UUIDs to include in the \"Service UUID\" field of\n\t\t\tthe Advertising Data.","Flags":[]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufactuer Data fields to include in\n\t\t\tthe Advertising Data. Keys are the Manufacturer ID\n\t\t\tto associate with the data.","Flags":[]},{"Name":"SolicitUUIDs","Type":"array{string}","Docs":"Array of UUIDs to include in \"Service Solicitation\"\n\t\t\tAdvertisement Data.","Flags":[]},{"Name":"ServiceData","Type":"dict","Docs":"Service Data elements to include. The keys are the\n\t\t\tUUID to associate with the data.","Flags":[]},{"Name":"Data","Type":"dict","Docs":"Advertising Type to include in the Advertising\n\t\t\tData. Key is the advertising type and value is the\n\t\t\tdata as byte array.\n\n\t\t\tNote: Types already handled by other properties shall\n\t\t\tnot be used.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[4]},{"Name":"Discoverable","Type":"bool","Docs":"Advertise as general discoverable. When present this\n\t\t\twill override adapter Discoverable property.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"DiscoverableTimeout","Type":"uint16","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"Includes","Type":"array{string}","Docs":"List of features to be included in the advertising\n\t\t\tpacket.\n\n\t\t\tPossible values: as found on\n\t\t\t\t\tLEAdvertisingManager.SupportedIncludes","Flags":[]},{"Name":"LocalName","Type":"string","Docs":"Local name to be used in the advertising report. If the\n\t\t\tstring is too big to fit into the packet it will be\n\t\t\ttruncated.\n\n\t\t\tIf this property is available 'local-name' cannot be\n\t\t\tpresent in the Includes.","Flags":[]},{"Name":"Appearance","Type":"uint16","Docs":"Appearance to be used in the advertising report.\n\n\t\t\tPossible values: as found on GAP Service.","Flags":[]},{"Name":"Duration","Type":"uint16_t","Docs":"Duration of the advertisement in seconds. If there are\n\t\t\tother applications advertising no duration is set the\n\t\t\tdefault is 2 seconds.","Flags":[]},{"Name":"Timeout","Type":"uint16_t","Docs":"Timeout of the advertisement in seconds. This defines\n\t\t\tthe lifetime of the advertisement.","Flags":[]}]},{"Title":"LE Advertising Manager hierarchy","Description":"\nThe Advertising Manager allows external applications to register Advertisement\nData which should be broadcast to devices. Advertisement Data elements must\nfollow the API for LE Advertisement Data described above.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisingManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters an advertisement object to be sent over the LE\n\t\t\tAdvertising channel. The service must be exported\n\t\t\tunder interface LEAdvertisement1.\n\t\t\tInvalidArguments error indicates that the object has\n\t\t\tinvalid or conflicting properties.\n\t\t\tInvalidLength error indicates that the data\n\t\t\tprovided generates a data packet which is too long.\n\t\t\tThe properties of this object are parsed when it is\n\t\t\tregistered, and any changes are ignored.\n\t\t\tIf the same object is registered twice it will result in\n\t\t\tan AlreadyExists error.\n\t\t\tIf the maximum number of advertisement instances is\n\t\t\treached it will result in NotPermitted error.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.InvalidLength\n\t\t\t\t\t org.bluez.Error.NotPermitted\n"},{"Name":"UnregisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters an advertisement that has been\n\t\t\tpreviously registered. The object path parameter must\n\t\t\tmatch the same value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"ActiveInstances","Type":"byte","Docs":"Number of active advertising instances.","Flags":[]},{"Name":"SupportedInstances","Type":"byte","Docs":"Number of available advertising instances.","Flags":[]},{"Name":"SupportedIncludes","Type":"array{string}","Docs":"List of supported system includes.\n\n\t\t\tPossible values: \"tx-power\"\n\t\t\t\t\t \"appearance\"\n\t\t\t\t\t \"local-name\"","Flags":[]}]}]},{"FileName":"agent-api.txt","Name":"BlueZ D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AgentManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"},{"Type":"string","Name":"capability"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers an agent handler.\n\t\t\tThe object path defines the path of the agent\n\t\t\tthat will be called when user input is needed.\n\t\t\tEvery application can register its own agent and\n\t\t\tfor all actions triggered by that application its\n\t\t\tagent is used.\n\t\t\tIt is not required by an application to register\n\t\t\tan agent. If an application does chooses to not\n\t\t\tregister an agent, the default agent is used. This\n\t\t\tis on most cases a good idea. Only application\n\t\t\tlike a pairing wizard should register their own\n\t\t\tagent.\n\t\t\tAn application can only register one agent. Multiple\n\t\t\tagents per application is not supported.\n\t\t\tThe capability parameter can have the values\n\t\t\t\"DisplayOnly\", \"DisplayYesNo\", \"KeyboardOnly\",\n\t\t\t\"NoInputNoOutput\" and \"KeyboardDisplay\" which\n\t\t\treflects the input and output capabilities of the\n\t\t\tagent.\n\t\t\tIf an empty string is used it will fallback to\n\t\t\t\"KeyboardDisplay\".\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"},{"Name":"RequestDefaultAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis requests is to make the application agent\n\t\t\tthe default agent. The application is required\n\t\t\tto register an agent.\n\t\t\tSpecial permission might be required to become\n\t\t\tthe default agent.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"RequestPinCode","ReturnType":"string","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a string of 1-16 characters\n\t\t\tlength. The string can be alphanumeric.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPinCode","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"pincode"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a pincode for an authentication.\n\t\t\tAn empty reply should be returned. When the pincode\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tThis is used during the pairing process of keyboards\n\t\t\tthat don't support Bluetooth 2.1 Secure Simple Pairing,\n\t\t\tin contrast to DisplayPasskey which is used for those\n\t\t\tthat do.\n\t\t\tThis method will only ever be called once since\n\t\t\tolder keyboards do not support typing notification.\n\t\t\tNote that the PIN will always be a 6-digit number,\n\t\t\tzero-padded to 6 digits. This is for harmony with\n\t\t\tthe later specification.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestPasskey","ReturnType":"uint32","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a numeric value\n\t\t\tbetween 0-999999.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPasskey","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"},{"Type":"uint16","Name":"entered"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a passkey for an authentication.\n\t\t\tThe entered parameter indicates the number of already\n\t\t\ttyped keys on the remote side.\n\t\t\tAn empty reply should be returned. When the passkey\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tDuring the pairing process this method might be\n\t\t\tcalled multiple times to update the entered value.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n"},{"Name":"RequestConfirmation","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to confirm a passkey for an authentication.\n\t\t\tTo confirm the value it should return an empty reply\n\t\t\tor an error in case the passkey is invalid.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestAuthorization","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called to request the user to\n\t\t\tauthorize an incoming pairing attempt which\n\t\t\twould in other circumstances trigger the just-works\n\t\t\tmodel, or when the user plugged in a device that\n\t\t\timplements cable pairing. In the latter case, the\n\t\t\tdevice would not be connected to the adapter via\n\t\t\tBluetooth yet.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"AuthorizeService","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to authorize a connection/service request.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"battery-api.txt","Name":"BlueZ D-Bus Battery API description","Description":"\n","Api":[{"Title":"Battery hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Battery1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Percentage","Type":"byte","Docs":"The percentage of battery left as an unsigned 8-bit integer.","Flags":[]}]}]},{"FileName":"device-api.txt","Name":"BlueZ D-Bus Device API description","Description":"\n","Api":[{"Title":"Device hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Device1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis is a generic method to connect any profiles\n\t\t\tthe remote device supports that can be connected\n\t\t\tto and have been flagged as auto-connectable on\n\t\t\tour side. If only subset of profiles is already\n\t\t\tconnected it will try to connect currently disconnected\n\t\t\tones.\n\t\t\tIf at least one profile was connected successfully this\n\t\t\tmethod will indicate success.\n\t\t\tFor dual-mode devices only one bearer is connected at\n\t\t\ttime, the conditions are in the following order:\n\t\t\t\t1. Connect the disconnected bearer if already\n\t\t\t\tconnected.\n\t\t\t\t2. Connect first the bonded bearer. If no\n\t\t\t\tbearers are bonded or both are skip and check\n\t\t\t\tlatest seen bearer.\n\t\t\t\t3. Connect last seen bearer, in case the\n\t\t\t\ttimestamps are the same BR/EDR takes\n\t\t\t\tprecedence.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.AlreadyConnected\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tThis method gracefully disconnects all connected\n\t\t\tprofiles and then terminates low-level ACL connection.\n\t\t\tACL connection will be terminated even if some profiles\n\t\t\twere not disconnected properly e.g. due to misbehaving\n\t\t\tdevice.\n\t\t\tThis method can be also used to cancel a preceding\n\t\t\tConnect call before a reply to it has been received.\n\t\t\tFor non-trusted devices connected over LE bearer calling\n\t\t\tthis method will disable incoming connections until\n\t\t\tConnect method is called again.\n\t\t\tPossible errors: org.bluez.Error.NotConnected\n"},{"Name":"ConnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method connects a specific profile of this\n\t\t\tdevice. The UUID provided is the remote service\n\t\t\tUUID for the profile.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotAvailable\n\t\t\t\t\t org.bluez.Error.NotReady\n"},{"Name":"DisconnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method disconnects a specific profile of\n\t\t\tthis device. The profile needs to be registered\n\t\t\tclient profile.\n\t\t\tThere is no connection tracking for a profile, so\n\t\t\tas long as the profile is registered this will always\n\t\t\tsucceed.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"Pair","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method will connect to the remote device,\n\t\t\tinitiate pairing and then retrieve all SDP records\n\t\t\t(or GATT primary services).\n\t\t\tIf the application has registered its own agent,\n\t\t\tthen that specific agent will be used. Otherwise\n\t\t\tit will use the default agent.\n\t\t\tOnly for applications like a pairing wizard it\n\t\t\twould make sense to have its own agent. In almost\n\t\t\tall other cases the default agent will handle\n\t\t\tthis just fine.\n\t\t\tIn case there is no application agent and also\n\t\t\tno default agent present, this method will fail.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.AuthenticationCanceled\n\t\t\t\t\t org.bluez.Error.AuthenticationFailed\n\t\t\t\t\t org.bluez.Error.AuthenticationRejected\n\t\t\t\t\t org.bluez.Error.AuthenticationTimeout\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"CancelPairing","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis method can be used to cancel a pairing\n\t\t\toperation initiated by the Pair method.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address of the remote device.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth device Address Type. For dual-mode and\n\t\t\tBR/EDR only devices this defaults to \"public\". Single\n\t\t\tmode LE devices may have either value. If remote device\n\t\t\tuses privacy than before pairing this represents address\n\t\t\ttype used for connection and Identity Address after\n\t\t\tpairing.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth remote name. This value can not be\n\t\t\tchanged. Use the Alias property instead.\n\n\t\t\tThis value is only present for completeness. It is\n\t\t\tbetter to always use the Alias property when\n\t\t\tdisplaying the devices name.\n\n\t\t\tIf the Alias property is unset, it will reflect\n\t\t\tthis value which makes it more convenient.","Flags":[5]},{"Name":"Icon","Type":"string","Docs":"Proposed icon name according to the freedesktop.org\n\t\t\ticon naming specification.","Flags":[5]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device of the remote device.","Flags":[5]},{"Name":"Appearance","Type":"uint16","Docs":"External appearance of device, as found on GAP service.","Flags":[5]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tremote services.","Flags":[5]},{"Name":"Paired","Type":"boolean","Docs":"Indicates if the remote device is paired.","Flags":[]},{"Name":"Connected","Type":"boolean","Docs":"Indicates if the remote device is currently connected.\n\t\t\tA PropertiesChanged signal indicate changes to this\n\t\t\tstatus.","Flags":[]},{"Name":"Trusted","Type":"boolean","Docs":"Indicates if the remote is seen as trusted. This\n\t\t\tsetting can be changed by the application.","Flags":[]},{"Name":"Blocked","Type":"boolean","Docs":"If set to true any incoming connections from the\n\t\t\tdevice will be immediately rejected. Any device\n\t\t\tdrivers will also be removed and no new ones will\n\t\t\tbe probed as long as the device is blocked.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The name alias for the remote device. The alias can\n\t\t\tbe used to have a different friendly name for the\n\t\t\tremote device.\n\n\t\t\tIn case no alias is set, it will return the remote\n\t\t\tdevice name. Setting an empty string as alias will\n\t\t\tconvert it back to the remote device name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to the remote name.","Flags":[]},{"Name":"Adapter","Type":"object","Docs":"The object path of the adapter the device belongs to.","Flags":[]},{"Name":"LegacyPairing","Type":"boolean","Docs":"Set to true if the device only supports the pre-2.1\n\t\t\tpairing mechanism. This property is useful during\n\t\t\tdevice discovery to anticipate whether legacy or\n\t\t\tsimple pairing will occur if pairing is initiated.\n\n\t\t\tNote that this property can exhibit false-positives\n\t\t\tin the case of Bluetooth 2.1 (or newer) devices that\n\t\t\thave disabled Extended Inquiry Response support.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Remote Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"RSSI","Type":"int16","Docs":"Received Signal Strength Indicator of the remote\n\t\t\tdevice (inquiry or advertising).","Flags":[5]},{"Name":"TxPower","Type":"int16","Docs":"Advertised transmitted power level (inquiry or\n\t\t\tadvertising).","Flags":[5]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufacturer specific advertisement data. Keys are\n\t\t\t16 bits Manufacturer ID followed by its byte array\n\t\t\tvalue.","Flags":[5]},{"Name":"ServiceData","Type":"dict","Docs":"Service advertisement data. Keys are the UUIDs in\n\t\t\tstring format followed by its byte array value.","Flags":[5]},{"Name":"ServicesResolved","Type":"bool","Docs":"Indicate whether or not service discovery has been\n\t\t\tresolved.","Flags":[]},{"Name":"AdvertisingFlags","Type":"array{byte}","Docs":"The Advertising Data Flags of the remote device.","Flags":[]},{"Name":"AdvertisingData","Type":"dict","Docs":"The Advertising Data of the remote device. Keys are\n\t\t\tare 8 bits AD Type followed by data as byte array.\n\n\t\t\tNote: Only types considered safe to be handled by\n\t\t\tapplication are exposed.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[]}]}]},{"FileName":"gatt-api.txt","Name":"BlueZ D-Bus GATT API description","Description":"GATT local and remote services share the same high-level D-Bus API. Local\nrefers to GATT based service exported by a BlueZ plugin or an external\napplication. Remote refers to GATT services exported by the peer.\n\nBlueZ acts as a proxy, translating ATT operations to D-Bus method calls and\nProperties (or the opposite). Support for D-Bus Object Manager is mandatory for\nexternal services to allow seamless GATT declarations (Service, Characteristic\nand Descriptors) discovery. Each GATT service tree is required to export a D-Bus\nObject Manager at its root that is solely responsible for the objects that\nbelong to that service.\n\nReleasing a registered GATT service is not defined yet. Any API extension\nshould avoid breaking the defined API, and if possible keep an unified GATT\nremote and local services representation.\n\n","Api":[{"Title":"Service hierarchy","Description":"\nGATT remote and local service representation. Object path for local services\nis freely definable.\n\nExternal applications implementing local services must register the services\nusing GattManager1 registration method and must implement the methods and\nproperties defined in GattService1 interface.\n","Service":"org.bluez","Interface":"org.bluez.GattService1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX","Methods":[],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit service UUID.","Flags":[1]},{"Name":"Primary","Type":"boolean","Docs":"Indicates whether or not this GATT service is a\n\t\t\tprimary service. If false, the service is secondary.","Flags":[1]},{"Name":"Device","Type":"object","Docs":"Object path of the Bluetooth device the service\n\t\t\tbelongs to. Only present on services from remote\n\t\t\tdevices.","Flags":[1,5]},{"Name":"Includes","Type":"array{object}","Docs":"Array of object paths representing the included\n\t\t\tservices of this service.","Flags":[1,5]}]},{"Title":"Characteristic hierarchy","Description":"\nFor local GATT defined services, the object paths need to follow the service\npath hierarchy and are freely definable.\n","Service":"org.bluez","Interface":"org.bluez.GattCharacteristic1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": uint16 offset\n\t\t\t\t\t \"device\": Object Device (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.InvalidOffset\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": boolean Is prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireWrite","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for writing. Usage of\n\t\t\tWriteValue will be locked causing it to return\n\t\t\tNotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tFor client it only works with characteristic that has\n\t\t\tWriteAcquired property which relies on\n\t\t\twrite-without-response Flag.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"MTU\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireNotify","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for notify. Usage of\n\t\t\tStartNotify will be locked causing it to return\n\t\t\tNotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tOnly works with characteristic that has NotifyAcquired\n\t\t\twhich relies on notify Flag and no other client have\n\t\t\tcalled StartNotify.\n\t\t\tNotification are enabled during this procedure so\n\t\t\tStartNotify shall not be called, any notification\n\t\t\twill be dispatched via file descriptor therefore the\n\t\t\tValue property is not affected during the time where\n\t\t\tnotify has been acquired.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"MTU\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StartNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tStarts a notification session from this characteristic\n\t\t\tif it supports value notifications or indications.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StopNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method will cancel any previous StartNotify\n\t\t\ttransaction. Note that notifications from a\n\t\t\tcharacteristic are shared between sessions thus\n\t\t\tcalling StopNotify will release a single session.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"},{"Name":"Confirm","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method doesn't expect a reply so it is just a\n\t\t\tconfirmation that value was received.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit characteristic UUID.","Flags":[1]},{"Name":"Service","Type":"object","Docs":"Object path of the GATT service the characteristic\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the characteristic. This property\n\t\t\tgets updated only after a successful read request and\n\t\t\twhen a notification or indication is received, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"WriteAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireWrite.\n\n\t\t\tFor client properties is ommited in case\n\t\t\t'write-without-response' flag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireWrite is supported.","Flags":[1,5]},{"Name":"NotifyAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireNotify.\n\n\t\t\tFor client this properties is ommited in case 'notify'\n\t\t\tflag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireNotify is supported.","Flags":[1,5]},{"Name":"Notifying","Type":"boolean","Docs":"True, if notifications or indications on this\n\t\t\tcharacteristic are currently enabled.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the characteristic value can be used. See\n\t\t\tCore spec \"Table 3.5: Characteristic Properties bit\n\t\t\tfield\", and \"Table 3.8: Characteristic Extended\n\t\t\tProperties bit field\". Allowed values:\n\n\t\t\t\t\"broadcast\"\n\t\t\t\t\"read\"\n\t\t\t\t\"write-without-response\"\n\t\t\t\t\"write\"\n\t\t\t\t\"notify\"\n\t\t\t\t\"indicate\"\n\t\t\t\t\"authenticated-signed-writes\"\n\t\t\t\t\"reliable-write\"\n\t\t\t\t\"writable-auxiliaries\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server only)\n\t\t\t\t\"secure-write\" (Server only)\n\t\t\t\t\"authorize\"","Flags":[1]}]},{"Title":"Characteristic Descriptors hierarchy","Description":"\nLocal or remote GATT characteristic descriptors hierarchy.\n","Service":"org.bluez","Interface":"org.bluez.GattDescriptor1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": boolean Is prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit descriptor UUID.","Flags":[1]},{"Name":"Characteristic","Type":"object","Docs":"Object path of the GATT characteristic the descriptor\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the descriptor. This property\n\t\t\tgets updated only after a successful read request, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the descriptor value can be used.\n\n\t\t\tPossible values:\n\n\t\t\t\t\"read\"\n\t\t\t\t\"write\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server Only)\n\t\t\t\t\"secure-write\" (Server Only)\n\t\t\t\t\"authorize\"","Flags":[1]}]},{"Title":"GATT Profile hierarchy","Description":"\nLocal profile (GATT client) instance. By registering this type of object\nan application effectively indicates support for a specific GATT profile\nand requests automatic connections to be established to devices\nsupporting it.\n","Service":"\u003capplication dependent\u003e","Interface":"org.bluez.GattProfile1","ObjectPath":"\u003capplication dependent\u003e","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. The profile can use it to\n\t\t\tdo cleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUIDs","Type":"array{string}","Docs":"128-bit GATT service UUIDs to auto connect.","Flags":[1]}]},{"Title":"GATT Manager hierarchy","Description":"\nGATT Manager allows external applications to register GATT services and\nprofiles.\n\nRegistering a profile allows applications to subscribe to *remote* services.\nThese must implement the GattProfile1 interface defined above.\n\nRegistering a service allows applications to publish a *local* GATT service,\nwhich then becomes available to remote devices. A GATT service is represented by\na D-Bus object hierarchy where the root node corresponds to a service and the\nchild nodes represent characteristics and descriptors that belong to that\nservice. Each node must implement one of GattService1, GattCharacteristic1,\nor GattDescriptor1 interfaces described above, based on the attribute it\nrepresents. Each node must also implement the standard D-Bus Properties\ninterface to expose their properties. These objects collectively represent a\nGATT service definition.\n\nTo make service registration simple, BlueZ requires that all objects that belong\nto a GATT service be grouped under a D-Bus Object Manager that solely manages\nthe objects of that service. Hence, the standard DBus.ObjectManager interface\nmust be available on the root service path. An example application hierarchy\ncontaining two separate GATT services may look like this:\n\n-\u003e /com/example\n | - org.freedesktop.DBus.ObjectManager\n |\n -\u003e /com/example/service0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattService1\n | |\n | -\u003e /com/example/service0/char0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1/desc0\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattDescriptor1\n |\n -\u003e /com/example/service1\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattService1\n |\n -\u003e /com/example/service1/char0\n - org.freedesktop.DBus.Properties\n - org.bluez.GattCharacteristic1\n\nWhen a service is registered, BlueZ will automatically obtain information about\nall objects using the service's Object Manager. Once a service has been\nregistered, the objects of a service should not be removed. If BlueZ receives an\nInterfacesRemoved signal from a service's Object Manager, it will immediately\nunregister the service. Similarly, if the application disconnects from the bus,\nall of its registered services will be automatically unregistered.\nInterfacesAdded signals will be ignored.\n\nExamples:\n\t- Client\n\t\ttest/example-gatt-client\n\t\tclient/bluetoothctl\n\t- Server\n\t\ttest/example-gatt-server\n\t\ttools/gatt-service\n\n","Service":"org.bluez","Interface":"org.bluez.GattManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a local GATT services hierarchy as described\n\t\t\tabove (GATT Server) and/or GATT profiles (GATT Client).\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering a GATT based\n\t\t\tservice or profile.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]}]},{"FileName":"health-api.txt","Name":"BlueZ D-Bus Health API description","Description":"\n","Api":[{"Title":"HealthManager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthManager1","ObjectPath":"/org/bluez/","Methods":[{"Name":"CreateApplication","ReturnType":"object","Args":[{"Type":"dict","Name":"config"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturns the path of the new registered application.\n\t\t\tApplication will be closed by the call or implicitly\n\t\t\twhen the programs leaves the bus.\n\t\t\tconfig:\n\t\t\t\tuint16 DataType:\n\t\t\t\t\tMandatory\n\t\t\t\tstring Role:\n\t\t\t\t\tMandatory. Possible values: \"source\",\n\t\t\t\t\t\t\t\t\t\"sink\"\n\t\t\t\tstring Description:\n\t\t\t\t\tOptional\n\t\t\t\tChannelType:\n\t\t\t\t\tOptional, just for sources. Possible\n\t\t\t\t\tvalues: \"reliable\", \"streaming\"\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DestroyApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCloses the HDP application identified by the object\n\t\t\tpath. Also application will be closed if the process\n\t\t\tthat started it leaves the bus. Only the creator of the\n\t\t\tapplication will be able to destroy it.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[]},{"Title":"HealthDevice hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthDevice1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Echo","ReturnType":"boolean","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tSends an echo petition to the remote service. Returns\n\t\t\tTrue if response matches with the buffer sent. If some\n\t\t\terror is detected False value is returned.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.OutOfRange\n"},{"Name":"CreateChannel","ReturnType":"object","Args":[{"Type":"object","Name":"application"},{"Type":"string","Name":"configuration"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCreates a new data channel. The configuration should\n\t\t\tindicate the channel quality of service using one of\n\t\t\tthis values \"reliable\", \"streaming\", \"any\".\n\t\t\tReturns the object path that identifies the data\n\t\t\tchannel that is already connected.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.HealthError\n"},{"Name":"DestroyChannel","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDestroys the data channel object. Only the creator of\n\t\t\tthe channel or the creator of the HealthApplication\n\t\t\tthat received the data channel will be able to destroy\n\t\t\tit.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[{"Name":"ChannelConnected","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a new data channel is\n\t\t\tcreated or when a known data channel is reconnected.\n\n"},{"Name":"ChannelDeleted","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a data channel is deleted.\n\n\t\t\tAfter this signal the data channel path will not be\n\t\t\tvalid and its path can be reused for future data\n\t\t\tchannels."}],"Properties":[{"Name":"MainChannel","Type":"object","Docs":"The first reliable channel opened. It is needed by\n\t\t\tupper applications in order to send specific protocol\n\t\t\tdata units. The first reliable can change after a\n\t\t\treconnection.","Flags":[]}]},{"Title":"HealthChannel hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthChannel1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/chanZZZ","Methods":[{"Name":"Acquire","ReturnType":"fd","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tReturns the file descriptor for this data channel. If\n\t\t\tthe data channel is not connected it will also\n\t\t\treconnect.\n\t\t\tPossible Errors: org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotAcquired","org.bluez.Error.NotAcquired"],"Docs":"\t\t\tReleases the fd. Application should also need to\n\t\t\tclose() it.\n\t\t\tPossible Errors: org.bluez.Error.NotAcquired\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The quality of service of the data channel. (\"reliable\"\n\t\t\tor \"streaming\")","Flags":[]},{"Name":"Device","Type":"object","Docs":"Identifies the Remote Device that is connected with.\n\t\t\tMaps with a HealthDevice object.","Flags":[]},{"Name":"Application","Type":"object","Docs":"Identifies the HealthApplication to which this channel\n\t\t\tis related to (which indirectly defines its role and\n\t\t\tdata type).","Flags":[]}]}]},{"FileName":"input-api.txt","Name":"BlueZ D-Bus Input API description","Description":"","Api":[{"Title":"Input hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Input1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"ReconnectMode","Type":"string","Docs":"Determines the Connectability mode of the HID device as\n\t\t\tdefined by the HID Profile specification, Section 5.4.2.\n\n\t\t\tThis mode is based in the two properties\n\t\t\tHIDReconnectInitiate (see Section 5.3.4.6) and\n\t\t\tHIDNormallyConnectable (see Section 5.3.4.14) which\n\t\t\tdefine the following four possible values:\n\n\t\t\t\"none\"\t\tDevice and host are not required to\n\t\t\t\t\tautomatically restore the connection.\n\n\t\t\t\"host\"\t\tBluetooth HID host restores connection.\n\n\t\t\t\"device\"\tBluetooth HID device restores\n\t\t\t\t\tconnection.\n\n\t\t\t\"any\"\t\tBluetooth HID device shall attempt to\n\t\t\t\t\trestore the lost connection, but\n\t\t\t\t\tBluetooth HID Host may also restore the\n\t\t\t\t\tconnection.","Flags":[]}]}]},{"FileName":"media-api.txt","Name":"BlueZ D-Bus Media API description","Description":"\n","Api":[{"Title":"Media hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Media1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a local end point to sender, the sender can\n\t\t\tregister as many end points as it likes.\n\t\t\tNote: If the sender disconnects the end points are\n\t\t\tautomatically unregistered.\n\t\t\tpossible properties:\n\t\t\t\tstring UUID:\n\t\t\t\t\tUUID of the profile which the endpoint\n\t\t\t\t\tis for.\n\t\t\t\tbyte Codec:\n\t\t\t\t\tAssigned number of codec that the\n\t\t\t\t\tendpoint implements. The values should\n\t\t\t\t\tmatch the profile specification which\n\t\t\t\t\tis indicated by the UUID.\n\t\t\t\tarray{byte} Capabilities:\n\t\t\t\t\tCapabilities blob, it is used as it is\n\t\t\t\t\tso the size and byte order must match.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported - emitted\n\t\t\t\t\t when interface for the end-point is\n\t\t\t\t\t disabled.\n"},{"Name":"UnregisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"}],"Errors":null,"Docs":"\t\t\tUnregister sender end point.\n"},{"Name":"RegisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a media player object to sender, the sender\n\t\t\tcan register as many objects as it likes.\n\t\t\tObject must implement at least\n\t\t\torg.mpris.MediaPlayer2.Player as defined in MPRIS 2.2\n\t\t\tspec:\n\t\t\thttp://specifications.freedesktop.org/mpris-spec/latest/\n\t\t\tNote: If the sender disconnects its objects are\n\t\t\tautomatically unregistered.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"UnregisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"}],"Errors":null,"Docs":"\t\t\tUnregister sender media player.\n"}],"Signals":[],"Properties":[]},{"Title":"Media Control hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaControl1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume playback.\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPause playback.\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStop playback.\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tNext item.\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPrevious item.\n"},{"Name":"VolumeUp","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step up\n"},{"Name":"VolumeDown","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step down\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"","Flags":[]},{"Name":"Player","Type":"object","Docs":"Addressed Player object path.","Flags":[5]}]},{"Title":"MediaPlayer1 hierarchy","Description":"","Service":"org.bluez (Controller role)","Interface":"org.bluez.MediaPlayer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tResume playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPause playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tStop playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tNext item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPrevious item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Equalizer","Type":"string","Docs":"Possible values: \"off\" or \"on\"","Flags":[]},{"Name":"Repeat","Type":"string","Docs":"Possible values: \"off\", \"singletrack\", \"alltracks\" or\n\t\t\t\t\t\"group\"","Flags":[]},{"Name":"Shuffle","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Scan","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Status","Type":"string","Docs":"Possible status: \"playing\", \"stopped\", \"paused\",\n\t\t\t\t\t\"forward-seek\", \"reverse-seek\"\n\t\t\t\t\tor \"error\"","Flags":[]},{"Name":"Position","Type":"uint32","Docs":"Playback position in milliseconds. Changing the\n\t\t\tposition may generate additional events that will be\n\t\t\tsent to the remote device. When position is 0 it means\n\t\t\tthe track is starting and when it's greater than or\n\t\t\tequal to track's duration the track has ended. Note\n\t\t\tthat even if duration is not available in metadata it's\n\t\t\tpossible to signal its end by setting position to the\n\t\t\tmaximum uint32 value.","Flags":[]},{"Name":"Track","Type":"dict","Docs":"Track metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title:","Type":"string","Docs":"Track title name","Flags":[]},{"Name":"Artist:","Type":"string","Docs":"Track artist name","Flags":[]},{"Name":"Album:","Type":"string","Docs":"Track album name","Flags":[]},{"Name":"Genre:","Type":"string","Docs":"Track genre name","Flags":[]},{"Name":"NumberOfTracks:","Type":"uint32","Docs":"Number of tracks in total","Flags":[]},{"Name":"TrackNumber:","Type":"uint32","Docs":"Track number","Flags":[]},{"Name":"Duration:","Type":"uint32","Docs":"Track duration in milliseconds","Flags":[]},{"Name":"Device","Type":"object","Docs":"Device object path.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Player name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Player type\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio\"\n\t\t\t\t\"Video\"\n\t\t\t\t\"Audio Broadcasting\"\n\t\t\t\t\"Video Broadcasting\"","Flags":[]},{"Name":"Subtype","Type":"string","Docs":"Player subtype\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio Book\"\n\t\t\t\t\"Podcast\"","Flags":[]},{"Name":"Browsable","Type":"boolean","Docs":"If present indicates the player can be browsed using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Searchable","Type":"boolean","Docs":"If present indicates the player can be searched using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Playlist","Type":"object","Docs":"Playlist object path.","Flags":[]}]},{"Title":"MediaFolder1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaFolder1","ObjectPath":"freely definable (Target role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX\n\t\t(Controller role)","Methods":[{"Name":"Search","ReturnType":"object","Args":[{"Type":"string","Name":"value"},{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tReturn a folder object containing the search result.\n\t\t\tTo list the items found use the folder object returned\n\t\t\tand pass to ChangeFolder.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ListItems","ReturnType":"array{objects, properties}","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturn a list of items found\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"object","Name":"folder"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tChange current folder.\n\t\t\tNote: By changing folder the items of previous folder\n\t\t\tmight be destroyed and have to be listed again, the\n\t\t\texception is NowPlaying folder which should be always\n\t\t\tpresent while the player is active.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"NumberOfItems","Type":"uint32","Docs":"Number of items in the folder","Flags":[]},{"Name":"Name","Type":"string","Docs":"Folder name:\n\n\t\t\tPossible values:\n\t\t\t\t\"/Filesystem/...\": Filesystem scope\n\t\t\t\t\"/NowPlaying/...\": NowPlaying scope\n\n\t\t\tNote: /NowPlaying folder might not be listed if player\n\t\t\tis stopped, folders created by Search are virtual so\n\t\t\tonce another Search is perform or the folder is\n\t\t\tchanged using ChangeFolder it will no longer be listed.\n\nFilters","Flags":[]},{"Name":"Start:","Type":"uint32","Docs":"Offset of the first item.\n\n\t\t\tDefault value: 0","Flags":[]},{"Name":"End:","Type":"uint32","Docs":"Offset of the last item.\n\n\t\t\tDefault value: NumbeOfItems","Flags":[]},{"Name":"Attributes","Type":"array{string}","Docs":"Item properties that should be included in the list.\n\n\t\t\tPossible Values:\n\n\t\t\t\t\"title\", \"artist\", \"album\", \"genre\",\n\t\t\t\t\"number-of-tracks\", \"number\", \"duration\"\n\n\t\t\tDefault Value: All","Flags":[]}]},{"Title":"MediaItem1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaItem1","ObjectPath":"freely definable (Target role)\n\t\t[variable\n\t\tprefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX\n\t\t(Controller role)","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPlay item\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"AddtoNowPlaying","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tAdd item to now playing list\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Player","Type":"object","Docs":"Player object path the item belongs to","Flags":[]},{"Name":"Name","Type":"string","Docs":"Item displayable name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Item type\n\n\t\t\tPossible values: \"video\", \"audio\", \"folder\"","Flags":[]},{"Name":"FolderType","Type":"string","Docs":"Folder type.\n\n\t\t\tPossible values: \"mixed\", \"titles\", \"albums\", \"artists\"\n\n\t\t\tAvailable if property Type is \"Folder\"","Flags":[5]},{"Name":"Playable","Type":"boolean","Docs":"Indicates if the item can be played\n\n\t\t\tAvailable if property Type is \"folder\"","Flags":[5]},{"Name":"Metadata","Type":"dict","Docs":"Item metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title","Type":"string","Docs":"Item title name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Artist","Type":"string","Docs":"Item artist name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Album","Type":"string","Docs":"Item album name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Genre","Type":"string","Docs":"Item genre name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"NumberOfTracks","Type":"uint32","Docs":"Item album number of tracks in total\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Number","Type":"uint32","Docs":"Item album number\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Duration","Type":"uint32","Docs":"Item duration in milliseconds\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]}]},{"Title":"MediaEndpoint1 hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.MediaEndpoint1","ObjectPath":"freely definable","Methods":[{"Name":"SetConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"},{"Type":"dict","Name":"properties"}],"Errors":null,"Docs":"\t\t\tSet configuration for the transport.\n"},{"Name":"SelectConfiguration","ReturnType":"array{byte}","Args":[{"Type":"array{byte}","Name":"capabilities"}],"Errors":null,"Docs":"\t\t\tSelect preferable configuration from the supported\n\t\t\tcapabilities.\n\t\t\tReturns a configuration which can be used to setup\n\t\t\ta transport.\n\t\t\tNote: There is no need to cache the selected\n\t\t\tconfiguration since on success the configuration is\n\t\t\tsend back as parameter of SetConfiguration.\n"},{"Name":"ClearConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"}],"Errors":null,"Docs":"\t\t\tClear transport configuration.\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the endpoint. An endpoint can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tendpoint, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[]},{"Title":"MediaTransport1 hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaTransport1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX","Methods":[{"Name":"Acquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAuthorized","org.bluez.Error.NotAuthorized"],"Docs":"\t\t\tAcquire transport file descriptor and the MTU for read\n\t\t\tand write respectively.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"TryAcquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAvailable","org.bluez.Error.NotAvailable"],"Docs":"\t\t\tAcquire transport file descriptor only if the transport\n\t\t\tis in \"pending\" state at the time the message is\n\t\t\treceived by BlueZ. Otherwise no request will be sent\n\t\t\tto the remote device and the function will just fail\n\t\t\twith org.bluez.Error.NotAvailable.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAvailable\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tReleases file descriptor.\n"}],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"Device object which the transport is connected to.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the transport is for.","Flags":[]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the transport support.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[]},{"Name":"Configuration","Type":"array{byte}","Docs":"Configuration blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[]},{"Name":"State","Type":"string","Docs":"Indicates the state of the transport. Possible\n\t\t\tvalues are:\n\t\t\t\t\"idle\": not streaming\n\t\t\t\t\"pending\": streaming but not acquired\n\t\t\t\t\"active\": streaming and acquired","Flags":[]},{"Name":"Delay","Type":"uint16","Docs":"Optional. Transport delay in 1/10 of millisecond, this\n\t\t\tproperty is only writeable when the transport was\n\t\t\tacquired by the sender.","Flags":[]},{"Name":"Volume","Type":"uint16","Docs":"Optional. Indicates volume level of the transport,\n\t\t\tthis property is only writeable when the transport was\n\t\t\tacquired by the sender.\n\n\t\t\tPossible Values: 0-127","Flags":[]}]}]},{"FileName":"network-api.txt","Name":"BlueZ D-Bus Network API description","Description":"\n","Api":[{"Title":"Network hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Network1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"string","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.AlreadyConnected","org.bluez.Error.AlreadyConnected"],"Docs":"\t\t\tConnect to the network device and return the network\n\t\t\tinterface name. Examples of the interface name are\n\t\t\tbnep0, bnep1 etc.\n\t\t\tuuid can be either one of \"gn\", \"panu\" or \"nap\" (case\n\t\t\tinsensitive) or a traditional string representation of\n\t\t\tUUID or a hexadecimal number.\n\t\t\tThe connection will be closed and network device\n\t\t\treleased either upon calling Disconnect() or when\n\t\t\tthe client disappears from the message bus.\n\t\t\tPossible errors: org.bluez.Error.AlreadyConnected\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnect from the network device.\n\t\t\tTo abort a connection attempt in case of errors or\n\t\t\ttimeouts in the client it is fine to call this method.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if the device is connected.","Flags":[]},{"Name":"Interface","Type":"string","Docs":"Indicates the network interface name when available.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"Indicates the connection role when available.","Flags":[]}]},{"Title":"Network server hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.NetworkServer1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"Register","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"},{"Type":"string","Name":"bridge"}],"Errors":null,"Docs":"\t\t\tRegister server for the provided UUID. Every new\n\t\t\tconnection to this server will be added the bridge\n\t\t\tinterface.\n\t\t\tValid UUIDs are \"gn\", \"panu\" or \"nap\".\n\t\t\tInitially no network server SDP is provided. Only\n\t\t\tafter this method a SDP record will be available\n\t\t\tand the BNEP server will be ready for incoming\n\t\t\tconnections.\n"},{"Name":"Unregister","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":null,"Docs":"\t\t\tUnregister the server for provided UUID.\n\t\t\tAll servers will be automatically unregistered when\n\t\t\tthe calling application terminates.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-agent-api.txt","Name":"OBEX D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.AgentManager1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tRegister an agent to request authorization of\n\t\t\tthe user to accept/reject objects. Object push\n\t\t\tservice needs to authorize each received object.\n\t\t\tPossible errors: org.bluez.obex.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.obex.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.obex.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"AuthorizePush","ReturnType":"string","Args":[{"Type":"object","Name":"transfer"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to accept/reject a Bluetooth object push request.\n\t\t\tReturns the full path (including the filename) where\n\t\t\tthe object shall be stored. The tranfer object will\n\t\t\tcontain a Filename property that contains the default\n\t\t\tlocation and name that can be returned.\n\t\t\tPossible errors: org.bluez.obex.Error.Rejected\n\t\t\t org.bluez.obex.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned. It cancels\n\t\t\tthe previous request.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-api.txt","Name":"OBEX D-Bus API description","Description":"\n","Api":[{"Title":"Client hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Client1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"CreateSession","ReturnType":"object","Args":[{"Type":"string","Name":"destination"},{"Type":"dict","Name":"args"}],"Errors":null,"Docs":"\t\t\tCreate a new OBEX session for the given remote address.\n\t\t\tThe last parameter is a dictionary to hold optional or\n\t\t\ttype-specific parameters. Typical parameters that can\n\t\t\tbe set in this dictionary include the following:\n\t\t\t\tstring \"Target\" : type of session to be created\n\t\t\t\tstring \"Source\" : local address to be used\n\t\t\t\tbyte \"Channel\"\n\t\t\tThe currently supported targets are the following:\n\t\t\t\t\"ftp\"\n\t\t\t\t\"map\"\n\t\t\t\t\"opp\"\n\t\t\t\t\"pbap\"\n\t\t\t\t\"sync\"\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"RemoveSession","ReturnType":"void","Args":[{"Type":"object","Name":"session"}],"Errors":null,"Docs":"\t\t\tUnregister session and abort pending transfers.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.NotAuthorized\n"}],"Signals":[],"Properties":[]},{"Title":"Session hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Session1","ObjectPath":"/org/bluez/obex/server/session{0, 1, 2, ...} or\n\t\t/org/bluez/obex/client/session{0, 1, 2, ...}","Methods":[{"Name":"GetCapabilities","ReturnType":"string","Args":[],"Errors":null,"Docs":"\t\t\tGet remote device capabilities.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Source","Type":"string","Docs":"Bluetooth adapter address","Flags":[]},{"Name":"Destination","Type":"string","Docs":"Bluetooth device address","Flags":[]},{"Name":"Channel","Type":"byte","Docs":"Bluetooth channel","Flags":[]},{"Name":"Target","Type":"string","Docs":"Target UUID","Flags":[]},{"Name":"Root","Type":"string","Docs":"Root path","Flags":[]}]},{"Title":"Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Transfer1","ObjectPath":"[Session object path]/transfer{0, 1, 2, ...}","Methods":[{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStops the current transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.InProgress\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Suspend","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tSuspend transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to suspend transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"},{"Name":"Resume","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to resume transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"}],"Signals":[],"Properties":[{"Name":"Status","Type":"string","Docs":"Inform the current status of the transfer.\n\n\t\t\tPossible values: \"queued\", \"active\", \"suspended\",\n\t\t\t\t\t\"complete\" or \"error\"","Flags":[]},{"Name":"Session","Type":"object","Docs":"The object path of the session the transfer belongs\n\t\t\tto.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Name of the transferred object. Either Name or Type\n\t\t\tor both will be present.","Flags":[]},{"Name":"Type","Type":"string","Docs":"Type of the transferred object. Either Name or Type\n\t\t\tor both will be present.\n\n\t\tuint64 Time [readonly, optional]\n\n\t\t\tTime of the transferred object if this is\n\t\t\tprovided by the remote party.\n\n\t\tuint64 Size [readonly, optional]\n\n\t\t\tSize of the transferred object. If the size is\n\t\t\tunknown, then this property will not be present.\n\n\t\tuint64 Transferred [readonly, optional]\n\n\t\t\tNumber of bytes transferred. For queued transfers, this\n\t\t\tvalue will not be present.","Flags":[]},{"Name":"Filename","Type":"string","Docs":"Complete name of the file being received or sent.\n\n\t\t\tFor incoming object push transaction, this will be\n\t\t\tthe proposed default location and name. It can be\n\t\t\toverwritten by the AuthorizePush agent callback\n\t\t\tand will be then updated accordingly.","Flags":[5]}]},{"Title":"Object Push hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.ObjectPush1","ObjectPath":"[Session object path]","Methods":[{"Name":"SendFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend one local file to the remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullBusinessCard","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRequest the business card from a remote device and\n\t\t\tstore it in the local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ExchangeBusinessCards","ReturnType":"object, dict","Args":[{"Type":"string","Name":"clientfile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tPush the client's business card to the remote device\n\t\t\tand then retrieve the remote business card and store\n\t\t\tit in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"File Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.FileTransfer","ObjectPath":"[Session object path]","Methods":[{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tChange the current folder of the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CreateFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tCreate a new folder in the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolder","ReturnType":"array{dict}","Args":[],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Object name in UTF-8 format\n\t\t\t\tstring Type : Either \"folder\" or \"file\"\n\t\t\t\tuint64 Size : Object size or number of items in\n\t\t\t\t\t\tfolder\n\t\t\t\tstring Permission : Group, owner and other\n\t\t\t\t\t\t\tpermission\n\t\t\t\tuint64 Modified : Last change\n\t\t\t\tuint64 Accessed : Last access\n\t\t\t\tuint64 Created : Creation date\n\t\t\tPossible errors: org.bluez.obex.Error.Failed\n"},{"Name":"GetFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from remote device) to the\n\t\t\ttarget file (on local filesystem).\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from local filesystem) to the\n\t\t\ttarget file (on remote device).\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CopyFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy a file within the remote device from source file\n\t\t\tto target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"MoveFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tMove a file within the remote device from source file\n\t\t\tto the target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Delete","ReturnType":"void","Args":[{"Type":"string","Name":"file"}],"Errors":null,"Docs":"\t\t\tDeletes the specified file/folder.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Phonebook Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.PhonebookAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"Select","ReturnType":"void","Args":[{"Type":"string","Name":"location"},{"Type":"string","Name":"phonebook"}],"Errors":null,"Docs":"\t\t\tSelect the phonebook object for other operations. Should\n\t\t\tbe call before all the other operations.\n\t\t\tlocation : Where the phonebook is stored, possible\n\t\t\tinputs :\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim\" ( \"sim1\" )\n\t\t\t\t\"sim2\"\n\t\t\t\t...\n\t\t\tphonebook : Possible inputs :\n\t\t\t\t\"pb\" :\tphonebook for the saved contacts\n\t\t\t\t\"ich\":\tincoming call history\n\t\t\t\t\"och\":\toutgoing call history\n\t\t\t\t\"mch\":\tmissing call history\n\t\t\t\t\"cch\":\tcombination of ich och mch\n\t\t\t\t\"spd\":\tspeed dials entry ( only for \"internal\" )\n\t\t\t\t\"fav\":\tfavorites entry ( only for \"internal\" )\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullAll","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn the entire phonebook object from the PSE server\n\t\t\tin plain string with vcard format, and store it in\n\t\t\ta local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible filters: Format, Order, Offset, MaxCount and\n\t\t\tFields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\torg.bluez.obex.Forbidden\n"},{"Name":"List","ReturnType":"array{string vcard, string name}","Args":[{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name. For example:\n\t\t\t\t\"1.vcf\" : \"John\"\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Forbidden\n"},{"Name":"Pull","ReturnType":"object, dict","Args":[{"Type":"string","Name":"vcard"},{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tGiven a vcard handle, retrieve the vcard in the current\n\t\t\tphonebook object and store it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossbile filters: Format and Fields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Search","ReturnType":"array{string vcard, string name}","Args":[{"Type":"string","Name":"field"},{"Type":"string","Name":"value"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tSearch for entries matching the given condition and\n\t\t\treturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name.\n\t\t\tvcard : name paired string match the search condition.\n\t\t\tfield : the field in the vcard to search with\n\t\t\t\t{ \"name\" (default) | \"number\" | \"sound\" }\n\t\t\tvalue : the string value to search for\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"GetSize","ReturnType":"uint16","Args":[],"Errors":null,"Docs":"\t\t\tReturn the number of entries in the selected phonebook\n\t\t\tobject that are actually used (i.e. indexes that\n\t\t\tcorrespond to non-NULL entries).\n\t\t\tPossible errors: org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateVersion","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAttempt to update PrimaryCounter and SecondaryCounter.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn All Available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Current folder.","Flags":[]},{"Name":"DatabaseIdentifier","Type":"string","Docs":"128 bits persistent database identifier.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"PrimaryCounter","Type":"string","Docs":"128 bits primary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"SecondaryCounter","Type":"string","Docs":"128 bits secondary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"FixedImageSize","Type":"bool","Docs":"Indicate support for fixed image size.\n\n\t\t\tPossible values: True if image is JPEG 300x300 pixels\n\t\t\totherwise False.","Flags":[5]}]},{"Title":"Synchronization hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Synchronization1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetLocation","ReturnType":"void","Args":[{"Type":"string","Name":"location"}],"Errors":null,"Docs":"\t\t\tSet the phonebook object store location for other\n\t\t\toperations. Should be called before all the other\n\t\t\toperations.\n\t\t\tlocation: Where the phonebook is stored, possible\n\t\t\tvalues:\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim1\"\n\t\t\t\t\"sim2\"\n\t\t\t\t......\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n"},{"Name":"GetPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRetrieve an entire Phonebook Object store from remote\n\t\t\tdevice, and stores it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend an entire Phonebook Object store to remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Message Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.MessageAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetFolder","ReturnType":"void","Args":[{"Type":"string","Name":"name"}],"Errors":null,"Docs":"\t\t\tSet working directory for current session, *name* may\n\t\t\tbe the directory name or '..[/dir]'.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolders","ReturnType":"array{dict}","Args":[{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Folder name\n\t\t\tPossible filters: Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn all available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"},{"Name":"ListMessages","ReturnType":"array{object, dict}","Args":[{"Type":"string","Name":"folder"},{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns an array containing the messages found in the\n\t\t\tgiven subfolder of the current folder, or in the\n\t\t\tcurrent folder if folder is empty.\n\t\t\tPossible Filters: Offset, MaxCount, SubjectLength, Fields,\n\t\t\tType, PeriodStart, PeriodEnd, Status, Recipient, Sender,\n\t\t\tPriority\n\t\t\tEach message is represented by an object path followed\n\t\t\tby a dictionary of the properties.\n\t\t\tProperties:\n\t\t\t\tstring Subject:\n\t\t\t\t\tMessage subject\n\t\t\t\tstring Timestamp:\n\t\t\t\t\tMessage timestamp\n\t\t\t\tstring Sender:\n\t\t\t\t\tMessage sender name\n\t\t\t\tstring SenderAddress:\n\t\t\t\t\tMessage sender address\n\t\t\t\tstring ReplyTo:\n\t\t\t\t\tMessage Reply-To address\n\t\t\t\tstring Recipient:\n\t\t\t\t\tMessage recipient name\n\t\t\t\tstring RecipientAddress:\n\t\t\t\t\tMessage recipient address\n\t\t\t\tstring Type:\n\t\t\t\t\tMessage type\n\t\t\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\t\t\"sms-cdma\" and \"mms\"\n\t\t\t\tuint64 Size:\n\t\t\t\t\tMessage size in bytes\n\t\t\t\tboolean Text:\n\t\t\t\t\tMessage text flag\n\t\t\t\t\tSpecifies whether message has textual\n\t\t\t\t\tcontent or is binary only\n\t\t\t\tstring Status:\n\t\t\t\t\tMessage status\n\t\t\t\t\tPossible values for received messages:\n\t\t\t\t\t\"complete\", \"fractioned\", \"notification\"\n\t\t\t\t\tPossible values for sent messages:\n\t\t\t\t\t\"delivery-success\", \"sending-success\",\n\t\t\t\t\t\"delivery-failure\", \"sending-failure\"\n\t\t\t\tuint64 AttachmentSize:\n\t\t\t\t\tMessage overall attachment size in bytes\n\t\t\t\tboolean Priority:\n\t\t\t\t\tMessage priority flag\n\t\t\t\tboolean Read:\n\t\t\t\t\tMessage read flag\n\t\t\t\tboolean Sent:\n\t\t\t\t\tMessage sent flag\n\t\t\t\tboolean Protected:\n\t\t\t\t\tMessage protected flag\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateInbox","ReturnType":"void","Args":null,"Errors":null,"Docs":""}],"Signals":[],"Properties":[]},{"Title":"Message hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Message1","ObjectPath":"[Session object path]/{message0,...}","Methods":[{"Name":"Get","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"boolean","Name":"attachment"}],"Errors":null,"Docs":"\t\t\tDownload message and store it in the target file.\n\t\t\tIf an empty target file is given, a temporary file\n\t\t\twill be automatically generated.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Folder which the message belongs to","Flags":[]},{"Name":"Subject","Type":"string","Docs":"Message subject","Flags":[]},{"Name":"Timestamp","Type":"string","Docs":"Message timestamp","Flags":[]},{"Name":"Sender","Type":"string","Docs":"Message sender name","Flags":[]},{"Name":"SenderAddress","Type":"string","Docs":"Message sender address","Flags":[]},{"Name":"ReplyTo","Type":"string","Docs":"Message Reply-To address","Flags":[]},{"Name":"Recipient","Type":"string","Docs":"Message recipient name","Flags":[]},{"Name":"RecipientAddress","Type":"string","Docs":"Message recipient address","Flags":[]},{"Name":"Type","Type":"string","Docs":"Message type\n\n\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\"sms-cdma\" and \"mms\"\n\n\t\tuint64 Size [readonly]\n\n\t\t\tMessage size in bytes","Flags":[]},{"Name":"Status","Type":"string","Docs":"Message reception status\n\n\t\t\tPossible values: \"complete\",\n\t\t\t\"fractioned\" and \"notification\"","Flags":[]},{"Name":"Priority","Type":"boolean","Docs":"Message priority flag","Flags":[]},{"Name":"Read","Type":"boolean","Docs":"Message read flag","Flags":[3]},{"Name":"Deleted","Type":"boolean","Docs":"Message deleted flag","Flags":[]},{"Name":"Sent","Type":"boolean","Docs":"Message sent flag","Flags":[]},{"Name":"Protected","Type":"boolean","Docs":"Message protected flag","Flags":[]}]}]},{"FileName":"profile-api.txt","Name":"BlueZ D-Bus Profile API description","Description":"\n","Api":[{"Title":"Profile Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ProfileManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"},{"Type":"string","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers a profile implementation.\n\t\t\tIf an application disconnects from the bus all\n\t\t\tits registered profiles will be removed.\n\t\t\tHFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault RFCOMM channel is 6. And this requires\n\t\t\t\tauthentication.\n\t\t\tAvailable options:\n\t\t\t\tstring Name\n\t\t\t\t\tHuman readable name for the profile\n\t\t\t\tstring Service\n\t\t\t\t\tThe primary service class UUID\n\t\t\t\t\t(if different from the actual\n\t\t\t\t\t profile UUID)\n\t\t\t\tstring Role\n\t\t\t\t\tFor asymmetric profiles that do not\n\t\t\t\t\thave UUIDs available to uniquely\n\t\t\t\t\tidentify each side this\n\t\t\t\t\tparameter allows specifying the\n\t\t\t\t\tprecise local role.\n\t\t\t\t\tPossible values: \"client\", \"server\"\n\t\t\t\tuint16 Channel\n\t\t\t\t\tRFCOMM channel number that is used\n\t\t\t\t\tfor client and server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tuint16 PSM\n\t\t\t\t\tPSM number that is used for client\n\t\t\t\t\tand server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tboolean RequireAuthentication\n\t\t\t\t\tPairing is required before connections\n\t\t\t\t\twill be established. No devices will\n\t\t\t\t\tbe connected if not paired.\n\t\t\t\tboolean RequireAuthorization\n\t\t\t\t\tRequest authorization before any\n\t\t\t\t\tconnection will be established.\n\t\t\t\tboolean AutoConnect\n\t\t\t\t\tIn case of a client UUID this will\n\t\t\t\t\tforce connection of the RFCOMM or\n\t\t\t\t\tL2CAP channels when a remote device\n\t\t\t\t\tis connected.\n\t\t\t\tstring ServiceRecord\n\t\t\t\t\tProvide a manual SDP record.\n\t\t\t\tuint16 Version\n\t\t\t\t\tProfile version (for SDP record)\n\t\t\t\tuint16 Features\n\t\t\t\t\tProfile features (for SDP record)\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the profile that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Profile hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Profile1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. A profile can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"NewConnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"int32","Name":"fd"},{"Type":"dict","Name":"fd_properties"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a new service level\n\t\t\tconnection has been made and authorized.\n\t\t\tCommon fd_properties:\n\t\t\tuint16 Version\t\tProfile version (optional)\n\t\t\tuint16 Features\t\tProfile features (optional)\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestDisconnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a profile gets\n\t\t\tdisconnected.\n\t\t\tThe file descriptor is no longer owned by the service\n\t\t\tdaemon and the profile implementation needs to take\n\t\t\tcare of cleaning up all connections.\n\t\t\tIf multiple file descriptors are indicated via\n\t\t\tNewConnection, it is expected that all of them\n\t\t\tare disconnected before returning from this\n\t\t\tmethod call.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"}],"Signals":[],"Properties":[]}]},{"FileName":"sap-api.txt","Name":"BlueZ D-Bus Sim Access API description","Description":"\n","Api":[{"Title":"Sim Access Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.SimAccess1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnects SAP client from the server.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if SAP client is connected to the server.","Flags":[]}]}]},{"FileName":"thermometer-api.txt","Name":"BlueZ D-Bus Thermometer API description","Description":"\tSantiago Carot-Nemesio \u003csancane@gmail.com\u003e\n\n","Api":[{"Title":"Health Thermometer Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ThermometerManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a watcher to monitor scanned measurements.\n\t\t\tThis agent will be notified about final temperature\n\t\t\tmeasurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"UnregisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tUnregisters a watcher.\n"},{"Name":"EnableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tEnables intermediate measurement notifications\n\t\t\tfor this agent. Intermediate measurements will\n\t\t\tbe enabled only for thermometers which support it.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DisableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDisables intermediate measurement notifications\n\t\t\tfor this agent. It will disable notifications in\n\t\t\tthermometers when the last agent removes the\n\t\t\twatcher for intermediate measurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\torg.bluez.Error.NotFound\n"}],"Signals":[],"Properties":[]},{"Title":"Health Thermometer Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Thermometer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Intermediate","Type":"boolean","Docs":"True if the thermometer supports intermediate\n\t\t\tmeasurement notifications.","Flags":[]},{"Name":"Interval","Type":"uint16","Docs":"(optional) The Measurement Interval defines the time (in\n\t\t\tseconds) between measurements. This interval is\n\t\t\tnot related to the intermediate measurements and\n\t\t\tmust be defined into a valid range. Setting it\n\t\t\tto zero means that no periodic measurements will\n\t\t\tbe taken.","Flags":[5]},{"Name":"Maximum","Type":"uint16","Docs":"(optional) Defines the maximum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]},{"Name":"Minimum","Type":"uint16","Docs":"(optional) Defines the minimum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]}]},{"Title":"Health Thermometer Watcher hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.ThermometerWatcher1","ObjectPath":"freely definable","Methods":[{"Name":"MeasurementReceived","ReturnType":"void","Args":[{"Type":"dict","Name":"measurement"}],"Errors":null,"Docs":"\t\t\tThis callback gets called when a measurement has been\n\t\t\tscanned in the thermometer.\n\t\t\tMeasurement:\n\t\t\t\tint16 Exponent:\n\t\t\t\tint32 Mantissa:\n\t\t\t\t\tExponent and Mantissa values as\n\t\t\t\t\textracted from float value defined by\n\t\t\t\t\tIEEE-11073-20601.\n\t\t\t\t\tMeasurement value is calculated as\n\t\t\t\t\t(Mantissa) * (10^Exponent)\n\t\t\t\t\tFor special cases Exponent is\n\t\t\t\t\tset to 0 and Mantissa is set to\n\t\t\t\t\tone of following values:\n\t\t\t\t\t+(2^23 - 1)\tNaN (invalid or\n\t\t\t\t\t\t\tmissing data)\n\t\t\t\t\t-(2^23)\t\tNRes\n\t\t\t\t\t+(2^23 - 2)\t+Infinity\n\t\t\t\t\t-(2^23 - 2)\t-Infinity\n\t\t\t\tstring Unit:\n\t\t\t\t\tPossible values: \"celsius\" or\n\t\t\t\t\t\t\t\"fahrenheit\"\n\t\t\t\tuint64 Time (optional):\n\t\t\t\t\tTime of measurement, if\n\t\t\t\t\tsupported by device.\n\t\t\t\t\tExpressed in seconds since epoch.\n\t\t\t\tstring Type (optional):\n\t\t\t\t\tOnly present if measurement type\n\t\t\t\t\tis known.\n\t\t\t\t\tPossible values: \"armpit\", \"body\",\n\t\t\t\t\t\t\"ear\", \"finger\", \"intestines\",\n\t\t\t\t\t\t\"mouth\", \"rectum\", \"toe\",\n\t\t\t\t\t\t\"tympanum\"\n\t\t\t\tstring Measurement:\n\t\t\t\t\tPossible values: \"final\" or\n\t\t\t\t\t\t\t\"intermediate\"\n"}],"Signals":[],"Properties":[]}]}]}go-bluetooth-bluez-5.60/bluez-5.53.json000077500000000000000000004746021420407601400176150ustar00rootroot00000000000000{"Version":"5.53","Api":[{"FileName":"adapter-api.txt","Name":"BlueZ D-Bus Adapter API description","Description":"\n","Api":[{"Title":"Adapter hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Adapter1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"StartDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method starts the device discovery session. This\n\t\t\tincludes an inquiry procedure and remote device name\n\t\t\tresolving. Use StopDiscovery to release the sessions\n\t\t\tacquired.\n\t\t\tThis process will start creating Device objects as\n\t\t\tnew devices are discovered.\n\t\t\tDuring discovery RSSI delta-threshold is imposed.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"StopDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method will cancel any previous StartDiscovery\n\t\t\ttransaction.\n\t\t\tNote that a discovery procedure is shared between all\n\t\t\tdiscovery sessions thus calling StopDiscovery will only\n\t\t\trelease a single session.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n"},{"Name":"RemoveDevice","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis removes the remote device object at the given\n\t\t\tpath. It will remove also the pairing information.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"SetDiscoveryFilter","ReturnType":"void","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method sets the device discovery filter for the\n\t\t\tcaller. When this method is called with no filter\n\t\t\tparameter, filter is removed.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tarray{string} UUIDs\n\t\t\t\tFilter by service UUIDs, empty means match\n\t\t\t\t_any_ UUID.\n\t\t\t\tWhen a remote device is found that advertises\n\t\t\t\tany UUID from UUIDs, it will be reported if:\n\t\t\t\t- Pathloss and RSSI are both empty.\n\t\t\t\t- only Pathloss param is set, device advertise\n\t\t\t\t TX pwer, and computed pathloss is less than\n\t\t\t\t Pathloss param.\n\t\t\t\t- only RSSI param is set, and received RSSI is\n\t\t\t\t higher than RSSI param.\n\t\t\tint16 RSSI\n\t\t\t\tRSSI threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated RSSI value. If one or more discovery\n\t\t\t\tfilters have been set, the RSSI delta-threshold,\n\t\t\t\tthat is imposed by StartDiscovery by default,\n\t\t\t\twill not be applied.\n\t\t\tuint16 Pathloss\n\t\t\t\tPathloss threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated Pathloss value.\n\t\t\tstring Transport (Default \"auto\")\n\t\t\t\tTransport parameter determines the type of\n\t\t\t\tscan.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"auto\"\t- interleaved scan\n\t\t\t\t\t\"bredr\"\t- BR/EDR inquiry\n\t\t\t\t\t\"le\"\t- LE scan only\n\t\t\t\tIf \"le\" or \"bredr\" Transport is requested,\n\t\t\t\tand the controller doesn't support it,\n\t\t\t\torg.bluez.Error.Failed error will be returned.\n\t\t\t\tIf \"auto\" transport is requested, scan will use\n\t\t\t\tLE, BREDR, or both, depending on what's\n\t\t\t\tcurrently enabled on the controller.\n\t\t\tbool DuplicateData (Default: true)\n\t\t\t\tDisables duplicate detection of advertisement\n\t\t\t\tdata.\n\t\t\t\tWhen enabled PropertiesChanged signals will be\n\t\t\t\tgenerated for either ManufacturerData and\n\t\t\t\tServiceData everytime they are discovered.\n\t\t\tbool Discoverable (Default: false)\n\t\t\t\tMake adapter discoverable while discovering,\n\t\t\t\tif the adapter is already discoverable setting\n\t\t\t\tthis filter won't do anything.\n\t\t\tWhen discovery filter is set, Device objects will be\n\t\t\tcreated as new devices with matching criteria are\n\t\t\tdiscovered regardless of they are connectable or\n\t\t\tdiscoverable which enables listening to\n\t\t\tnon-connectable and non-discoverable devices.\n\t\t\tWhen multiple clients call SetDiscoveryFilter, their\n\t\t\tfilters are internally merged, and notifications about\n\t\t\tnew devices are sent to all clients. Therefore, each\n\t\t\tclient must check that device updates actually match\n\t\t\tits filter.\n\t\t\tWhen SetDiscoveryFilter is called multiple times by the\n\t\t\tsame client, last filter passed will be active for\n\t\t\tgiven client.\n\t\t\tSetDiscoveryFilter can be called before StartDiscovery.\n\t\t\tIt is useful when client will create first discovery\n\t\t\tsession, to ensure that proper scan will be started\n\t\t\tright after call to StartDiscovery.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"GetDiscoveryFilters","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn available filters that can be given to\n\t\t\tSetDiscoveryFilter.\n\t\t\tPossible errors: None\n"},{"Name":"ConnectDevice","ReturnType":"object","Args":[{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method connects to device without need of\n\t\t\tperforming General Discovery. Connection mechanism is\n\t\t\tsimilar to Connect method from Device1 interface with\n\t\t\texception that this method returns success when physical\n\t\t\tconnection is established. After this method returns,\n\t\t\tservices discovery will continue and any supported\n\t\t\tprofile will be connected. There is no need for calling\n\t\t\tConnect on Device1 after this call. If connection was\n\t\t\tsuccessful this method returns object path to created\n\t\t\tdevice object.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tstring Address\n\t\t\t\tThe Bluetooth device address of the remote\n\t\t\t\tdevice. This parameter is mandatory.\n\t\t\tstring AddressType\n\t\t\t\tThe Bluetooth device Address Type. This is\n\t\t\t\taddress type that should be used for initial\n\t\t\t\tconnection. If this parameter is not present\n\t\t\t\tBR/EDR device is created.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"public\" - Public address\n\t\t\t\t\t\"random\" - Random address\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth Address Type. For dual-mode and BR/EDR\n\t\t\tonly adapter this defaults to \"public\". Single mode LE\n\t\t\tadapters may have either value. With privacy enabled\n\t\t\tthis contains type of Identity Address and not type of\n\t\t\taddress used for connection.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth system name (pretty hostname).\n\n\t\t\tThis property is either a static system default\n\t\t\tor controlled by an external daemon providing\n\t\t\taccess to the pretty hostname configuration.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The Bluetooth friendly name. This value can be\n\t\t\tchanged.\n\n\t\t\tIn case no alias is set, it will return the system\n\t\t\tprovided name. Setting an empty string as alias will\n\t\t\tconvert it back to the system provided name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to system name.\n\n\t\t\tOn a well configured system, this property never\n\t\t\tneeds to be changed since it defaults to the system\n\t\t\tname and provides the pretty hostname. Only if the\n\t\t\tlocal name needs to be different from the pretty\n\t\t\thostname, this property should be used as last\n\t\t\tresort.","Flags":[]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device.\n\n\t\t\tThis property represents the value that is either\n\t\t\tautomatically configured by DMI/ACPI information\n\t\t\tor provided as static configuration.","Flags":[]},{"Name":"Powered","Type":"boolean","Docs":"Switch an adapter on or off. This will also set the\n\t\t\tappropriate connectable state of the controller.\n\n\t\t\tThe value of this property is not persistent. After\n\t\t\trestart or unplugging of the adapter it will reset\n\t\t\tback to false.","Flags":[]},{"Name":"Discoverable","Type":"boolean","Docs":"Switch an adapter to discoverable or non-discoverable\n\t\t\tto either make it visible or hide it. This is a global\n\t\t\tsetting and should only be used by the settings\n\t\t\tapplication.\n\n\t\t\tIf the DiscoverableTimeout is set to a non-zero\n\t\t\tvalue then the system will set this value back to\n\t\t\tfalse after the timer expired.\n\n\t\t\tIn case the adapter is switched off, setting this\n\t\t\tvalue will fail.\n\n\t\t\tWhen changing the Powered property the new state of\n\t\t\tthis property will be updated via a PropertiesChanged\n\t\t\tsignal.\n\n\t\t\tFor any new adapter this settings defaults to false.","Flags":[]},{"Name":"Pairable","Type":"boolean","Docs":"Switch an adapter to pairable or non-pairable. This is\n\t\t\ta global setting and should only be used by the\n\t\t\tsettings application.\n\n\t\t\tNote that this property only affects incoming pairing\n\t\t\trequests.\n\n\t\t\tFor any new adapter this settings defaults to true.","Flags":[]},{"Name":"PairableTimeout","Type":"uint32","Docs":"The pairable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tpairable mode forever.\n\n\t\t\tThe default value for pairable timeout should be\n\t\t\tdisabled (value 0).","Flags":[]},{"Name":"DiscoverableTimeout","Type":"uint32","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tThe default value for the discoverable timeout should\n\t\t\tbe 180 seconds (3 minutes).","Flags":[]},{"Name":"Discovering","Type":"boolean","Docs":"Indicates that a device discovery procedure is active.","Flags":[]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tlocal services.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Local Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]}]}]},{"FileName":"advertising-api.txt","Name":"BlueZ D-Bus LE Advertising API Description","Description":"Advertising packets are structured data which is broadcast on the LE Advertising\nchannels and available for all devices in range. Because of the limited space\navailable in LE Advertising packets (31 bytes), each packet's contents must be\ncarefully controlled.\n\nBlueZ acts as a store for the Advertisement Data which is meant to be sent.\nIt constructs the correct Advertisement Data from the structured\ndata and configured the kernel to send the correct advertisement.\n\nAdvertisement Data objects are registered freely and then referenced by BlueZ\nwhen constructing the data sent to the kernel.\n\n","Api":[{"Title":"LE Advertisement Data hierarchy","Description":"\nSpecifies the Advertisement Data to be broadcast and some advertising\nparameters. Properties which are not present will not be included in the\ndata. Required advertisement data types will always be included.\nAll UUIDs are 128-bit versions in the API, and 16 or 32-bit\nversions of the same UUID will be used in the advertising data as appropriate.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisement1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tremoves the Advertisement. A client can use it to do\n\t\t\tcleanup tasks. There is no need to call\n\t\t\tUnregisterAdvertisement because when this method gets\n\t\t\tcalled it has already been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"Determines the type of advertising packet requested.\n\n\t\t\tPossible values: \"broadcast\" or \"peripheral\"","Flags":[]},{"Name":"ServiceUUIDs","Type":"array{string}","Docs":"List of UUIDs to include in the \"Service UUID\" field of\n\t\t\tthe Advertising Data.","Flags":[]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufactuer Data fields to include in\n\t\t\tthe Advertising Data. Keys are the Manufacturer ID\n\t\t\tto associate with the data.","Flags":[]},{"Name":"SolicitUUIDs","Type":"array{string}","Docs":"Array of UUIDs to include in \"Service Solicitation\"\n\t\t\tAdvertisement Data.","Flags":[]},{"Name":"ServiceData","Type":"dict","Docs":"Service Data elements to include. The keys are the\n\t\t\tUUID to associate with the data.","Flags":[]},{"Name":"Data","Type":"dict","Docs":"Advertising Type to include in the Advertising\n\t\t\tData. Key is the advertising type and value is the\n\t\t\tdata as byte array.\n\n\t\t\tNote: Types already handled by other properties shall\n\t\t\tnot be used.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[4]},{"Name":"Discoverable","Type":"bool","Docs":"Advertise as general discoverable. When present this\n\t\t\twill override adapter Discoverable property.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"DiscoverableTimeout","Type":"uint16","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"Includes","Type":"array{string}","Docs":"List of features to be included in the advertising\n\t\t\tpacket.\n\n\t\t\tPossible values: as found on\n\t\t\t\t\tLEAdvertisingManager.SupportedIncludes","Flags":[]},{"Name":"LocalName","Type":"string","Docs":"Local name to be used in the advertising report. If the\n\t\t\tstring is too big to fit into the packet it will be\n\t\t\ttruncated.\n\n\t\t\tIf this property is available 'local-name' cannot be\n\t\t\tpresent in the Includes.","Flags":[]},{"Name":"Appearance","Type":"uint16","Docs":"Appearance to be used in the advertising report.\n\n\t\t\tPossible values: as found on GAP Service.","Flags":[]},{"Name":"Duration","Type":"uint16_t","Docs":"Duration of the advertisement in seconds. If there are\n\t\t\tother applications advertising no duration is set the\n\t\t\tdefault is 2 seconds.","Flags":[]},{"Name":"Timeout","Type":"uint16_t","Docs":"Timeout of the advertisement in seconds. This defines\n\t\t\tthe lifetime of the advertisement.","Flags":[]},{"Name":"SecondaryChannel","Type":"string","Docs":"Secondary channel to be used. Primary channel is\n\t\t\talways set to \"1M\" except when \"Coded\" is set.\n\n\t\t\tPossible value: \"1M\" (default)\n\t\t\t\t\t\"2M\"\n\t\t\t\t\t\"Coded\"","Flags":[4]}]},{"Title":"LE Advertising Manager hierarchy","Description":"\nThe Advertising Manager allows external applications to register Advertisement\nData which should be broadcast to devices. Advertisement Data elements must\nfollow the API for LE Advertisement Data described above.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisingManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters an advertisement object to be sent over the LE\n\t\t\tAdvertising channel. The service must be exported\n\t\t\tunder interface LEAdvertisement1.\n\t\t\tInvalidArguments error indicates that the object has\n\t\t\tinvalid or conflicting properties.\n\t\t\tInvalidLength error indicates that the data\n\t\t\tprovided generates a data packet which is too long.\n\t\t\tThe properties of this object are parsed when it is\n\t\t\tregistered, and any changes are ignored.\n\t\t\tIf the same object is registered twice it will result in\n\t\t\tan AlreadyExists error.\n\t\t\tIf the maximum number of advertisement instances is\n\t\t\treached it will result in NotPermitted error.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.InvalidLength\n\t\t\t\t\t org.bluez.Error.NotPermitted\n"},{"Name":"UnregisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters an advertisement that has been\n\t\t\tpreviously registered. The object path parameter must\n\t\t\tmatch the same value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"ActiveInstances","Type":"byte","Docs":"Number of active advertising instances.","Flags":[]},{"Name":"SupportedInstances","Type":"byte","Docs":"Number of available advertising instances.","Flags":[]},{"Name":"SupportedIncludes","Type":"array{string}","Docs":"List of supported system includes.\n\n\t\t\tPossible values: \"tx-power\"\n\t\t\t\t\t \"appearance\"\n\t\t\t\t\t \"local-name\"","Flags":[]},{"Name":"SupportedSecondaryChannels","Type":"array{string}","Docs":"List of supported Secondary channels. Secondary\n\t\t\tchannels can be used to advertise with the\n\t\t\tcorresponding PHY.\n\n\t\t\tPossible values: \"1M\"\n\t\t\t\t\t \"2M\"\n\t\t\t\t\t \"Coded\"","Flags":[4]}]}]},{"FileName":"agent-api.txt","Name":"BlueZ D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AgentManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"},{"Type":"string","Name":"capability"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers an agent handler.\n\t\t\tThe object path defines the path of the agent\n\t\t\tthat will be called when user input is needed.\n\t\t\tEvery application can register its own agent and\n\t\t\tfor all actions triggered by that application its\n\t\t\tagent is used.\n\t\t\tIt is not required by an application to register\n\t\t\tan agent. If an application does chooses to not\n\t\t\tregister an agent, the default agent is used. This\n\t\t\tis on most cases a good idea. Only application\n\t\t\tlike a pairing wizard should register their own\n\t\t\tagent.\n\t\t\tAn application can only register one agent. Multiple\n\t\t\tagents per application is not supported.\n\t\t\tThe capability parameter can have the values\n\t\t\t\"DisplayOnly\", \"DisplayYesNo\", \"KeyboardOnly\",\n\t\t\t\"NoInputNoOutput\" and \"KeyboardDisplay\" which\n\t\t\treflects the input and output capabilities of the\n\t\t\tagent.\n\t\t\tIf an empty string is used it will fallback to\n\t\t\t\"KeyboardDisplay\".\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"},{"Name":"RequestDefaultAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis requests is to make the application agent\n\t\t\tthe default agent. The application is required\n\t\t\tto register an agent.\n\t\t\tSpecial permission might be required to become\n\t\t\tthe default agent.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"RequestPinCode","ReturnType":"string","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a string of 1-16 characters\n\t\t\tlength. The string can be alphanumeric.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPinCode","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"pincode"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a pincode for an authentication.\n\t\t\tAn empty reply should be returned. When the pincode\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tThis is used during the pairing process of keyboards\n\t\t\tthat don't support Bluetooth 2.1 Secure Simple Pairing,\n\t\t\tin contrast to DisplayPasskey which is used for those\n\t\t\tthat do.\n\t\t\tThis method will only ever be called once since\n\t\t\tolder keyboards do not support typing notification.\n\t\t\tNote that the PIN will always be a 6-digit number,\n\t\t\tzero-padded to 6 digits. This is for harmony with\n\t\t\tthe later specification.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestPasskey","ReturnType":"uint32","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a numeric value\n\t\t\tbetween 0-999999.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPasskey","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"},{"Type":"uint16","Name":"entered"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a passkey for an authentication.\n\t\t\tThe entered parameter indicates the number of already\n\t\t\ttyped keys on the remote side.\n\t\t\tAn empty reply should be returned. When the passkey\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tDuring the pairing process this method might be\n\t\t\tcalled multiple times to update the entered value.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n"},{"Name":"RequestConfirmation","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to confirm a passkey for an authentication.\n\t\t\tTo confirm the value it should return an empty reply\n\t\t\tor an error in case the passkey is invalid.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestAuthorization","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called to request the user to\n\t\t\tauthorize an incoming pairing attempt which\n\t\t\twould in other circumstances trigger the just-works\n\t\t\tmodel, or when the user plugged in a device that\n\t\t\timplements cable pairing. In the latter case, the\n\t\t\tdevice would not be connected to the adapter via\n\t\t\tBluetooth yet.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"AuthorizeService","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to authorize a connection/service request.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"battery-api.txt","Name":"BlueZ D-Bus Battery API description","Description":"\n","Api":[{"Title":"Battery hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Battery1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Percentage","Type":"byte","Docs":"The percentage of battery left as an unsigned 8-bit integer.","Flags":[]}]}]},{"FileName":"device-api.txt","Name":"BlueZ D-Bus Device API description","Description":"\n","Api":[{"Title":"Device hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Device1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis is a generic method to connect any profiles\n\t\t\tthe remote device supports that can be connected\n\t\t\tto and have been flagged as auto-connectable on\n\t\t\tour side. If only subset of profiles is already\n\t\t\tconnected it will try to connect currently disconnected\n\t\t\tones.\n\t\t\tIf at least one profile was connected successfully this\n\t\t\tmethod will indicate success.\n\t\t\tFor dual-mode devices only one bearer is connected at\n\t\t\ttime, the conditions are in the following order:\n\t\t\t\t1. Connect the disconnected bearer if already\n\t\t\t\tconnected.\n\t\t\t\t2. Connect first the bonded bearer. If no\n\t\t\t\tbearers are bonded or both are skip and check\n\t\t\t\tlatest seen bearer.\n\t\t\t\t3. Connect last seen bearer, in case the\n\t\t\t\ttimestamps are the same BR/EDR takes\n\t\t\t\tprecedence.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.AlreadyConnected\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tThis method gracefully disconnects all connected\n\t\t\tprofiles and then terminates low-level ACL connection.\n\t\t\tACL connection will be terminated even if some profiles\n\t\t\twere not disconnected properly e.g. due to misbehaving\n\t\t\tdevice.\n\t\t\tThis method can be also used to cancel a preceding\n\t\t\tConnect call before a reply to it has been received.\n\t\t\tFor non-trusted devices connected over LE bearer calling\n\t\t\tthis method will disable incoming connections until\n\t\t\tConnect method is called again.\n\t\t\tPossible errors: org.bluez.Error.NotConnected\n"},{"Name":"ConnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method connects a specific profile of this\n\t\t\tdevice. The UUID provided is the remote service\n\t\t\tUUID for the profile.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotAvailable\n\t\t\t\t\t org.bluez.Error.NotReady\n"},{"Name":"DisconnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method disconnects a specific profile of\n\t\t\tthis device. The profile needs to be registered\n\t\t\tclient profile.\n\t\t\tThere is no connection tracking for a profile, so\n\t\t\tas long as the profile is registered this will always\n\t\t\tsucceed.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"Pair","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method will connect to the remote device,\n\t\t\tinitiate pairing and then retrieve all SDP records\n\t\t\t(or GATT primary services).\n\t\t\tIf the application has registered its own agent,\n\t\t\tthen that specific agent will be used. Otherwise\n\t\t\tit will use the default agent.\n\t\t\tOnly for applications like a pairing wizard it\n\t\t\twould make sense to have its own agent. In almost\n\t\t\tall other cases the default agent will handle\n\t\t\tthis just fine.\n\t\t\tIn case there is no application agent and also\n\t\t\tno default agent present, this method will fail.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.AuthenticationCanceled\n\t\t\t\t\t org.bluez.Error.AuthenticationFailed\n\t\t\t\t\t org.bluez.Error.AuthenticationRejected\n\t\t\t\t\t org.bluez.Error.AuthenticationTimeout\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"CancelPairing","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis method can be used to cancel a pairing\n\t\t\toperation initiated by the Pair method.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address of the remote device.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth device Address Type. For dual-mode and\n\t\t\tBR/EDR only devices this defaults to \"public\". Single\n\t\t\tmode LE devices may have either value. If remote device\n\t\t\tuses privacy than before pairing this represents address\n\t\t\ttype used for connection and Identity Address after\n\t\t\tpairing.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth remote name. This value can not be\n\t\t\tchanged. Use the Alias property instead.\n\n\t\t\tThis value is only present for completeness. It is\n\t\t\tbetter to always use the Alias property when\n\t\t\tdisplaying the devices name.\n\n\t\t\tIf the Alias property is unset, it will reflect\n\t\t\tthis value which makes it more convenient.","Flags":[5]},{"Name":"Icon","Type":"string","Docs":"Proposed icon name according to the freedesktop.org\n\t\t\ticon naming specification.","Flags":[5]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device of the remote device.","Flags":[5]},{"Name":"Appearance","Type":"uint16","Docs":"External appearance of device, as found on GAP service.","Flags":[5]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tremote services.","Flags":[5]},{"Name":"Paired","Type":"boolean","Docs":"Indicates if the remote device is paired.","Flags":[]},{"Name":"Connected","Type":"boolean","Docs":"Indicates if the remote device is currently connected.\n\t\t\tA PropertiesChanged signal indicate changes to this\n\t\t\tstatus.","Flags":[]},{"Name":"Trusted","Type":"boolean","Docs":"Indicates if the remote is seen as trusted. This\n\t\t\tsetting can be changed by the application.","Flags":[]},{"Name":"Blocked","Type":"boolean","Docs":"If set to true any incoming connections from the\n\t\t\tdevice will be immediately rejected. Any device\n\t\t\tdrivers will also be removed and no new ones will\n\t\t\tbe probed as long as the device is blocked.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The name alias for the remote device. The alias can\n\t\t\tbe used to have a different friendly name for the\n\t\t\tremote device.\n\n\t\t\tIn case no alias is set, it will return the remote\n\t\t\tdevice name. Setting an empty string as alias will\n\t\t\tconvert it back to the remote device name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to the remote name.","Flags":[]},{"Name":"Adapter","Type":"object","Docs":"The object path of the adapter the device belongs to.","Flags":[]},{"Name":"LegacyPairing","Type":"boolean","Docs":"Set to true if the device only supports the pre-2.1\n\t\t\tpairing mechanism. This property is useful during\n\t\t\tdevice discovery to anticipate whether legacy or\n\t\t\tsimple pairing will occur if pairing is initiated.\n\n\t\t\tNote that this property can exhibit false-positives\n\t\t\tin the case of Bluetooth 2.1 (or newer) devices that\n\t\t\thave disabled Extended Inquiry Response support.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Remote Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"RSSI","Type":"int16","Docs":"Received Signal Strength Indicator of the remote\n\t\t\tdevice (inquiry or advertising).","Flags":[5]},{"Name":"TxPower","Type":"int16","Docs":"Advertised transmitted power level (inquiry or\n\t\t\tadvertising).","Flags":[5]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufacturer specific advertisement data. Keys are\n\t\t\t16 bits Manufacturer ID followed by its byte array\n\t\t\tvalue.","Flags":[5]},{"Name":"ServiceData","Type":"dict","Docs":"Service advertisement data. Keys are the UUIDs in\n\t\t\tstring format followed by its byte array value.","Flags":[5]},{"Name":"ServicesResolved","Type":"bool","Docs":"Indicate whether or not service discovery has been\n\t\t\tresolved.","Flags":[]},{"Name":"AdvertisingFlags","Type":"array{byte}","Docs":"The Advertising Data Flags of the remote device.","Flags":[]},{"Name":"AdvertisingData","Type":"dict","Docs":"The Advertising Data of the remote device. Keys are\n\t\t\tare 8 bits AD Type followed by data as byte array.\n\n\t\t\tNote: Only types considered safe to be handled by\n\t\t\tapplication are exposed.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[]}]}]},{"FileName":"gatt-api.txt","Name":"BlueZ D-Bus GATT API description","Description":"GATT local and remote services share the same high-level D-Bus API. Local\nrefers to GATT based service exported by a BlueZ plugin or an external\napplication. Remote refers to GATT services exported by the peer.\n\nBlueZ acts as a proxy, translating ATT operations to D-Bus method calls and\nProperties (or the opposite). Support for D-Bus Object Manager is mandatory for\nexternal services to allow seamless GATT declarations (Service, Characteristic\nand Descriptors) discovery. Each GATT service tree is required to export a D-Bus\nObject Manager at its root that is solely responsible for the objects that\nbelong to that service.\n\nReleasing a registered GATT service is not defined yet. Any API extension\nshould avoid breaking the defined API, and if possible keep an unified GATT\nremote and local services representation.\n\n","Api":[{"Title":"Service hierarchy","Description":"\nGATT remote and local service representation. Object path for local services\nis freely definable.\n\nExternal applications implementing local services must register the services\nusing GattManager1 registration method and must implement the methods and\nproperties defined in GattService1 interface.\n","Service":"org.bluez","Interface":"org.bluez.GattService1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX","Methods":[],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit service UUID.","Flags":[1]},{"Name":"Primary","Type":"boolean","Docs":"Indicates whether or not this GATT service is a\n\t\t\tprimary service. If false, the service is secondary.","Flags":[1]},{"Name":"Device","Type":"object","Docs":"Object path of the Bluetooth device the service\n\t\t\tbelongs to. Only present on services from remote\n\t\t\tdevices.","Flags":[1,5]},{"Name":"Includes","Type":"array{object}","Docs":"Array of object paths representing the included\n\t\t\tservices of this service.","Flags":[1,5]},{"Name":"Handle","Type":"uint16","Docs":"Service handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic hierarchy","Description":"\nFor local GATT defined services, the object paths need to follow the service\npath hierarchy and are freely definable.\n","Service":"org.bluez","Interface":"org.bluez.GattCharacteristic1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": uint16 offset\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Object Device (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.InvalidOffset\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"type\": string\n\t\t\t\t\t\tPossible values:\n\t\t\t\t\t\t\"command\": Write without\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\"request\": Write with response\n\t\t\t\t\t\t\"reliable\": Reliable Write\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": True if prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireWrite","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for writing. Only\n\t\t\tsockets are supported. Usage of WriteValue will be\n\t\t\tlocked causing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tFor client it only works with characteristic that has\n\t\t\tWriteAcquired property which relies on\n\t\t\twrite-without-response Flag.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireNotify","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for notify. Only\n\t\t\tsockets are support. Usage of StartNotify will be locked\n\t\t\tcausing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tOnly works with characteristic that has NotifyAcquired\n\t\t\twhich relies on notify Flag and no other client have\n\t\t\tcalled StartNotify.\n\t\t\tNotification are enabled during this procedure so\n\t\t\tStartNotify shall not be called, any notification\n\t\t\twill be dispatched via file descriptor therefore the\n\t\t\tValue property is not affected during the time where\n\t\t\tnotify has been acquired.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StartNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tStarts a notification session from this characteristic\n\t\t\tif it supports value notifications or indications.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StopNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method will cancel any previous StartNotify\n\t\t\ttransaction. Note that notifications from a\n\t\t\tcharacteristic are shared between sessions thus\n\t\t\tcalling StopNotify will release a single session.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"},{"Name":"Confirm","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method doesn't expect a reply so it is just a\n\t\t\tconfirmation that value was received.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit characteristic UUID.","Flags":[1]},{"Name":"Service","Type":"object","Docs":"Object path of the GATT service the characteristic\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the characteristic. This property\n\t\t\tgets updated only after a successful read request and\n\t\t\twhen a notification or indication is received, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"WriteAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireWrite.\n\n\t\t\tFor client properties is ommited in case\n\t\t\t'write-without-response' flag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireWrite is supported.","Flags":[1,5]},{"Name":"NotifyAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireNotify.\n\n\t\t\tFor client this properties is ommited in case 'notify'\n\t\t\tflag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireNotify is supported.","Flags":[1,5]},{"Name":"Notifying","Type":"boolean","Docs":"True, if notifications or indications on this\n\t\t\tcharacteristic are currently enabled.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the characteristic value can be used. See\n\t\t\tCore spec \"Table 3.5: Characteristic Properties bit\n\t\t\tfield\", and \"Table 3.8: Characteristic Extended\n\t\t\tProperties bit field\". Allowed values:\n\n\t\t\t\t\"broadcast\"\n\t\t\t\t\"read\"\n\t\t\t\t\"write-without-response\"\n\t\t\t\t\"write\"\n\t\t\t\t\"notify\"\n\t\t\t\t\"indicate\"\n\t\t\t\t\"authenticated-signed-writes\"\n\t\t\t\t\"extended-properties\"\n\t\t\t\t\"reliable-write\"\n\t\t\t\t\"writable-auxiliaries\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server only)\n\t\t\t\t\"secure-write\" (Server only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic Descriptors hierarchy","Description":"\nLocal or remote GATT characteristic descriptors hierarchy.\n","Service":"org.bluez","Interface":"org.bluez.GattDescriptor1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": boolean Is prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit descriptor UUID.","Flags":[1]},{"Name":"Characteristic","Type":"object","Docs":"Object path of the GATT characteristic the descriptor\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the descriptor. This property\n\t\t\tgets updated only after a successful read request, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the descriptor value can be used.\n\n\t\t\tPossible values:\n\n\t\t\t\t\"read\"\n\t\t\t\t\"write\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server Only)\n\t\t\t\t\"secure-write\" (Server Only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"GATT Profile hierarchy","Description":"\nLocal profile (GATT client) instance. By registering this type of object\nan application effectively indicates support for a specific GATT profile\nand requests automatic connections to be established to devices\nsupporting it.\n","Service":"\u003capplication dependent\u003e","Interface":"org.bluez.GattProfile1","ObjectPath":"\u003capplication dependent\u003e","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. The profile can use it to\n\t\t\tdo cleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUIDs","Type":"array{string}","Docs":"128-bit GATT service UUIDs to auto connect.","Flags":[1]}]},{"Title":"GATT Manager hierarchy","Description":"\nGATT Manager allows external applications to register GATT services and\nprofiles.\n\nRegistering a profile allows applications to subscribe to *remote* services.\nThese must implement the GattProfile1 interface defined above.\n\nRegistering a service allows applications to publish a *local* GATT service,\nwhich then becomes available to remote devices. A GATT service is represented by\na D-Bus object hierarchy where the root node corresponds to a service and the\nchild nodes represent characteristics and descriptors that belong to that\nservice. Each node must implement one of GattService1, GattCharacteristic1,\nor GattDescriptor1 interfaces described above, based on the attribute it\nrepresents. Each node must also implement the standard D-Bus Properties\ninterface to expose their properties. These objects collectively represent a\nGATT service definition.\n\nTo make service registration simple, BlueZ requires that all objects that belong\nto a GATT service be grouped under a D-Bus Object Manager that solely manages\nthe objects of that service. Hence, the standard DBus.ObjectManager interface\nmust be available on the root service path. An example application hierarchy\ncontaining two separate GATT services may look like this:\n\n-\u003e /com/example\n | - org.freedesktop.DBus.ObjectManager\n |\n -\u003e /com/example/service0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattService1\n | |\n | -\u003e /com/example/service0/char0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1/desc0\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattDescriptor1\n |\n -\u003e /com/example/service1\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattService1\n |\n -\u003e /com/example/service1/char0\n - org.freedesktop.DBus.Properties\n - org.bluez.GattCharacteristic1\n\nWhen a service is registered, BlueZ will automatically obtain information about\nall objects using the service's Object Manager. Once a service has been\nregistered, the objects of a service should not be removed. If BlueZ receives an\nInterfacesRemoved signal from a service's Object Manager, it will immediately\nunregister the service. Similarly, if the application disconnects from the bus,\nall of its registered services will be automatically unregistered.\nInterfacesAdded signals will be ignored.\n\nExamples:\n\t- Client\n\t\ttest/example-gatt-client\n\t\tclient/bluetoothctl\n\t- Server\n\t\ttest/example-gatt-server\n\t\ttools/gatt-service\n\n","Service":"org.bluez","Interface":"org.bluez.GattManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a local GATT services hierarchy as described\n\t\t\tabove (GATT Server) and/or GATT profiles (GATT Client).\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering a GATT based\n\t\t\tservice or profile.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]}]},{"FileName":"health-api.txt","Name":"BlueZ D-Bus Health API description","Description":"\n","Api":[{"Title":"HealthManager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthManager1","ObjectPath":"/org/bluez/","Methods":[{"Name":"CreateApplication","ReturnType":"object","Args":[{"Type":"dict","Name":"config"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturns the path of the new registered application.\n\t\t\tApplication will be closed by the call or implicitly\n\t\t\twhen the programs leaves the bus.\n\t\t\tconfig:\n\t\t\t\tuint16 DataType:\n\t\t\t\t\tMandatory\n\t\t\t\tstring Role:\n\t\t\t\t\tMandatory. Possible values: \"source\",\n\t\t\t\t\t\t\t\t\t\"sink\"\n\t\t\t\tstring Description:\n\t\t\t\t\tOptional\n\t\t\t\tChannelType:\n\t\t\t\t\tOptional, just for sources. Possible\n\t\t\t\t\tvalues: \"reliable\", \"streaming\"\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DestroyApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCloses the HDP application identified by the object\n\t\t\tpath. Also application will be closed if the process\n\t\t\tthat started it leaves the bus. Only the creator of the\n\t\t\tapplication will be able to destroy it.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[]},{"Title":"HealthDevice hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthDevice1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Echo","ReturnType":"boolean","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tSends an echo petition to the remote service. Returns\n\t\t\tTrue if response matches with the buffer sent. If some\n\t\t\terror is detected False value is returned.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.OutOfRange\n"},{"Name":"CreateChannel","ReturnType":"object","Args":[{"Type":"object","Name":"application"},{"Type":"string","Name":"configuration"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCreates a new data channel. The configuration should\n\t\t\tindicate the channel quality of service using one of\n\t\t\tthis values \"reliable\", \"streaming\", \"any\".\n\t\t\tReturns the object path that identifies the data\n\t\t\tchannel that is already connected.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.HealthError\n"},{"Name":"DestroyChannel","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDestroys the data channel object. Only the creator of\n\t\t\tthe channel or the creator of the HealthApplication\n\t\t\tthat received the data channel will be able to destroy\n\t\t\tit.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[{"Name":"ChannelConnected","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a new data channel is\n\t\t\tcreated or when a known data channel is reconnected.\n\n"},{"Name":"ChannelDeleted","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a data channel is deleted.\n\n\t\t\tAfter this signal the data channel path will not be\n\t\t\tvalid and its path can be reused for future data\n\t\t\tchannels."}],"Properties":[{"Name":"MainChannel","Type":"object","Docs":"The first reliable channel opened. It is needed by\n\t\t\tupper applications in order to send specific protocol\n\t\t\tdata units. The first reliable can change after a\n\t\t\treconnection.","Flags":[]}]},{"Title":"HealthChannel hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthChannel1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/chanZZZ","Methods":[{"Name":"Acquire","ReturnType":"fd","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tReturns the file descriptor for this data channel. If\n\t\t\tthe data channel is not connected it will also\n\t\t\treconnect.\n\t\t\tPossible Errors: org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotAcquired","org.bluez.Error.NotAcquired"],"Docs":"\t\t\tReleases the fd. Application should also need to\n\t\t\tclose() it.\n\t\t\tPossible Errors: org.bluez.Error.NotAcquired\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The quality of service of the data channel. (\"reliable\"\n\t\t\tor \"streaming\")","Flags":[]},{"Name":"Device","Type":"object","Docs":"Identifies the Remote Device that is connected with.\n\t\t\tMaps with a HealthDevice object.","Flags":[]},{"Name":"Application","Type":"object","Docs":"Identifies the HealthApplication to which this channel\n\t\t\tis related to (which indirectly defines its role and\n\t\t\tdata type).","Flags":[]}]}]},{"FileName":"input-api.txt","Name":"BlueZ D-Bus Input API description","Description":"","Api":[{"Title":"Input hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Input1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"ReconnectMode","Type":"string","Docs":"Determines the Connectability mode of the HID device as\n\t\t\tdefined by the HID Profile specification, Section 5.4.2.\n\n\t\t\tThis mode is based in the two properties\n\t\t\tHIDReconnectInitiate (see Section 5.3.4.6) and\n\t\t\tHIDNormallyConnectable (see Section 5.3.4.14) which\n\t\t\tdefine the following four possible values:\n\n\t\t\t\"none\"\t\tDevice and host are not required to\n\t\t\t\t\tautomatically restore the connection.\n\n\t\t\t\"host\"\t\tBluetooth HID host restores connection.\n\n\t\t\t\"device\"\tBluetooth HID device restores\n\t\t\t\t\tconnection.\n\n\t\t\t\"any\"\t\tBluetooth HID device shall attempt to\n\t\t\t\t\trestore the lost connection, but\n\t\t\t\t\tBluetooth HID Host may also restore the\n\t\t\t\t\tconnection.","Flags":[]}]}]},{"FileName":"media-api.txt","Name":"BlueZ D-Bus Media API description","Description":"\n","Api":[{"Title":"Media hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Media1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a local end point to sender, the sender can\n\t\t\tregister as many end points as it likes.\n\t\t\tNote: If the sender disconnects the end points are\n\t\t\tautomatically unregistered.\n\t\t\tpossible properties:\n\t\t\t\tstring UUID:\n\t\t\t\t\tUUID of the profile which the endpoint\n\t\t\t\t\tis for.\n\t\t\t\tbyte Codec:\n\t\t\t\t\tAssigned number of codec that the\n\t\t\t\t\tendpoint implements. The values should\n\t\t\t\t\tmatch the profile specification which\n\t\t\t\t\tis indicated by the UUID.\n\t\t\t\tarray{byte} Capabilities:\n\t\t\t\t\tCapabilities blob, it is used as it is\n\t\t\t\t\tso the size and byte order must match.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported - emitted\n\t\t\t\t\t when interface for the end-point is\n\t\t\t\t\t disabled.\n"},{"Name":"UnregisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"}],"Errors":null,"Docs":"\t\t\tUnregister sender end point.\n"},{"Name":"RegisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a media player object to sender, the sender\n\t\t\tcan register as many objects as it likes.\n\t\t\tObject must implement at least\n\t\t\torg.mpris.MediaPlayer2.Player as defined in MPRIS 2.2\n\t\t\tspec:\n\t\t\thttp://specifications.freedesktop.org/mpris-spec/latest/\n\t\t\tNote: If the sender disconnects its objects are\n\t\t\tautomatically unregistered.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"UnregisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"}],"Errors":null,"Docs":"\t\t\tUnregister sender media player.\n"},{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"root"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister endpoints an player objects within root\n\t\t\tobject which must implement ObjectManager.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Media Control hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaControl1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume playback.\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPause playback.\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStop playback.\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tNext item.\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPrevious item.\n"},{"Name":"VolumeUp","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step up\n"},{"Name":"VolumeDown","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step down\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"","Flags":[]},{"Name":"Player","Type":"object","Docs":"Addressed Player object path.","Flags":[5]}]},{"Title":"MediaPlayer1 hierarchy","Description":"","Service":"org.bluez (Controller role)","Interface":"org.bluez.MediaPlayer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tResume playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPause playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tStop playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tNext item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPrevious item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Equalizer","Type":"string","Docs":"Possible values: \"off\" or \"on\"","Flags":[]},{"Name":"Repeat","Type":"string","Docs":"Possible values: \"off\", \"singletrack\", \"alltracks\" or\n\t\t\t\t\t\"group\"","Flags":[]},{"Name":"Shuffle","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Scan","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Status","Type":"string","Docs":"Possible status: \"playing\", \"stopped\", \"paused\",\n\t\t\t\t\t\"forward-seek\", \"reverse-seek\"\n\t\t\t\t\tor \"error\"","Flags":[]},{"Name":"Position","Type":"uint32","Docs":"Playback position in milliseconds. Changing the\n\t\t\tposition may generate additional events that will be\n\t\t\tsent to the remote device. When position is 0 it means\n\t\t\tthe track is starting and when it's greater than or\n\t\t\tequal to track's duration the track has ended. Note\n\t\t\tthat even if duration is not available in metadata it's\n\t\t\tpossible to signal its end by setting position to the\n\t\t\tmaximum uint32 value.","Flags":[]},{"Name":"Track","Type":"dict","Docs":"Track metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title:","Type":"string","Docs":"Track title name","Flags":[]},{"Name":"Artist:","Type":"string","Docs":"Track artist name","Flags":[]},{"Name":"Album:","Type":"string","Docs":"Track album name","Flags":[]},{"Name":"Genre:","Type":"string","Docs":"Track genre name","Flags":[]},{"Name":"NumberOfTracks:","Type":"uint32","Docs":"Number of tracks in total","Flags":[]},{"Name":"TrackNumber:","Type":"uint32","Docs":"Track number","Flags":[]},{"Name":"Duration:","Type":"uint32","Docs":"Track duration in milliseconds","Flags":[]},{"Name":"Device","Type":"object","Docs":"Device object path.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Player name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Player type\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio\"\n\t\t\t\t\"Video\"\n\t\t\t\t\"Audio Broadcasting\"\n\t\t\t\t\"Video Broadcasting\"","Flags":[]},{"Name":"Subtype","Type":"string","Docs":"Player subtype\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio Book\"\n\t\t\t\t\"Podcast\"","Flags":[]},{"Name":"Browsable","Type":"boolean","Docs":"If present indicates the player can be browsed using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Searchable","Type":"boolean","Docs":"If present indicates the player can be searched using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Playlist","Type":"object","Docs":"Playlist object path.","Flags":[]}]},{"Title":"MediaFolder1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaFolder1","ObjectPath":"freely definable (Target role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX\n\t\t(Controller role)","Methods":[{"Name":"Search","ReturnType":"object","Args":[{"Type":"string","Name":"value"},{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tReturn a folder object containing the search result.\n\t\t\tTo list the items found use the folder object returned\n\t\t\tand pass to ChangeFolder.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ListItems","ReturnType":"array{objects, properties}","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturn a list of items found\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"object","Name":"folder"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tChange current folder.\n\t\t\tNote: By changing folder the items of previous folder\n\t\t\tmight be destroyed and have to be listed again, the\n\t\t\texception is NowPlaying folder which should be always\n\t\t\tpresent while the player is active.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"NumberOfItems","Type":"uint32","Docs":"Number of items in the folder","Flags":[]},{"Name":"Name","Type":"string","Docs":"Folder name:\n\n\t\t\tPossible values:\n\t\t\t\t\"/Filesystem/...\": Filesystem scope\n\t\t\t\t\"/NowPlaying/...\": NowPlaying scope\n\n\t\t\tNote: /NowPlaying folder might not be listed if player\n\t\t\tis stopped, folders created by Search are virtual so\n\t\t\tonce another Search is perform or the folder is\n\t\t\tchanged using ChangeFolder it will no longer be listed.\n\nFilters","Flags":[]},{"Name":"Start:","Type":"uint32","Docs":"Offset of the first item.\n\n\t\t\tDefault value: 0","Flags":[]},{"Name":"End:","Type":"uint32","Docs":"Offset of the last item.\n\n\t\t\tDefault value: NumbeOfItems","Flags":[]},{"Name":"Attributes","Type":"array{string}","Docs":"Item properties that should be included in the list.\n\n\t\t\tPossible Values:\n\n\t\t\t\t\"title\", \"artist\", \"album\", \"genre\",\n\t\t\t\t\"number-of-tracks\", \"number\", \"duration\"\n\n\t\t\tDefault Value: All","Flags":[]}]},{"Title":"MediaItem1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaItem1","ObjectPath":"freely definable (Target role)\n\t\t[variable\n\t\tprefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX\n\t\t(Controller role)","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPlay item\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"AddtoNowPlaying","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tAdd item to now playing list\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Player","Type":"object","Docs":"Player object path the item belongs to","Flags":[]},{"Name":"Name","Type":"string","Docs":"Item displayable name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Item type\n\n\t\t\tPossible values: \"video\", \"audio\", \"folder\"","Flags":[]},{"Name":"FolderType","Type":"string","Docs":"Folder type.\n\n\t\t\tPossible values: \"mixed\", \"titles\", \"albums\", \"artists\"\n\n\t\t\tAvailable if property Type is \"Folder\"","Flags":[5]},{"Name":"Playable","Type":"boolean","Docs":"Indicates if the item can be played\n\n\t\t\tAvailable if property Type is \"folder\"","Flags":[5]},{"Name":"Metadata","Type":"dict","Docs":"Item metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title","Type":"string","Docs":"Item title name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Artist","Type":"string","Docs":"Item artist name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Album","Type":"string","Docs":"Item album name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Genre","Type":"string","Docs":"Item genre name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"NumberOfTracks","Type":"uint32","Docs":"Item album number of tracks in total\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Number","Type":"uint32","Docs":"Item album number\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Duration","Type":"uint32","Docs":"Item duration in milliseconds\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]}]},{"Title":"MediaEndpoint1 hierarchy","Description":"","Service":"unique name (Server role)\n\t\torg.bluez (Client role)","Interface":"org.bluez.MediaEndpoint1","ObjectPath":"freely definable (Server role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX\n\t\t(Client role)","Methods":[{"Name":"SetConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"},{"Type":"dict","Name":"properties"}],"Errors":null,"Docs":"\t\t\tSet configuration for the transport.\n\t\t\tFor client role transport must be set with a server\n\t\t\tendpoint oject which will be configured and the\n\t\t\tproperties must contain the following properties:\n\t\t\t\tarray{byte} Capabilities\n"},{"Name":"SelectConfiguration","ReturnType":"array{byte}","Args":[{"Type":"array{byte}","Name":"capabilities"}],"Errors":null,"Docs":"\t\t\tSelect preferable configuration from the supported\n\t\t\tcapabilities.\n\t\t\tReturns a configuration which can be used to setup\n\t\t\ta transport.\n\t\t\tNote: There is no need to cache the selected\n\t\t\tconfiguration since on success the configuration is\n\t\t\tsend back as parameter of SetConfiguration.\n"},{"Name":"ClearConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"}],"Errors":null,"Docs":"\t\t\tClear transport configuration.\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the endpoint. An endpoint can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tendpoint, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the endpoint is for.","Flags":[5]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the endpoint implements.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[5]},{"Name":"Capabilities","Type":"array{byte}","Docs":"Capabilities blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[5]},{"Name":"Device","Type":"object","Docs":"Device object which the endpoint is belongs to.","Flags":[5]}]},{"Title":"MediaTransport1 hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaTransport1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX","Methods":[{"Name":"Acquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAuthorized","org.bluez.Error.NotAuthorized"],"Docs":"\t\t\tAcquire transport file descriptor and the MTU for read\n\t\t\tand write respectively.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"TryAcquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAvailable","org.bluez.Error.NotAvailable"],"Docs":"\t\t\tAcquire transport file descriptor only if the transport\n\t\t\tis in \"pending\" state at the time the message is\n\t\t\treceived by BlueZ. Otherwise no request will be sent\n\t\t\tto the remote device and the function will just fail\n\t\t\twith org.bluez.Error.NotAvailable.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAvailable\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tReleases file descriptor.\n"}],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"Device object which the transport is connected to.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the transport is for.","Flags":[]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the transport support.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[]},{"Name":"Configuration","Type":"array{byte}","Docs":"Configuration blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[]},{"Name":"State","Type":"string","Docs":"Indicates the state of the transport. Possible\n\t\t\tvalues are:\n\t\t\t\t\"idle\": not streaming\n\t\t\t\t\"pending\": streaming but not acquired\n\t\t\t\t\"active\": streaming and acquired","Flags":[]},{"Name":"Delay","Type":"uint16","Docs":"Optional. Transport delay in 1/10 of millisecond, this\n\t\t\tproperty is only writeable when the transport was\n\t\t\tacquired by the sender.","Flags":[]},{"Name":"Volume","Type":"uint16","Docs":"Optional. Indicates volume level of the transport,\n\t\t\tthis property is only writeable when the transport was\n\t\t\tacquired by the sender.\n\n\t\t\tPossible Values: 0-127","Flags":[]},{"Name":"Endpoint","Type":"object","Docs":"Endpoint object which the transport is associated\n\t\t\twith.","Flags":[5]}]}]},{"FileName":"mesh-api.txt","Name":"BlueZ D-Bus Mesh API description","Description":"","Api":[{"Title":"Mesh Network Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Network1","ObjectPath":"/org/bluez/mesh","Methods":[{"Name":"Join","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application has to call to\n\t\tbecome a provisioned node on a mesh network. The call will\n\t\tinitiate broadcasting of Unprovisioned Device Beacon.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The application hierarchy\n\t\talso contains a provision agent object that implements\n\t\torg.bluez.mesh.ProvisionAgent1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Cancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"Attach","ReturnType":"object node, array{byte, array{(uint16, dict)}} configuration","Args":[{"Type":"object","Name":"app_root"},{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis is the first method that an application must call to get\n\t\taccess to mesh node functionalities.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe token parameter is a 64-bit number that has been assigned to\n\t\tthe application when it first got provisioned/joined mesh\n\t\tnetwork, i.e. upon receiving JoinComplete() method. The daemon\n\t\tuses the token to verify whether the application is authorized\n\t\tto assume the mesh node identity.\n\t\tIn case of success, the method call returns mesh node object\n\t\t(see Mesh Node Hierarchy section) and current configuration\n\t\tsettings. The return value of configuration parameter is an\n\t\tarray, where each entry is a structure that contains element\n\t\tconfiguration. The element configuration structure is organized\n\t\tas follows:\n\t\tbyte\n\t\t\tElement index, identifies the element to which this\n\t\t\tconfiguration entry pertains.\n\t\tarray{struct}\n\t\t\tModels array where each entry is a structure with the\n\t\t\tfollowing members:\n\t\t\tuint16\n\t\t\t\tEither a SIG Model Identifier or, if Vendor key\n\t\t\t\tis present in model configuration dictionary, a\n\t\t\t\t16-bit vendor-assigned Model Identifier\n\t\t\tdict\n\t\t\t\tA dictionary that contains model configuration\n\t\t\t\twith the following keys defined:\n\t\t\t\tarray{uint16} Bindings\n\t\t\t\t\tIndices of application keys bound to the\n\t\t\t\t\tmodel\n\t\t\t\tuint32 PublicationPeriod\n\t\t\t\t\tModel publication period in milliseconds\n\t\t\t\tuint16 Vendor\n\t\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\t\tBluetooth SIG\n\t\t\t\tarray{variant} Subscriptions\n\t\t\t\t\tAddresses the model is subscribed to.\n\t\t\t\t\tEach address is provided either as\n\t\t\t\t\tuint16 for group addresses, or\n\t\t\t\t\tas array{byte} for virtual labels.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.Failed\n"},{"Name":"Leave","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis removes the configuration information about the mesh node\n\t\tidentified by the 64-bit token parameter. The token parameter\n\t\thas been obtained as a result of successful Join() method call.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"CreateNetwork","ReturnType":"uint64 token","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application calls to become\n\t\ta Provisioner node, and a Configuration Client on a newly\n\t\tcreated Mesh Network.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface, and a org.bluez.mesh.Provisioner1 interface. The\n\t\tapplication represents a node where child mesh elements have\n\t\ttheir own objects that implement org.bluez.mesh.Element1\n\t\tinterface. The application hierarchy also contains a provision\n\t\tagent object that implements org.bluez.mesh.ProvisionAgent1\n\t\tinterface. The standard DBus.ObjectManager interface must be\n\t\tavailable on the app_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tThe returned token must be preserved by the application in\n\t\torder to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n\t\tThe other information the bluetooth-meshd daemon will preserve\n\t\tabout the initial node, is to give it the initial primary\n\t\tunicast address (0x0001), and create and assign a net_key as the\n\t\tprimary network net_index (0x000).\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Import","ReturnType":"uint64 token","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"array{byte}[16]","Name":"dev_key"},{"Type":"array{byte}[16]","Name":"net_key"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"flags"},{"Type":"uint32","Name":"iv_index"},{"Type":"uint16","Name":"unicast"}],"Errors":null,"Docs":"\t\tThis method creates a local mesh node based on node\n\t\tconfiguration that has been generated outside bluetooth-meshd.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tThe dev_key parameter is the 16-byte value of the dev key of\n\t\tthe imported mesh node.\n\t\tRemaining parameters correspond to provisioning data:\n\t\tThe net_key and net_index parameters describe the network (or a\n\t\tsubnet, if net_index is not 0) the imported mesh node belongs\n\t\tto.\n\t\tThe flags parameter is a dictionary containing provisioning\n\t\tflags. Supported values are:\n\t\t\tboolean IVUpdate\n\t\t\t\tWhen true, indicates that the network is in the\n\t\t\t\tmiddle of IV Index Update procedure.\n\t\t\tboolean KeyRefresh\n\t\t\t\tWhen true, indicates that the specified net key\n\t\t\t\tis in the middle of a key refresh procedure.\n\t\tThe iv_index parameter is the current IV Index value used by\n\t\tthe network. This value is known by the provisioner.\n\t\tThe unicast parameter is the primary unicast address of the\n\t\timported node.\n\t\tThe returned token must be preserved by the application in\n\t\torder to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.NotSupported,\n\t\t\torg.bluez.mesh.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Node Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Node1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"Send","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"key_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe key_index parameter determines which application key to use\n\t\tfor encrypting the message. The key_index must be valid for that\n\t\telement, i.e., the application key must be bound to a model on\n\t\tthis element. Otherwise, org.bluez.mesh.Error.NotAuthorized will\n\t\tbe returned.\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tbluetooth-meshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"DevKeySend","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel encoded with the device key of the remote node.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe remote parameter, if true, looks up the device key by the\n\t\tdestination address in the key database to encrypt the message.\n\t\tIf remote is true, but requested key does not exist, a NotFound\n\t\terror will be returned. If set to false, the local node's\n\t\tdevice key is used.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddNetKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"subnet_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe subnet_index parameter refers to the subnet index of the\n\t\tnetwork that is being added or updated. This key must exist in\n\t\tthe local key database.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddAppKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"app_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe app_index parameter refers to the application key which is\n\t\tbeing added or updated. This key must exist in the local key\n\t\tdatabase.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"Publish","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"model"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a publication originated by a local\n\t\tmodel. If the model does not exist, or it has no publication\n\t\trecord, the method returns org.bluez.mesh.Error.DoesNotExist\n\t\terror.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe model parameter contains a model ID, as defined by the\n\t\tBluetooth SIG.\n\t\tSince only one Publish record may exist per element-model, the\n\t\tdestination and key_index are obtained from the Publication\n\t\trecord cached by the daemon.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"VendorPublish","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"vendor"},{"Type":"uint16","Name":"model_id"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a publication originated by a local\n\t\tvendor model. If the model does not exist, or it has no\n\t\tpublication record, the method returns\n\t\torg.bluez.mesh.Error.DoesNotExist error.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe vendor parameter is a 16-bit Bluetooth-assigned Company ID.\n\t\tThe model_id parameter is a 16-bit vendor-assigned Model\n\t\tIdentifier.\n\t\tSince only one Publish record may exist per element-model, the\n\t\tdestination and key_index are obtained from the Publication\n\t\trecord cached by the daemon.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[{"Name":"Features","Type":"dict","Docs":"The dictionary that contains information about feature support.\n\t\tThe following keys are defined:","Flags":[1]},{"Name":"Friend","Type":"boolean","Docs":"Indicates the ability to establish a friendship with a\n\t\t\tLow Power node","Flags":[]},{"Name":"LowPower","Type":"boolean","Docs":"Indicates support for operating in Low Power node mode","Flags":[]},{"Name":"Proxy","Type":"boolean","Docs":"Indicates support for GATT proxy","Flags":[]},{"Name":"Relay","Type":"boolean","Docs":"Indicates support for relaying messages\n\n\tIf a key is absent from the dictionary, the feature is not supported.\n\tOtherwise, true means that the feature is enabled and false means that\n\tthe feature is disabled.","Flags":[]},{"Name":"Beacon","Type":"boolean","Docs":"This property indicates whether the periodic beaconing is\n\t\tenabled (true) or disabled (false).\n\n\tuint8 BeaconFlags [read-only]\n\n\t\tThis property may be read at any time to determine the flag\n\t\tfield setting on sent and received beacons of the primary\n\t\tnetwork key.","Flags":[1]},{"Name":"IvIndex","Type":"uint32","Docs":"This property may be read at any time to determine the IV_Index\n\t\tthat the current network is on. This information is only useful\n\t\tfor provisioning.","Flags":[1]},{"Name":"SecondsSinceLastHeard","Type":"uint32","Docs":"This property may be read at any time to determine the number of\n\t\tseconds since mesh network layer traffic was last detected on\n\t\tthis node's network.","Flags":[1]},{"Name":"Addresses","Type":"array{uint16}","Docs":"This property contains unicast addresses of node's elements.","Flags":[1]},{"Name":"SequenceNumber","Type":"uint32","Docs":"This property may be read at any time to determine the\n\t\tsequence number.","Flags":[1]}]},{"Title":"Mesh Provisioning Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Management1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"UnprovisionedScan","ReturnType":"void","Args":[{"Type":"uint16","Name":"seconds"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to start listening\n\t\t(scanning) for unprovisioned devices in the area. Scanning\n\t\twill continue for the specified number of seconds, or, if 0 is\n\t\tspecified, then continuously until UnprovisionedScanCancel() is\n\t\tcalled or if AddNode() method is called.\n\t\tEach time a unique unprovisioned beacon is heard, the\n\t\tScanResult() method on the app will be called with the result.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"UnprovisionedScanCancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"AddNode","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to add the\n\t\tunprovisioned device specified by uuid, to the Network.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID\n\t\tof the unprovisioned device to be added to the network.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n"},{"Name":"CreateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tnetwork subnet key.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"ImportSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}[16]","Name":"net_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add a network subnet\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThe net_key parameter is the 16-byte value of the net key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"UpdateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new network\n\t\tsubnet key, and set it's key refresh state to Phase 1.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to update. Note that the subnet must\n\t\texist prior to updating.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"DeleteSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application that to delete a subnet.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to delete. The primary net key (0x000)\n\t\tmay not be deleted.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"SetKeyPhase","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint8","Name":"phase"}],"Errors":null,"Docs":"\t\tThis method is used to set the master key update phase of the\n\t\tgiven subnet. When finalizing the procedure, it is important\n\t\tto CompleteAppKeyUpdate() on all app keys that have been\n\t\tupdated during the procedure prior to setting phase 3.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which subnet phase to set.\n\t\tThe phase parameter is used to cycle the local key database\n\t\tthrough the phases as defined by the Mesh Profile Specification.\n\t\tAllowed values:\n\t\t\t0 - Cancel Key Refresh (May only be called from Phase 1,\n\t\t\t\tand should never be called once the new key has\n\t\t\t\tstarted propagating)\n\t\t\t1 - Invalid Argument (see NetKeyUpdate method)\n\t\t\t2 - Go to Phase 2 (May only be called from Phase 1)\n\t\t\t3 - Complete Key Refresh procedure (May only be called\n\t\t\t\tfrom Phase 2)\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is the responsibility of the application to maintain the key\n\t\trefresh phases per the Mesh Profile Specification.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"CreateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tapplication key.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"ImportAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"},{"Type":"array{byte}[16]","Name":"app_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add an application\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to import.\n\t\tThe app_key parameter is the 16-byte value of the key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"UpdateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new\n\t\tapplication key.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to update. Note that the subnet that\n\t\tthe key is bound to must exist and be in Phase 1.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"DeleteAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete an application\n\t\tkey.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to delete.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"ImportRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"},{"Type":"array{byte}[16]","Name":"device_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to import a remote node\n\t\tthat has been provisioned by an external process.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being imported.\n\t\tThe count parameter specifies the number of elements that are\n\t\tassigned to this remote node.\n\t\tThe device_key parameter is the access layer key that will be\n\t\twill used to decrypt privledged messages from this remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"DeleteRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete a remote node\n\t\tfrom the local device key database.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being deleted.\n\t\tThe count parameter specifies the number of elements that were\n\t\tassigned to the remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Application Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Application1","ObjectPath":"\u003capp_root\u003e","Methods":[{"Name":"JoinComplete","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby a Join() method call successfully completed.\n\t\tThe token parameter serves as a unique identifier of the\n\t\tparticular node. The token must be preserved by the application\n\t\tin order to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n"},{"Name":"JoinFailed","ReturnType":"void","Args":[{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tJoin() has failed.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"timeout\", \"bad-pdu\",\n\t\t\"confirmation-failed\", \"out-of-resources\", \"decryption-error\",\n\t\t\"unexpected-error\", \"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[{"Name":"CompanyID","Type":"uint16","Docs":"A 16-bit Bluetooth-assigned Company Identifier of the vendor as\n\t\tdefined by Bluetooth SIG","Flags":[1]},{"Name":"ProductID","Type":"uint16","Docs":"A 16-bit vendor-assigned product identifier","Flags":[1]},{"Name":"VersionID","Type":"uint16","Docs":"A 16-bit vendor-assigned product version identifier","Flags":[1]},{"Name":"CRPL","Type":"uint16","Docs":"A 16-bit minimum number of replay protection list entries","Flags":[1,5]}]},{"Title":"Mesh Element Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Element1","ObjectPath":"\u003capp_defined_element_path\u003e","Methods":[{"Name":"MessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"uint16","Name":"key_index"},{"Type":"variant","Name":"destination"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a message\n\t\tarrives addressed to the application.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe key_index parameter indicates which application key has been\n\t\tused to decode the incoming message. The same key_index should\n\t\tbe used by the application when sending a response to this\n\t\tmessage (in case a response is expected).\n\t\tThe destination parameter contains the destination address of\n\t\treceived message. Underlying variant types are:\n\t\tuint16\n\t\t\tDestination is an unicast address, or a well known\n\t\t\tgroup address\n\t\tarray{byte}\n\t\t\tDestination is a virtual address label\n\t\tThe data parameter is the incoming message.\n"},{"Name":"DevKeyMessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by meshd daemon when a message arrives\n\t\taddressed to the application, which was sent with the remote\n\t\tnode's device key.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe remote parameter if true indicates that the device key\n\t\tused to decrypt the message was from the sender. False\n\t\tindicates that the local nodes device key was used, and the\n\t\tmessage has permissions to modify local states.\n\t\tThe net_index parameter indicates what subnet the message was\n\t\treceived on, and if a response is required, the same subnet\n\t\tmust be used to send the response.\n\t\tThe data parameter is the incoming message.\n"},{"Name":"UpdateModelConfiguration","ReturnType":"void","Args":[{"Type":"uint16","Name":"model_id"},{"Type":"dict","Name":"config"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a model's\n\t\tconfiguration is updated.\n\t\tThe model_id parameter contains BT SIG Model Identifier or, if\n\t\tVendor key is present in config dictionary, a 16-bit\n\t\tvendor-assigned Model Identifier.\n\t\tThe config parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tarray{uint16} Bindings\n\t\t\tIndices of application keys bound to the model\n\t\tuint32 PublicationPeriod\n\t\t\tModel publication period in milliseconds\n\t\tuint16 Vendor\n\t\t\tA 16-bit Bluetooth-assigned Company Identifier of the\n\t\t\tvendor as defined by Bluetooth SIG\n\t\tarray{variant} Subscriptions\n\t\t\tAddresses the model is subscribed to.\n\t\t\tEach address is provided either as uint16 for group\n\t\t\taddresses, or as array{byte} for virtual labels.\n"}],"Signals":[],"Properties":[{"Name":"Models","Type":"array{uint16}","Docs":"An array of SIG Model Identifiers. The array may be empty.","Flags":[1]},{"Name":"VendorModels","Type":"array{(uint16, uint16)}","Docs":"An array of pairs (vendor, model ID): vendor is a 16-bit\n\t\tBluetooth-assigned Company ID as defined by Bluetooth SIG.\n\t\tmodel ID is a 16-bit vendor-assigned Model Identifier\n\n\t\tThe array may be empty.","Flags":[1]},{"Name":"Location","Type":"uint16","Docs":"Location descriptor as defined in the GATT Bluetooth Namespace\n\t\tDescriptors section of the Bluetooth SIG Assigned Numbers","Flags":[1,5]}]},{"Title":"Mesh Attention Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Attention1","ObjectPath":"freely definable","Methods":[{"Name":"SetTimer","ReturnType":"void","Args":[{"Type":"uint8","Name":"element_index"},{"Type":"uint16","Name":"time"}],"Errors":null,"Docs":"\t\tThe element_index parameter is the element's index within the\n\t\tnode where the health server model is hosted.\n\t\tThe time parameter indicates how many seconds the attention\n\t\tstate shall be on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"},{"Name":"GetTimer","ReturnType":"uint16","Args":[{"Type":"uint16","Name":"element"}],"Errors":null,"Docs":"\t\tThe element parameter is the unicast address within the node\n\t\twhere the health server model is hosted.\n\t\tReturns the number of seconds for how long the attention action\n\t\tremains staying on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Provisioner Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Provisioner1","ObjectPath":"freely definable","Methods":[{"Name":"ScanResult","ReturnType":"void","Args":[{"Type":"int16","Name":"rssi"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThe method is called from the bluetooth-meshd daemon when a\n\t\tunique UUID has been seen during UnprovisionedScan() for\n\t\tunprovsioned devices.\n\t\tThe rssi parameter is a signed, normalized measurement of the\n\t\tsignal strength of the recieved unprovisioned beacon.\n\t\tThe data parameter is a variable length byte array, that may\n\t\thave 1, 2 or 3 distinct fields contained in it including the 16\n\t\tbyte remote device UUID (always), a 32 bit mask of OOB\n\t\tauthentication flags (optional), and a 32 bit URI hash (if URI\n\t\tbit set in OOB mask). Whether these fields exist or not is a\n\t\tdecision of the remote device.\n\t\tIf a beacon with a UUID that has already been reported is\n\t\trecieved by the daemon, it will be silently discarded unless it\n\t\twas recieved at a higher rssi power level.\n"},{"Name":"RequestProvData","ReturnType":"uint16 net_index, uint16 unicast","Args":[{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is implemented by a Provisioner capable application\n\t\tand is called when the remote device has been fully\n\t\tauthenticated and confirmed.\n\t\tThe count parameter is the number of consecutive unicast\n\t\taddresses the remote device is requesting.\n\t\tReturn Parameters are from the Mesh Profile Spec:\n\t\tnet_index - Subnet index of the net_key\n\t\tunicast - Primary Unicast address of the new node\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Abort\n"},{"Name":"AddNodeComplete","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"uint16","Name":"unicast"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby an AddNode() method call successfully completed.\n\t\tThe unicast parameter is the primary address that has been\n\t\tassigned to the new node, and the address of it's config server.\n\t\tThe count parameter is the number of unicast addresses assigned\n\t\tto the new node.\n\t\tThe new node may now be sent messages using the credentials\n\t\tsupplied by the RequestProvData method.\n"},{"Name":"AddNodeFailed","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tAddNode() has failed. Depending on how far Provisioning\n\t\tproceeded before failing, some cleanup of cached data may be\n\t\trequired.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"aborted\", \"timeout\",\n\t\t\"bad-pdu\", \"confirmation-failed\", \"out-of-resources\",\n\t\t\"decryption-error\", \"unexpected-error\",\n\t\t\"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[]},{"Title":"Provisioning Agent Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.ProvisionAgent1","ObjectPath":"freely definable","Methods":[{"Name":"PrivateKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the Provisioner\n\t\thas requested Out-Of-Band ECC key exchange. The Private key is\n\t\treturned to the Daemon, and the Public Key is delivered to the\n\t\tremote Provisioner using a method that does not involve the\n\t\tBluetooth Mesh system. The Private Key returned must be 32\n\t\toctets in size, or the Provisioning procedure will fail and be\n\t\tcanceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Unprovisioned device.\n"},{"Name":"PublicKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the local device is\n\t\tthe Provisioner, and is requestng Out-Of-Band ECC key exchange.\n\t\tThe Public key is returned to the Daemon that is the matched\n\t\tpair of the Private key of the remote device. The Public Key\n\t\treturned must be 64 octets in size, or the Provisioning\n\t\tprocedure will fail and be canceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Provisioner.\n"},{"Name":"DisplayString","ReturnType":"void","Args":[{"Type":"string","Name":"value"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter \"ABCDE\" on remote device\".\n"},{"Name":"DisplayNumeric","ReturnType":"void","Args":[{"Type":"string","Name":"type"},{"Type":"uint32","Name":"number"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter 14939264 on remote device\".\n\t\tThe type parameter indicates the display method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Locally blink LED\n\t\t\t\"beep\" - Locally make a noise\n\t\t\t\"vibrate\" - Locally vibrate\n\t\t\t\"out-numeric\" - Display value to enter remotely\n\t\t\t\"push\" - Request pushes on remote button\n\t\t\t\"twist\" - Request twists on remote knob\n\t\tThe number parameter is the specific value represented by the\n\t\tPrompt.\n"},{"Name":"PromptNumeric","ReturnType":"uint32","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requests the user to\n\t\tenter a decimal value between 1-99999999.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Enter times remote LED blinked\n\t\t\t\"beep\" - Enter times remote device beeped\n\t\t\t\"vibrate\" - Enter times remote device vibrated\n\t\t\t\"in-numeric\" - Enter remotely displayed value\n\t\t\t\"push\" - Push local button remotely requested times\n\t\t\t\"twist\" - Twist local knob remotely requested times\n\t\tThis agent should prompt the user for specific input. For\n\t\tinstance: \"Enter value being displayed by remote device\".\n"},{"Name":"PromptStatic","ReturnType":"array{byte}[16]","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requires a 16 octet byte\n\t\tarray, as an Out-of-Band authentication.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"static-oob\" - return 16 octet array\n\t\t\t\"in-alpha\" - return 16 octet alpha array\n\t\tThe Static data returned must be 16 octets in size, or the\n\t\tProvisioning procedure will fail and be canceled. If input type\n\t\tis \"in-alpha\", the printable characters should be\n\t\tleft-justified, with trailing 0x00 octets filling the remaining\n\t\tbytes.\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\tThis method gets called by the daemon to cancel any existing\n\t\tAgent Requests. When called, any pending user input should be\n\t\tcanceled, and any display requests removed.\n"}],"Signals":[],"Properties":[{"Name":"Capabilities","Type":"array{string}","Docs":"An array of strings with the following allowed values:\n\t\t\t\"blink\"\n\t\t\t\"beep\"\n\t\t\t\"vibrate\"\n\t\t\t\"out-numeric\"\n\t\t\t\"out-alpha\"\n\t\t\t\"push\"\n\t\t\t\"twist\"\n\t\t\t\"in-numeric\"\n\t\t\t\"in-alpha\"\n\t\t\t\"static-oob\"\n\t\t\t\"public-oob\"","Flags":[1]},{"Name":"OutOfBandInfo","Type":"array{string}","Docs":"Indicates availability of OOB data. An array of strings with the\n\t\tfollowing allowed values:\n\t\t\t\"other\"\n\t\t\t\"uri\"\n\t\t\t\"machine-code-2d\"\n\t\t\t\"bar-code\"\n\t\t\t\"nfc\"\n\t\t\t\"number\"\n\t\t\t\"string\"\n\t\t\t\"on-box\"\n\t\t\t\"in-box\"\n\t\t\t\"on-paper\",\n\t\t\t\"in-manual\"\n\t\t\t\"on-device\"","Flags":[1,5]},{"Name":"URI","Type":"string","Docs":"Uniform Resource Identifier points to out-of-band (OOB)\n\t\tinformation (e.g., a public key)","Flags":[1,5]}]}]},{"FileName":"network-api.txt","Name":"BlueZ D-Bus Network API description","Description":"\n","Api":[{"Title":"Network hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Network1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"string","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.AlreadyConnected","org.bluez.Error.AlreadyConnected"],"Docs":"\t\t\tConnect to the network device and return the network\n\t\t\tinterface name. Examples of the interface name are\n\t\t\tbnep0, bnep1 etc.\n\t\t\tuuid can be either one of \"gn\", \"panu\" or \"nap\" (case\n\t\t\tinsensitive) or a traditional string representation of\n\t\t\tUUID or a hexadecimal number.\n\t\t\tThe connection will be closed and network device\n\t\t\treleased either upon calling Disconnect() or when\n\t\t\tthe client disappears from the message bus.\n\t\t\tPossible errors: org.bluez.Error.AlreadyConnected\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnect from the network device.\n\t\t\tTo abort a connection attempt in case of errors or\n\t\t\ttimeouts in the client it is fine to call this method.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if the device is connected.","Flags":[]},{"Name":"Interface","Type":"string","Docs":"Indicates the network interface name when available.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"Indicates the connection role when available.","Flags":[]}]},{"Title":"Network server hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.NetworkServer1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"Register","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"},{"Type":"string","Name":"bridge"}],"Errors":null,"Docs":"\t\t\tRegister server for the provided UUID. Every new\n\t\t\tconnection to this server will be added the bridge\n\t\t\tinterface.\n\t\t\tValid UUIDs are \"gn\", \"panu\" or \"nap\".\n\t\t\tInitially no network server SDP is provided. Only\n\t\t\tafter this method a SDP record will be available\n\t\t\tand the BNEP server will be ready for incoming\n\t\t\tconnections.\n"},{"Name":"Unregister","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":null,"Docs":"\t\t\tUnregister the server for provided UUID.\n\t\t\tAll servers will be automatically unregistered when\n\t\t\tthe calling application terminates.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-agent-api.txt","Name":"OBEX D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.AgentManager1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tRegister an agent to request authorization of\n\t\t\tthe user to accept/reject objects. Object push\n\t\t\tservice needs to authorize each received object.\n\t\t\tPossible errors: org.bluez.obex.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.obex.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.obex.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"AuthorizePush","ReturnType":"string","Args":[{"Type":"object","Name":"transfer"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to accept/reject a Bluetooth object push request.\n\t\t\tReturns the full path (including the filename) where\n\t\t\tthe object shall be stored. The tranfer object will\n\t\t\tcontain a Filename property that contains the default\n\t\t\tlocation and name that can be returned.\n\t\t\tPossible errors: org.bluez.obex.Error.Rejected\n\t\t\t org.bluez.obex.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned. It cancels\n\t\t\tthe previous request.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-api.txt","Name":"OBEX D-Bus API description","Description":"\n","Api":[{"Title":"Client hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Client1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"CreateSession","ReturnType":"object","Args":[{"Type":"string","Name":"destination"},{"Type":"dict","Name":"args"}],"Errors":null,"Docs":"\t\t\tCreate a new OBEX session for the given remote address.\n\t\t\tThe last parameter is a dictionary to hold optional or\n\t\t\ttype-specific parameters. Typical parameters that can\n\t\t\tbe set in this dictionary include the following:\n\t\t\t\tstring \"Target\" : type of session to be created\n\t\t\t\tstring \"Source\" : local address to be used\n\t\t\t\tbyte \"Channel\"\n\t\t\tThe currently supported targets are the following:\n\t\t\t\t\"ftp\"\n\t\t\t\t\"map\"\n\t\t\t\t\"opp\"\n\t\t\t\t\"pbap\"\n\t\t\t\t\"sync\"\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"RemoveSession","ReturnType":"void","Args":[{"Type":"object","Name":"session"}],"Errors":null,"Docs":"\t\t\tUnregister session and abort pending transfers.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.NotAuthorized\n"}],"Signals":[],"Properties":[]},{"Title":"Session hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Session1","ObjectPath":"/org/bluez/obex/server/session{0, 1, 2, ...} or\n\t\t/org/bluez/obex/client/session{0, 1, 2, ...}","Methods":[{"Name":"GetCapabilities","ReturnType":"string","Args":[],"Errors":null,"Docs":"\t\t\tGet remote device capabilities.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Source","Type":"string","Docs":"Bluetooth adapter address","Flags":[]},{"Name":"Destination","Type":"string","Docs":"Bluetooth device address","Flags":[]},{"Name":"Channel","Type":"byte","Docs":"Bluetooth channel","Flags":[]},{"Name":"Target","Type":"string","Docs":"Target UUID","Flags":[]},{"Name":"Root","Type":"string","Docs":"Root path","Flags":[]}]},{"Title":"Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Transfer1","ObjectPath":"[Session object path]/transfer{0, 1, 2, ...}","Methods":[{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStops the current transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.InProgress\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Suspend","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tSuspend transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to suspend transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"},{"Name":"Resume","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to resume transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"}],"Signals":[],"Properties":[{"Name":"Status","Type":"string","Docs":"Inform the current status of the transfer.\n\n\t\t\tPossible values: \"queued\", \"active\", \"suspended\",\n\t\t\t\t\t\"complete\" or \"error\"","Flags":[]},{"Name":"Session","Type":"object","Docs":"The object path of the session the transfer belongs\n\t\t\tto.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Name of the transferred object. Either Name or Type\n\t\t\tor both will be present.","Flags":[]},{"Name":"Type","Type":"string","Docs":"Type of the transferred object. Either Name or Type\n\t\t\tor both will be present.\n\n\t\tuint64 Time [readonly, optional]\n\n\t\t\tTime of the transferred object if this is\n\t\t\tprovided by the remote party.\n\n\t\tuint64 Size [readonly, optional]\n\n\t\t\tSize of the transferred object. If the size is\n\t\t\tunknown, then this property will not be present.\n\n\t\tuint64 Transferred [readonly, optional]\n\n\t\t\tNumber of bytes transferred. For queued transfers, this\n\t\t\tvalue will not be present.","Flags":[]},{"Name":"Filename","Type":"string","Docs":"Complete name of the file being received or sent.\n\n\t\t\tFor incoming object push transaction, this will be\n\t\t\tthe proposed default location and name. It can be\n\t\t\toverwritten by the AuthorizePush agent callback\n\t\t\tand will be then updated accordingly.","Flags":[5]}]},{"Title":"Object Push hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.ObjectPush1","ObjectPath":"[Session object path]","Methods":[{"Name":"SendFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend one local file to the remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullBusinessCard","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRequest the business card from a remote device and\n\t\t\tstore it in the local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ExchangeBusinessCards","ReturnType":"object, dict","Args":[{"Type":"string","Name":"clientfile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tPush the client's business card to the remote device\n\t\t\tand then retrieve the remote business card and store\n\t\t\tit in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"File Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.FileTransfer","ObjectPath":"[Session object path]","Methods":[{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tChange the current folder of the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CreateFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tCreate a new folder in the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolder","ReturnType":"array{dict}","Args":[],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Object name in UTF-8 format\n\t\t\t\tstring Type : Either \"folder\" or \"file\"\n\t\t\t\tuint64 Size : Object size or number of items in\n\t\t\t\t\t\tfolder\n\t\t\t\tstring Permission : Group, owner and other\n\t\t\t\t\t\t\tpermission\n\t\t\t\tuint64 Modified : Last change\n\t\t\t\tuint64 Accessed : Last access\n\t\t\t\tuint64 Created : Creation date\n\t\t\tPossible errors: org.bluez.obex.Error.Failed\n"},{"Name":"GetFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from remote device) to the\n\t\t\ttarget file (on local filesystem).\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from local filesystem) to the\n\t\t\ttarget file (on remote device).\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CopyFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy a file within the remote device from source file\n\t\t\tto target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"MoveFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tMove a file within the remote device from source file\n\t\t\tto the target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Delete","ReturnType":"void","Args":[{"Type":"string","Name":"file"}],"Errors":null,"Docs":"\t\t\tDeletes the specified file/folder.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Phonebook Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.PhonebookAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"Select","ReturnType":"void","Args":[{"Type":"string","Name":"location"},{"Type":"string","Name":"phonebook"}],"Errors":null,"Docs":"\t\t\tSelect the phonebook object for other operations. Should\n\t\t\tbe call before all the other operations.\n\t\t\tlocation : Where the phonebook is stored, possible\n\t\t\tinputs :\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim\" ( \"sim1\" )\n\t\t\t\t\"sim2\"\n\t\t\t\t...\n\t\t\tphonebook : Possible inputs :\n\t\t\t\t\"pb\" :\tphonebook for the saved contacts\n\t\t\t\t\"ich\":\tincoming call history\n\t\t\t\t\"och\":\toutgoing call history\n\t\t\t\t\"mch\":\tmissing call history\n\t\t\t\t\"cch\":\tcombination of ich och mch\n\t\t\t\t\"spd\":\tspeed dials entry ( only for \"internal\" )\n\t\t\t\t\"fav\":\tfavorites entry ( only for \"internal\" )\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullAll","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn the entire phonebook object from the PSE server\n\t\t\tin plain string with vcard format, and store it in\n\t\t\ta local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible filters: Format, Order, Offset, MaxCount and\n\t\t\tFields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\torg.bluez.obex.Forbidden\n"},{"Name":"List","ReturnType":"array{string vcard, string name}","Args":[{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name. For example:\n\t\t\t\t\"1.vcf\" : \"John\"\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Forbidden\n"},{"Name":"Pull","ReturnType":"object, dict","Args":[{"Type":"string","Name":"vcard"},{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tGiven a vcard handle, retrieve the vcard in the current\n\t\t\tphonebook object and store it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossbile filters: Format and Fields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Search","ReturnType":"array{string vcard, string name}","Args":[{"Type":"string","Name":"field"},{"Type":"string","Name":"value"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tSearch for entries matching the given condition and\n\t\t\treturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name.\n\t\t\tvcard : name paired string match the search condition.\n\t\t\tfield : the field in the vcard to search with\n\t\t\t\t{ \"name\" (default) | \"number\" | \"sound\" }\n\t\t\tvalue : the string value to search for\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"GetSize","ReturnType":"uint16","Args":[],"Errors":null,"Docs":"\t\t\tReturn the number of entries in the selected phonebook\n\t\t\tobject that are actually used (i.e. indexes that\n\t\t\tcorrespond to non-NULL entries).\n\t\t\tPossible errors: org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateVersion","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAttempt to update PrimaryCounter and SecondaryCounter.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn All Available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Current folder.","Flags":[]},{"Name":"DatabaseIdentifier","Type":"string","Docs":"128 bits persistent database identifier.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"PrimaryCounter","Type":"string","Docs":"128 bits primary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"SecondaryCounter","Type":"string","Docs":"128 bits secondary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"FixedImageSize","Type":"bool","Docs":"Indicate support for fixed image size.\n\n\t\t\tPossible values: True if image is JPEG 300x300 pixels\n\t\t\totherwise False.","Flags":[5]}]},{"Title":"Synchronization hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Synchronization1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetLocation","ReturnType":"void","Args":[{"Type":"string","Name":"location"}],"Errors":null,"Docs":"\t\t\tSet the phonebook object store location for other\n\t\t\toperations. Should be called before all the other\n\t\t\toperations.\n\t\t\tlocation: Where the phonebook is stored, possible\n\t\t\tvalues:\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim1\"\n\t\t\t\t\"sim2\"\n\t\t\t\t......\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n"},{"Name":"GetPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRetrieve an entire Phonebook Object store from remote\n\t\t\tdevice, and stores it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend an entire Phonebook Object store to remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Message Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.MessageAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetFolder","ReturnType":"void","Args":[{"Type":"string","Name":"name"}],"Errors":null,"Docs":"\t\t\tSet working directory for current session, *name* may\n\t\t\tbe the directory name or '..[/dir]'.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolders","ReturnType":"array{dict}","Args":[{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Folder name\n\t\t\tPossible filters: Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn all available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"},{"Name":"ListMessages","ReturnType":"array{object, dict}","Args":[{"Type":"string","Name":"folder"},{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns an array containing the messages found in the\n\t\t\tgiven subfolder of the current folder, or in the\n\t\t\tcurrent folder if folder is empty.\n\t\t\tPossible Filters: Offset, MaxCount, SubjectLength, Fields,\n\t\t\tType, PeriodStart, PeriodEnd, Status, Recipient, Sender,\n\t\t\tPriority\n\t\t\tEach message is represented by an object path followed\n\t\t\tby a dictionary of the properties.\n\t\t\tProperties:\n\t\t\t\tstring Subject:\n\t\t\t\t\tMessage subject\n\t\t\t\tstring Timestamp:\n\t\t\t\t\tMessage timestamp\n\t\t\t\tstring Sender:\n\t\t\t\t\tMessage sender name\n\t\t\t\tstring SenderAddress:\n\t\t\t\t\tMessage sender address\n\t\t\t\tstring ReplyTo:\n\t\t\t\t\tMessage Reply-To address\n\t\t\t\tstring Recipient:\n\t\t\t\t\tMessage recipient name\n\t\t\t\tstring RecipientAddress:\n\t\t\t\t\tMessage recipient address\n\t\t\t\tstring Type:\n\t\t\t\t\tMessage type\n\t\t\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\t\t\"sms-cdma\" and \"mms\"\n\t\t\t\tuint64 Size:\n\t\t\t\t\tMessage size in bytes\n\t\t\t\tboolean Text:\n\t\t\t\t\tMessage text flag\n\t\t\t\t\tSpecifies whether message has textual\n\t\t\t\t\tcontent or is binary only\n\t\t\t\tstring Status:\n\t\t\t\t\tMessage status\n\t\t\t\t\tPossible values for received messages:\n\t\t\t\t\t\"complete\", \"fractioned\", \"notification\"\n\t\t\t\t\tPossible values for sent messages:\n\t\t\t\t\t\"delivery-success\", \"sending-success\",\n\t\t\t\t\t\"delivery-failure\", \"sending-failure\"\n\t\t\t\tuint64 AttachmentSize:\n\t\t\t\t\tMessage overall attachment size in bytes\n\t\t\t\tboolean Priority:\n\t\t\t\t\tMessage priority flag\n\t\t\t\tboolean Read:\n\t\t\t\t\tMessage read flag\n\t\t\t\tboolean Sent:\n\t\t\t\t\tMessage sent flag\n\t\t\t\tboolean Protected:\n\t\t\t\t\tMessage protected flag\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateInbox","ReturnType":"void","Args":null,"Errors":null,"Docs":""}],"Signals":[],"Properties":[]},{"Title":"Message hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Message1","ObjectPath":"[Session object path]/{message0,...}","Methods":[{"Name":"Get","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"boolean","Name":"attachment"}],"Errors":null,"Docs":"\t\t\tDownload message and store it in the target file.\n\t\t\tIf an empty target file is given, a temporary file\n\t\t\twill be automatically generated.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Folder which the message belongs to","Flags":[]},{"Name":"Subject","Type":"string","Docs":"Message subject","Flags":[]},{"Name":"Timestamp","Type":"string","Docs":"Message timestamp","Flags":[]},{"Name":"Sender","Type":"string","Docs":"Message sender name","Flags":[]},{"Name":"SenderAddress","Type":"string","Docs":"Message sender address","Flags":[]},{"Name":"ReplyTo","Type":"string","Docs":"Message Reply-To address","Flags":[]},{"Name":"Recipient","Type":"string","Docs":"Message recipient name","Flags":[]},{"Name":"RecipientAddress","Type":"string","Docs":"Message recipient address","Flags":[]},{"Name":"Type","Type":"string","Docs":"Message type\n\n\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\"sms-cdma\" and \"mms\"\n\n\t\tuint64 Size [readonly]\n\n\t\t\tMessage size in bytes","Flags":[]},{"Name":"Status","Type":"string","Docs":"Message reception status\n\n\t\t\tPossible values: \"complete\",\n\t\t\t\"fractioned\" and \"notification\"","Flags":[]},{"Name":"Priority","Type":"boolean","Docs":"Message priority flag","Flags":[]},{"Name":"Read","Type":"boolean","Docs":"Message read flag","Flags":[3]},{"Name":"Deleted","Type":"boolean","Docs":"Message deleted flag","Flags":[]},{"Name":"Sent","Type":"boolean","Docs":"Message sent flag","Flags":[]},{"Name":"Protected","Type":"boolean","Docs":"Message protected flag","Flags":[]}]}]},{"FileName":"profile-api.txt","Name":"BlueZ D-Bus Profile API description","Description":"\n","Api":[{"Title":"Profile Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ProfileManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"},{"Type":"string","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers a profile implementation.\n\t\t\tIf an application disconnects from the bus all\n\t\t\tits registered profiles will be removed.\n\t\t\tHFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault RFCOMM channel is 6. And this requires\n\t\t\t\tauthentication.\n\t\t\tAvailable options:\n\t\t\t\tstring Name\n\t\t\t\t\tHuman readable name for the profile\n\t\t\t\tstring Service\n\t\t\t\t\tThe primary service class UUID\n\t\t\t\t\t(if different from the actual\n\t\t\t\t\t profile UUID)\n\t\t\t\tstring Role\n\t\t\t\t\tFor asymmetric profiles that do not\n\t\t\t\t\thave UUIDs available to uniquely\n\t\t\t\t\tidentify each side this\n\t\t\t\t\tparameter allows specifying the\n\t\t\t\t\tprecise local role.\n\t\t\t\t\tPossible values: \"client\", \"server\"\n\t\t\t\tuint16 Channel\n\t\t\t\t\tRFCOMM channel number that is used\n\t\t\t\t\tfor client and server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tuint16 PSM\n\t\t\t\t\tPSM number that is used for client\n\t\t\t\t\tand server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tboolean RequireAuthentication\n\t\t\t\t\tPairing is required before connections\n\t\t\t\t\twill be established. No devices will\n\t\t\t\t\tbe connected if not paired.\n\t\t\t\tboolean RequireAuthorization\n\t\t\t\t\tRequest authorization before any\n\t\t\t\t\tconnection will be established.\n\t\t\t\tboolean AutoConnect\n\t\t\t\t\tIn case of a client UUID this will\n\t\t\t\t\tforce connection of the RFCOMM or\n\t\t\t\t\tL2CAP channels when a remote device\n\t\t\t\t\tis connected.\n\t\t\t\tstring ServiceRecord\n\t\t\t\t\tProvide a manual SDP record.\n\t\t\t\tuint16 Version\n\t\t\t\t\tProfile version (for SDP record)\n\t\t\t\tuint16 Features\n\t\t\t\t\tProfile features (for SDP record)\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the profile that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Profile hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Profile1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. A profile can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"NewConnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"int32","Name":"fd"},{"Type":"dict","Name":"fd_properties"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a new service level\n\t\t\tconnection has been made and authorized.\n\t\t\tCommon fd_properties:\n\t\t\tuint16 Version\t\tProfile version (optional)\n\t\t\tuint16 Features\t\tProfile features (optional)\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestDisconnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a profile gets\n\t\t\tdisconnected.\n\t\t\tThe file descriptor is no longer owned by the service\n\t\t\tdaemon and the profile implementation needs to take\n\t\t\tcare of cleaning up all connections.\n\t\t\tIf multiple file descriptors are indicated via\n\t\t\tNewConnection, it is expected that all of them\n\t\t\tare disconnected before returning from this\n\t\t\tmethod call.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"}],"Signals":[],"Properties":[]}]},{"FileName":"sap-api.txt","Name":"BlueZ D-Bus Sim Access API description","Description":"\n","Api":[{"Title":"Sim Access Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.SimAccess1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnects SAP client from the server.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if SAP client is connected to the server.","Flags":[]}]}]},{"FileName":"thermometer-api.txt","Name":"BlueZ D-Bus Thermometer API description","Description":"\tSantiago Carot-Nemesio \u003csancane@gmail.com\u003e\n\n","Api":[{"Title":"Health Thermometer Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ThermometerManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a watcher to monitor scanned measurements.\n\t\t\tThis agent will be notified about final temperature\n\t\t\tmeasurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"UnregisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tUnregisters a watcher.\n"},{"Name":"EnableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tEnables intermediate measurement notifications\n\t\t\tfor this agent. Intermediate measurements will\n\t\t\tbe enabled only for thermometers which support it.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DisableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDisables intermediate measurement notifications\n\t\t\tfor this agent. It will disable notifications in\n\t\t\tthermometers when the last agent removes the\n\t\t\twatcher for intermediate measurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\torg.bluez.Error.NotFound\n"}],"Signals":[],"Properties":[]},{"Title":"Health Thermometer Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Thermometer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Intermediate","Type":"boolean","Docs":"True if the thermometer supports intermediate\n\t\t\tmeasurement notifications.","Flags":[]},{"Name":"Interval","Type":"uint16","Docs":"(optional) The Measurement Interval defines the time (in\n\t\t\tseconds) between measurements. This interval is\n\t\t\tnot related to the intermediate measurements and\n\t\t\tmust be defined into a valid range. Setting it\n\t\t\tto zero means that no periodic measurements will\n\t\t\tbe taken.","Flags":[5]},{"Name":"Maximum","Type":"uint16","Docs":"(optional) Defines the maximum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]},{"Name":"Minimum","Type":"uint16","Docs":"(optional) Defines the minimum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]}]},{"Title":"Health Thermometer Watcher hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.ThermometerWatcher1","ObjectPath":"freely definable","Methods":[{"Name":"MeasurementReceived","ReturnType":"void","Args":[{"Type":"dict","Name":"measurement"}],"Errors":null,"Docs":"\t\t\tThis callback gets called when a measurement has been\n\t\t\tscanned in the thermometer.\n\t\t\tMeasurement:\n\t\t\t\tint16 Exponent:\n\t\t\t\tint32 Mantissa:\n\t\t\t\t\tExponent and Mantissa values as\n\t\t\t\t\textracted from float value defined by\n\t\t\t\t\tIEEE-11073-20601.\n\t\t\t\t\tMeasurement value is calculated as\n\t\t\t\t\t(Mantissa) * (10^Exponent)\n\t\t\t\t\tFor special cases Exponent is\n\t\t\t\t\tset to 0 and Mantissa is set to\n\t\t\t\t\tone of following values:\n\t\t\t\t\t+(2^23 - 1)\tNaN (invalid or\n\t\t\t\t\t\t\tmissing data)\n\t\t\t\t\t-(2^23)\t\tNRes\n\t\t\t\t\t+(2^23 - 2)\t+Infinity\n\t\t\t\t\t-(2^23 - 2)\t-Infinity\n\t\t\t\tstring Unit:\n\t\t\t\t\tPossible values: \"celsius\" or\n\t\t\t\t\t\t\t\"fahrenheit\"\n\t\t\t\tuint64 Time (optional):\n\t\t\t\t\tTime of measurement, if\n\t\t\t\t\tsupported by device.\n\t\t\t\t\tExpressed in seconds since epoch.\n\t\t\t\tstring Type (optional):\n\t\t\t\t\tOnly present if measurement type\n\t\t\t\t\tis known.\n\t\t\t\t\tPossible values: \"armpit\", \"body\",\n\t\t\t\t\t\t\"ear\", \"finger\", \"intestines\",\n\t\t\t\t\t\t\"mouth\", \"rectum\", \"toe\",\n\t\t\t\t\t\t\"tympanum\"\n\t\t\t\tstring Measurement:\n\t\t\t\t\tPossible values: \"final\" or\n\t\t\t\t\t\t\t\"intermediate\"\n"}],"Signals":[],"Properties":[]}]}]}go-bluetooth-bluez-5.60/bluez-5.54.json000077500000000000000000004756431420407601400176240ustar00rootroot00000000000000{"Version":"5.54","Api":[{"FileName":"adapter-api.txt","Name":"BlueZ D-Bus Adapter API description","Description":"\n","Api":[{"Title":"Adapter hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Adapter1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"StartDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method starts the device discovery session. This\n\t\t\tincludes an inquiry procedure and remote device name\n\t\t\tresolving. Use StopDiscovery to release the sessions\n\t\t\tacquired.\n\t\t\tThis process will start creating Device objects as\n\t\t\tnew devices are discovered.\n\t\t\tDuring discovery RSSI delta-threshold is imposed.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"StopDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method will cancel any previous StartDiscovery\n\t\t\ttransaction.\n\t\t\tNote that a discovery procedure is shared between all\n\t\t\tdiscovery sessions thus calling StopDiscovery will only\n\t\t\trelease a single session.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n"},{"Name":"RemoveDevice","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis removes the remote device object at the given\n\t\t\tpath. It will remove also the pairing information.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"SetDiscoveryFilter","ReturnType":"void","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method sets the device discovery filter for the\n\t\t\tcaller. When this method is called with no filter\n\t\t\tparameter, filter is removed.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tarray{string} UUIDs\n\t\t\t\tFilter by service UUIDs, empty means match\n\t\t\t\t_any_ UUID.\n\t\t\t\tWhen a remote device is found that advertises\n\t\t\t\tany UUID from UUIDs, it will be reported if:\n\t\t\t\t- Pathloss and RSSI are both empty.\n\t\t\t\t- only Pathloss param is set, device advertise\n\t\t\t\t TX pwer, and computed pathloss is less than\n\t\t\t\t Pathloss param.\n\t\t\t\t- only RSSI param is set, and received RSSI is\n\t\t\t\t higher than RSSI param.\n\t\t\tint16 RSSI\n\t\t\t\tRSSI threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated RSSI value. If one or more discovery\n\t\t\t\tfilters have been set, the RSSI delta-threshold,\n\t\t\t\tthat is imposed by StartDiscovery by default,\n\t\t\t\twill not be applied.\n\t\t\tuint16 Pathloss\n\t\t\t\tPathloss threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated Pathloss value.\n\t\t\tstring Transport (Default \"auto\")\n\t\t\t\tTransport parameter determines the type of\n\t\t\t\tscan.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"auto\"\t- interleaved scan\n\t\t\t\t\t\"bredr\"\t- BR/EDR inquiry\n\t\t\t\t\t\"le\"\t- LE scan only\n\t\t\t\tIf \"le\" or \"bredr\" Transport is requested,\n\t\t\t\tand the controller doesn't support it,\n\t\t\t\torg.bluez.Error.Failed error will be returned.\n\t\t\t\tIf \"auto\" transport is requested, scan will use\n\t\t\t\tLE, BREDR, or both, depending on what's\n\t\t\t\tcurrently enabled on the controller.\n\t\t\tbool DuplicateData (Default: true)\n\t\t\t\tDisables duplicate detection of advertisement\n\t\t\t\tdata.\n\t\t\t\tWhen enabled PropertiesChanged signals will be\n\t\t\t\tgenerated for either ManufacturerData and\n\t\t\t\tServiceData everytime they are discovered.\n\t\t\tbool Discoverable (Default: false)\n\t\t\t\tMake adapter discoverable while discovering,\n\t\t\t\tif the adapter is already discoverable setting\n\t\t\t\tthis filter won't do anything.\n\t\t\tstring Pattern (Default: none)\n\t\t\t\tDiscover devices where the pattern matches\n\t\t\t\teither the prefix of the address or\n\t\t\t\tdevice name which is convenient way to limited\n\t\t\t\tthe number of device objects created during a\n\t\t\t\tdiscovery.\n\t\t\t\tWhen set disregards device discoverable flags.\n\t\t\t\tNote: The pattern matching is ignored if there\n\t\t\t\tare other client that don't set any pattern as\n\t\t\t\tit work as a logical OR, also setting empty\n\t\t\t\tstring \"\" pattern will match any device found.\n\t\t\tWhen discovery filter is set, Device objects will be\n\t\t\tcreated as new devices with matching criteria are\n\t\t\tdiscovered regardless of they are connectable or\n\t\t\tdiscoverable which enables listening to\n\t\t\tnon-connectable and non-discoverable devices.\n\t\t\tWhen multiple clients call SetDiscoveryFilter, their\n\t\t\tfilters are internally merged, and notifications about\n\t\t\tnew devices are sent to all clients. Therefore, each\n\t\t\tclient must check that device updates actually match\n\t\t\tits filter.\n\t\t\tWhen SetDiscoveryFilter is called multiple times by the\n\t\t\tsame client, last filter passed will be active for\n\t\t\tgiven client.\n\t\t\tSetDiscoveryFilter can be called before StartDiscovery.\n\t\t\tIt is useful when client will create first discovery\n\t\t\tsession, to ensure that proper scan will be started\n\t\t\tright after call to StartDiscovery.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"GetDiscoveryFilters","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn available filters that can be given to\n\t\t\tSetDiscoveryFilter.\n\t\t\tPossible errors: None\n"},{"Name":"ConnectDevice","ReturnType":"object","Args":[{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method connects to device without need of\n\t\t\tperforming General Discovery. Connection mechanism is\n\t\t\tsimilar to Connect method from Device1 interface with\n\t\t\texception that this method returns success when physical\n\t\t\tconnection is established. After this method returns,\n\t\t\tservices discovery will continue and any supported\n\t\t\tprofile will be connected. There is no need for calling\n\t\t\tConnect on Device1 after this call. If connection was\n\t\t\tsuccessful this method returns object path to created\n\t\t\tdevice object.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tstring Address\n\t\t\t\tThe Bluetooth device address of the remote\n\t\t\t\tdevice. This parameter is mandatory.\n\t\t\tstring AddressType\n\t\t\t\tThe Bluetooth device Address Type. This is\n\t\t\t\taddress type that should be used for initial\n\t\t\t\tconnection. If this parameter is not present\n\t\t\t\tBR/EDR device is created.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"public\" - Public address\n\t\t\t\t\t\"random\" - Random address\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth Address Type. For dual-mode and BR/EDR\n\t\t\tonly adapter this defaults to \"public\". Single mode LE\n\t\t\tadapters may have either value. With privacy enabled\n\t\t\tthis contains type of Identity Address and not type of\n\t\t\taddress used for connection.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth system name (pretty hostname).\n\n\t\t\tThis property is either a static system default\n\t\t\tor controlled by an external daemon providing\n\t\t\taccess to the pretty hostname configuration.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The Bluetooth friendly name. This value can be\n\t\t\tchanged.\n\n\t\t\tIn case no alias is set, it will return the system\n\t\t\tprovided name. Setting an empty string as alias will\n\t\t\tconvert it back to the system provided name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to system name.\n\n\t\t\tOn a well configured system, this property never\n\t\t\tneeds to be changed since it defaults to the system\n\t\t\tname and provides the pretty hostname. Only if the\n\t\t\tlocal name needs to be different from the pretty\n\t\t\thostname, this property should be used as last\n\t\t\tresort.","Flags":[]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device.\n\n\t\t\tThis property represents the value that is either\n\t\t\tautomatically configured by DMI/ACPI information\n\t\t\tor provided as static configuration.","Flags":[]},{"Name":"Powered","Type":"boolean","Docs":"Switch an adapter on or off. This will also set the\n\t\t\tappropriate connectable state of the controller.\n\n\t\t\tThe value of this property is not persistent. After\n\t\t\trestart or unplugging of the adapter it will reset\n\t\t\tback to false.","Flags":[]},{"Name":"Discoverable","Type":"boolean","Docs":"Switch an adapter to discoverable or non-discoverable\n\t\t\tto either make it visible or hide it. This is a global\n\t\t\tsetting and should only be used by the settings\n\t\t\tapplication.\n\n\t\t\tIf the DiscoverableTimeout is set to a non-zero\n\t\t\tvalue then the system will set this value back to\n\t\t\tfalse after the timer expired.\n\n\t\t\tIn case the adapter is switched off, setting this\n\t\t\tvalue will fail.\n\n\t\t\tWhen changing the Powered property the new state of\n\t\t\tthis property will be updated via a PropertiesChanged\n\t\t\tsignal.\n\n\t\t\tFor any new adapter this settings defaults to false.","Flags":[]},{"Name":"Pairable","Type":"boolean","Docs":"Switch an adapter to pairable or non-pairable. This is\n\t\t\ta global setting and should only be used by the\n\t\t\tsettings application.\n\n\t\t\tNote that this property only affects incoming pairing\n\t\t\trequests.\n\n\t\t\tFor any new adapter this settings defaults to true.","Flags":[]},{"Name":"PairableTimeout","Type":"uint32","Docs":"The pairable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tpairable mode forever.\n\n\t\t\tThe default value for pairable timeout should be\n\t\t\tdisabled (value 0).","Flags":[]},{"Name":"DiscoverableTimeout","Type":"uint32","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tThe default value for the discoverable timeout should\n\t\t\tbe 180 seconds (3 minutes).","Flags":[]},{"Name":"Discovering","Type":"boolean","Docs":"Indicates that a device discovery procedure is active.","Flags":[]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tlocal services.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Local Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]}]}]},{"FileName":"advertising-api.txt","Name":"BlueZ D-Bus LE Advertising API Description","Description":"Advertising packets are structured data which is broadcast on the LE Advertising\nchannels and available for all devices in range. Because of the limited space\navailable in LE Advertising packets (31 bytes), each packet's contents must be\ncarefully controlled.\n\nBlueZ acts as a store for the Advertisement Data which is meant to be sent.\nIt constructs the correct Advertisement Data from the structured\ndata and configured the kernel to send the correct advertisement.\n\nAdvertisement Data objects are registered freely and then referenced by BlueZ\nwhen constructing the data sent to the kernel.\n\n","Api":[{"Title":"LE Advertisement Data hierarchy","Description":"\nSpecifies the Advertisement Data to be broadcast and some advertising\nparameters. Properties which are not present will not be included in the\ndata. Required advertisement data types will always be included.\nAll UUIDs are 128-bit versions in the API, and 16 or 32-bit\nversions of the same UUID will be used in the advertising data as appropriate.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisement1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tremoves the Advertisement. A client can use it to do\n\t\t\tcleanup tasks. There is no need to call\n\t\t\tUnregisterAdvertisement because when this method gets\n\t\t\tcalled it has already been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"Determines the type of advertising packet requested.\n\n\t\t\tPossible values: \"broadcast\" or \"peripheral\"","Flags":[]},{"Name":"ServiceUUIDs","Type":"array{string}","Docs":"List of UUIDs to include in the \"Service UUID\" field of\n\t\t\tthe Advertising Data.","Flags":[]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufactuer Data fields to include in\n\t\t\tthe Advertising Data. Keys are the Manufacturer ID\n\t\t\tto associate with the data.","Flags":[]},{"Name":"SolicitUUIDs","Type":"array{string}","Docs":"Array of UUIDs to include in \"Service Solicitation\"\n\t\t\tAdvertisement Data.","Flags":[]},{"Name":"ServiceData","Type":"dict","Docs":"Service Data elements to include. The keys are the\n\t\t\tUUID to associate with the data.","Flags":[]},{"Name":"Data","Type":"dict","Docs":"Advertising Type to include in the Advertising\n\t\t\tData. Key is the advertising type and value is the\n\t\t\tdata as byte array.\n\n\t\t\tNote: Types already handled by other properties shall\n\t\t\tnot be used.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[4]},{"Name":"Discoverable","Type":"bool","Docs":"Advertise as general discoverable. When present this\n\t\t\twill override adapter Discoverable property.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"DiscoverableTimeout","Type":"uint16","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"Includes","Type":"array{string}","Docs":"List of features to be included in the advertising\n\t\t\tpacket.\n\n\t\t\tPossible values: as found on\n\t\t\t\t\tLEAdvertisingManager.SupportedIncludes","Flags":[]},{"Name":"LocalName","Type":"string","Docs":"Local name to be used in the advertising report. If the\n\t\t\tstring is too big to fit into the packet it will be\n\t\t\ttruncated.\n\n\t\t\tIf this property is available 'local-name' cannot be\n\t\t\tpresent in the Includes.","Flags":[]},{"Name":"Appearance","Type":"uint16","Docs":"Appearance to be used in the advertising report.\n\n\t\t\tPossible values: as found on GAP Service.","Flags":[]},{"Name":"Duration","Type":"uint16_t","Docs":"Duration of the advertisement in seconds. If there are\n\t\t\tother applications advertising no duration is set the\n\t\t\tdefault is 2 seconds.","Flags":[]},{"Name":"Timeout","Type":"uint16_t","Docs":"Timeout of the advertisement in seconds. This defines\n\t\t\tthe lifetime of the advertisement.","Flags":[]},{"Name":"SecondaryChannel","Type":"string","Docs":"Secondary channel to be used. Primary channel is\n\t\t\talways set to \"1M\" except when \"Coded\" is set.\n\n\t\t\tPossible value: \"1M\" (default)\n\t\t\t\t\t\"2M\"\n\t\t\t\t\t\"Coded\"","Flags":[4]}]},{"Title":"LE Advertising Manager hierarchy","Description":"\nThe Advertising Manager allows external applications to register Advertisement\nData which should be broadcast to devices. Advertisement Data elements must\nfollow the API for LE Advertisement Data described above.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisingManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters an advertisement object to be sent over the LE\n\t\t\tAdvertising channel. The service must be exported\n\t\t\tunder interface LEAdvertisement1.\n\t\t\tInvalidArguments error indicates that the object has\n\t\t\tinvalid or conflicting properties.\n\t\t\tInvalidLength error indicates that the data\n\t\t\tprovided generates a data packet which is too long.\n\t\t\tThe properties of this object are parsed when it is\n\t\t\tregistered, and any changes are ignored.\n\t\t\tIf the same object is registered twice it will result in\n\t\t\tan AlreadyExists error.\n\t\t\tIf the maximum number of advertisement instances is\n\t\t\treached it will result in NotPermitted error.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.InvalidLength\n\t\t\t\t\t org.bluez.Error.NotPermitted\n"},{"Name":"UnregisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters an advertisement that has been\n\t\t\tpreviously registered. The object path parameter must\n\t\t\tmatch the same value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"ActiveInstances","Type":"byte","Docs":"Number of active advertising instances.","Flags":[]},{"Name":"SupportedInstances","Type":"byte","Docs":"Number of available advertising instances.","Flags":[]},{"Name":"SupportedIncludes","Type":"array{string}","Docs":"List of supported system includes.\n\n\t\t\tPossible values: \"tx-power\"\n\t\t\t\t\t \"appearance\"\n\t\t\t\t\t \"local-name\"","Flags":[]},{"Name":"SupportedSecondaryChannels","Type":"array{string}","Docs":"List of supported Secondary channels. Secondary\n\t\t\tchannels can be used to advertise with the\n\t\t\tcorresponding PHY.\n\n\t\t\tPossible values: \"1M\"\n\t\t\t\t\t \"2M\"\n\t\t\t\t\t \"Coded\"","Flags":[4]}]}]},{"FileName":"agent-api.txt","Name":"BlueZ D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AgentManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"},{"Type":"string","Name":"capability"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers an agent handler.\n\t\t\tThe object path defines the path of the agent\n\t\t\tthat will be called when user input is needed.\n\t\t\tEvery application can register its own agent and\n\t\t\tfor all actions triggered by that application its\n\t\t\tagent is used.\n\t\t\tIt is not required by an application to register\n\t\t\tan agent. If an application does chooses to not\n\t\t\tregister an agent, the default agent is used. This\n\t\t\tis on most cases a good idea. Only application\n\t\t\tlike a pairing wizard should register their own\n\t\t\tagent.\n\t\t\tAn application can only register one agent. Multiple\n\t\t\tagents per application is not supported.\n\t\t\tThe capability parameter can have the values\n\t\t\t\"DisplayOnly\", \"DisplayYesNo\", \"KeyboardOnly\",\n\t\t\t\"NoInputNoOutput\" and \"KeyboardDisplay\" which\n\t\t\treflects the input and output capabilities of the\n\t\t\tagent.\n\t\t\tIf an empty string is used it will fallback to\n\t\t\t\"KeyboardDisplay\".\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"},{"Name":"RequestDefaultAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis requests is to make the application agent\n\t\t\tthe default agent. The application is required\n\t\t\tto register an agent.\n\t\t\tSpecial permission might be required to become\n\t\t\tthe default agent.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"RequestPinCode","ReturnType":"string","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a string of 1-16 characters\n\t\t\tlength. The string can be alphanumeric.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPinCode","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"pincode"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a pincode for an authentication.\n\t\t\tAn empty reply should be returned. When the pincode\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tThis is used during the pairing process of keyboards\n\t\t\tthat don't support Bluetooth 2.1 Secure Simple Pairing,\n\t\t\tin contrast to DisplayPasskey which is used for those\n\t\t\tthat do.\n\t\t\tThis method will only ever be called once since\n\t\t\tolder keyboards do not support typing notification.\n\t\t\tNote that the PIN will always be a 6-digit number,\n\t\t\tzero-padded to 6 digits. This is for harmony with\n\t\t\tthe later specification.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestPasskey","ReturnType":"uint32","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a numeric value\n\t\t\tbetween 0-999999.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPasskey","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"},{"Type":"uint16","Name":"entered"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a passkey for an authentication.\n\t\t\tThe entered parameter indicates the number of already\n\t\t\ttyped keys on the remote side.\n\t\t\tAn empty reply should be returned. When the passkey\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tDuring the pairing process this method might be\n\t\t\tcalled multiple times to update the entered value.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n"},{"Name":"RequestConfirmation","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to confirm a passkey for an authentication.\n\t\t\tTo confirm the value it should return an empty reply\n\t\t\tor an error in case the passkey is invalid.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestAuthorization","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called to request the user to\n\t\t\tauthorize an incoming pairing attempt which\n\t\t\twould in other circumstances trigger the just-works\n\t\t\tmodel, or when the user plugged in a device that\n\t\t\timplements cable pairing. In the latter case, the\n\t\t\tdevice would not be connected to the adapter via\n\t\t\tBluetooth yet.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"AuthorizeService","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to authorize a connection/service request.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"battery-api.txt","Name":"BlueZ D-Bus Battery API description","Description":"\n","Api":[{"Title":"Battery hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Battery1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Percentage","Type":"byte","Docs":"The percentage of battery left as an unsigned 8-bit integer.","Flags":[]}]}]},{"FileName":"device-api.txt","Name":"BlueZ D-Bus Device API description","Description":"\n","Api":[{"Title":"Device hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Device1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis is a generic method to connect any profiles\n\t\t\tthe remote device supports that can be connected\n\t\t\tto and have been flagged as auto-connectable on\n\t\t\tour side. If only subset of profiles is already\n\t\t\tconnected it will try to connect currently disconnected\n\t\t\tones.\n\t\t\tIf at least one profile was connected successfully this\n\t\t\tmethod will indicate success.\n\t\t\tFor dual-mode devices only one bearer is connected at\n\t\t\ttime, the conditions are in the following order:\n\t\t\t\t1. Connect the disconnected bearer if already\n\t\t\t\tconnected.\n\t\t\t\t2. Connect first the bonded bearer. If no\n\t\t\t\tbearers are bonded or both are skip and check\n\t\t\t\tlatest seen bearer.\n\t\t\t\t3. Connect last seen bearer, in case the\n\t\t\t\ttimestamps are the same BR/EDR takes\n\t\t\t\tprecedence.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.AlreadyConnected\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tThis method gracefully disconnects all connected\n\t\t\tprofiles and then terminates low-level ACL connection.\n\t\t\tACL connection will be terminated even if some profiles\n\t\t\twere not disconnected properly e.g. due to misbehaving\n\t\t\tdevice.\n\t\t\tThis method can be also used to cancel a preceding\n\t\t\tConnect call before a reply to it has been received.\n\t\t\tFor non-trusted devices connected over LE bearer calling\n\t\t\tthis method will disable incoming connections until\n\t\t\tConnect method is called again.\n\t\t\tPossible errors: org.bluez.Error.NotConnected\n"},{"Name":"ConnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method connects a specific profile of this\n\t\t\tdevice. The UUID provided is the remote service\n\t\t\tUUID for the profile.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotAvailable\n\t\t\t\t\t org.bluez.Error.NotReady\n"},{"Name":"DisconnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method disconnects a specific profile of\n\t\t\tthis device. The profile needs to be registered\n\t\t\tclient profile.\n\t\t\tThere is no connection tracking for a profile, so\n\t\t\tas long as the profile is registered this will always\n\t\t\tsucceed.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"Pair","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method will connect to the remote device,\n\t\t\tinitiate pairing and then retrieve all SDP records\n\t\t\t(or GATT primary services).\n\t\t\tIf the application has registered its own agent,\n\t\t\tthen that specific agent will be used. Otherwise\n\t\t\tit will use the default agent.\n\t\t\tOnly for applications like a pairing wizard it\n\t\t\twould make sense to have its own agent. In almost\n\t\t\tall other cases the default agent will handle\n\t\t\tthis just fine.\n\t\t\tIn case there is no application agent and also\n\t\t\tno default agent present, this method will fail.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.AuthenticationCanceled\n\t\t\t\t\t org.bluez.Error.AuthenticationFailed\n\t\t\t\t\t org.bluez.Error.AuthenticationRejected\n\t\t\t\t\t org.bluez.Error.AuthenticationTimeout\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"CancelPairing","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis method can be used to cancel a pairing\n\t\t\toperation initiated by the Pair method.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address of the remote device.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth device Address Type. For dual-mode and\n\t\t\tBR/EDR only devices this defaults to \"public\". Single\n\t\t\tmode LE devices may have either value. If remote device\n\t\t\tuses privacy than before pairing this represents address\n\t\t\ttype used for connection and Identity Address after\n\t\t\tpairing.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth remote name. This value can not be\n\t\t\tchanged. Use the Alias property instead.\n\n\t\t\tThis value is only present for completeness. It is\n\t\t\tbetter to always use the Alias property when\n\t\t\tdisplaying the devices name.\n\n\t\t\tIf the Alias property is unset, it will reflect\n\t\t\tthis value which makes it more convenient.","Flags":[5]},{"Name":"Icon","Type":"string","Docs":"Proposed icon name according to the freedesktop.org\n\t\t\ticon naming specification.","Flags":[5]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device of the remote device.","Flags":[5]},{"Name":"Appearance","Type":"uint16","Docs":"External appearance of device, as found on GAP service.","Flags":[5]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tremote services.","Flags":[5]},{"Name":"Paired","Type":"boolean","Docs":"Indicates if the remote device is paired.","Flags":[]},{"Name":"Connected","Type":"boolean","Docs":"Indicates if the remote device is currently connected.\n\t\t\tA PropertiesChanged signal indicate changes to this\n\t\t\tstatus.","Flags":[]},{"Name":"Trusted","Type":"boolean","Docs":"Indicates if the remote is seen as trusted. This\n\t\t\tsetting can be changed by the application.","Flags":[]},{"Name":"Blocked","Type":"boolean","Docs":"If set to true any incoming connections from the\n\t\t\tdevice will be immediately rejected. Any device\n\t\t\tdrivers will also be removed and no new ones will\n\t\t\tbe probed as long as the device is blocked.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The name alias for the remote device. The alias can\n\t\t\tbe used to have a different friendly name for the\n\t\t\tremote device.\n\n\t\t\tIn case no alias is set, it will return the remote\n\t\t\tdevice name. Setting an empty string as alias will\n\t\t\tconvert it back to the remote device name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to the remote name.","Flags":[]},{"Name":"Adapter","Type":"object","Docs":"The object path of the adapter the device belongs to.","Flags":[]},{"Name":"LegacyPairing","Type":"boolean","Docs":"Set to true if the device only supports the pre-2.1\n\t\t\tpairing mechanism. This property is useful during\n\t\t\tdevice discovery to anticipate whether legacy or\n\t\t\tsimple pairing will occur if pairing is initiated.\n\n\t\t\tNote that this property can exhibit false-positives\n\t\t\tin the case of Bluetooth 2.1 (or newer) devices that\n\t\t\thave disabled Extended Inquiry Response support.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Remote Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"RSSI","Type":"int16","Docs":"Received Signal Strength Indicator of the remote\n\t\t\tdevice (inquiry or advertising).","Flags":[5]},{"Name":"TxPower","Type":"int16","Docs":"Advertised transmitted power level (inquiry or\n\t\t\tadvertising).","Flags":[5]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufacturer specific advertisement data. Keys are\n\t\t\t16 bits Manufacturer ID followed by its byte array\n\t\t\tvalue.","Flags":[5]},{"Name":"ServiceData","Type":"dict","Docs":"Service advertisement data. Keys are the UUIDs in\n\t\t\tstring format followed by its byte array value.","Flags":[5]},{"Name":"ServicesResolved","Type":"bool","Docs":"Indicate whether or not service discovery has been\n\t\t\tresolved.","Flags":[]},{"Name":"AdvertisingFlags","Type":"array{byte}","Docs":"The Advertising Data Flags of the remote device.","Flags":[]},{"Name":"AdvertisingData","Type":"dict","Docs":"The Advertising Data of the remote device. Keys are\n\t\t\tare 8 bits AD Type followed by data as byte array.\n\n\t\t\tNote: Only types considered safe to be handled by\n\t\t\tapplication are exposed.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[]}]}]},{"FileName":"gatt-api.txt","Name":"BlueZ D-Bus GATT API description","Description":"GATT local and remote services share the same high-level D-Bus API. Local\nrefers to GATT based service exported by a BlueZ plugin or an external\napplication. Remote refers to GATT services exported by the peer.\n\nBlueZ acts as a proxy, translating ATT operations to D-Bus method calls and\nProperties (or the opposite). Support for D-Bus Object Manager is mandatory for\nexternal services to allow seamless GATT declarations (Service, Characteristic\nand Descriptors) discovery. Each GATT service tree is required to export a D-Bus\nObject Manager at its root that is solely responsible for the objects that\nbelong to that service.\n\nReleasing a registered GATT service is not defined yet. Any API extension\nshould avoid breaking the defined API, and if possible keep an unified GATT\nremote and local services representation.\n\n","Api":[{"Title":"Service hierarchy","Description":"\nGATT remote and local service representation. Object path for local services\nis freely definable.\n\nExternal applications implementing local services must register the services\nusing GattManager1 registration method and must implement the methods and\nproperties defined in GattService1 interface.\n","Service":"org.bluez","Interface":"org.bluez.GattService1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX","Methods":[],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit service UUID.","Flags":[1]},{"Name":"Primary","Type":"boolean","Docs":"Indicates whether or not this GATT service is a\n\t\t\tprimary service. If false, the service is secondary.","Flags":[1]},{"Name":"Device","Type":"object","Docs":"Object path of the Bluetooth device the service\n\t\t\tbelongs to. Only present on services from remote\n\t\t\tdevices.","Flags":[1,5]},{"Name":"Includes","Type":"array{object}","Docs":"Array of object paths representing the included\n\t\t\tservices of this service.","Flags":[1,5]},{"Name":"Handle","Type":"uint16","Docs":"Service handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic hierarchy","Description":"\nFor local GATT defined services, the object paths need to follow the service\npath hierarchy and are freely definable.\n","Service":"org.bluez","Interface":"org.bluez.GattCharacteristic1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": uint16 offset\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Object Device (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.InvalidOffset\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"type\": string\n\t\t\t\t\t\tPossible values:\n\t\t\t\t\t\t\"command\": Write without\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\"request\": Write with response\n\t\t\t\t\t\t\"reliable\": Reliable Write\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": True if prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireWrite","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for writing. Only\n\t\t\tsockets are supported. Usage of WriteValue will be\n\t\t\tlocked causing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tFor client it only works with characteristic that has\n\t\t\tWriteAcquired property which relies on\n\t\t\twrite-without-response Flag.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireNotify","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for notify. Only\n\t\t\tsockets are support. Usage of StartNotify will be locked\n\t\t\tcausing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tOnly works with characteristic that has NotifyAcquired\n\t\t\twhich relies on notify Flag and no other client have\n\t\t\tcalled StartNotify.\n\t\t\tNotification are enabled during this procedure so\n\t\t\tStartNotify shall not be called, any notification\n\t\t\twill be dispatched via file descriptor therefore the\n\t\t\tValue property is not affected during the time where\n\t\t\tnotify has been acquired.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StartNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tStarts a notification session from this characteristic\n\t\t\tif it supports value notifications or indications.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StopNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method will cancel any previous StartNotify\n\t\t\ttransaction. Note that notifications from a\n\t\t\tcharacteristic are shared between sessions thus\n\t\t\tcalling StopNotify will release a single session.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"},{"Name":"Confirm","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method doesn't expect a reply so it is just a\n\t\t\tconfirmation that value was received.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit characteristic UUID.","Flags":[1]},{"Name":"Service","Type":"object","Docs":"Object path of the GATT service the characteristic\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the characteristic. This property\n\t\t\tgets updated only after a successful read request and\n\t\t\twhen a notification or indication is received, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"WriteAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireWrite.\n\n\t\t\tFor client properties is ommited in case\n\t\t\t'write-without-response' flag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireWrite is supported.","Flags":[1,5]},{"Name":"NotifyAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireNotify.\n\n\t\t\tFor client this properties is ommited in case 'notify'\n\t\t\tflag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireNotify is supported.","Flags":[1,5]},{"Name":"Notifying","Type":"boolean","Docs":"True, if notifications or indications on this\n\t\t\tcharacteristic are currently enabled.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the characteristic value can be used. See\n\t\t\tCore spec \"Table 3.5: Characteristic Properties bit\n\t\t\tfield\", and \"Table 3.8: Characteristic Extended\n\t\t\tProperties bit field\". Allowed values:\n\n\t\t\t\t\"broadcast\"\n\t\t\t\t\"read\"\n\t\t\t\t\"write-without-response\"\n\t\t\t\t\"write\"\n\t\t\t\t\"notify\"\n\t\t\t\t\"indicate\"\n\t\t\t\t\"authenticated-signed-writes\"\n\t\t\t\t\"extended-properties\"\n\t\t\t\t\"reliable-write\"\n\t\t\t\t\"writable-auxiliaries\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server only)\n\t\t\t\t\"secure-write\" (Server only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic Descriptors hierarchy","Description":"\nLocal or remote GATT characteristic descriptors hierarchy.\n","Service":"org.bluez","Interface":"org.bluez.GattDescriptor1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": boolean Is prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit descriptor UUID.","Flags":[1]},{"Name":"Characteristic","Type":"object","Docs":"Object path of the GATT characteristic the descriptor\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the descriptor. This property\n\t\t\tgets updated only after a successful read request, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the descriptor value can be used.\n\n\t\t\tPossible values:\n\n\t\t\t\t\"read\"\n\t\t\t\t\"write\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server Only)\n\t\t\t\t\"secure-write\" (Server Only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"GATT Profile hierarchy","Description":"\nLocal profile (GATT client) instance. By registering this type of object\nan application effectively indicates support for a specific GATT profile\nand requests automatic connections to be established to devices\nsupporting it.\n","Service":"\u003capplication dependent\u003e","Interface":"org.bluez.GattProfile1","ObjectPath":"\u003capplication dependent\u003e","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. The profile can use it to\n\t\t\tdo cleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUIDs","Type":"array{string}","Docs":"128-bit GATT service UUIDs to auto connect.","Flags":[1]}]},{"Title":"GATT Manager hierarchy","Description":"\nGATT Manager allows external applications to register GATT services and\nprofiles.\n\nRegistering a profile allows applications to subscribe to *remote* services.\nThese must implement the GattProfile1 interface defined above.\n\nRegistering a service allows applications to publish a *local* GATT service,\nwhich then becomes available to remote devices. A GATT service is represented by\na D-Bus object hierarchy where the root node corresponds to a service and the\nchild nodes represent characteristics and descriptors that belong to that\nservice. Each node must implement one of GattService1, GattCharacteristic1,\nor GattDescriptor1 interfaces described above, based on the attribute it\nrepresents. Each node must also implement the standard D-Bus Properties\ninterface to expose their properties. These objects collectively represent a\nGATT service definition.\n\nTo make service registration simple, BlueZ requires that all objects that belong\nto a GATT service be grouped under a D-Bus Object Manager that solely manages\nthe objects of that service. Hence, the standard DBus.ObjectManager interface\nmust be available on the root service path. An example application hierarchy\ncontaining two separate GATT services may look like this:\n\n-\u003e /com/example\n | - org.freedesktop.DBus.ObjectManager\n |\n -\u003e /com/example/service0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattService1\n | |\n | -\u003e /com/example/service0/char0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1/desc0\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattDescriptor1\n |\n -\u003e /com/example/service1\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattService1\n |\n -\u003e /com/example/service1/char0\n - org.freedesktop.DBus.Properties\n - org.bluez.GattCharacteristic1\n\nWhen a service is registered, BlueZ will automatically obtain information about\nall objects using the service's Object Manager. Once a service has been\nregistered, the objects of a service should not be removed. If BlueZ receives an\nInterfacesRemoved signal from a service's Object Manager, it will immediately\nunregister the service. Similarly, if the application disconnects from the bus,\nall of its registered services will be automatically unregistered.\nInterfacesAdded signals will be ignored.\n\nExamples:\n\t- Client\n\t\ttest/example-gatt-client\n\t\tclient/bluetoothctl\n\t- Server\n\t\ttest/example-gatt-server\n\t\ttools/gatt-service\n\n","Service":"org.bluez","Interface":"org.bluez.GattManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a local GATT services hierarchy as described\n\t\t\tabove (GATT Server) and/or GATT profiles (GATT Client).\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering a GATT based\n\t\t\tservice or profile.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]}]},{"FileName":"health-api.txt","Name":"BlueZ D-Bus Health API description","Description":"\n","Api":[{"Title":"HealthManager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthManager1","ObjectPath":"/org/bluez/","Methods":[{"Name":"CreateApplication","ReturnType":"object","Args":[{"Type":"dict","Name":"config"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturns the path of the new registered application.\n\t\t\tApplication will be closed by the call or implicitly\n\t\t\twhen the programs leaves the bus.\n\t\t\tconfig:\n\t\t\t\tuint16 DataType:\n\t\t\t\t\tMandatory\n\t\t\t\tstring Role:\n\t\t\t\t\tMandatory. Possible values: \"source\",\n\t\t\t\t\t\t\t\t\t\"sink\"\n\t\t\t\tstring Description:\n\t\t\t\t\tOptional\n\t\t\t\tChannelType:\n\t\t\t\t\tOptional, just for sources. Possible\n\t\t\t\t\tvalues: \"reliable\", \"streaming\"\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DestroyApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCloses the HDP application identified by the object\n\t\t\tpath. Also application will be closed if the process\n\t\t\tthat started it leaves the bus. Only the creator of the\n\t\t\tapplication will be able to destroy it.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[]},{"Title":"HealthDevice hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthDevice1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Echo","ReturnType":"boolean","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tSends an echo petition to the remote service. Returns\n\t\t\tTrue if response matches with the buffer sent. If some\n\t\t\terror is detected False value is returned.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.OutOfRange\n"},{"Name":"CreateChannel","ReturnType":"object","Args":[{"Type":"object","Name":"application"},{"Type":"string","Name":"configuration"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCreates a new data channel. The configuration should\n\t\t\tindicate the channel quality of service using one of\n\t\t\tthis values \"reliable\", \"streaming\", \"any\".\n\t\t\tReturns the object path that identifies the data\n\t\t\tchannel that is already connected.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.HealthError\n"},{"Name":"DestroyChannel","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDestroys the data channel object. Only the creator of\n\t\t\tthe channel or the creator of the HealthApplication\n\t\t\tthat received the data channel will be able to destroy\n\t\t\tit.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[{"Name":"ChannelConnected","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a new data channel is\n\t\t\tcreated or when a known data channel is reconnected.\n\n"},{"Name":"ChannelDeleted","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a data channel is deleted.\n\n\t\t\tAfter this signal the data channel path will not be\n\t\t\tvalid and its path can be reused for future data\n\t\t\tchannels."}],"Properties":[{"Name":"MainChannel","Type":"object","Docs":"The first reliable channel opened. It is needed by\n\t\t\tupper applications in order to send specific protocol\n\t\t\tdata units. The first reliable can change after a\n\t\t\treconnection.","Flags":[]}]},{"Title":"HealthChannel hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthChannel1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/chanZZZ","Methods":[{"Name":"Acquire","ReturnType":"fd","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tReturns the file descriptor for this data channel. If\n\t\t\tthe data channel is not connected it will also\n\t\t\treconnect.\n\t\t\tPossible Errors: org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotAcquired","org.bluez.Error.NotAcquired"],"Docs":"\t\t\tReleases the fd. Application should also need to\n\t\t\tclose() it.\n\t\t\tPossible Errors: org.bluez.Error.NotAcquired\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The quality of service of the data channel. (\"reliable\"\n\t\t\tor \"streaming\")","Flags":[]},{"Name":"Device","Type":"object","Docs":"Identifies the Remote Device that is connected with.\n\t\t\tMaps with a HealthDevice object.","Flags":[]},{"Name":"Application","Type":"object","Docs":"Identifies the HealthApplication to which this channel\n\t\t\tis related to (which indirectly defines its role and\n\t\t\tdata type).","Flags":[]}]}]},{"FileName":"input-api.txt","Name":"BlueZ D-Bus Input API description","Description":"","Api":[{"Title":"Input hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Input1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"ReconnectMode","Type":"string","Docs":"Determines the Connectability mode of the HID device as\n\t\t\tdefined by the HID Profile specification, Section 5.4.2.\n\n\t\t\tThis mode is based in the two properties\n\t\t\tHIDReconnectInitiate (see Section 5.3.4.6) and\n\t\t\tHIDNormallyConnectable (see Section 5.3.4.14) which\n\t\t\tdefine the following four possible values:\n\n\t\t\t\"none\"\t\tDevice and host are not required to\n\t\t\t\t\tautomatically restore the connection.\n\n\t\t\t\"host\"\t\tBluetooth HID host restores connection.\n\n\t\t\t\"device\"\tBluetooth HID device restores\n\t\t\t\t\tconnection.\n\n\t\t\t\"any\"\t\tBluetooth HID device shall attempt to\n\t\t\t\t\trestore the lost connection, but\n\t\t\t\t\tBluetooth HID Host may also restore the\n\t\t\t\t\tconnection.","Flags":[]}]}]},{"FileName":"media-api.txt","Name":"BlueZ D-Bus Media API description","Description":"\n","Api":[{"Title":"Media hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Media1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a local end point to sender, the sender can\n\t\t\tregister as many end points as it likes.\n\t\t\tNote: If the sender disconnects the end points are\n\t\t\tautomatically unregistered.\n\t\t\tpossible properties:\n\t\t\t\tstring UUID:\n\t\t\t\t\tUUID of the profile which the endpoint\n\t\t\t\t\tis for.\n\t\t\t\tbyte Codec:\n\t\t\t\t\tAssigned number of codec that the\n\t\t\t\t\tendpoint implements. The values should\n\t\t\t\t\tmatch the profile specification which\n\t\t\t\t\tis indicated by the UUID.\n\t\t\t\tarray{byte} Capabilities:\n\t\t\t\t\tCapabilities blob, it is used as it is\n\t\t\t\t\tso the size and byte order must match.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported - emitted\n\t\t\t\t\t when interface for the end-point is\n\t\t\t\t\t disabled.\n"},{"Name":"UnregisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"}],"Errors":null,"Docs":"\t\t\tUnregister sender end point.\n"},{"Name":"RegisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a media player object to sender, the sender\n\t\t\tcan register as many objects as it likes.\n\t\t\tObject must implement at least\n\t\t\torg.mpris.MediaPlayer2.Player as defined in MPRIS 2.2\n\t\t\tspec:\n\t\t\thttp://specifications.freedesktop.org/mpris-spec/latest/\n\t\t\tNote: If the sender disconnects its objects are\n\t\t\tautomatically unregistered.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"UnregisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"}],"Errors":null,"Docs":"\t\t\tUnregister sender media player.\n"},{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"root"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister endpoints an player objects within root\n\t\t\tobject which must implement ObjectManager.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Media Control hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaControl1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume playback.\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPause playback.\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStop playback.\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tNext item.\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPrevious item.\n"},{"Name":"VolumeUp","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step up\n"},{"Name":"VolumeDown","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step down\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"","Flags":[]},{"Name":"Player","Type":"object","Docs":"Addressed Player object path.","Flags":[5]}]},{"Title":"MediaPlayer1 hierarchy","Description":"","Service":"org.bluez (Controller role)","Interface":"org.bluez.MediaPlayer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tResume playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPause playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tStop playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tNext item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPrevious item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Equalizer","Type":"string","Docs":"Possible values: \"off\" or \"on\"","Flags":[]},{"Name":"Repeat","Type":"string","Docs":"Possible values: \"off\", \"singletrack\", \"alltracks\" or\n\t\t\t\t\t\"group\"","Flags":[]},{"Name":"Shuffle","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Scan","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Status","Type":"string","Docs":"Possible status: \"playing\", \"stopped\", \"paused\",\n\t\t\t\t\t\"forward-seek\", \"reverse-seek\"\n\t\t\t\t\tor \"error\"","Flags":[]},{"Name":"Position","Type":"uint32","Docs":"Playback position in milliseconds. Changing the\n\t\t\tposition may generate additional events that will be\n\t\t\tsent to the remote device. When position is 0 it means\n\t\t\tthe track is starting and when it's greater than or\n\t\t\tequal to track's duration the track has ended. Note\n\t\t\tthat even if duration is not available in metadata it's\n\t\t\tpossible to signal its end by setting position to the\n\t\t\tmaximum uint32 value.","Flags":[]},{"Name":"Track","Type":"dict","Docs":"Track metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title:","Type":"string","Docs":"Track title name","Flags":[]},{"Name":"Artist:","Type":"string","Docs":"Track artist name","Flags":[]},{"Name":"Album:","Type":"string","Docs":"Track album name","Flags":[]},{"Name":"Genre:","Type":"string","Docs":"Track genre name","Flags":[]},{"Name":"NumberOfTracks:","Type":"uint32","Docs":"Number of tracks in total","Flags":[]},{"Name":"TrackNumber:","Type":"uint32","Docs":"Track number","Flags":[]},{"Name":"Duration:","Type":"uint32","Docs":"Track duration in milliseconds","Flags":[]},{"Name":"Device","Type":"object","Docs":"Device object path.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Player name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Player type\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio\"\n\t\t\t\t\"Video\"\n\t\t\t\t\"Audio Broadcasting\"\n\t\t\t\t\"Video Broadcasting\"","Flags":[]},{"Name":"Subtype","Type":"string","Docs":"Player subtype\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio Book\"\n\t\t\t\t\"Podcast\"","Flags":[]},{"Name":"Browsable","Type":"boolean","Docs":"If present indicates the player can be browsed using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Searchable","Type":"boolean","Docs":"If present indicates the player can be searched using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Playlist","Type":"object","Docs":"Playlist object path.","Flags":[]}]},{"Title":"MediaFolder1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaFolder1","ObjectPath":"freely definable (Target role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX\n\t\t(Controller role)","Methods":[{"Name":"Search","ReturnType":"object","Args":[{"Type":"string","Name":"value"},{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tReturn a folder object containing the search result.\n\t\t\tTo list the items found use the folder object returned\n\t\t\tand pass to ChangeFolder.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ListItems","ReturnType":"array{objects, properties}","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturn a list of items found\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"object","Name":"folder"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tChange current folder.\n\t\t\tNote: By changing folder the items of previous folder\n\t\t\tmight be destroyed and have to be listed again, the\n\t\t\texception is NowPlaying folder which should be always\n\t\t\tpresent while the player is active.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"NumberOfItems","Type":"uint32","Docs":"Number of items in the folder","Flags":[]},{"Name":"Name","Type":"string","Docs":"Folder name:\n\n\t\t\tPossible values:\n\t\t\t\t\"/Filesystem/...\": Filesystem scope\n\t\t\t\t\"/NowPlaying/...\": NowPlaying scope\n\n\t\t\tNote: /NowPlaying folder might not be listed if player\n\t\t\tis stopped, folders created by Search are virtual so\n\t\t\tonce another Search is perform or the folder is\n\t\t\tchanged using ChangeFolder it will no longer be listed.\n\nFilters","Flags":[]},{"Name":"Start:","Type":"uint32","Docs":"Offset of the first item.\n\n\t\t\tDefault value: 0","Flags":[]},{"Name":"End:","Type":"uint32","Docs":"Offset of the last item.\n\n\t\t\tDefault value: NumbeOfItems","Flags":[]},{"Name":"Attributes","Type":"array{string}","Docs":"Item properties that should be included in the list.\n\n\t\t\tPossible Values:\n\n\t\t\t\t\"title\", \"artist\", \"album\", \"genre\",\n\t\t\t\t\"number-of-tracks\", \"number\", \"duration\"\n\n\t\t\tDefault Value: All","Flags":[]}]},{"Title":"MediaItem1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaItem1","ObjectPath":"freely definable (Target role)\n\t\t[variable\n\t\tprefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX\n\t\t(Controller role)","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPlay item\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"AddtoNowPlaying","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tAdd item to now playing list\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Player","Type":"object","Docs":"Player object path the item belongs to","Flags":[]},{"Name":"Name","Type":"string","Docs":"Item displayable name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Item type\n\n\t\t\tPossible values: \"video\", \"audio\", \"folder\"","Flags":[]},{"Name":"FolderType","Type":"string","Docs":"Folder type.\n\n\t\t\tPossible values: \"mixed\", \"titles\", \"albums\", \"artists\"\n\n\t\t\tAvailable if property Type is \"Folder\"","Flags":[5]},{"Name":"Playable","Type":"boolean","Docs":"Indicates if the item can be played\n\n\t\t\tAvailable if property Type is \"folder\"","Flags":[5]},{"Name":"Metadata","Type":"dict","Docs":"Item metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title","Type":"string","Docs":"Item title name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Artist","Type":"string","Docs":"Item artist name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Album","Type":"string","Docs":"Item album name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Genre","Type":"string","Docs":"Item genre name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"NumberOfTracks","Type":"uint32","Docs":"Item album number of tracks in total\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Number","Type":"uint32","Docs":"Item album number\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Duration","Type":"uint32","Docs":"Item duration in milliseconds\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]}]},{"Title":"MediaEndpoint1 hierarchy","Description":"","Service":"unique name (Server role)\n\t\torg.bluez (Client role)","Interface":"org.bluez.MediaEndpoint1","ObjectPath":"freely definable (Server role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX\n\t\t(Client role)","Methods":[{"Name":"SetConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"},{"Type":"dict","Name":"properties"}],"Errors":null,"Docs":"\t\t\tSet configuration for the transport.\n\t\t\tFor client role transport must be set with a server\n\t\t\tendpoint oject which will be configured and the\n\t\t\tproperties must contain the following properties:\n\t\t\t\tarray{byte} Capabilities\n"},{"Name":"SelectConfiguration","ReturnType":"array{byte}","Args":[{"Type":"array{byte}","Name":"capabilities"}],"Errors":null,"Docs":"\t\t\tSelect preferable configuration from the supported\n\t\t\tcapabilities.\n\t\t\tReturns a configuration which can be used to setup\n\t\t\ta transport.\n\t\t\tNote: There is no need to cache the selected\n\t\t\tconfiguration since on success the configuration is\n\t\t\tsend back as parameter of SetConfiguration.\n"},{"Name":"ClearConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"}],"Errors":null,"Docs":"\t\t\tClear transport configuration.\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the endpoint. An endpoint can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tendpoint, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the endpoint is for.","Flags":[5]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the endpoint implements.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[5]},{"Name":"Capabilities","Type":"array{byte}","Docs":"Capabilities blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[5]},{"Name":"Device","Type":"object","Docs":"Device object which the endpoint is belongs to.","Flags":[5]}]},{"Title":"MediaTransport1 hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaTransport1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX","Methods":[{"Name":"Acquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAuthorized","org.bluez.Error.NotAuthorized"],"Docs":"\t\t\tAcquire transport file descriptor and the MTU for read\n\t\t\tand write respectively.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"TryAcquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAvailable","org.bluez.Error.NotAvailable"],"Docs":"\t\t\tAcquire transport file descriptor only if the transport\n\t\t\tis in \"pending\" state at the time the message is\n\t\t\treceived by BlueZ. Otherwise no request will be sent\n\t\t\tto the remote device and the function will just fail\n\t\t\twith org.bluez.Error.NotAvailable.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAvailable\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tReleases file descriptor.\n"}],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"Device object which the transport is connected to.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the transport is for.","Flags":[]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the transport support.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[]},{"Name":"Configuration","Type":"array{byte}","Docs":"Configuration blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[]},{"Name":"State","Type":"string","Docs":"Indicates the state of the transport. Possible\n\t\t\tvalues are:\n\t\t\t\t\"idle\": not streaming\n\t\t\t\t\"pending\": streaming but not acquired\n\t\t\t\t\"active\": streaming and acquired","Flags":[]},{"Name":"Delay","Type":"uint16","Docs":"Optional. Transport delay in 1/10 of millisecond, this\n\t\t\tproperty is only writeable when the transport was\n\t\t\tacquired by the sender.","Flags":[]},{"Name":"Volume","Type":"uint16","Docs":"Optional. Indicates volume level of the transport,\n\t\t\tthis property is only writeable when the transport was\n\t\t\tacquired by the sender.\n\n\t\t\tPossible Values: 0-127","Flags":[]},{"Name":"Endpoint","Type":"object","Docs":"Endpoint object which the transport is associated\n\t\t\twith.","Flags":[5]}]}]},{"FileName":"mesh-api.txt","Name":"BlueZ D-Bus Mesh API description","Description":"","Api":[{"Title":"Mesh Network Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Network1","ObjectPath":"/org/bluez/mesh","Methods":[{"Name":"Join","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application has to call to\n\t\tbecome a provisioned node on a mesh network. The call will\n\t\tinitiate broadcasting of Unprovisioned Device Beacon.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The application hierarchy\n\t\talso contains a provision agent object that implements\n\t\torg.bluez.mesh.ProvisionAgent1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Cancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"Attach","ReturnType":"object node, array{byte, array{(uint16, dict)}} configuration","Args":[{"Type":"object","Name":"app_root"},{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis is the first method that an application must call to get\n\t\taccess to mesh node functionalities.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe token parameter is a 64-bit number that has been assigned to\n\t\tthe application when it first got provisioned/joined mesh\n\t\tnetwork, i.e. upon receiving JoinComplete() method. The daemon\n\t\tuses the token to verify whether the application is authorized\n\t\tto assume the mesh node identity.\n\t\tIn case of success, the method call returns mesh node object\n\t\t(see Mesh Node Hierarchy section) and current configuration\n\t\tsettings. The return value of configuration parameter is an\n\t\tarray, where each entry is a structure that contains element\n\t\tconfiguration. The element configuration structure is organized\n\t\tas follows:\n\t\tbyte\n\t\t\tElement index, identifies the element to which this\n\t\t\tconfiguration entry pertains.\n\t\tarray{struct}\n\t\t\tModels array where each entry is a structure with the\n\t\t\tfollowing members:\n\t\t\tuint16\n\t\t\t\tEither a SIG Model Identifier or, if Vendor key\n\t\t\t\tis present in model configuration dictionary, a\n\t\t\t\t16-bit vendor-assigned Model Identifier\n\t\t\tdict\n\t\t\t\tA dictionary that contains model configuration\n\t\t\t\twith the following keys defined:\n\t\t\t\tarray{uint16} Bindings\n\t\t\t\t\tIndices of application keys bound to the\n\t\t\t\t\tmodel\n\t\t\t\tuint32 PublicationPeriod\n\t\t\t\t\tModel publication period in milliseconds\n\t\t\t\tuint16 Vendor\n\t\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\t\tBluetooth SIG\n\t\t\t\tarray{variant} Subscriptions\n\t\t\t\t\tAddresses the model is subscribed to.\n\t\t\t\t\tEach address is provided either as\n\t\t\t\t\tuint16 for group addresses, or\n\t\t\t\t\tas array{byte} for virtual labels.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.Failed\n"},{"Name":"Leave","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis removes the configuration information about the mesh node\n\t\tidentified by the 64-bit token parameter. The token parameter\n\t\thas been obtained as a result of successful Join() method call.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"CreateNetwork","ReturnType":"uint64 token","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application calls to become\n\t\ta Provisioner node, and a Configuration Client on a newly\n\t\tcreated Mesh Network.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface, and a org.bluez.mesh.Provisioner1 interface. The\n\t\tapplication represents a node where child mesh elements have\n\t\ttheir own objects that implement org.bluez.mesh.Element1\n\t\tinterface. The application hierarchy also contains a provision\n\t\tagent object that implements org.bluez.mesh.ProvisionAgent1\n\t\tinterface. The standard DBus.ObjectManager interface must be\n\t\tavailable on the app_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tThe returned token must be preserved by the application in\n\t\torder to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n\t\tThe other information the bluetooth-meshd daemon will preserve\n\t\tabout the initial node, is to give it the initial primary\n\t\tunicast address (0x0001), and create and assign a net_key as the\n\t\tprimary network net_index (0x000).\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Import","ReturnType":"uint64 token","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"array{byte}[16]","Name":"dev_key"},{"Type":"array{byte}[16]","Name":"net_key"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"flags"},{"Type":"uint32","Name":"iv_index"},{"Type":"uint16","Name":"unicast"}],"Errors":null,"Docs":"\t\tThis method creates a local mesh node based on node\n\t\tconfiguration that has been generated outside bluetooth-meshd.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tThe dev_key parameter is the 16-byte value of the dev key of\n\t\tthe imported mesh node.\n\t\tRemaining parameters correspond to provisioning data:\n\t\tThe net_key and net_index parameters describe the network (or a\n\t\tsubnet, if net_index is not 0) the imported mesh node belongs\n\t\tto.\n\t\tThe flags parameter is a dictionary containing provisioning\n\t\tflags. Supported values are:\n\t\t\tboolean IVUpdate\n\t\t\t\tWhen true, indicates that the network is in the\n\t\t\t\tmiddle of IV Index Update procedure.\n\t\t\tboolean KeyRefresh\n\t\t\t\tWhen true, indicates that the specified net key\n\t\t\t\tis in the middle of a key refresh procedure.\n\t\tThe iv_index parameter is the current IV Index value used by\n\t\tthe network. This value is known by the provisioner.\n\t\tThe unicast parameter is the primary unicast address of the\n\t\timported node.\n\t\tThe returned token must be preserved by the application in\n\t\torder to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.NotSupported,\n\t\t\torg.bluez.mesh.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Node Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Node1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"Send","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"key_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe key_index parameter determines which application key to use\n\t\tfor encrypting the message. The key_index must be valid for that\n\t\telement, i.e., the application key must be bound to a model on\n\t\tthis element. Otherwise, org.bluez.mesh.Error.NotAuthorized will\n\t\tbe returned.\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tbluetooth-meshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"DevKeySend","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel encoded with the device key of the remote node.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe remote parameter, if true, looks up the device key by the\n\t\tdestination address in the key database to encrypt the message.\n\t\tIf remote is true, but requested key does not exist, a NotFound\n\t\terror will be returned. If set to false, the local node's\n\t\tdevice key is used.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddNetKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"subnet_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe subnet_index parameter refers to the subnet index of the\n\t\tnetwork that is being added or updated. This key must exist in\n\t\tthe local key database.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddAppKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"app_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe app_index parameter refers to the application key which is\n\t\tbeing added or updated. This key must exist in the local key\n\t\tdatabase.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"Publish","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"model"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a publication originated by a local\n\t\tmodel. If the model does not exist, or it has no publication\n\t\trecord, the method returns org.bluez.mesh.Error.DoesNotExist\n\t\terror.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe model parameter contains a model ID, as defined by the\n\t\tBluetooth SIG.\n\t\tSince only one Publish record may exist per element-model, the\n\t\tdestination and key_index are obtained from the Publication\n\t\trecord cached by the daemon.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"VendorPublish","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"vendor"},{"Type":"uint16","Name":"model_id"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a publication originated by a local\n\t\tvendor model. If the model does not exist, or it has no\n\t\tpublication record, the method returns\n\t\torg.bluez.mesh.Error.DoesNotExist error.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe vendor parameter is a 16-bit Bluetooth-assigned Company ID.\n\t\tThe model_id parameter is a 16-bit vendor-assigned Model\n\t\tIdentifier.\n\t\tSince only one Publish record may exist per element-model, the\n\t\tdestination and key_index are obtained from the Publication\n\t\trecord cached by the daemon.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[{"Name":"Features","Type":"dict","Docs":"The dictionary that contains information about feature support.\n\t\tThe following keys are defined:","Flags":[1]},{"Name":"Friend","Type":"boolean","Docs":"Indicates the ability to establish a friendship with a\n\t\t\tLow Power node","Flags":[]},{"Name":"LowPower","Type":"boolean","Docs":"Indicates support for operating in Low Power node mode","Flags":[]},{"Name":"Proxy","Type":"boolean","Docs":"Indicates support for GATT proxy","Flags":[]},{"Name":"Relay","Type":"boolean","Docs":"Indicates support for relaying messages\n\n\tIf a key is absent from the dictionary, the feature is not supported.\n\tOtherwise, true means that the feature is enabled and false means that\n\tthe feature is disabled.","Flags":[]},{"Name":"Beacon","Type":"boolean","Docs":"This property indicates whether the periodic beaconing is\n\t\tenabled (true) or disabled (false).\n\n\tuint8 BeaconFlags [read-only]\n\n\t\tThis property may be read at any time to determine the flag\n\t\tfield setting on sent and received beacons of the primary\n\t\tnetwork key.","Flags":[1]},{"Name":"IvIndex","Type":"uint32","Docs":"This property may be read at any time to determine the IV_Index\n\t\tthat the current network is on. This information is only useful\n\t\tfor provisioning.","Flags":[1]},{"Name":"SecondsSinceLastHeard","Type":"uint32","Docs":"This property may be read at any time to determine the number of\n\t\tseconds since mesh network layer traffic was last detected on\n\t\tthis node's network.","Flags":[1]},{"Name":"Addresses","Type":"array{uint16}","Docs":"This property contains unicast addresses of node's elements.","Flags":[1]},{"Name":"SequenceNumber","Type":"uint32","Docs":"This property may be read at any time to determine the\n\t\tsequence number.","Flags":[1]}]},{"Title":"Mesh Provisioning Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Management1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"UnprovisionedScan","ReturnType":"void","Args":[{"Type":"uint16","Name":"seconds"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to start listening\n\t\t(scanning) for unprovisioned devices in the area. Scanning\n\t\twill continue for the specified number of seconds, or, if 0 is\n\t\tspecified, then continuously until UnprovisionedScanCancel() is\n\t\tcalled or if AddNode() method is called.\n\t\tEach time a unique unprovisioned beacon is heard, the\n\t\tScanResult() method on the app will be called with the result.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"UnprovisionedScanCancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"AddNode","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to add the\n\t\tunprovisioned device specified by uuid, to the Network.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID\n\t\tof the unprovisioned device to be added to the network.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n"},{"Name":"CreateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tnetwork subnet key.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"ImportSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}[16]","Name":"net_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add a network subnet\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThe net_key parameter is the 16-byte value of the net key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"UpdateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new network\n\t\tsubnet key, and set it's key refresh state to Phase 1.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to update. Note that the subnet must\n\t\texist prior to updating.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"DeleteSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application that to delete a subnet.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to delete. The primary net key (0x000)\n\t\tmay not be deleted.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"SetKeyPhase","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint8","Name":"phase"}],"Errors":null,"Docs":"\t\tThis method is used to set the master key update phase of the\n\t\tgiven subnet. When finalizing the procedure, it is important\n\t\tto CompleteAppKeyUpdate() on all app keys that have been\n\t\tupdated during the procedure prior to setting phase 3.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which subnet phase to set.\n\t\tThe phase parameter is used to cycle the local key database\n\t\tthrough the phases as defined by the Mesh Profile Specification.\n\t\tAllowed values:\n\t\t\t0 - Cancel Key Refresh (May only be called from Phase 1,\n\t\t\t\tand should never be called once the new key has\n\t\t\t\tstarted propagating)\n\t\t\t1 - Invalid Argument (see NetKeyUpdate method)\n\t\t\t2 - Go to Phase 2 (May only be called from Phase 1)\n\t\t\t3 - Complete Key Refresh procedure (May only be called\n\t\t\t\tfrom Phase 2)\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is the responsibility of the application to maintain the key\n\t\trefresh phases per the Mesh Profile Specification.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"CreateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tapplication key.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"ImportAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"},{"Type":"array{byte}[16]","Name":"app_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add an application\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to import.\n\t\tThe app_key parameter is the 16-byte value of the key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"UpdateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new\n\t\tapplication key.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to update. Note that the subnet that\n\t\tthe key is bound to must exist and be in Phase 1.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"DeleteAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete an application\n\t\tkey.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to delete.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"ImportRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"},{"Type":"array{byte}[16]","Name":"device_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to import a remote node\n\t\tthat has been provisioned by an external process.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being imported.\n\t\tThe count parameter specifies the number of elements that are\n\t\tassigned to this remote node.\n\t\tThe device_key parameter is the access layer key that will be\n\t\twill used to decrypt privledged messages from this remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"DeleteRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete a remote node\n\t\tfrom the local device key database.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being deleted.\n\t\tThe count parameter specifies the number of elements that were\n\t\tassigned to the remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Application Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Application1","ObjectPath":"\u003capp_root\u003e","Methods":[{"Name":"JoinComplete","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby a Join() method call successfully completed.\n\t\tThe token parameter serves as a unique identifier of the\n\t\tparticular node. The token must be preserved by the application\n\t\tin order to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n"},{"Name":"JoinFailed","ReturnType":"void","Args":[{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tJoin() has failed.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"timeout\", \"bad-pdu\",\n\t\t\"confirmation-failed\", \"out-of-resources\", \"decryption-error\",\n\t\t\"unexpected-error\", \"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[{"Name":"CompanyID","Type":"uint16","Docs":"A 16-bit Bluetooth-assigned Company Identifier of the vendor as\n\t\tdefined by Bluetooth SIG","Flags":[1]},{"Name":"ProductID","Type":"uint16","Docs":"A 16-bit vendor-assigned product identifier","Flags":[1]},{"Name":"VersionID","Type":"uint16","Docs":"A 16-bit vendor-assigned product version identifier","Flags":[1]},{"Name":"CRPL","Type":"uint16","Docs":"A 16-bit minimum number of replay protection list entries","Flags":[1,5]}]},{"Title":"Mesh Element Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Element1","ObjectPath":"\u003capp_defined_element_path\u003e","Methods":[{"Name":"MessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"uint16","Name":"key_index"},{"Type":"variant","Name":"destination"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a message\n\t\tarrives addressed to the application.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe key_index parameter indicates which application key has been\n\t\tused to decode the incoming message. The same key_index should\n\t\tbe used by the application when sending a response to this\n\t\tmessage (in case a response is expected).\n\t\tThe destination parameter contains the destination address of\n\t\treceived message. Underlying variant types are:\n\t\tuint16\n\t\t\tDestination is an unicast address, or a well known\n\t\t\tgroup address\n\t\tarray{byte}\n\t\t\tDestination is a virtual address label\n\t\tThe data parameter is the incoming message.\n"},{"Name":"DevKeyMessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by meshd daemon when a message arrives\n\t\taddressed to the application, which was sent with the remote\n\t\tnode's device key.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe remote parameter if true indicates that the device key\n\t\tused to decrypt the message was from the sender. False\n\t\tindicates that the local nodes device key was used, and the\n\t\tmessage has permissions to modify local states.\n\t\tThe net_index parameter indicates what subnet the message was\n\t\treceived on, and if a response is required, the same subnet\n\t\tmust be used to send the response.\n\t\tThe data parameter is the incoming message.\n"},{"Name":"UpdateModelConfiguration","ReturnType":"void","Args":[{"Type":"uint16","Name":"model_id"},{"Type":"dict","Name":"config"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a model's\n\t\tconfiguration is updated.\n\t\tThe model_id parameter contains BT SIG Model Identifier or, if\n\t\tVendor key is present in config dictionary, a 16-bit\n\t\tvendor-assigned Model Identifier.\n\t\tThe config parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tarray{uint16} Bindings\n\t\t\tIndices of application keys bound to the model\n\t\tuint32 PublicationPeriod\n\t\t\tModel publication period in milliseconds\n\t\tuint16 Vendor\n\t\t\tA 16-bit Bluetooth-assigned Company Identifier of the\n\t\t\tvendor as defined by Bluetooth SIG\n\t\tarray{variant} Subscriptions\n\t\t\tAddresses the model is subscribed to.\n\t\t\tEach address is provided either as uint16 for group\n\t\t\taddresses, or as array{byte} for virtual labels.\n"}],"Signals":[],"Properties":[{"Name":"Models","Type":"array{uint16}","Docs":"An array of SIG Model Identifiers. The array may be empty.","Flags":[1]},{"Name":"VendorModels","Type":"array{(uint16, uint16)}","Docs":"An array of pairs (vendor, model ID): vendor is a 16-bit\n\t\tBluetooth-assigned Company ID as defined by Bluetooth SIG.\n\t\tmodel ID is a 16-bit vendor-assigned Model Identifier\n\n\t\tThe array may be empty.","Flags":[1]},{"Name":"Location","Type":"uint16","Docs":"Location descriptor as defined in the GATT Bluetooth Namespace\n\t\tDescriptors section of the Bluetooth SIG Assigned Numbers","Flags":[1,5]}]},{"Title":"Mesh Attention Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Attention1","ObjectPath":"freely definable","Methods":[{"Name":"SetTimer","ReturnType":"void","Args":[{"Type":"uint8","Name":"element_index"},{"Type":"uint16","Name":"time"}],"Errors":null,"Docs":"\t\tThe element_index parameter is the element's index within the\n\t\tnode where the health server model is hosted.\n\t\tThe time parameter indicates how many seconds the attention\n\t\tstate shall be on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"},{"Name":"GetTimer","ReturnType":"uint16","Args":[{"Type":"uint16","Name":"element"}],"Errors":null,"Docs":"\t\tThe element parameter is the unicast address within the node\n\t\twhere the health server model is hosted.\n\t\tReturns the number of seconds for how long the attention action\n\t\tremains staying on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Provisioner Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Provisioner1","ObjectPath":"freely definable","Methods":[{"Name":"ScanResult","ReturnType":"void","Args":[{"Type":"int16","Name":"rssi"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThe method is called from the bluetooth-meshd daemon when a\n\t\tunique UUID has been seen during UnprovisionedScan() for\n\t\tunprovsioned devices.\n\t\tThe rssi parameter is a signed, normalized measurement of the\n\t\tsignal strength of the recieved unprovisioned beacon.\n\t\tThe data parameter is a variable length byte array, that may\n\t\thave 1, 2 or 3 distinct fields contained in it including the 16\n\t\tbyte remote device UUID (always), a 32 bit mask of OOB\n\t\tauthentication flags (optional), and a 32 bit URI hash (if URI\n\t\tbit set in OOB mask). Whether these fields exist or not is a\n\t\tdecision of the remote device.\n\t\tIf a beacon with a UUID that has already been reported is\n\t\trecieved by the daemon, it will be silently discarded unless it\n\t\twas recieved at a higher rssi power level.\n"},{"Name":"RequestProvData","ReturnType":"uint16 net_index, uint16 unicast","Args":[{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is implemented by a Provisioner capable application\n\t\tand is called when the remote device has been fully\n\t\tauthenticated and confirmed.\n\t\tThe count parameter is the number of consecutive unicast\n\t\taddresses the remote device is requesting.\n\t\tReturn Parameters are from the Mesh Profile Spec:\n\t\tnet_index - Subnet index of the net_key\n\t\tunicast - Primary Unicast address of the new node\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Abort\n"},{"Name":"AddNodeComplete","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"uint16","Name":"unicast"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby an AddNode() method call successfully completed.\n\t\tThe unicast parameter is the primary address that has been\n\t\tassigned to the new node, and the address of it's config server.\n\t\tThe count parameter is the number of unicast addresses assigned\n\t\tto the new node.\n\t\tThe new node may now be sent messages using the credentials\n\t\tsupplied by the RequestProvData method.\n"},{"Name":"AddNodeFailed","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tAddNode() has failed. Depending on how far Provisioning\n\t\tproceeded before failing, some cleanup of cached data may be\n\t\trequired.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"aborted\", \"timeout\",\n\t\t\"bad-pdu\", \"confirmation-failed\", \"out-of-resources\",\n\t\t\"decryption-error\", \"unexpected-error\",\n\t\t\"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[]},{"Title":"Provisioning Agent Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.ProvisionAgent1","ObjectPath":"freely definable","Methods":[{"Name":"PrivateKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the Provisioner\n\t\thas requested Out-Of-Band ECC key exchange. The Private key is\n\t\treturned to the Daemon, and the Public Key is delivered to the\n\t\tremote Provisioner using a method that does not involve the\n\t\tBluetooth Mesh system. The Private Key returned must be 32\n\t\toctets in size, or the Provisioning procedure will fail and be\n\t\tcanceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Unprovisioned device.\n"},{"Name":"PublicKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the local device is\n\t\tthe Provisioner, and is requestng Out-Of-Band ECC key exchange.\n\t\tThe Public key is returned to the Daemon that is the matched\n\t\tpair of the Private key of the remote device. The Public Key\n\t\treturned must be 64 octets in size, or the Provisioning\n\t\tprocedure will fail and be canceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Provisioner.\n"},{"Name":"DisplayString","ReturnType":"void","Args":[{"Type":"string","Name":"value"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter \"ABCDE\" on remote device\".\n"},{"Name":"DisplayNumeric","ReturnType":"void","Args":[{"Type":"string","Name":"type"},{"Type":"uint32","Name":"number"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter 14939264 on remote device\".\n\t\tThe type parameter indicates the display method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Locally blink LED\n\t\t\t\"beep\" - Locally make a noise\n\t\t\t\"vibrate\" - Locally vibrate\n\t\t\t\"out-numeric\" - Display value to enter remotely\n\t\t\t\"push\" - Request pushes on remote button\n\t\t\t\"twist\" - Request twists on remote knob\n\t\tThe number parameter is the specific value represented by the\n\t\tPrompt.\n"},{"Name":"PromptNumeric","ReturnType":"uint32","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requests the user to\n\t\tenter a decimal value between 1-99999999.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Enter times remote LED blinked\n\t\t\t\"beep\" - Enter times remote device beeped\n\t\t\t\"vibrate\" - Enter times remote device vibrated\n\t\t\t\"in-numeric\" - Enter remotely displayed value\n\t\t\t\"push\" - Push local button remotely requested times\n\t\t\t\"twist\" - Twist local knob remotely requested times\n\t\tThis agent should prompt the user for specific input. For\n\t\tinstance: \"Enter value being displayed by remote device\".\n"},{"Name":"PromptStatic","ReturnType":"array{byte}[16]","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requires a 16 octet byte\n\t\tarray, as an Out-of-Band authentication.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"static-oob\" - return 16 octet array\n\t\t\t\"in-alpha\" - return 16 octet alpha array\n\t\tThe Static data returned must be 16 octets in size, or the\n\t\tProvisioning procedure will fail and be canceled. If input type\n\t\tis \"in-alpha\", the printable characters should be\n\t\tleft-justified, with trailing 0x00 octets filling the remaining\n\t\tbytes.\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\tThis method gets called by the daemon to cancel any existing\n\t\tAgent Requests. When called, any pending user input should be\n\t\tcanceled, and any display requests removed.\n"}],"Signals":[],"Properties":[{"Name":"Capabilities","Type":"array{string}","Docs":"An array of strings with the following allowed values:\n\t\t\t\"blink\"\n\t\t\t\"beep\"\n\t\t\t\"vibrate\"\n\t\t\t\"out-numeric\"\n\t\t\t\"out-alpha\"\n\t\t\t\"push\"\n\t\t\t\"twist\"\n\t\t\t\"in-numeric\"\n\t\t\t\"in-alpha\"\n\t\t\t\"static-oob\"\n\t\t\t\"public-oob\"","Flags":[1]},{"Name":"OutOfBandInfo","Type":"array{string}","Docs":"Indicates availability of OOB data. An array of strings with the\n\t\tfollowing allowed values:\n\t\t\t\"other\"\n\t\t\t\"uri\"\n\t\t\t\"machine-code-2d\"\n\t\t\t\"bar-code\"\n\t\t\t\"nfc\"\n\t\t\t\"number\"\n\t\t\t\"string\"\n\t\t\t\"on-box\"\n\t\t\t\"in-box\"\n\t\t\t\"on-paper\",\n\t\t\t\"in-manual\"\n\t\t\t\"on-device\"","Flags":[1,5]},{"Name":"URI","Type":"string","Docs":"Uniform Resource Identifier points to out-of-band (OOB)\n\t\tinformation (e.g., a public key)","Flags":[1,5]}]}]},{"FileName":"network-api.txt","Name":"BlueZ D-Bus Network API description","Description":"\n","Api":[{"Title":"Network hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Network1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"string","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.AlreadyConnected","org.bluez.Error.AlreadyConnected"],"Docs":"\t\t\tConnect to the network device and return the network\n\t\t\tinterface name. Examples of the interface name are\n\t\t\tbnep0, bnep1 etc.\n\t\t\tuuid can be either one of \"gn\", \"panu\" or \"nap\" (case\n\t\t\tinsensitive) or a traditional string representation of\n\t\t\tUUID or a hexadecimal number.\n\t\t\tThe connection will be closed and network device\n\t\t\treleased either upon calling Disconnect() or when\n\t\t\tthe client disappears from the message bus.\n\t\t\tPossible errors: org.bluez.Error.AlreadyConnected\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnect from the network device.\n\t\t\tTo abort a connection attempt in case of errors or\n\t\t\ttimeouts in the client it is fine to call this method.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if the device is connected.","Flags":[]},{"Name":"Interface","Type":"string","Docs":"Indicates the network interface name when available.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"Indicates the connection role when available.","Flags":[]}]},{"Title":"Network server hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.NetworkServer1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"Register","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"},{"Type":"string","Name":"bridge"}],"Errors":null,"Docs":"\t\t\tRegister server for the provided UUID. Every new\n\t\t\tconnection to this server will be added the bridge\n\t\t\tinterface.\n\t\t\tValid UUIDs are \"gn\", \"panu\" or \"nap\".\n\t\t\tInitially no network server SDP is provided. Only\n\t\t\tafter this method a SDP record will be available\n\t\t\tand the BNEP server will be ready for incoming\n\t\t\tconnections.\n"},{"Name":"Unregister","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":null,"Docs":"\t\t\tUnregister the server for provided UUID.\n\t\t\tAll servers will be automatically unregistered when\n\t\t\tthe calling application terminates.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-agent-api.txt","Name":"OBEX D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.AgentManager1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tRegister an agent to request authorization of\n\t\t\tthe user to accept/reject objects. Object push\n\t\t\tservice needs to authorize each received object.\n\t\t\tPossible errors: org.bluez.obex.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.obex.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.obex.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"AuthorizePush","ReturnType":"string","Args":[{"Type":"object","Name":"transfer"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to accept/reject a Bluetooth object push request.\n\t\t\tReturns the full path (including the filename) where\n\t\t\tthe object shall be stored. The tranfer object will\n\t\t\tcontain a Filename property that contains the default\n\t\t\tlocation and name that can be returned.\n\t\t\tPossible errors: org.bluez.obex.Error.Rejected\n\t\t\t org.bluez.obex.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned. It cancels\n\t\t\tthe previous request.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-api.txt","Name":"OBEX D-Bus API description","Description":"\n","Api":[{"Title":"Client hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Client1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"CreateSession","ReturnType":"object","Args":[{"Type":"string","Name":"destination"},{"Type":"dict","Name":"args"}],"Errors":null,"Docs":"\t\t\tCreate a new OBEX session for the given remote address.\n\t\t\tThe last parameter is a dictionary to hold optional or\n\t\t\ttype-specific parameters. Typical parameters that can\n\t\t\tbe set in this dictionary include the following:\n\t\t\t\tstring \"Target\" : type of session to be created\n\t\t\t\tstring \"Source\" : local address to be used\n\t\t\t\tbyte \"Channel\"\n\t\t\tThe currently supported targets are the following:\n\t\t\t\t\"ftp\"\n\t\t\t\t\"map\"\n\t\t\t\t\"opp\"\n\t\t\t\t\"pbap\"\n\t\t\t\t\"sync\"\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"RemoveSession","ReturnType":"void","Args":[{"Type":"object","Name":"session"}],"Errors":null,"Docs":"\t\t\tUnregister session and abort pending transfers.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.NotAuthorized\n"}],"Signals":[],"Properties":[]},{"Title":"Session hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Session1","ObjectPath":"/org/bluez/obex/server/session{0, 1, 2, ...} or\n\t\t/org/bluez/obex/client/session{0, 1, 2, ...}","Methods":[{"Name":"GetCapabilities","ReturnType":"string","Args":[],"Errors":null,"Docs":"\t\t\tGet remote device capabilities.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Source","Type":"string","Docs":"Bluetooth adapter address","Flags":[]},{"Name":"Destination","Type":"string","Docs":"Bluetooth device address","Flags":[]},{"Name":"Channel","Type":"byte","Docs":"Bluetooth channel","Flags":[]},{"Name":"Target","Type":"string","Docs":"Target UUID","Flags":[]},{"Name":"Root","Type":"string","Docs":"Root path","Flags":[]}]},{"Title":"Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Transfer1","ObjectPath":"[Session object path]/transfer{0, 1, 2, ...}","Methods":[{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStops the current transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.InProgress\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Suspend","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tSuspend transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to suspend transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"},{"Name":"Resume","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to resume transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"}],"Signals":[],"Properties":[{"Name":"Status","Type":"string","Docs":"Inform the current status of the transfer.\n\n\t\t\tPossible values: \"queued\", \"active\", \"suspended\",\n\t\t\t\t\t\"complete\" or \"error\"","Flags":[]},{"Name":"Session","Type":"object","Docs":"The object path of the session the transfer belongs\n\t\t\tto.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Name of the transferred object. Either Name or Type\n\t\t\tor both will be present.","Flags":[]},{"Name":"Type","Type":"string","Docs":"Type of the transferred object. Either Name or Type\n\t\t\tor both will be present.\n\n\t\tuint64 Time [readonly, optional]\n\n\t\t\tTime of the transferred object if this is\n\t\t\tprovided by the remote party.\n\n\t\tuint64 Size [readonly, optional]\n\n\t\t\tSize of the transferred object. If the size is\n\t\t\tunknown, then this property will not be present.\n\n\t\tuint64 Transferred [readonly, optional]\n\n\t\t\tNumber of bytes transferred. For queued transfers, this\n\t\t\tvalue will not be present.","Flags":[]},{"Name":"Filename","Type":"string","Docs":"Complete name of the file being received or sent.\n\n\t\t\tFor incoming object push transaction, this will be\n\t\t\tthe proposed default location and name. It can be\n\t\t\toverwritten by the AuthorizePush agent callback\n\t\t\tand will be then updated accordingly.","Flags":[5]}]},{"Title":"Object Push hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.ObjectPush1","ObjectPath":"[Session object path]","Methods":[{"Name":"SendFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend one local file to the remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullBusinessCard","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRequest the business card from a remote device and\n\t\t\tstore it in the local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ExchangeBusinessCards","ReturnType":"object, dict","Args":[{"Type":"string","Name":"clientfile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tPush the client's business card to the remote device\n\t\t\tand then retrieve the remote business card and store\n\t\t\tit in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"File Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.FileTransfer","ObjectPath":"[Session object path]","Methods":[{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tChange the current folder of the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CreateFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tCreate a new folder in the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolder","ReturnType":"array{dict}","Args":[],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Object name in UTF-8 format\n\t\t\t\tstring Type : Either \"folder\" or \"file\"\n\t\t\t\tuint64 Size : Object size or number of items in\n\t\t\t\t\t\tfolder\n\t\t\t\tstring Permission : Group, owner and other\n\t\t\t\t\t\t\tpermission\n\t\t\t\tuint64 Modified : Last change\n\t\t\t\tuint64 Accessed : Last access\n\t\t\t\tuint64 Created : Creation date\n\t\t\tPossible errors: org.bluez.obex.Error.Failed\n"},{"Name":"GetFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from remote device) to the\n\t\t\ttarget file (on local filesystem).\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from local filesystem) to the\n\t\t\ttarget file (on remote device).\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CopyFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy a file within the remote device from source file\n\t\t\tto target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"MoveFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tMove a file within the remote device from source file\n\t\t\tto the target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Delete","ReturnType":"void","Args":[{"Type":"string","Name":"file"}],"Errors":null,"Docs":"\t\t\tDeletes the specified file/folder.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Phonebook Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.PhonebookAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"Select","ReturnType":"void","Args":[{"Type":"string","Name":"location"},{"Type":"string","Name":"phonebook"}],"Errors":null,"Docs":"\t\t\tSelect the phonebook object for other operations. Should\n\t\t\tbe call before all the other operations.\n\t\t\tlocation : Where the phonebook is stored, possible\n\t\t\tinputs :\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim\" ( \"sim1\" )\n\t\t\t\t\"sim2\"\n\t\t\t\t...\n\t\t\tphonebook : Possible inputs :\n\t\t\t\t\"pb\" :\tphonebook for the saved contacts\n\t\t\t\t\"ich\":\tincoming call history\n\t\t\t\t\"och\":\toutgoing call history\n\t\t\t\t\"mch\":\tmissing call history\n\t\t\t\t\"cch\":\tcombination of ich och mch\n\t\t\t\t\"spd\":\tspeed dials entry ( only for \"internal\" )\n\t\t\t\t\"fav\":\tfavorites entry ( only for \"internal\" )\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullAll","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn the entire phonebook object from the PSE server\n\t\t\tin plain string with vcard format, and store it in\n\t\t\ta local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible filters: Format, Order, Offset, MaxCount and\n\t\t\tFields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\torg.bluez.obex.Forbidden\n"},{"Name":"List","ReturnType":"array{string vcard, string name}","Args":[{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name. For example:\n\t\t\t\t\"1.vcf\" : \"John\"\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Forbidden\n"},{"Name":"Pull","ReturnType":"object, dict","Args":[{"Type":"string","Name":"vcard"},{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tGiven a vcard handle, retrieve the vcard in the current\n\t\t\tphonebook object and store it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossbile filters: Format and Fields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Search","ReturnType":"array{string vcard, string name}","Args":[{"Type":"string","Name":"field"},{"Type":"string","Name":"value"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tSearch for entries matching the given condition and\n\t\t\treturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name.\n\t\t\tvcard : name paired string match the search condition.\n\t\t\tfield : the field in the vcard to search with\n\t\t\t\t{ \"name\" (default) | \"number\" | \"sound\" }\n\t\t\tvalue : the string value to search for\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"GetSize","ReturnType":"uint16","Args":[],"Errors":null,"Docs":"\t\t\tReturn the number of entries in the selected phonebook\n\t\t\tobject that are actually used (i.e. indexes that\n\t\t\tcorrespond to non-NULL entries).\n\t\t\tPossible errors: org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateVersion","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAttempt to update PrimaryCounter and SecondaryCounter.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn All Available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Current folder.","Flags":[]},{"Name":"DatabaseIdentifier","Type":"string","Docs":"128 bits persistent database identifier.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"PrimaryCounter","Type":"string","Docs":"128 bits primary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"SecondaryCounter","Type":"string","Docs":"128 bits secondary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"FixedImageSize","Type":"bool","Docs":"Indicate support for fixed image size.\n\n\t\t\tPossible values: True if image is JPEG 300x300 pixels\n\t\t\totherwise False.","Flags":[5]}]},{"Title":"Synchronization hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Synchronization1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetLocation","ReturnType":"void","Args":[{"Type":"string","Name":"location"}],"Errors":null,"Docs":"\t\t\tSet the phonebook object store location for other\n\t\t\toperations. Should be called before all the other\n\t\t\toperations.\n\t\t\tlocation: Where the phonebook is stored, possible\n\t\t\tvalues:\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim1\"\n\t\t\t\t\"sim2\"\n\t\t\t\t......\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n"},{"Name":"GetPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRetrieve an entire Phonebook Object store from remote\n\t\t\tdevice, and stores it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend an entire Phonebook Object store to remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Message Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.MessageAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetFolder","ReturnType":"void","Args":[{"Type":"string","Name":"name"}],"Errors":null,"Docs":"\t\t\tSet working directory for current session, *name* may\n\t\t\tbe the directory name or '..[/dir]'.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolders","ReturnType":"array{dict}","Args":[{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Folder name\n\t\t\tPossible filters: Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn all available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"},{"Name":"ListMessages","ReturnType":"array{object, dict}","Args":[{"Type":"string","Name":"folder"},{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns an array containing the messages found in the\n\t\t\tgiven subfolder of the current folder, or in the\n\t\t\tcurrent folder if folder is empty.\n\t\t\tPossible Filters: Offset, MaxCount, SubjectLength, Fields,\n\t\t\tType, PeriodStart, PeriodEnd, Status, Recipient, Sender,\n\t\t\tPriority\n\t\t\tEach message is represented by an object path followed\n\t\t\tby a dictionary of the properties.\n\t\t\tProperties:\n\t\t\t\tstring Subject:\n\t\t\t\t\tMessage subject\n\t\t\t\tstring Timestamp:\n\t\t\t\t\tMessage timestamp\n\t\t\t\tstring Sender:\n\t\t\t\t\tMessage sender name\n\t\t\t\tstring SenderAddress:\n\t\t\t\t\tMessage sender address\n\t\t\t\tstring ReplyTo:\n\t\t\t\t\tMessage Reply-To address\n\t\t\t\tstring Recipient:\n\t\t\t\t\tMessage recipient name\n\t\t\t\tstring RecipientAddress:\n\t\t\t\t\tMessage recipient address\n\t\t\t\tstring Type:\n\t\t\t\t\tMessage type\n\t\t\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\t\t\"sms-cdma\" and \"mms\"\n\t\t\t\tuint64 Size:\n\t\t\t\t\tMessage size in bytes\n\t\t\t\tboolean Text:\n\t\t\t\t\tMessage text flag\n\t\t\t\t\tSpecifies whether message has textual\n\t\t\t\t\tcontent or is binary only\n\t\t\t\tstring Status:\n\t\t\t\t\tMessage status\n\t\t\t\t\tPossible values for received messages:\n\t\t\t\t\t\"complete\", \"fractioned\", \"notification\"\n\t\t\t\t\tPossible values for sent messages:\n\t\t\t\t\t\"delivery-success\", \"sending-success\",\n\t\t\t\t\t\"delivery-failure\", \"sending-failure\"\n\t\t\t\tuint64 AttachmentSize:\n\t\t\t\t\tMessage overall attachment size in bytes\n\t\t\t\tboolean Priority:\n\t\t\t\t\tMessage priority flag\n\t\t\t\tboolean Read:\n\t\t\t\t\tMessage read flag\n\t\t\t\tboolean Sent:\n\t\t\t\t\tMessage sent flag\n\t\t\t\tboolean Protected:\n\t\t\t\t\tMessage protected flag\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateInbox","ReturnType":"void","Args":null,"Errors":null,"Docs":""}],"Signals":[],"Properties":[]},{"Title":"Message hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Message1","ObjectPath":"[Session object path]/{message0,...}","Methods":[{"Name":"Get","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"boolean","Name":"attachment"}],"Errors":null,"Docs":"\t\t\tDownload message and store it in the target file.\n\t\t\tIf an empty target file is given, a temporary file\n\t\t\twill be automatically generated.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Folder which the message belongs to","Flags":[]},{"Name":"Subject","Type":"string","Docs":"Message subject","Flags":[]},{"Name":"Timestamp","Type":"string","Docs":"Message timestamp","Flags":[]},{"Name":"Sender","Type":"string","Docs":"Message sender name","Flags":[]},{"Name":"SenderAddress","Type":"string","Docs":"Message sender address","Flags":[]},{"Name":"ReplyTo","Type":"string","Docs":"Message Reply-To address","Flags":[]},{"Name":"Recipient","Type":"string","Docs":"Message recipient name","Flags":[]},{"Name":"RecipientAddress","Type":"string","Docs":"Message recipient address","Flags":[]},{"Name":"Type","Type":"string","Docs":"Message type\n\n\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\"sms-cdma\" and \"mms\"\n\n\t\tuint64 Size [readonly]\n\n\t\t\tMessage size in bytes","Flags":[]},{"Name":"Status","Type":"string","Docs":"Message reception status\n\n\t\t\tPossible values: \"complete\",\n\t\t\t\"fractioned\" and \"notification\"","Flags":[]},{"Name":"Priority","Type":"boolean","Docs":"Message priority flag","Flags":[]},{"Name":"Read","Type":"boolean","Docs":"Message read flag","Flags":[3]},{"Name":"Deleted","Type":"boolean","Docs":"Message deleted flag","Flags":[]},{"Name":"Sent","Type":"boolean","Docs":"Message sent flag","Flags":[]},{"Name":"Protected","Type":"boolean","Docs":"Message protected flag","Flags":[]}]}]},{"FileName":"profile-api.txt","Name":"BlueZ D-Bus Profile API description","Description":"\n","Api":[{"Title":"Profile Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ProfileManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"},{"Type":"string","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers a profile implementation.\n\t\t\tIf an application disconnects from the bus all\n\t\t\tits registered profiles will be removed.\n\t\t\tHFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault RFCOMM channel is 6. And this requires\n\t\t\t\tauthentication.\n\t\t\tAvailable options:\n\t\t\t\tstring Name\n\t\t\t\t\tHuman readable name for the profile\n\t\t\t\tstring Service\n\t\t\t\t\tThe primary service class UUID\n\t\t\t\t\t(if different from the actual\n\t\t\t\t\t profile UUID)\n\t\t\t\tstring Role\n\t\t\t\t\tFor asymmetric profiles that do not\n\t\t\t\t\thave UUIDs available to uniquely\n\t\t\t\t\tidentify each side this\n\t\t\t\t\tparameter allows specifying the\n\t\t\t\t\tprecise local role.\n\t\t\t\t\tPossible values: \"client\", \"server\"\n\t\t\t\tuint16 Channel\n\t\t\t\t\tRFCOMM channel number that is used\n\t\t\t\t\tfor client and server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tuint16 PSM\n\t\t\t\t\tPSM number that is used for client\n\t\t\t\t\tand server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tboolean RequireAuthentication\n\t\t\t\t\tPairing is required before connections\n\t\t\t\t\twill be established. No devices will\n\t\t\t\t\tbe connected if not paired.\n\t\t\t\tboolean RequireAuthorization\n\t\t\t\t\tRequest authorization before any\n\t\t\t\t\tconnection will be established.\n\t\t\t\tboolean AutoConnect\n\t\t\t\t\tIn case of a client UUID this will\n\t\t\t\t\tforce connection of the RFCOMM or\n\t\t\t\t\tL2CAP channels when a remote device\n\t\t\t\t\tis connected.\n\t\t\t\tstring ServiceRecord\n\t\t\t\t\tProvide a manual SDP record.\n\t\t\t\tuint16 Version\n\t\t\t\t\tProfile version (for SDP record)\n\t\t\t\tuint16 Features\n\t\t\t\t\tProfile features (for SDP record)\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the profile that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Profile hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Profile1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. A profile can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"NewConnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"int32","Name":"fd"},{"Type":"dict","Name":"fd_properties"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a new service level\n\t\t\tconnection has been made and authorized.\n\t\t\tCommon fd_properties:\n\t\t\tuint16 Version\t\tProfile version (optional)\n\t\t\tuint16 Features\t\tProfile features (optional)\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestDisconnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a profile gets\n\t\t\tdisconnected.\n\t\t\tThe file descriptor is no longer owned by the service\n\t\t\tdaemon and the profile implementation needs to take\n\t\t\tcare of cleaning up all connections.\n\t\t\tIf multiple file descriptors are indicated via\n\t\t\tNewConnection, it is expected that all of them\n\t\t\tare disconnected before returning from this\n\t\t\tmethod call.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"}],"Signals":[],"Properties":[]}]},{"FileName":"sap-api.txt","Name":"BlueZ D-Bus Sim Access API description","Description":"\n","Api":[{"Title":"Sim Access Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.SimAccess1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnects SAP client from the server.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if SAP client is connected to the server.","Flags":[]}]}]},{"FileName":"thermometer-api.txt","Name":"BlueZ D-Bus Thermometer API description","Description":"\tSantiago Carot-Nemesio \u003csancane@gmail.com\u003e\n\n","Api":[{"Title":"Health Thermometer Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ThermometerManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a watcher to monitor scanned measurements.\n\t\t\tThis agent will be notified about final temperature\n\t\t\tmeasurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"UnregisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tUnregisters a watcher.\n"},{"Name":"EnableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tEnables intermediate measurement notifications\n\t\t\tfor this agent. Intermediate measurements will\n\t\t\tbe enabled only for thermometers which support it.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DisableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDisables intermediate measurement notifications\n\t\t\tfor this agent. It will disable notifications in\n\t\t\tthermometers when the last agent removes the\n\t\t\twatcher for intermediate measurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\torg.bluez.Error.NotFound\n"}],"Signals":[],"Properties":[]},{"Title":"Health Thermometer Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Thermometer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Intermediate","Type":"boolean","Docs":"True if the thermometer supports intermediate\n\t\t\tmeasurement notifications.","Flags":[]},{"Name":"Interval","Type":"uint16","Docs":"(optional) The Measurement Interval defines the time (in\n\t\t\tseconds) between measurements. This interval is\n\t\t\tnot related to the intermediate measurements and\n\t\t\tmust be defined into a valid range. Setting it\n\t\t\tto zero means that no periodic measurements will\n\t\t\tbe taken.","Flags":[5]},{"Name":"Maximum","Type":"uint16","Docs":"(optional) Defines the maximum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]},{"Name":"Minimum","Type":"uint16","Docs":"(optional) Defines the minimum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]}]},{"Title":"Health Thermometer Watcher hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.ThermometerWatcher1","ObjectPath":"freely definable","Methods":[{"Name":"MeasurementReceived","ReturnType":"void","Args":[{"Type":"dict","Name":"measurement"}],"Errors":null,"Docs":"\t\t\tThis callback gets called when a measurement has been\n\t\t\tscanned in the thermometer.\n\t\t\tMeasurement:\n\t\t\t\tint16 Exponent:\n\t\t\t\tint32 Mantissa:\n\t\t\t\t\tExponent and Mantissa values as\n\t\t\t\t\textracted from float value defined by\n\t\t\t\t\tIEEE-11073-20601.\n\t\t\t\t\tMeasurement value is calculated as\n\t\t\t\t\t(Mantissa) * (10^Exponent)\n\t\t\t\t\tFor special cases Exponent is\n\t\t\t\t\tset to 0 and Mantissa is set to\n\t\t\t\t\tone of following values:\n\t\t\t\t\t+(2^23 - 1)\tNaN (invalid or\n\t\t\t\t\t\t\tmissing data)\n\t\t\t\t\t-(2^23)\t\tNRes\n\t\t\t\t\t+(2^23 - 2)\t+Infinity\n\t\t\t\t\t-(2^23 - 2)\t-Infinity\n\t\t\t\tstring Unit:\n\t\t\t\t\tPossible values: \"celsius\" or\n\t\t\t\t\t\t\t\"fahrenheit\"\n\t\t\t\tuint64 Time (optional):\n\t\t\t\t\tTime of measurement, if\n\t\t\t\t\tsupported by device.\n\t\t\t\t\tExpressed in seconds since epoch.\n\t\t\t\tstring Type (optional):\n\t\t\t\t\tOnly present if measurement type\n\t\t\t\t\tis known.\n\t\t\t\t\tPossible values: \"armpit\", \"body\",\n\t\t\t\t\t\t\"ear\", \"finger\", \"intestines\",\n\t\t\t\t\t\t\"mouth\", \"rectum\", \"toe\",\n\t\t\t\t\t\t\"tympanum\"\n\t\t\t\tstring Measurement:\n\t\t\t\t\tPossible values: \"final\" or\n\t\t\t\t\t\t\t\"intermediate\"\n"}],"Signals":[],"Properties":[]}]}]}go-bluetooth-bluez-5.60/bluez-5.55.json000077500000000000000000005217011420407601400176100ustar00rootroot00000000000000{"Version":"5.55","Api":[{"FileName":"adapter-api.txt","Name":"BlueZ D-Bus Adapter API description","Description":"\n","Api":[{"Title":"Adapter hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Adapter1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"StartDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method starts the device discovery session. This\n\t\t\tincludes an inquiry procedure and remote device name\n\t\t\tresolving. Use StopDiscovery to release the sessions\n\t\t\tacquired.\n\t\t\tThis process will start creating Device objects as\n\t\t\tnew devices are discovered.\n\t\t\tDuring discovery RSSI delta-threshold is imposed.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"StopDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method will cancel any previous StartDiscovery\n\t\t\ttransaction.\n\t\t\tNote that a discovery procedure is shared between all\n\t\t\tdiscovery sessions thus calling StopDiscovery will only\n\t\t\trelease a single session.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n"},{"Name":"RemoveDevice","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis removes the remote device object at the given\n\t\t\tpath. It will remove also the pairing information.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"SetDiscoveryFilter","ReturnType":"void","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method sets the device discovery filter for the\n\t\t\tcaller. When this method is called with no filter\n\t\t\tparameter, filter is removed.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tarray{string} UUIDs\n\t\t\t\tFilter by service UUIDs, empty means match\n\t\t\t\t_any_ UUID.\n\t\t\t\tWhen a remote device is found that advertises\n\t\t\t\tany UUID from UUIDs, it will be reported if:\n\t\t\t\t- Pathloss and RSSI are both empty.\n\t\t\t\t- only Pathloss param is set, device advertise\n\t\t\t\t TX pwer, and computed pathloss is less than\n\t\t\t\t Pathloss param.\n\t\t\t\t- only RSSI param is set, and received RSSI is\n\t\t\t\t higher than RSSI param.\n\t\t\tint16 RSSI\n\t\t\t\tRSSI threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated RSSI value. If one or more discovery\n\t\t\t\tfilters have been set, the RSSI delta-threshold,\n\t\t\t\tthat is imposed by StartDiscovery by default,\n\t\t\t\twill not be applied.\n\t\t\tuint16 Pathloss\n\t\t\t\tPathloss threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated Pathloss value.\n\t\t\tstring Transport (Default \"auto\")\n\t\t\t\tTransport parameter determines the type of\n\t\t\t\tscan.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"auto\"\t- interleaved scan\n\t\t\t\t\t\"bredr\"\t- BR/EDR inquiry\n\t\t\t\t\t\"le\"\t- LE scan only\n\t\t\t\tIf \"le\" or \"bredr\" Transport is requested,\n\t\t\t\tand the controller doesn't support it,\n\t\t\t\torg.bluez.Error.Failed error will be returned.\n\t\t\t\tIf \"auto\" transport is requested, scan will use\n\t\t\t\tLE, BREDR, or both, depending on what's\n\t\t\t\tcurrently enabled on the controller.\n\t\t\tbool DuplicateData (Default: true)\n\t\t\t\tDisables duplicate detection of advertisement\n\t\t\t\tdata.\n\t\t\t\tWhen enabled PropertiesChanged signals will be\n\t\t\t\tgenerated for either ManufacturerData and\n\t\t\t\tServiceData everytime they are discovered.\n\t\t\tbool Discoverable (Default: false)\n\t\t\t\tMake adapter discoverable while discovering,\n\t\t\t\tif the adapter is already discoverable setting\n\t\t\t\tthis filter won't do anything.\n\t\t\tstring Pattern (Default: none)\n\t\t\t\tDiscover devices where the pattern matches\n\t\t\t\teither the prefix of the address or\n\t\t\t\tdevice name which is convenient way to limited\n\t\t\t\tthe number of device objects created during a\n\t\t\t\tdiscovery.\n\t\t\t\tWhen set disregards device discoverable flags.\n\t\t\t\tNote: The pattern matching is ignored if there\n\t\t\t\tare other client that don't set any pattern as\n\t\t\t\tit work as a logical OR, also setting empty\n\t\t\t\tstring \"\" pattern will match any device found.\n\t\t\tWhen discovery filter is set, Device objects will be\n\t\t\tcreated as new devices with matching criteria are\n\t\t\tdiscovered regardless of they are connectable or\n\t\t\tdiscoverable which enables listening to\n\t\t\tnon-connectable and non-discoverable devices.\n\t\t\tWhen multiple clients call SetDiscoveryFilter, their\n\t\t\tfilters are internally merged, and notifications about\n\t\t\tnew devices are sent to all clients. Therefore, each\n\t\t\tclient must check that device updates actually match\n\t\t\tits filter.\n\t\t\tWhen SetDiscoveryFilter is called multiple times by the\n\t\t\tsame client, last filter passed will be active for\n\t\t\tgiven client.\n\t\t\tSetDiscoveryFilter can be called before StartDiscovery.\n\t\t\tIt is useful when client will create first discovery\n\t\t\tsession, to ensure that proper scan will be started\n\t\t\tright after call to StartDiscovery.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"GetDiscoveryFilters","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn available filters that can be given to\n\t\t\tSetDiscoveryFilter.\n\t\t\tPossible errors: None\n"},{"Name":"ConnectDevice","ReturnType":"object","Args":[{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method connects to device without need of\n\t\t\tperforming General Discovery. Connection mechanism is\n\t\t\tsimilar to Connect method from Device1 interface with\n\t\t\texception that this method returns success when physical\n\t\t\tconnection is established. After this method returns,\n\t\t\tservices discovery will continue and any supported\n\t\t\tprofile will be connected. There is no need for calling\n\t\t\tConnect on Device1 after this call. If connection was\n\t\t\tsuccessful this method returns object path to created\n\t\t\tdevice object.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tstring Address\n\t\t\t\tThe Bluetooth device address of the remote\n\t\t\t\tdevice. This parameter is mandatory.\n\t\t\tstring AddressType\n\t\t\t\tThe Bluetooth device Address Type. This is\n\t\t\t\taddress type that should be used for initial\n\t\t\t\tconnection. If this parameter is not present\n\t\t\t\tBR/EDR device is created.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"public\" - Public address\n\t\t\t\t\t\"random\" - Random address\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth Address Type. For dual-mode and BR/EDR\n\t\t\tonly adapter this defaults to \"public\". Single mode LE\n\t\t\tadapters may have either value. With privacy enabled\n\t\t\tthis contains type of Identity Address and not type of\n\t\t\taddress used for connection.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth system name (pretty hostname).\n\n\t\t\tThis property is either a static system default\n\t\t\tor controlled by an external daemon providing\n\t\t\taccess to the pretty hostname configuration.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The Bluetooth friendly name. This value can be\n\t\t\tchanged.\n\n\t\t\tIn case no alias is set, it will return the system\n\t\t\tprovided name. Setting an empty string as alias will\n\t\t\tconvert it back to the system provided name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to system name.\n\n\t\t\tOn a well configured system, this property never\n\t\t\tneeds to be changed since it defaults to the system\n\t\t\tname and provides the pretty hostname. Only if the\n\t\t\tlocal name needs to be different from the pretty\n\t\t\thostname, this property should be used as last\n\t\t\tresort.","Flags":[]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device.\n\n\t\t\tThis property represents the value that is either\n\t\t\tautomatically configured by DMI/ACPI information\n\t\t\tor provided as static configuration.","Flags":[]},{"Name":"Powered","Type":"boolean","Docs":"Switch an adapter on or off. This will also set the\n\t\t\tappropriate connectable state of the controller.\n\n\t\t\tThe value of this property is not persistent. After\n\t\t\trestart or unplugging of the adapter it will reset\n\t\t\tback to false.","Flags":[]},{"Name":"Discoverable","Type":"boolean","Docs":"Switch an adapter to discoverable or non-discoverable\n\t\t\tto either make it visible or hide it. This is a global\n\t\t\tsetting and should only be used by the settings\n\t\t\tapplication.\n\n\t\t\tIf the DiscoverableTimeout is set to a non-zero\n\t\t\tvalue then the system will set this value back to\n\t\t\tfalse after the timer expired.\n\n\t\t\tIn case the adapter is switched off, setting this\n\t\t\tvalue will fail.\n\n\t\t\tWhen changing the Powered property the new state of\n\t\t\tthis property will be updated via a PropertiesChanged\n\t\t\tsignal.\n\n\t\t\tFor any new adapter this settings defaults to false.","Flags":[]},{"Name":"Pairable","Type":"boolean","Docs":"Switch an adapter to pairable or non-pairable. This is\n\t\t\ta global setting and should only be used by the\n\t\t\tsettings application.\n\n\t\t\tNote that this property only affects incoming pairing\n\t\t\trequests.\n\n\t\t\tFor any new adapter this settings defaults to true.","Flags":[]},{"Name":"PairableTimeout","Type":"uint32","Docs":"The pairable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tpairable mode forever.\n\n\t\t\tThe default value for pairable timeout should be\n\t\t\tdisabled (value 0).","Flags":[]},{"Name":"DiscoverableTimeout","Type":"uint32","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tThe default value for the discoverable timeout should\n\t\t\tbe 180 seconds (3 minutes).","Flags":[]},{"Name":"Discovering","Type":"boolean","Docs":"Indicates that a device discovery procedure is active.","Flags":[]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tlocal services.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Local Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"Roles","Type":"array{string}","Docs":"List of supported roles. Possible values:\n\t\t\t\t\"central\": Supports the central role.\n\t\t\t\t\"peripheral\": Supports the peripheral role.\n\t\t\t\t\"central-peripheral\": Supports both roles\n\t\t\t\t\t\t concurrently.","Flags":[]}]}]},{"FileName":"advertisement-monitor-api.txt","Name":"BlueZ D-Bus Advertisement Monitor API Description","Description":"This API allows an client to specify a job of monitoring advertisements by\nregistering the root of hierarchy and then exposing advertisement monitors\nunder the root with filtering conditions, thresholds of RSSI and timers\nof RSSI thresholds.\n\nOnce a monitoring job is activated by BlueZ, the client can expect to get\nnotified on the targeted advertisements no matter if there is an ongoing\ndiscovery session (a discovery session is started/stopped with methods in\norg.bluez.Adapter1 interface).\n\n","Api":[{"Title":"Advertisement Monitor hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdvertisementMonitor1 [experimental]","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis gets called as a signal for a client to perform\n\t\t\tclean-up when (1)a monitor cannot be activated after it\n\t\t\twas exposed or (2)a monitor has been deactivated.\n"},{"Name":"Activate","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAfter a monitor was exposed, this gets called as a\n\t\t\tsignal for client to get acknowledged when a monitor\n\t\t\thas been activated, so the client can expect to receive\n\t\t\tcalls on DeviceFound() or DeviceLost().\n"},{"Name":"DeviceFound","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":null,"Docs":"\t\t\tThis gets called to notify the client of finding the\n\t\t\ttargeted device. Once receiving the call, the client\n\t\t\tshould start to monitor the corresponding device to\n\t\t\tretrieve the changes on RSSI and advertisement content.\n"},{"Name":"DeviceLost","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":null,"Docs":"\t\t\tThis gets called to notify the client of losing the\n\t\t\ttargeted device. Once receiving this call, the client\n\t\t\tshould stop monitoring the corresponding device.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The type of the monitor. See SupportedMonitorTypes in\n\t\t\torg.bluez.AdvertisementMonitorManager1 for the available\n\t\t\toptions.\n\n\t\t(Int16, Uint16, Int16, Uint16) RSSIThreshholdsAndTimers [read-only, optional]\n\n\t\t\tThis contains HighRSSIThreshold, HighRSSIThresholdTimer,\n\t\t\tLowRSSIThreshold, LowRSSIThresholdTimer in order. The\n\t\t\tunit of HighRSSIThreshold and LowRSSIThreshold is dBm.\n\t\t\tThe unit of HighRSSIThresholdTimer and\n\t\t\tLowRSSIThresholdTimer is second.\n\n\t\t\tIf these are provided, RSSI would be used as a factor to\n\t\t\tnotify the client of whether a device stays in range or\n\t\t\tmove out of range. A device is considered in-range when\n\t\t\tthe RSSIs of the received advertisement(s) during\n\t\t\tHighRSSIThresholdTimer seconds exceed HighRSSIThreshold.\n\t\t\tLikewise, a device is considered out-of-range when the\n\t\t\tRSSIs of the received advertisement(s) during\n\t\t\tLowRSSIThresholdTimer do not reach LowRSSIThreshold.","Flags":[1]},{"Name":"Patterns","Type":"array{(uint8, uint8, string)}","Docs":"If Type is set to 0x01, this must exist and has at least\n\t\t\tone entry in the array.\n\n\t\t\tThe structure of a pattern contains the following.\n\t\t\tuint8 start_position\n\t\t\t\tThe index in an AD data field where the search\n\t\t\t\tshould start. The beginning of an AD data field\n\t\t\t\tis index 0.\n\t\t\tuint8 AD_data_type\n\t\t\t\tSee https://www.bluetooth.com/specifications/\n\t\t\t\tassigned-numbers/generic-access-profile/ for\n\t\t\t\tthe possible allowed value.\n\t\t\tstring content_of_pattern\n\t\t\t\tThis is the value of the pattern.","Flags":[1,5]}]},{"Title":"Advertisement Monitor Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdvertisementMonitorManager1 [experimental]","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterMonitor","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers a hierarchy of advertisement monitors.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering advertisement monitors.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterMonitor","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters advertisement monitors that have been\n\t\t\tpreviously registered. The object path parameter must\n\t\t\tmatch the same value that has been used on\n\t\t\tregistration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"SupportedMonitorTypes","Type":"array{string}","Docs":"This lists the supported types of advertisement\n\t\t\tmonitors. An application should check this before\n\t\t\tinstantiate and expose an object of\n\t\t\torg.bluez.AdvertisementMonitor1.\n\n\t\t\tPossible values for monitor types:\n\n\t\t\t\"or_patterns\"\n\t\t\t\tPatterns with logic OR applied. With this type,\n\t\t\t\tproperty \"Patterns\" must exist and has at least\n\t\t\t\tone pattern.","Flags":[1]},{"Name":"SupportedFeatures","Type":"array{string}","Docs":"This lists the features of advertisement monitoring\n\t\t\tsupported by BlueZ.\n\n\t\t\tPossible values for features:\n\n\t\t\t\"controller-patterns\"\n\t\t\t\tIf the controller is capable of performing\n\t\t\t\tadvertisement monitoring by patterns, BlueZ\n\t\t\t\twould offload the patterns to the controller to\n\t\t\t\treduce power consumption.","Flags":[1]}]}]},{"FileName":"advertising-api.txt","Name":"BlueZ D-Bus LE Advertising API Description","Description":"Advertising packets are structured data which is broadcast on the LE Advertising\nchannels and available for all devices in range. Because of the limited space\navailable in LE Advertising packets (31 bytes), each packet's contents must be\ncarefully controlled.\n\nBlueZ acts as a store for the Advertisement Data which is meant to be sent.\nIt constructs the correct Advertisement Data from the structured\ndata and configured the kernel to send the correct advertisement.\n\nAdvertisement Data objects are registered freely and then referenced by BlueZ\nwhen constructing the data sent to the kernel.\n\n","Api":[{"Title":"LE Advertisement Data hierarchy","Description":"\nSpecifies the Advertisement Data to be broadcast and some advertising\nparameters. Properties which are not present will not be included in the\ndata. Required advertisement data types will always be included.\nAll UUIDs are 128-bit versions in the API, and 16 or 32-bit\nversions of the same UUID will be used in the advertising data as appropriate.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisement1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tremoves the Advertisement. A client can use it to do\n\t\t\tcleanup tasks. There is no need to call\n\t\t\tUnregisterAdvertisement because when this method gets\n\t\t\tcalled it has already been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"Determines the type of advertising packet requested.\n\n\t\t\tPossible values: \"broadcast\" or \"peripheral\"","Flags":[]},{"Name":"ServiceUUIDs","Type":"array{string}","Docs":"List of UUIDs to include in the \"Service UUID\" field of\n\t\t\tthe Advertising Data.","Flags":[]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufactuer Data fields to include in\n\t\t\tthe Advertising Data. Keys are the Manufacturer ID\n\t\t\tto associate with the data.","Flags":[]},{"Name":"SolicitUUIDs","Type":"array{string}","Docs":"Array of UUIDs to include in \"Service Solicitation\"\n\t\t\tAdvertisement Data.","Flags":[]},{"Name":"ServiceData","Type":"dict","Docs":"Service Data elements to include. The keys are the\n\t\t\tUUID to associate with the data.","Flags":[]},{"Name":"Data","Type":"dict","Docs":"Advertising Type to include in the Advertising\n\t\t\tData. Key is the advertising type and value is the\n\t\t\tdata as byte array.\n\n\t\t\tNote: Types already handled by other properties shall\n\t\t\tnot be used.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[4]},{"Name":"Discoverable","Type":"bool","Docs":"Advertise as general discoverable. When present this\n\t\t\twill override adapter Discoverable property.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"DiscoverableTimeout","Type":"uint16","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"Includes","Type":"array{string}","Docs":"List of features to be included in the advertising\n\t\t\tpacket.\n\n\t\t\tPossible values: as found on\n\t\t\t\t\tLEAdvertisingManager.SupportedIncludes","Flags":[]},{"Name":"LocalName","Type":"string","Docs":"Local name to be used in the advertising report. If the\n\t\t\tstring is too big to fit into the packet it will be\n\t\t\ttruncated.\n\n\t\t\tIf this property is available 'local-name' cannot be\n\t\t\tpresent in the Includes.","Flags":[]},{"Name":"Appearance","Type":"uint16","Docs":"Appearance to be used in the advertising report.\n\n\t\t\tPossible values: as found on GAP Service.","Flags":[]},{"Name":"Duration","Type":"uint16_t","Docs":"Duration of the advertisement in seconds. If there are\n\t\t\tother applications advertising no duration is set the\n\t\t\tdefault is 2 seconds.","Flags":[]},{"Name":"Timeout","Type":"uint16_t","Docs":"Timeout of the advertisement in seconds. This defines\n\t\t\tthe lifetime of the advertisement.","Flags":[]},{"Name":"SecondaryChannel","Type":"string","Docs":"Secondary channel to be used. Primary channel is\n\t\t\talways set to \"1M\" except when \"Coded\" is set.\n\n\t\t\tPossible value: \"1M\" (default)\n\t\t\t\t\t\"2M\"\n\t\t\t\t\t\"Coded\"","Flags":[4]}]},{"Title":"LE Advertising Manager hierarchy","Description":"\nThe Advertising Manager allows external applications to register Advertisement\nData which should be broadcast to devices. Advertisement Data elements must\nfollow the API for LE Advertisement Data described above.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisingManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters an advertisement object to be sent over the LE\n\t\t\tAdvertising channel. The service must be exported\n\t\t\tunder interface LEAdvertisement1.\n\t\t\tInvalidArguments error indicates that the object has\n\t\t\tinvalid or conflicting properties.\n\t\t\tInvalidLength error indicates that the data\n\t\t\tprovided generates a data packet which is too long.\n\t\t\tThe properties of this object are parsed when it is\n\t\t\tregistered, and any changes are ignored.\n\t\t\tIf the same object is registered twice it will result in\n\t\t\tan AlreadyExists error.\n\t\t\tIf the maximum number of advertisement instances is\n\t\t\treached it will result in NotPermitted error.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.InvalidLength\n\t\t\t\t\t org.bluez.Error.NotPermitted\n"},{"Name":"UnregisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters an advertisement that has been\n\t\t\tpreviously registered. The object path parameter must\n\t\t\tmatch the same value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"ActiveInstances","Type":"byte","Docs":"Number of active advertising instances.","Flags":[]},{"Name":"SupportedInstances","Type":"byte","Docs":"Number of available advertising instances.","Flags":[]},{"Name":"SupportedIncludes","Type":"array{string}","Docs":"List of supported system includes.\n\n\t\t\tPossible values: \"tx-power\"\n\t\t\t\t\t \"appearance\"\n\t\t\t\t\t \"local-name\"","Flags":[]},{"Name":"SupportedSecondaryChannels","Type":"array{string}","Docs":"List of supported Secondary channels. Secondary\n\t\t\tchannels can be used to advertise with the\n\t\t\tcorresponding PHY.\n\n\t\t\tPossible values: \"1M\"\n\t\t\t\t\t \"2M\"\n\t\t\t\t\t \"Coded\"","Flags":[4]}]}]},{"FileName":"agent-api.txt","Name":"BlueZ D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AgentManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"},{"Type":"string","Name":"capability"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers an agent handler.\n\t\t\tThe object path defines the path of the agent\n\t\t\tthat will be called when user input is needed.\n\t\t\tEvery application can register its own agent and\n\t\t\tfor all actions triggered by that application its\n\t\t\tagent is used.\n\t\t\tIt is not required by an application to register\n\t\t\tan agent. If an application does chooses to not\n\t\t\tregister an agent, the default agent is used. This\n\t\t\tis on most cases a good idea. Only application\n\t\t\tlike a pairing wizard should register their own\n\t\t\tagent.\n\t\t\tAn application can only register one agent. Multiple\n\t\t\tagents per application is not supported.\n\t\t\tThe capability parameter can have the values\n\t\t\t\"DisplayOnly\", \"DisplayYesNo\", \"KeyboardOnly\",\n\t\t\t\"NoInputNoOutput\" and \"KeyboardDisplay\" which\n\t\t\treflects the input and output capabilities of the\n\t\t\tagent.\n\t\t\tIf an empty string is used it will fallback to\n\t\t\t\"KeyboardDisplay\".\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"},{"Name":"RequestDefaultAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis requests is to make the application agent\n\t\t\tthe default agent. The application is required\n\t\t\tto register an agent.\n\t\t\tSpecial permission might be required to become\n\t\t\tthe default agent.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"RequestPinCode","ReturnType":"string","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a string of 1-16 characters\n\t\t\tlength. The string can be alphanumeric.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPinCode","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"pincode"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a pincode for an authentication.\n\t\t\tAn empty reply should be returned. When the pincode\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tThis is used during the pairing process of keyboards\n\t\t\tthat don't support Bluetooth 2.1 Secure Simple Pairing,\n\t\t\tin contrast to DisplayPasskey which is used for those\n\t\t\tthat do.\n\t\t\tThis method will only ever be called once since\n\t\t\tolder keyboards do not support typing notification.\n\t\t\tNote that the PIN will always be a 6-digit number,\n\t\t\tzero-padded to 6 digits. This is for harmony with\n\t\t\tthe later specification.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestPasskey","ReturnType":"uint32","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a numeric value\n\t\t\tbetween 0-999999.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPasskey","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"},{"Type":"uint16","Name":"entered"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a passkey for an authentication.\n\t\t\tThe entered parameter indicates the number of already\n\t\t\ttyped keys on the remote side.\n\t\t\tAn empty reply should be returned. When the passkey\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tDuring the pairing process this method might be\n\t\t\tcalled multiple times to update the entered value.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n"},{"Name":"RequestConfirmation","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to confirm a passkey for an authentication.\n\t\t\tTo confirm the value it should return an empty reply\n\t\t\tor an error in case the passkey is invalid.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestAuthorization","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called to request the user to\n\t\t\tauthorize an incoming pairing attempt which\n\t\t\twould in other circumstances trigger the just-works\n\t\t\tmodel, or when the user plugged in a device that\n\t\t\timplements cable pairing. In the latter case, the\n\t\t\tdevice would not be connected to the adapter via\n\t\t\tBluetooth yet.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"AuthorizeService","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to authorize a connection/service request.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"battery-api.txt","Name":"BlueZ D-Bus Battery API description","Description":"\n","Api":[{"Title":"Battery hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Battery1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Percentage","Type":"byte","Docs":"The percentage of battery left as an unsigned 8-bit integer.","Flags":[]}]}]},{"FileName":"device-api.txt","Name":"BlueZ D-Bus Device API description","Description":"\n","Api":[{"Title":"Device hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Device1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis is a generic method to connect any profiles\n\t\t\tthe remote device supports that can be connected\n\t\t\tto and have been flagged as auto-connectable on\n\t\t\tour side. If only subset of profiles is already\n\t\t\tconnected it will try to connect currently disconnected\n\t\t\tones.\n\t\t\tIf at least one profile was connected successfully this\n\t\t\tmethod will indicate success.\n\t\t\tFor dual-mode devices only one bearer is connected at\n\t\t\ttime, the conditions are in the following order:\n\t\t\t\t1. Connect the disconnected bearer if already\n\t\t\t\tconnected.\n\t\t\t\t2. Connect first the bonded bearer. If no\n\t\t\t\tbearers are bonded or both are skip and check\n\t\t\t\tlatest seen bearer.\n\t\t\t\t3. Connect last seen bearer, in case the\n\t\t\t\ttimestamps are the same BR/EDR takes\n\t\t\t\tprecedence.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.AlreadyConnected\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tThis method gracefully disconnects all connected\n\t\t\tprofiles and then terminates low-level ACL connection.\n\t\t\tACL connection will be terminated even if some profiles\n\t\t\twere not disconnected properly e.g. due to misbehaving\n\t\t\tdevice.\n\t\t\tThis method can be also used to cancel a preceding\n\t\t\tConnect call before a reply to it has been received.\n\t\t\tFor non-trusted devices connected over LE bearer calling\n\t\t\tthis method will disable incoming connections until\n\t\t\tConnect method is called again.\n\t\t\tPossible errors: org.bluez.Error.NotConnected\n"},{"Name":"ConnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method connects a specific profile of this\n\t\t\tdevice. The UUID provided is the remote service\n\t\t\tUUID for the profile.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotAvailable\n\t\t\t\t\t org.bluez.Error.NotReady\n"},{"Name":"DisconnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method disconnects a specific profile of\n\t\t\tthis device. The profile needs to be registered\n\t\t\tclient profile.\n\t\t\tThere is no connection tracking for a profile, so\n\t\t\tas long as the profile is registered this will always\n\t\t\tsucceed.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"Pair","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method will connect to the remote device,\n\t\t\tinitiate pairing and then retrieve all SDP records\n\t\t\t(or GATT primary services).\n\t\t\tIf the application has registered its own agent,\n\t\t\tthen that specific agent will be used. Otherwise\n\t\t\tit will use the default agent.\n\t\t\tOnly for applications like a pairing wizard it\n\t\t\twould make sense to have its own agent. In almost\n\t\t\tall other cases the default agent will handle\n\t\t\tthis just fine.\n\t\t\tIn case there is no application agent and also\n\t\t\tno default agent present, this method will fail.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.AuthenticationCanceled\n\t\t\t\t\t org.bluez.Error.AuthenticationFailed\n\t\t\t\t\t org.bluez.Error.AuthenticationRejected\n\t\t\t\t\t org.bluez.Error.AuthenticationTimeout\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"CancelPairing","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis method can be used to cancel a pairing\n\t\t\toperation initiated by the Pair method.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address of the remote device.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth device Address Type. For dual-mode and\n\t\t\tBR/EDR only devices this defaults to \"public\". Single\n\t\t\tmode LE devices may have either value. If remote device\n\t\t\tuses privacy than before pairing this represents address\n\t\t\ttype used for connection and Identity Address after\n\t\t\tpairing.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth remote name. This value can not be\n\t\t\tchanged. Use the Alias property instead.\n\n\t\t\tThis value is only present for completeness. It is\n\t\t\tbetter to always use the Alias property when\n\t\t\tdisplaying the devices name.\n\n\t\t\tIf the Alias property is unset, it will reflect\n\t\t\tthis value which makes it more convenient.","Flags":[5]},{"Name":"Icon","Type":"string","Docs":"Proposed icon name according to the freedesktop.org\n\t\t\ticon naming specification.","Flags":[5]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device of the remote device.","Flags":[5]},{"Name":"Appearance","Type":"uint16","Docs":"External appearance of device, as found on GAP service.","Flags":[5]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tremote services.","Flags":[5]},{"Name":"Paired","Type":"boolean","Docs":"Indicates if the remote device is paired.","Flags":[]},{"Name":"Connected","Type":"boolean","Docs":"Indicates if the remote device is currently connected.\n\t\t\tA PropertiesChanged signal indicate changes to this\n\t\t\tstatus.","Flags":[]},{"Name":"Trusted","Type":"boolean","Docs":"Indicates if the remote is seen as trusted. This\n\t\t\tsetting can be changed by the application.","Flags":[]},{"Name":"Blocked","Type":"boolean","Docs":"If set to true any incoming connections from the\n\t\t\tdevice will be immediately rejected. Any device\n\t\t\tdrivers will also be removed and no new ones will\n\t\t\tbe probed as long as the device is blocked.","Flags":[]},{"Name":"WakeAllowed","Type":"boolean","Docs":"If set to true this device will be allowed to wake the\n\t\t\thost from system suspend.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The name alias for the remote device. The alias can\n\t\t\tbe used to have a different friendly name for the\n\t\t\tremote device.\n\n\t\t\tIn case no alias is set, it will return the remote\n\t\t\tdevice name. Setting an empty string as alias will\n\t\t\tconvert it back to the remote device name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to the remote name.","Flags":[]},{"Name":"Adapter","Type":"object","Docs":"The object path of the adapter the device belongs to.","Flags":[]},{"Name":"LegacyPairing","Type":"boolean","Docs":"Set to true if the device only supports the pre-2.1\n\t\t\tpairing mechanism. This property is useful during\n\t\t\tdevice discovery to anticipate whether legacy or\n\t\t\tsimple pairing will occur if pairing is initiated.\n\n\t\t\tNote that this property can exhibit false-positives\n\t\t\tin the case of Bluetooth 2.1 (or newer) devices that\n\t\t\thave disabled Extended Inquiry Response support.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Remote Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"RSSI","Type":"int16","Docs":"Received Signal Strength Indicator of the remote\n\t\t\tdevice (inquiry or advertising).","Flags":[5]},{"Name":"TxPower","Type":"int16","Docs":"Advertised transmitted power level (inquiry or\n\t\t\tadvertising).","Flags":[5]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufacturer specific advertisement data. Keys are\n\t\t\t16 bits Manufacturer ID followed by its byte array\n\t\t\tvalue.","Flags":[5]},{"Name":"ServiceData","Type":"dict","Docs":"Service advertisement data. Keys are the UUIDs in\n\t\t\tstring format followed by its byte array value.","Flags":[5]},{"Name":"ServicesResolved","Type":"bool","Docs":"Indicate whether or not service discovery has been\n\t\t\tresolved.","Flags":[]},{"Name":"AdvertisingFlags","Type":"array{byte}","Docs":"The Advertising Data Flags of the remote device.","Flags":[]},{"Name":"AdvertisingData","Type":"dict","Docs":"The Advertising Data of the remote device. Keys are\n\t\t\tare 8 bits AD Type followed by data as byte array.\n\n\t\t\tNote: Only types considered safe to be handled by\n\t\t\tapplication are exposed.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[]}]}]},{"FileName":"gatt-api.txt","Name":"BlueZ D-Bus GATT API description","Description":"GATT local and remote services share the same high-level D-Bus API. Local\nrefers to GATT based service exported by a BlueZ plugin or an external\napplication. Remote refers to GATT services exported by the peer.\n\nBlueZ acts as a proxy, translating ATT operations to D-Bus method calls and\nProperties (or the opposite). Support for D-Bus Object Manager is mandatory for\nexternal services to allow seamless GATT declarations (Service, Characteristic\nand Descriptors) discovery. Each GATT service tree is required to export a D-Bus\nObject Manager at its root that is solely responsible for the objects that\nbelong to that service.\n\nReleasing a registered GATT service is not defined yet. Any API extension\nshould avoid breaking the defined API, and if possible keep an unified GATT\nremote and local services representation.\n\n","Api":[{"Title":"Service hierarchy","Description":"\nGATT remote and local service representation. Object path for local services\nis freely definable.\n\nExternal applications implementing local services must register the services\nusing GattManager1 registration method and must implement the methods and\nproperties defined in GattService1 interface.\n","Service":"org.bluez","Interface":"org.bluez.GattService1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX","Methods":[],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit service UUID.","Flags":[1]},{"Name":"Primary","Type":"boolean","Docs":"Indicates whether or not this GATT service is a\n\t\t\tprimary service. If false, the service is secondary.","Flags":[1]},{"Name":"Device","Type":"object","Docs":"Object path of the Bluetooth device the service\n\t\t\tbelongs to. Only present on services from remote\n\t\t\tdevices.","Flags":[1,5]},{"Name":"Includes","Type":"array{object}","Docs":"Array of object paths representing the included\n\t\t\tservices of this service.","Flags":[1,5]},{"Name":"Handle","Type":"uint16","Docs":"Service handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic hierarchy","Description":"\nFor local GATT defined services, the object paths need to follow the service\npath hierarchy and are freely definable.\n","Service":"org.bluez","Interface":"org.bluez.GattCharacteristic1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": uint16 offset\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Object Device (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.InvalidOffset\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"type\": string\n\t\t\t\t\t\tPossible values:\n\t\t\t\t\t\t\"command\": Write without\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\"request\": Write with response\n\t\t\t\t\t\t\"reliable\": Reliable Write\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": True if prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireWrite","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for writing. Only\n\t\t\tsockets are supported. Usage of WriteValue will be\n\t\t\tlocked causing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tFor client it only works with characteristic that has\n\t\t\tWriteAcquired property which relies on\n\t\t\twrite-without-response Flag.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireNotify","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for notify. Only\n\t\t\tsockets are support. Usage of StartNotify will be locked\n\t\t\tcausing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tOnly works with characteristic that has NotifyAcquired\n\t\t\twhich relies on notify Flag and no other client have\n\t\t\tcalled StartNotify.\n\t\t\tNotification are enabled during this procedure so\n\t\t\tStartNotify shall not be called, any notification\n\t\t\twill be dispatched via file descriptor therefore the\n\t\t\tValue property is not affected during the time where\n\t\t\tnotify has been acquired.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StartNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tStarts a notification session from this characteristic\n\t\t\tif it supports value notifications or indications.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StopNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method will cancel any previous StartNotify\n\t\t\ttransaction. Note that notifications from a\n\t\t\tcharacteristic are shared between sessions thus\n\t\t\tcalling StopNotify will release a single session.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"},{"Name":"Confirm","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method doesn't expect a reply so it is just a\n\t\t\tconfirmation that value was received.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit characteristic UUID.","Flags":[1]},{"Name":"Service","Type":"object","Docs":"Object path of the GATT service the characteristic\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the characteristic. This property\n\t\t\tgets updated only after a successful read request and\n\t\t\twhen a notification or indication is received, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"WriteAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireWrite.\n\n\t\t\tFor client properties is ommited in case\n\t\t\t'write-without-response' flag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireWrite is supported.","Flags":[1,5]},{"Name":"NotifyAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireNotify.\n\n\t\t\tFor client this properties is ommited in case 'notify'\n\t\t\tflag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireNotify is supported.","Flags":[1,5]},{"Name":"Notifying","Type":"boolean","Docs":"True, if notifications or indications on this\n\t\t\tcharacteristic are currently enabled.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the characteristic value can be used. See\n\t\t\tCore spec \"Table 3.5: Characteristic Properties bit\n\t\t\tfield\", and \"Table 3.8: Characteristic Extended\n\t\t\tProperties bit field\". Allowed values:\n\n\t\t\t\t\"broadcast\"\n\t\t\t\t\"read\"\n\t\t\t\t\"write-without-response\"\n\t\t\t\t\"write\"\n\t\t\t\t\"notify\"\n\t\t\t\t\"indicate\"\n\t\t\t\t\"authenticated-signed-writes\"\n\t\t\t\t\"extended-properties\"\n\t\t\t\t\"reliable-write\"\n\t\t\t\t\"writable-auxiliaries\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server only)\n\t\t\t\t\"secure-write\" (Server only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic Descriptors hierarchy","Description":"\nLocal or remote GATT characteristic descriptors hierarchy.\n","Service":"org.bluez","Interface":"org.bluez.GattDescriptor1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": boolean Is prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit descriptor UUID.","Flags":[1]},{"Name":"Characteristic","Type":"object","Docs":"Object path of the GATT characteristic the descriptor\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the descriptor. This property\n\t\t\tgets updated only after a successful read request, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the descriptor value can be used.\n\n\t\t\tPossible values:\n\n\t\t\t\t\"read\"\n\t\t\t\t\"write\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server Only)\n\t\t\t\t\"secure-write\" (Server Only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"GATT Profile hierarchy","Description":"\nLocal profile (GATT client) instance. By registering this type of object\nan application effectively indicates support for a specific GATT profile\nand requests automatic connections to be established to devices\nsupporting it.\n","Service":"\u003capplication dependent\u003e","Interface":"org.bluez.GattProfile1","ObjectPath":"\u003capplication dependent\u003e","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. The profile can use it to\n\t\t\tdo cleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUIDs","Type":"array{string}","Docs":"128-bit GATT service UUIDs to auto connect.","Flags":[1]}]},{"Title":"GATT Manager hierarchy","Description":"\nGATT Manager allows external applications to register GATT services and\nprofiles.\n\nRegistering a profile allows applications to subscribe to *remote* services.\nThese must implement the GattProfile1 interface defined above.\n\nRegistering a service allows applications to publish a *local* GATT service,\nwhich then becomes available to remote devices. A GATT service is represented by\na D-Bus object hierarchy where the root node corresponds to a service and the\nchild nodes represent characteristics and descriptors that belong to that\nservice. Each node must implement one of GattService1, GattCharacteristic1,\nor GattDescriptor1 interfaces described above, based on the attribute it\nrepresents. Each node must also implement the standard D-Bus Properties\ninterface to expose their properties. These objects collectively represent a\nGATT service definition.\n\nTo make service registration simple, BlueZ requires that all objects that belong\nto a GATT service be grouped under a D-Bus Object Manager that solely manages\nthe objects of that service. Hence, the standard DBus.ObjectManager interface\nmust be available on the root service path. An example application hierarchy\ncontaining two separate GATT services may look like this:\n\n-\u003e /com/example\n | - org.freedesktop.DBus.ObjectManager\n |\n -\u003e /com/example/service0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattService1\n | |\n | -\u003e /com/example/service0/char0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1/desc0\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattDescriptor1\n |\n -\u003e /com/example/service1\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattService1\n |\n -\u003e /com/example/service1/char0\n - org.freedesktop.DBus.Properties\n - org.bluez.GattCharacteristic1\n\nWhen a service is registered, BlueZ will automatically obtain information about\nall objects using the service's Object Manager. Once a service has been\nregistered, the objects of a service should not be removed. If BlueZ receives an\nInterfacesRemoved signal from a service's Object Manager, it will immediately\nunregister the service. Similarly, if the application disconnects from the bus,\nall of its registered services will be automatically unregistered.\nInterfacesAdded signals will be ignored.\n\nExamples:\n\t- Client\n\t\ttest/example-gatt-client\n\t\tclient/bluetoothctl\n\t- Server\n\t\ttest/example-gatt-server\n\t\ttools/gatt-service\n\n","Service":"org.bluez","Interface":"org.bluez.GattManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a local GATT services hierarchy as described\n\t\t\tabove (GATT Server) and/or GATT profiles (GATT Client).\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering a GATT based\n\t\t\tservice or profile.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]}]},{"FileName":"health-api.txt","Name":"BlueZ D-Bus Health API description","Description":"\n","Api":[{"Title":"HealthManager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthManager1","ObjectPath":"/org/bluez/","Methods":[{"Name":"CreateApplication","ReturnType":"object","Args":[{"Type":"dict","Name":"config"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturns the path of the new registered application.\n\t\t\tApplication will be closed by the call or implicitly\n\t\t\twhen the programs leaves the bus.\n\t\t\tconfig:\n\t\t\t\tuint16 DataType:\n\t\t\t\t\tMandatory\n\t\t\t\tstring Role:\n\t\t\t\t\tMandatory. Possible values: \"source\",\n\t\t\t\t\t\t\t\t\t\"sink\"\n\t\t\t\tstring Description:\n\t\t\t\t\tOptional\n\t\t\t\tChannelType:\n\t\t\t\t\tOptional, just for sources. Possible\n\t\t\t\t\tvalues: \"reliable\", \"streaming\"\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DestroyApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCloses the HDP application identified by the object\n\t\t\tpath. Also application will be closed if the process\n\t\t\tthat started it leaves the bus. Only the creator of the\n\t\t\tapplication will be able to destroy it.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[]},{"Title":"HealthDevice hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthDevice1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Echo","ReturnType":"boolean","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tSends an echo petition to the remote service. Returns\n\t\t\tTrue if response matches with the buffer sent. If some\n\t\t\terror is detected False value is returned.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.OutOfRange\n"},{"Name":"CreateChannel","ReturnType":"object","Args":[{"Type":"object","Name":"application"},{"Type":"string","Name":"configuration"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCreates a new data channel. The configuration should\n\t\t\tindicate the channel quality of service using one of\n\t\t\tthis values \"reliable\", \"streaming\", \"any\".\n\t\t\tReturns the object path that identifies the data\n\t\t\tchannel that is already connected.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.HealthError\n"},{"Name":"DestroyChannel","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDestroys the data channel object. Only the creator of\n\t\t\tthe channel or the creator of the HealthApplication\n\t\t\tthat received the data channel will be able to destroy\n\t\t\tit.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[{"Name":"ChannelConnected","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a new data channel is\n\t\t\tcreated or when a known data channel is reconnected.\n\n"},{"Name":"ChannelDeleted","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a data channel is deleted.\n\n\t\t\tAfter this signal the data channel path will not be\n\t\t\tvalid and its path can be reused for future data\n\t\t\tchannels."}],"Properties":[{"Name":"MainChannel","Type":"object","Docs":"The first reliable channel opened. It is needed by\n\t\t\tupper applications in order to send specific protocol\n\t\t\tdata units. The first reliable can change after a\n\t\t\treconnection.","Flags":[]}]},{"Title":"HealthChannel hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthChannel1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/chanZZZ","Methods":[{"Name":"Acquire","ReturnType":"fd","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tReturns the file descriptor for this data channel. If\n\t\t\tthe data channel is not connected it will also\n\t\t\treconnect.\n\t\t\tPossible Errors: org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotAcquired","org.bluez.Error.NotAcquired"],"Docs":"\t\t\tReleases the fd. Application should also need to\n\t\t\tclose() it.\n\t\t\tPossible Errors: org.bluez.Error.NotAcquired\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The quality of service of the data channel. (\"reliable\"\n\t\t\tor \"streaming\")","Flags":[]},{"Name":"Device","Type":"object","Docs":"Identifies the Remote Device that is connected with.\n\t\t\tMaps with a HealthDevice object.","Flags":[]},{"Name":"Application","Type":"object","Docs":"Identifies the HealthApplication to which this channel\n\t\t\tis related to (which indirectly defines its role and\n\t\t\tdata type).","Flags":[]}]}]},{"FileName":"input-api.txt","Name":"BlueZ D-Bus Input API description","Description":"","Api":[{"Title":"Input hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Input1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"ReconnectMode","Type":"string","Docs":"Determines the Connectability mode of the HID device as\n\t\t\tdefined by the HID Profile specification, Section 5.4.2.\n\n\t\t\tThis mode is based in the two properties\n\t\t\tHIDReconnectInitiate (see Section 5.3.4.6) and\n\t\t\tHIDNormallyConnectable (see Section 5.3.4.14) which\n\t\t\tdefine the following four possible values:\n\n\t\t\t\"none\"\t\tDevice and host are not required to\n\t\t\t\t\tautomatically restore the connection.\n\n\t\t\t\"host\"\t\tBluetooth HID host restores connection.\n\n\t\t\t\"device\"\tBluetooth HID device restores\n\t\t\t\t\tconnection.\n\n\t\t\t\"any\"\t\tBluetooth HID device shall attempt to\n\t\t\t\t\trestore the lost connection, but\n\t\t\t\t\tBluetooth HID Host may also restore the\n\t\t\t\t\tconnection.","Flags":[]}]}]},{"FileName":"media-api.txt","Name":"BlueZ D-Bus Media API description","Description":"\n","Api":[{"Title":"Media hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Media1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a local end point to sender, the sender can\n\t\t\tregister as many end points as it likes.\n\t\t\tNote: If the sender disconnects the end points are\n\t\t\tautomatically unregistered.\n\t\t\tpossible properties:\n\t\t\t\tstring UUID:\n\t\t\t\t\tUUID of the profile which the endpoint\n\t\t\t\t\tis for.\n\t\t\t\tbyte Codec:\n\t\t\t\t\tAssigned number of codec that the\n\t\t\t\t\tendpoint implements. The values should\n\t\t\t\t\tmatch the profile specification which\n\t\t\t\t\tis indicated by the UUID.\n\t\t\t\tarray{byte} Capabilities:\n\t\t\t\t\tCapabilities blob, it is used as it is\n\t\t\t\t\tso the size and byte order must match.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported - emitted\n\t\t\t\t\t when interface for the end-point is\n\t\t\t\t\t disabled.\n"},{"Name":"UnregisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"}],"Errors":null,"Docs":"\t\t\tUnregister sender end point.\n"},{"Name":"RegisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a media player object to sender, the sender\n\t\t\tcan register as many objects as it likes.\n\t\t\tObject must implement at least\n\t\t\torg.mpris.MediaPlayer2.Player as defined in MPRIS 2.2\n\t\t\tspec:\n\t\t\thttp://specifications.freedesktop.org/mpris-spec/latest/\n\t\t\tNote: If the sender disconnects its objects are\n\t\t\tautomatically unregistered.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"UnregisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"}],"Errors":null,"Docs":"\t\t\tUnregister sender media player.\n"},{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"root"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister endpoints an player objects within root\n\t\t\tobject which must implement ObjectManager.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Media Control hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaControl1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume playback.\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPause playback.\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStop playback.\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tNext item.\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPrevious item.\n"},{"Name":"VolumeUp","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step up\n"},{"Name":"VolumeDown","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step down\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"","Flags":[]},{"Name":"Player","Type":"object","Docs":"Addressed Player object path.","Flags":[5]}]},{"Title":"MediaPlayer1 hierarchy","Description":"","Service":"org.bluez (Controller role)","Interface":"org.bluez.MediaPlayer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tResume playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPause playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tStop playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tNext item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPrevious item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Press","ReturnType":"void","Args":[{"Type":"byte","Name":"avc_key"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tPress a specific key to send as passthrough command.\n\t\t\tThe key will be released automatically. Use Hold()\n\t\t\tinstead if the intention is to hold down the key.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Hold","ReturnType":"void","Args":[{"Type":"byte","Name":"avc_key"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tPress and hold a specific key to send as passthrough\n\t\t\tcommand. It is your responsibility to make sure that\n\t\t\tRelease() is called after calling this method. The held\n\t\t\tkey will also be released when any other method in this\n\t\t\tinterface is called.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRelease the previously held key invoked using Hold().\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Equalizer","Type":"string","Docs":"Possible values: \"off\" or \"on\"","Flags":[]},{"Name":"Repeat","Type":"string","Docs":"Possible values: \"off\", \"singletrack\", \"alltracks\" or\n\t\t\t\t\t\"group\"","Flags":[]},{"Name":"Shuffle","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Scan","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Status","Type":"string","Docs":"Possible status: \"playing\", \"stopped\", \"paused\",\n\t\t\t\t\t\"forward-seek\", \"reverse-seek\"\n\t\t\t\t\tor \"error\"","Flags":[]},{"Name":"Position","Type":"uint32","Docs":"Playback position in milliseconds. Changing the\n\t\t\tposition may generate additional events that will be\n\t\t\tsent to the remote device. When position is 0 it means\n\t\t\tthe track is starting and when it's greater than or\n\t\t\tequal to track's duration the track has ended. Note\n\t\t\tthat even if duration is not available in metadata it's\n\t\t\tpossible to signal its end by setting position to the\n\t\t\tmaximum uint32 value.","Flags":[]},{"Name":"Track","Type":"dict","Docs":"Track metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title:","Type":"string","Docs":"Track title name","Flags":[]},{"Name":"Artist:","Type":"string","Docs":"Track artist name","Flags":[]},{"Name":"Album:","Type":"string","Docs":"Track album name","Flags":[]},{"Name":"Genre:","Type":"string","Docs":"Track genre name","Flags":[]},{"Name":"NumberOfTracks:","Type":"uint32","Docs":"Number of tracks in total","Flags":[]},{"Name":"TrackNumber:","Type":"uint32","Docs":"Track number","Flags":[]},{"Name":"Duration:","Type":"uint32","Docs":"Track duration in milliseconds","Flags":[]},{"Name":"Device","Type":"object","Docs":"Device object path.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Player name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Player type\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio\"\n\t\t\t\t\"Video\"\n\t\t\t\t\"Audio Broadcasting\"\n\t\t\t\t\"Video Broadcasting\"","Flags":[]},{"Name":"Subtype","Type":"string","Docs":"Player subtype\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio Book\"\n\t\t\t\t\"Podcast\"","Flags":[]},{"Name":"Browsable","Type":"boolean","Docs":"If present indicates the player can be browsed using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Searchable","Type":"boolean","Docs":"If present indicates the player can be searched using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Playlist","Type":"object","Docs":"Playlist object path.","Flags":[]}]},{"Title":"MediaFolder1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaFolder1","ObjectPath":"freely definable (Target role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX\n\t\t(Controller role)","Methods":[{"Name":"Search","ReturnType":"object","Args":[{"Type":"string","Name":"value"},{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tReturn a folder object containing the search result.\n\t\t\tTo list the items found use the folder object returned\n\t\t\tand pass to ChangeFolder.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ListItems","ReturnType":"array{objects, properties}","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturn a list of items found\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"object","Name":"folder"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tChange current folder.\n\t\t\tNote: By changing folder the items of previous folder\n\t\t\tmight be destroyed and have to be listed again, the\n\t\t\texception is NowPlaying folder which should be always\n\t\t\tpresent while the player is active.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"NumberOfItems","Type":"uint32","Docs":"Number of items in the folder","Flags":[]},{"Name":"Name","Type":"string","Docs":"Folder name:\n\n\t\t\tPossible values:\n\t\t\t\t\"/Filesystem/...\": Filesystem scope\n\t\t\t\t\"/NowPlaying/...\": NowPlaying scope\n\n\t\t\tNote: /NowPlaying folder might not be listed if player\n\t\t\tis stopped, folders created by Search are virtual so\n\t\t\tonce another Search is perform or the folder is\n\t\t\tchanged using ChangeFolder it will no longer be listed.\n\nFilters","Flags":[]},{"Name":"Start:","Type":"uint32","Docs":"Offset of the first item.\n\n\t\t\tDefault value: 0","Flags":[]},{"Name":"End:","Type":"uint32","Docs":"Offset of the last item.\n\n\t\t\tDefault value: NumbeOfItems","Flags":[]},{"Name":"Attributes","Type":"array{string}","Docs":"Item properties that should be included in the list.\n\n\t\t\tPossible Values:\n\n\t\t\t\t\"title\", \"artist\", \"album\", \"genre\",\n\t\t\t\t\"number-of-tracks\", \"number\", \"duration\"\n\n\t\t\tDefault Value: All","Flags":[]}]},{"Title":"MediaItem1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaItem1","ObjectPath":"freely definable (Target role)\n\t\t[variable\n\t\tprefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX\n\t\t(Controller role)","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPlay item\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"AddtoNowPlaying","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tAdd item to now playing list\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Player","Type":"object","Docs":"Player object path the item belongs to","Flags":[]},{"Name":"Name","Type":"string","Docs":"Item displayable name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Item type\n\n\t\t\tPossible values: \"video\", \"audio\", \"folder\"","Flags":[]},{"Name":"FolderType","Type":"string","Docs":"Folder type.\n\n\t\t\tPossible values: \"mixed\", \"titles\", \"albums\", \"artists\"\n\n\t\t\tAvailable if property Type is \"Folder\"","Flags":[5]},{"Name":"Playable","Type":"boolean","Docs":"Indicates if the item can be played\n\n\t\t\tAvailable if property Type is \"folder\"","Flags":[5]},{"Name":"Metadata","Type":"dict","Docs":"Item metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title","Type":"string","Docs":"Item title name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Artist","Type":"string","Docs":"Item artist name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Album","Type":"string","Docs":"Item album name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Genre","Type":"string","Docs":"Item genre name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"NumberOfTracks","Type":"uint32","Docs":"Item album number of tracks in total\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Number","Type":"uint32","Docs":"Item album number\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Duration","Type":"uint32","Docs":"Item duration in milliseconds\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]}]},{"Title":"MediaEndpoint1 hierarchy","Description":"","Service":"unique name (Server role)\n\t\torg.bluez (Client role)","Interface":"org.bluez.MediaEndpoint1","ObjectPath":"freely definable (Server role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX\n\t\t(Client role)","Methods":[{"Name":"SetConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"},{"Type":"dict","Name":"properties"}],"Errors":null,"Docs":"\t\t\tSet configuration for the transport.\n\t\t\tFor client role transport must be set with a server\n\t\t\tendpoint oject which will be configured and the\n\t\t\tproperties must contain the following properties:\n\t\t\t\tarray{byte} Capabilities\n"},{"Name":"SelectConfiguration","ReturnType":"array{byte}","Args":[{"Type":"array{byte}","Name":"capabilities"}],"Errors":null,"Docs":"\t\t\tSelect preferable configuration from the supported\n\t\t\tcapabilities.\n\t\t\tReturns a configuration which can be used to setup\n\t\t\ta transport.\n\t\t\tNote: There is no need to cache the selected\n\t\t\tconfiguration since on success the configuration is\n\t\t\tsend back as parameter of SetConfiguration.\n"},{"Name":"ClearConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"}],"Errors":null,"Docs":"\t\t\tClear transport configuration.\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the endpoint. An endpoint can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tendpoint, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the endpoint is for.","Flags":[5]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the endpoint implements.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[5]},{"Name":"Capabilities","Type":"array{byte}","Docs":"Capabilities blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[5]},{"Name":"Device","Type":"object","Docs":"Device object which the endpoint is belongs to.","Flags":[5]},{"Name":"DelayReporting","Type":"bool","Docs":"Indicates if endpoint supports Delay Reporting.","Flags":[5]}]},{"Title":"MediaTransport1 hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaTransport1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX","Methods":[{"Name":"Acquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAuthorized","org.bluez.Error.NotAuthorized"],"Docs":"\t\t\tAcquire transport file descriptor and the MTU for read\n\t\t\tand write respectively.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"TryAcquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAvailable","org.bluez.Error.NotAvailable"],"Docs":"\t\t\tAcquire transport file descriptor only if the transport\n\t\t\tis in \"pending\" state at the time the message is\n\t\t\treceived by BlueZ. Otherwise no request will be sent\n\t\t\tto the remote device and the function will just fail\n\t\t\twith org.bluez.Error.NotAvailable.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAvailable\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tReleases file descriptor.\n"}],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"Device object which the transport is connected to.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the transport is for.","Flags":[]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the transport support.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[]},{"Name":"Configuration","Type":"array{byte}","Docs":"Configuration blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[]},{"Name":"State","Type":"string","Docs":"Indicates the state of the transport. Possible\n\t\t\tvalues are:\n\t\t\t\t\"idle\": not streaming\n\t\t\t\t\"pending\": streaming but not acquired\n\t\t\t\t\"active\": streaming and acquired","Flags":[]},{"Name":"Delay","Type":"uint16","Docs":"Optional. Transport delay in 1/10 of millisecond, this\n\t\t\tproperty is only writeable when the transport was\n\t\t\tacquired by the sender.","Flags":[]},{"Name":"Volume","Type":"uint16","Docs":"Optional. Indicates volume level of the transport,\n\t\t\tthis property is only writeable when the transport was\n\t\t\tacquired by the sender.\n\n\t\t\tPossible Values: 0-127","Flags":[]},{"Name":"Endpoint","Type":"object","Docs":"Endpoint object which the transport is associated\n\t\t\twith.","Flags":[5]}]}]},{"FileName":"mesh-api.txt","Name":"BlueZ D-Bus Mesh API description","Description":"","Api":[{"Title":"Mesh Network Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Network1","ObjectPath":"/org/bluez/mesh","Methods":[{"Name":"Join","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application has to call to\n\t\tbecome a provisioned node on a mesh network. The call will\n\t\tinitiate broadcasting of Unprovisioned Device Beacon.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The application hierarchy\n\t\talso contains a provision agent object that implements\n\t\torg.bluez.mesh.ProvisionAgent1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tWhen provisioning finishes, the daemon will call either\n\t\tJoinComplete or JoinFailed method on object implementing\n\t\torg.bluez.mesh.Application1 interface.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Cancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"Attach","ReturnType":"object node, array{byte, array{(uint16, dict)}} configuration","Args":[{"Type":"object","Name":"app_root"},{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis is the first method that an application must call to get\n\t\taccess to mesh node functionalities.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe token parameter is a 64-bit number that has been assigned to\n\t\tthe application when it first got provisioned/joined mesh\n\t\tnetwork, i.e. upon receiving JoinComplete() method. The daemon\n\t\tuses the token to verify whether the application is authorized\n\t\tto assume the mesh node identity.\n\t\tIn case of success, the method call returns mesh node object\n\t\t(see Mesh Node Hierarchy section) and current configuration\n\t\tsettings. The return value of configuration parameter is an\n\t\tarray, where each entry is a structure that contains element\n\t\tconfiguration. The element configuration structure is organized\n\t\tas follows:\n\t\tbyte\n\t\t\tElement index, identifies the element to which this\n\t\t\tconfiguration entry pertains.\n\t\tarray{struct}\n\t\t\tModels array where each entry is a structure with the\n\t\t\tfollowing members:\n\t\t\tuint16\n\t\t\t\tEither a SIG Model Identifier or, if Vendor key\n\t\t\t\tis present in model configuration dictionary, a\n\t\t\t\t16-bit vendor-assigned Model Identifier\n\t\t\tdict\n\t\t\t\tA dictionary that contains model configuration\n\t\t\t\twith the following keys defined:\n\t\t\t\tarray{uint16} Bindings\n\t\t\t\t\tIndices of application keys bound to the\n\t\t\t\t\tmodel\n\t\t\t\tuint32 PublicationPeriod\n\t\t\t\t\tModel publication period in milliseconds\n\t\t\t\tuint16 Vendor\n\t\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\t\tBluetooth SIG\n\t\t\t\tarray{variant} Subscriptions\n\t\t\t\t\tAddresses the model is subscribed to.\n\t\t\t\t\tEach address is provided either as\n\t\t\t\t\tuint16 for group addresses, or\n\t\t\t\t\tas array{byte} for virtual labels.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.Busy,\n\t\t\torg.bluez.mesh.Error.Failed\n"},{"Name":"Leave","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis removes the configuration information about the mesh node\n\t\tidentified by the 64-bit token parameter. The token parameter\n\t\thas been obtained as a result of successful Join() method call.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"CreateNetwork","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application calls to become\n\t\ta Provisioner node, and a Configuration Client on a newly\n\t\tcreated Mesh Network.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface, and a org.bluez.mesh.Provisioner1 interface. The\n\t\tapplication represents a node where child mesh elements have\n\t\ttheir own objects that implement org.bluez.mesh.Element1\n\t\tinterface. The application hierarchy also contains a provision\n\t\tagent object that implements org.bluez.mesh.ProvisionAgent1\n\t\tinterface. The standard DBus.ObjectManager interface must be\n\t\tavailable on the app_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tThe other information the bluetooth-meshd daemon will preserve\n\t\tabout the initial node, is to give it the initial primary\n\t\tunicast address (0x0001), and create and assign a net_key as the\n\t\tprimary network net_index (0x000).\n\t\tUpon successful processing of Create() method, the daemon\n\t\twill call JoinComplete method on object implementing\n\t\torg.bluez.mesh.Application1.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Import","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"array{byte}[16]","Name":"dev_key"},{"Type":"array{byte}[16]","Name":"net_key"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"flags"},{"Type":"uint32","Name":"iv_index"},{"Type":"uint16","Name":"unicast"}],"Errors":null,"Docs":"\t\tThis method creates a local mesh node based on node\n\t\tconfiguration that has been generated outside bluetooth-meshd.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error.\n\t\tThe dev_key parameter is the 16-byte value of the dev key of\n\t\tthe imported mesh node.\n\t\tRemaining parameters correspond to provisioning data:\n\t\tThe net_key and net_index parameters describe the network (or a\n\t\tsubnet, if net_index is not 0) the imported mesh node belongs\n\t\tto.\n\t\tThe flags parameter is a dictionary containing provisioning\n\t\tflags. Supported values are:\n\t\t\tboolean IvUpdate\n\t\t\t\tWhen true, indicates that the network is in the\n\t\t\t\tmiddle of IV Index Update procedure.\n\t\t\tboolean KeyRefresh\n\t\t\t\tWhen true, indicates that the specified net key\n\t\t\t\tis in the middle of a key refresh procedure.\n\t\tThe iv_index parameter is the current IV Index value used by\n\t\tthe network. This value is known by the provisioner.\n\t\tThe unicast parameter is the primary unicast address of the\n\t\timported node.\n\t\tUpon successful processing of Import() method, the daemon will\n\t\tcall JoinComplete method on object implementing\n\t\torg.bluez.mesh.Application1 interface.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.NotSupported,\n\t\t\torg.bluez.mesh.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Node Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Node1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"Send","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"key_index"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe key_index parameter determines which application key to use\n\t\tfor encrypting the message. The key_index must be valid for that\n\t\telement, i.e., the application key must be bound to a model on\n\t\tthis element. Otherwise, org.bluez.mesh.Error.NotAuthorized will\n\t\tbe returned.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tbluetooth-meshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"DevKeySend","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel encoded with the device key of the remote node.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe remote parameter, if true, looks up the device key by the\n\t\tdestination address in the key database to encrypt the message.\n\t\tIf remote is true, but requested key does not exist, a NotFound\n\t\terror will be returned. If set to false, the local node's\n\t\tdevice key is used.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddNetKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"subnet_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe subnet_index parameter refers to the subnet index of the\n\t\tnetwork that is being added or updated. This key must exist in\n\t\tthe local key database.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddAppKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"app_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe app_index parameter refers to the application key which is\n\t\tbeing added or updated. This key must exist in the local key\n\t\tdatabase.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"Publish","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"model"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a publication originated by a local\n\t\tmodel. If the model does not exist, or it has no publication\n\t\trecord, the method returns org.bluez.mesh.Error.DoesNotExist\n\t\terror.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe model parameter contains a model ID, as defined by the\n\t\tBluetooth SIG. If the options dictionary contains a \"Vendor\"\n\t\tkey, then this ID is defined by the specified vendor.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\t\tuint16 Vendor\n\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\tBluetooth SIG. This key should only exist when\n\t\t\t\tpublishing on a Vendor defined model.\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tSince only one Publish record may exist per element-model, the\n\t\tdestination and key_index are obtained from the Publication\n\t\trecord cached by the daemon.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[{"Name":"Features","Type":"dict","Docs":"The dictionary that contains information about feature support.\n\t\tThe following keys are defined:","Flags":[1]},{"Name":"Friend","Type":"boolean","Docs":"Indicates the ability to establish a friendship with a\n\t\t\tLow Power node","Flags":[]},{"Name":"LowPower","Type":"boolean","Docs":"Indicates support for operating in Low Power node mode","Flags":[]},{"Name":"Proxy","Type":"boolean","Docs":"Indicates support for GATT proxy","Flags":[]},{"Name":"Relay","Type":"boolean","Docs":"Indicates support for relaying messages\n\n\tIf a key is absent from the dictionary, the feature is not supported.\n\tOtherwise, true means that the feature is enabled and false means that\n\tthe feature is disabled.","Flags":[]},{"Name":"Beacon","Type":"boolean","Docs":"This property indicates whether the periodic beaconing is\n\t\tenabled (true) or disabled (false).","Flags":[1]},{"Name":"IvUpdate","Type":"boolean","Docs":"When true, indicates that the network is in the middle of IV\n\t\tIndex Update procedure. This information is only useful for\n\t\tprovisioning.","Flags":[1]},{"Name":"IvIndex","Type":"uint32","Docs":"This property may be read at any time to determine the IV_Index\n\t\tthat the current network is on. This information is only useful\n\t\tfor provisioning.","Flags":[1]},{"Name":"SecondsSinceLastHeard","Type":"uint32","Docs":"This property may be read at any time to determine the number of\n\t\tseconds since mesh network layer traffic was last detected on\n\t\tthis node's network.","Flags":[1]},{"Name":"Addresses","Type":"array{uint16}","Docs":"This property contains unicast addresses of node's elements.","Flags":[1]},{"Name":"SequenceNumber","Type":"uint32","Docs":"This property may be read at any time to determine the\n\t\tsequence number.","Flags":[1]}]},{"Title":"Mesh Provisioning Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Management1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"UnprovisionedScan","ReturnType":"void","Args":[{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to start listening\n\t\t(scanning) for unprovisioned devices in the area.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tuint16 Seconds\n\t\t\tSpecifies number of seconds for scanning to be active.\n\t\t\tIf set to 0 or if this key is not present, then the\n\t\t\tscanning will continue until UnprovisionedScanCancel()\n\t\t\tor AddNode() methods are called.\n\t\tEach time a unique unprovisioned beacon is heard, the\n\t\tScanResult() method on the app will be called with the result.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"UnprovisionedScanCancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"AddNode","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to add the\n\t\tunprovisioned device specified by uuid, to the Network.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID\n\t\tof the unprovisioned device to be added to the network.\n\t\tThe options parameter is a dictionary that may contain\n\t\tadditional configuration info (currently an empty placeholder\n\t\tfor forward compatibility).\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n"},{"Name":"CreateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tnetwork subnet key.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"ImportSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}[16]","Name":"net_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add a network subnet\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThe net_key parameter is the 16-byte value of the net key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"UpdateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new network\n\t\tsubnet key, and set it's key refresh state to Phase 1.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to update. Note that the subnet must\n\t\texist prior to updating.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"DeleteSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application that to delete a subnet.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to delete. The primary net key (0x000)\n\t\tmay not be deleted.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"SetKeyPhase","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint8","Name":"phase"}],"Errors":null,"Docs":"\t\tThis method is used to set the master key update phase of the\n\t\tgiven subnet. When finalizing the procedure, it is important\n\t\tto CompleteAppKeyUpdate() on all app keys that have been\n\t\tupdated during the procedure prior to setting phase 3.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which subnet phase to set.\n\t\tThe phase parameter is used to cycle the local key database\n\t\tthrough the phases as defined by the Mesh Profile Specification.\n\t\tAllowed values:\n\t\t\t0 - Cancel Key Refresh (May only be called from Phase 1,\n\t\t\t\tand should never be called once the new key has\n\t\t\t\tstarted propagating)\n\t\t\t1 - Invalid Argument (see NetKeyUpdate method)\n\t\t\t2 - Go to Phase 2 (May only be called from Phase 1)\n\t\t\t3 - Complete Key Refresh procedure (May only be called\n\t\t\t\tfrom Phase 2)\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is the responsibility of the application to maintain the key\n\t\trefresh phases per the Mesh Profile Specification.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"CreateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tapplication key.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"ImportAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"},{"Type":"array{byte}[16]","Name":"app_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add an application\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to import.\n\t\tThe app_key parameter is the 16-byte value of the key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"UpdateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new\n\t\tapplication key.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to update. Note that the subnet that\n\t\tthe key is bound to must exist and be in Phase 1.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InProgress\n"},{"Name":"DeleteAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete an application\n\t\tkey.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to delete.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"ImportRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"},{"Type":"array{byte}[16]","Name":"device_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to import a remote node\n\t\tthat has been provisioned by an external process.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being imported.\n\t\tThe count parameter specifies the number of elements that are\n\t\tassigned to this remote node.\n\t\tThe device_key parameter is the access layer key that will be\n\t\twill used to decrypt privledged messages from this remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"DeleteRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete a remote node\n\t\tfrom the local device key database.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being deleted.\n\t\tThe count parameter specifies the number of elements that were\n\t\tassigned to the remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Application Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Application1","ObjectPath":"\u003capp_root\u003e","Methods":[{"Name":"JoinComplete","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby a Join() method call successfully completed.\n\t\tThe token parameter serves as a unique identifier of the\n\t\tparticular node. The token must be preserved by the application\n\t\tin order to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n\t\tIf this method returns an error, the daemon will assume that the\n\t\tapplication failed to preserve the token, and will remove the\n\t\tfreshly created node.\n"},{"Name":"JoinFailed","ReturnType":"void","Args":[{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tJoin() has failed.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"timeout\", \"bad-pdu\",\n\t\t\"confirmation-failed\", \"out-of-resources\", \"decryption-error\",\n\t\t\"unexpected-error\", \"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[{"Name":"CompanyID","Type":"uint16","Docs":"A 16-bit Bluetooth-assigned Company Identifier of the vendor as\n\t\tdefined by Bluetooth SIG","Flags":[1]},{"Name":"ProductID","Type":"uint16","Docs":"A 16-bit vendor-assigned product identifier","Flags":[1]},{"Name":"VersionID","Type":"uint16","Docs":"A 16-bit vendor-assigned product version identifier","Flags":[1]},{"Name":"CRPL","Type":"uint16","Docs":"A 16-bit minimum number of replay protection list entries","Flags":[1,5]}]},{"Title":"Mesh Element Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Element1","ObjectPath":"\u003capp_defined_element_path\u003e","Methods":[{"Name":"MessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"uint16","Name":"key_index"},{"Type":"variant","Name":"destination"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a message\n\t\tarrives addressed to the application.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe key_index parameter indicates which application key has been\n\t\tused to decode the incoming message. The same key_index should\n\t\tbe used by the application when sending a response to this\n\t\tmessage (in case a response is expected).\n\t\tThe destination parameter contains the destination address of\n\t\treceived message. Underlying variant types are:\n\t\tuint16\n\t\t\tDestination is an unicast address, or a well known\n\t\t\tgroup address\n\t\tarray{byte}\n\t\t\tDestination is a virtual address label\n\t\tThe data parameter is the incoming message.\n"},{"Name":"DevKeyMessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by meshd daemon when a message arrives\n\t\taddressed to the application, which was sent with the remote\n\t\tnode's device key.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe remote parameter if true indicates that the device key\n\t\tused to decrypt the message was from the sender. False\n\t\tindicates that the local nodes device key was used, and the\n\t\tmessage has permissions to modify local states.\n\t\tThe net_index parameter indicates what subnet the message was\n\t\treceived on, and if a response is required, the same subnet\n\t\tmust be used to send the response.\n\t\tThe data parameter is the incoming message.\n"},{"Name":"UpdateModelConfiguration","ReturnType":"void","Args":[{"Type":"uint16","Name":"model_id"},{"Type":"dict","Name":"config"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a model's\n\t\tconfiguration is updated.\n\t\tThe model_id parameter contains BT SIG Model Identifier or, if\n\t\tVendor key is present in config dictionary, a 16-bit\n\t\tvendor-assigned Model Identifier.\n\t\tThe config parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tarray{uint16} Bindings\n\t\t\tIndices of application keys bound to the model\n\t\tuint32 PublicationPeriod\n\t\t\tModel publication period in milliseconds\n\t\tuint16 Vendor\n\t\t\tA 16-bit Bluetooth-assigned Company Identifier of the\n\t\t\tvendor as defined by Bluetooth SIG\n\t\tarray{variant} Subscriptions\n\t\t\tAddresses the model is subscribed to.\n\t\t\tEach address is provided either as uint16 for group\n\t\t\taddresses, or as array{byte} for virtual labels.\n"}],"Signals":[],"Properties":[{"Name":"Models","Type":"array{(uint16 id, dict caps)}","Docs":"An array of SIG Models:\n\n\t\t\tid - SIG Model Identifier\n\n\t\t\toptions - a dictionary that may contain additional model\n\t\t\tinfo. The following keys are defined:","Flags":[1]},{"Name":"Publish","Type":"boolean","Docs":"supports publication mechanism. If not\n\t\t\t\t\tpresent, publication is enabled.","Flags":[]},{"Name":"Subscribe","Type":"boolean","Docs":"supports subscription mechanism. If not\n\t\t\t\t\tpresent, subscriptons are enabled.\n\n\t\tThe array may be empty.","Flags":[]},{"Name":"VendorModels","Type":"array{(uint16 vendor, uint16 id, dict options)}","Docs":"An array of Vendor Models:\n\n\t\t\tvendor - a 16-bit Bluetooth-assigned Company ID as\n\t\t\tdefined by Bluetooth SIG.\n\n\t\t\tid - a 16-bit vendor-assigned Model Identifier\n\n\t\t\toptions - a dictionary that may contain additional model\n\t\t\tinfo. The following keys are defined:","Flags":[1]},{"Name":"Publish","Type":"boolean","Docs":"supports publication mechanism","Flags":[]},{"Name":"Subscribe","Type":"boolean","Docs":"supports subscription mechanism\n\n\t\tThe array may be empty.","Flags":[]},{"Name":"Location","Type":"uint16","Docs":"Location descriptor as defined in the GATT Bluetooth Namespace\n\t\tDescriptors section of the Bluetooth SIG Assigned Numbers","Flags":[1,5]}]},{"Title":"Mesh Attention Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Attention1","ObjectPath":"freely definable","Methods":[{"Name":"SetTimer","ReturnType":"void","Args":[{"Type":"uint8","Name":"element_index"},{"Type":"uint16","Name":"time"}],"Errors":null,"Docs":"\t\tThe element_index parameter is the element's index within the\n\t\tnode where the health server model is hosted.\n\t\tThe time parameter indicates how many seconds the attention\n\t\tstate shall be on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"},{"Name":"GetTimer","ReturnType":"uint16","Args":[{"Type":"uint16","Name":"element"}],"Errors":null,"Docs":"\t\tThe element parameter is the unicast address within the node\n\t\twhere the health server model is hosted.\n\t\tReturns the number of seconds for how long the attention action\n\t\tremains staying on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Provisioner Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Provisioner1","ObjectPath":"freely definable","Methods":[{"Name":"ScanResult","ReturnType":"void","Args":[{"Type":"int16","Name":"rssi"},{"Type":"array{byte}","Name":"data"},{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThe method is called from the bluetooth-meshd daemon when a\n\t\tunique UUID has been seen during UnprovisionedScan() for\n\t\tunprovsioned devices.\n\t\tThe rssi parameter is a signed, normalized measurement of the\n\t\tsignal strength of the recieved unprovisioned beacon.\n\t\tThe data parameter is a variable length byte array, that may\n\t\thave 1, 2 or 3 distinct fields contained in it including the 16\n\t\tbyte remote device UUID (always), a 16 bit mask of OOB\n\t\tauthentication flags (optional), and a 32 bit URI hash (if URI\n\t\tbit set in OOB mask). Whether these fields exist or not is a\n\t\tdecision of the remote device.\n\t\tThe options parameter is a dictionary that may contain\n\t\tadditional scan result info (currently an empty placeholder for\n\t\tforward compatibility).\n\t\tIf a beacon with a UUID that has already been reported is\n\t\trecieved by the daemon, it will be silently discarded unless it\n\t\twas recieved at a higher rssi power level.\n"},{"Name":"RequestProvData","ReturnType":"uint16 net_index, uint16 unicast","Args":[{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is implemented by a Provisioner capable application\n\t\tand is called when the remote device has been fully\n\t\tauthenticated and confirmed.\n\t\tThe count parameter is the number of consecutive unicast\n\t\taddresses the remote device is requesting.\n\t\tReturn Parameters are from the Mesh Profile Spec:\n\t\tnet_index - Subnet index of the net_key\n\t\tunicast - Primary Unicast address of the new node\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Abort\n"},{"Name":"AddNodeComplete","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"uint16","Name":"unicast"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby an AddNode() method call successfully completed.\n\t\tThe unicast parameter is the primary address that has been\n\t\tassigned to the new node, and the address of it's config server.\n\t\tThe count parameter is the number of unicast addresses assigned\n\t\tto the new node.\n\t\tThe new node may now be sent messages using the credentials\n\t\tsupplied by the RequestProvData method.\n"},{"Name":"AddNodeFailed","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tAddNode() has failed. Depending on how far Provisioning\n\t\tproceeded before failing, some cleanup of cached data may be\n\t\trequired.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"aborted\", \"timeout\",\n\t\t\"bad-pdu\", \"confirmation-failed\", \"out-of-resources\",\n\t\t\"decryption-error\", \"unexpected-error\",\n\t\t\"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[]},{"Title":"Provisioning Agent Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.ProvisionAgent1","ObjectPath":"freely definable","Methods":[{"Name":"PrivateKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the Provisioner\n\t\thas requested Out-Of-Band ECC key exchange. The Private key is\n\t\treturned to the Daemon, and the Public Key is delivered to the\n\t\tremote Provisioner using a method that does not involve the\n\t\tBluetooth Mesh system. The Private Key returned must be 32\n\t\toctets in size, or the Provisioning procedure will fail and be\n\t\tcanceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Unprovisioned device.\n"},{"Name":"PublicKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the local device is\n\t\tthe Provisioner, and is requestng Out-Of-Band ECC key exchange.\n\t\tThe Public key is returned to the Daemon that is the matched\n\t\tpair of the Private key of the remote device. The Public Key\n\t\treturned must be 64 octets in size, or the Provisioning\n\t\tprocedure will fail and be canceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Provisioner.\n"},{"Name":"DisplayString","ReturnType":"void","Args":[{"Type":"string","Name":"value"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter \"ABCDE\" on remote device\".\n"},{"Name":"DisplayNumeric","ReturnType":"void","Args":[{"Type":"string","Name":"type"},{"Type":"uint32","Name":"number"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter 14939264 on remote device\".\n\t\tThe type parameter indicates the display method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Locally blink LED\n\t\t\t\"beep\" - Locally make a noise\n\t\t\t\"vibrate\" - Locally vibrate\n\t\t\t\"out-numeric\" - Display value to enter remotely\n\t\t\t\"push\" - Request pushes on remote button\n\t\t\t\"twist\" - Request twists on remote knob\n\t\tThe number parameter is the specific value represented by the\n\t\tPrompt.\n"},{"Name":"PromptNumeric","ReturnType":"uint32","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requests the user to\n\t\tenter a decimal value between 1-99999999.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Enter times remote LED blinked\n\t\t\t\"beep\" - Enter times remote device beeped\n\t\t\t\"vibrate\" - Enter times remote device vibrated\n\t\t\t\"in-numeric\" - Enter remotely displayed value\n\t\t\t\"push\" - Push local button remotely requested times\n\t\t\t\"twist\" - Twist local knob remotely requested times\n\t\tThis agent should prompt the user for specific input. For\n\t\tinstance: \"Enter value being displayed by remote device\".\n"},{"Name":"PromptStatic","ReturnType":"array{byte}[16]","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requires a 16 octet byte\n\t\tarray, as an Out-of-Band authentication.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"static-oob\" - return 16 octet array\n\t\t\t\"in-alpha\" - return 16 octet alpha array\n\t\tThe Static data returned must be 16 octets in size, or the\n\t\tProvisioning procedure will fail and be canceled. If input type\n\t\tis \"in-alpha\", the printable characters should be\n\t\tleft-justified, with trailing 0x00 octets filling the remaining\n\t\tbytes.\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\tThis method gets called by the daemon to cancel any existing\n\t\tAgent Requests. When called, any pending user input should be\n\t\tcanceled, and any display requests removed.\n"}],"Signals":[],"Properties":[{"Name":"Capabilities","Type":"array{string}","Docs":"An array of strings with the following allowed values:\n\t\t\t\"blink\"\n\t\t\t\"beep\"\n\t\t\t\"vibrate\"\n\t\t\t\"out-numeric\"\n\t\t\t\"out-alpha\"\n\t\t\t\"push\"\n\t\t\t\"twist\"\n\t\t\t\"in-numeric\"\n\t\t\t\"in-alpha\"\n\t\t\t\"static-oob\"\n\t\t\t\"public-oob\"","Flags":[1]},{"Name":"OutOfBandInfo","Type":"array{string}","Docs":"Indicates availability of OOB data. An array of strings with the\n\t\tfollowing allowed values:\n\t\t\t\"other\"\n\t\t\t\"uri\"\n\t\t\t\"machine-code-2d\"\n\t\t\t\"bar-code\"\n\t\t\t\"nfc\"\n\t\t\t\"number\"\n\t\t\t\"string\"\n\t\t\t\"on-box\"\n\t\t\t\"in-box\"\n\t\t\t\"on-paper\",\n\t\t\t\"in-manual\"\n\t\t\t\"on-device\"","Flags":[1,5]},{"Name":"URI","Type":"string","Docs":"Uniform Resource Identifier points to out-of-band (OOB)\n\t\tinformation (e.g., a public key)","Flags":[1,5]}]}]},{"FileName":"network-api.txt","Name":"BlueZ D-Bus Network API description","Description":"\n","Api":[{"Title":"Network hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Network1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"string","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.AlreadyConnected","org.bluez.Error.AlreadyConnected"],"Docs":"\t\t\tConnect to the network device and return the network\n\t\t\tinterface name. Examples of the interface name are\n\t\t\tbnep0, bnep1 etc.\n\t\t\tuuid can be either one of \"gn\", \"panu\" or \"nap\" (case\n\t\t\tinsensitive) or a traditional string representation of\n\t\t\tUUID or a hexadecimal number.\n\t\t\tThe connection will be closed and network device\n\t\t\treleased either upon calling Disconnect() or when\n\t\t\tthe client disappears from the message bus.\n\t\t\tPossible errors: org.bluez.Error.AlreadyConnected\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnect from the network device.\n\t\t\tTo abort a connection attempt in case of errors or\n\t\t\ttimeouts in the client it is fine to call this method.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if the device is connected.","Flags":[]},{"Name":"Interface","Type":"string","Docs":"Indicates the network interface name when available.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"Indicates the connection role when available.","Flags":[]}]},{"Title":"Network server hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.NetworkServer1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"Register","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"},{"Type":"string","Name":"bridge"}],"Errors":null,"Docs":"\t\t\tRegister server for the provided UUID. Every new\n\t\t\tconnection to this server will be added the bridge\n\t\t\tinterface.\n\t\t\tValid UUIDs are \"gn\", \"panu\" or \"nap\".\n\t\t\tInitially no network server SDP is provided. Only\n\t\t\tafter this method a SDP record will be available\n\t\t\tand the BNEP server will be ready for incoming\n\t\t\tconnections.\n"},{"Name":"Unregister","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":null,"Docs":"\t\t\tUnregister the server for provided UUID.\n\t\t\tAll servers will be automatically unregistered when\n\t\t\tthe calling application terminates.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-agent-api.txt","Name":"OBEX D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.AgentManager1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tRegister an agent to request authorization of\n\t\t\tthe user to accept/reject objects. Object push\n\t\t\tservice needs to authorize each received object.\n\t\t\tPossible errors: org.bluez.obex.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.obex.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.obex.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"AuthorizePush","ReturnType":"string","Args":[{"Type":"object","Name":"transfer"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to accept/reject a Bluetooth object push request.\n\t\t\tReturns the full path (including the filename) where\n\t\t\tthe object shall be stored. The tranfer object will\n\t\t\tcontain a Filename property that contains the default\n\t\t\tlocation and name that can be returned.\n\t\t\tPossible errors: org.bluez.obex.Error.Rejected\n\t\t\t org.bluez.obex.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned. It cancels\n\t\t\tthe previous request.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-api.txt","Name":"OBEX D-Bus API description","Description":"\n","Api":[{"Title":"Client hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Client1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"CreateSession","ReturnType":"object","Args":[{"Type":"string","Name":"destination"},{"Type":"dict","Name":"args"}],"Errors":null,"Docs":"\t\t\tCreate a new OBEX session for the given remote address.\n\t\t\tThe last parameter is a dictionary to hold optional or\n\t\t\ttype-specific parameters. Typical parameters that can\n\t\t\tbe set in this dictionary include the following:\n\t\t\t\tstring \"Target\" : type of session to be created\n\t\t\t\tstring \"Source\" : local address to be used\n\t\t\t\tbyte \"Channel\"\n\t\t\tThe currently supported targets are the following:\n\t\t\t\t\"ftp\"\n\t\t\t\t\"map\"\n\t\t\t\t\"opp\"\n\t\t\t\t\"pbap\"\n\t\t\t\t\"sync\"\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"RemoveSession","ReturnType":"void","Args":[{"Type":"object","Name":"session"}],"Errors":null,"Docs":"\t\t\tUnregister session and abort pending transfers.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.NotAuthorized\n"}],"Signals":[],"Properties":[]},{"Title":"Session hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Session1","ObjectPath":"/org/bluez/obex/server/session{0, 1, 2, ...} or\n\t\t/org/bluez/obex/client/session{0, 1, 2, ...}","Methods":[{"Name":"GetCapabilities","ReturnType":"string","Args":[],"Errors":null,"Docs":"\t\t\tGet remote device capabilities.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Source","Type":"string","Docs":"Bluetooth adapter address","Flags":[]},{"Name":"Destination","Type":"string","Docs":"Bluetooth device address","Flags":[]},{"Name":"Channel","Type":"byte","Docs":"Bluetooth channel","Flags":[]},{"Name":"Target","Type":"string","Docs":"Target UUID","Flags":[]},{"Name":"Root","Type":"string","Docs":"Root path","Flags":[]}]},{"Title":"Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Transfer1","ObjectPath":"[Session object path]/transfer{0, 1, 2, ...}","Methods":[{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStops the current transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.InProgress\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Suspend","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tSuspend transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to suspend transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"},{"Name":"Resume","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to resume transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"}],"Signals":[],"Properties":[{"Name":"Status","Type":"string","Docs":"Inform the current status of the transfer.\n\n\t\t\tPossible values: \"queued\", \"active\", \"suspended\",\n\t\t\t\t\t\"complete\" or \"error\"","Flags":[]},{"Name":"Session","Type":"object","Docs":"The object path of the session the transfer belongs\n\t\t\tto.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Name of the transferred object. Either Name or Type\n\t\t\tor both will be present.","Flags":[]},{"Name":"Type","Type":"string","Docs":"Type of the transferred object. Either Name or Type\n\t\t\tor both will be present.\n\n\t\tuint64 Time [readonly, optional]\n\n\t\t\tTime of the transferred object if this is\n\t\t\tprovided by the remote party.\n\n\t\tuint64 Size [readonly, optional]\n\n\t\t\tSize of the transferred object. If the size is\n\t\t\tunknown, then this property will not be present.\n\n\t\tuint64 Transferred [readonly, optional]\n\n\t\t\tNumber of bytes transferred. For queued transfers, this\n\t\t\tvalue will not be present.","Flags":[]},{"Name":"Filename","Type":"string","Docs":"Complete name of the file being received or sent.\n\n\t\t\tFor incoming object push transaction, this will be\n\t\t\tthe proposed default location and name. It can be\n\t\t\toverwritten by the AuthorizePush agent callback\n\t\t\tand will be then updated accordingly.","Flags":[5]}]},{"Title":"Object Push hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.ObjectPush1","ObjectPath":"[Session object path]","Methods":[{"Name":"SendFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend one local file to the remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullBusinessCard","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRequest the business card from a remote device and\n\t\t\tstore it in the local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ExchangeBusinessCards","ReturnType":"object, dict","Args":[{"Type":"string","Name":"clientfile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tPush the client's business card to the remote device\n\t\t\tand then retrieve the remote business card and store\n\t\t\tit in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"File Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.FileTransfer","ObjectPath":"[Session object path]","Methods":[{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tChange the current folder of the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CreateFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tCreate a new folder in the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolder","ReturnType":"array{dict}","Args":[],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Object name in UTF-8 format\n\t\t\t\tstring Type : Either \"folder\" or \"file\"\n\t\t\t\tuint64 Size : Object size or number of items in\n\t\t\t\t\t\tfolder\n\t\t\t\tstring Permission : Group, owner and other\n\t\t\t\t\t\t\tpermission\n\t\t\t\tuint64 Modified : Last change\n\t\t\t\tuint64 Accessed : Last access\n\t\t\t\tuint64 Created : Creation date\n\t\t\tPossible errors: org.bluez.obex.Error.Failed\n"},{"Name":"GetFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from remote device) to the\n\t\t\ttarget file (on local filesystem).\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from local filesystem) to the\n\t\t\ttarget file (on remote device).\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CopyFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy a file within the remote device from source file\n\t\t\tto target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"MoveFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tMove a file within the remote device from source file\n\t\t\tto the target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Delete","ReturnType":"void","Args":[{"Type":"string","Name":"file"}],"Errors":null,"Docs":"\t\t\tDeletes the specified file/folder.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Phonebook Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.PhonebookAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"Select","ReturnType":"void","Args":[{"Type":"string","Name":"location"},{"Type":"string","Name":"phonebook"}],"Errors":null,"Docs":"\t\t\tSelect the phonebook object for other operations. Should\n\t\t\tbe call before all the other operations.\n\t\t\tlocation : Where the phonebook is stored, possible\n\t\t\tinputs :\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim\" ( \"sim1\" )\n\t\t\t\t\"sim2\"\n\t\t\t\t...\n\t\t\tphonebook : Possible inputs :\n\t\t\t\t\"pb\" :\tphonebook for the saved contacts\n\t\t\t\t\"ich\":\tincoming call history\n\t\t\t\t\"och\":\toutgoing call history\n\t\t\t\t\"mch\":\tmissing call history\n\t\t\t\t\"cch\":\tcombination of ich och mch\n\t\t\t\t\"spd\":\tspeed dials entry ( only for \"internal\" )\n\t\t\t\t\"fav\":\tfavorites entry ( only for \"internal\" )\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullAll","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn the entire phonebook object from the PSE server\n\t\t\tin plain string with vcard format, and store it in\n\t\t\ta local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible filters: Format, Order, Offset, MaxCount and\n\t\t\tFields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\torg.bluez.obex.Forbidden\n"},{"Name":"List","ReturnType":"array{string vcard, string name}","Args":[{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name. For example:\n\t\t\t\t\"1.vcf\" : \"John\"\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Forbidden\n"},{"Name":"Pull","ReturnType":"object, dict","Args":[{"Type":"string","Name":"vcard"},{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tGiven a vcard handle, retrieve the vcard in the current\n\t\t\tphonebook object and store it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossbile filters: Format and Fields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Search","ReturnType":"array{string vcard, string name}","Args":[{"Type":"string","Name":"field"},{"Type":"string","Name":"value"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tSearch for entries matching the given condition and\n\t\t\treturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name.\n\t\t\tvcard : name paired string match the search condition.\n\t\t\tfield : the field in the vcard to search with\n\t\t\t\t{ \"name\" (default) | \"number\" | \"sound\" }\n\t\t\tvalue : the string value to search for\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"GetSize","ReturnType":"uint16","Args":[],"Errors":null,"Docs":"\t\t\tReturn the number of entries in the selected phonebook\n\t\t\tobject that are actually used (i.e. indexes that\n\t\t\tcorrespond to non-NULL entries).\n\t\t\tPossible errors: org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateVersion","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAttempt to update PrimaryCounter and SecondaryCounter.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn All Available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Current folder.","Flags":[]},{"Name":"DatabaseIdentifier","Type":"string","Docs":"128 bits persistent database identifier.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"PrimaryCounter","Type":"string","Docs":"128 bits primary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"SecondaryCounter","Type":"string","Docs":"128 bits secondary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"FixedImageSize","Type":"bool","Docs":"Indicate support for fixed image size.\n\n\t\t\tPossible values: True if image is JPEG 300x300 pixels\n\t\t\totherwise False.","Flags":[5]}]},{"Title":"Synchronization hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Synchronization1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetLocation","ReturnType":"void","Args":[{"Type":"string","Name":"location"}],"Errors":null,"Docs":"\t\t\tSet the phonebook object store location for other\n\t\t\toperations. Should be called before all the other\n\t\t\toperations.\n\t\t\tlocation: Where the phonebook is stored, possible\n\t\t\tvalues:\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim1\"\n\t\t\t\t\"sim2\"\n\t\t\t\t......\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n"},{"Name":"GetPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRetrieve an entire Phonebook Object store from remote\n\t\t\tdevice, and stores it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend an entire Phonebook Object store to remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Message Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.MessageAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetFolder","ReturnType":"void","Args":[{"Type":"string","Name":"name"}],"Errors":null,"Docs":"\t\t\tSet working directory for current session, *name* may\n\t\t\tbe the directory name or '..[/dir]'.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolders","ReturnType":"array{dict}","Args":[{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Folder name\n\t\t\tPossible filters: Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn all available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"},{"Name":"ListMessages","ReturnType":"array{object, dict}","Args":[{"Type":"string","Name":"folder"},{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns an array containing the messages found in the\n\t\t\tgiven subfolder of the current folder, or in the\n\t\t\tcurrent folder if folder is empty.\n\t\t\tPossible Filters: Offset, MaxCount, SubjectLength, Fields,\n\t\t\tType, PeriodStart, PeriodEnd, Status, Recipient, Sender,\n\t\t\tPriority\n\t\t\tEach message is represented by an object path followed\n\t\t\tby a dictionary of the properties.\n\t\t\tProperties:\n\t\t\t\tstring Subject:\n\t\t\t\t\tMessage subject\n\t\t\t\tstring Timestamp:\n\t\t\t\t\tMessage timestamp\n\t\t\t\tstring Sender:\n\t\t\t\t\tMessage sender name\n\t\t\t\tstring SenderAddress:\n\t\t\t\t\tMessage sender address\n\t\t\t\tstring ReplyTo:\n\t\t\t\t\tMessage Reply-To address\n\t\t\t\tstring Recipient:\n\t\t\t\t\tMessage recipient name\n\t\t\t\tstring RecipientAddress:\n\t\t\t\t\tMessage recipient address\n\t\t\t\tstring Type:\n\t\t\t\t\tMessage type\n\t\t\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\t\t\"sms-cdma\" and \"mms\"\n\t\t\t\tuint64 Size:\n\t\t\t\t\tMessage size in bytes\n\t\t\t\tboolean Text:\n\t\t\t\t\tMessage text flag\n\t\t\t\t\tSpecifies whether message has textual\n\t\t\t\t\tcontent or is binary only\n\t\t\t\tstring Status:\n\t\t\t\t\tMessage status\n\t\t\t\t\tPossible values for received messages:\n\t\t\t\t\t\"complete\", \"fractioned\", \"notification\"\n\t\t\t\t\tPossible values for sent messages:\n\t\t\t\t\t\"delivery-success\", \"sending-success\",\n\t\t\t\t\t\"delivery-failure\", \"sending-failure\"\n\t\t\t\tuint64 AttachmentSize:\n\t\t\t\t\tMessage overall attachment size in bytes\n\t\t\t\tboolean Priority:\n\t\t\t\t\tMessage priority flag\n\t\t\t\tboolean Read:\n\t\t\t\t\tMessage read flag\n\t\t\t\tboolean Sent:\n\t\t\t\t\tMessage sent flag\n\t\t\t\tboolean Protected:\n\t\t\t\t\tMessage protected flag\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateInbox","ReturnType":"void","Args":null,"Errors":null,"Docs":""}],"Signals":[],"Properties":[]},{"Title":"Message hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Message1","ObjectPath":"[Session object path]/{message0,...}","Methods":[{"Name":"Get","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"boolean","Name":"attachment"}],"Errors":null,"Docs":"\t\t\tDownload message and store it in the target file.\n\t\t\tIf an empty target file is given, a temporary file\n\t\t\twill be automatically generated.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Folder which the message belongs to","Flags":[]},{"Name":"Subject","Type":"string","Docs":"Message subject","Flags":[]},{"Name":"Timestamp","Type":"string","Docs":"Message timestamp","Flags":[]},{"Name":"Sender","Type":"string","Docs":"Message sender name","Flags":[]},{"Name":"SenderAddress","Type":"string","Docs":"Message sender address","Flags":[]},{"Name":"ReplyTo","Type":"string","Docs":"Message Reply-To address","Flags":[]},{"Name":"Recipient","Type":"string","Docs":"Message recipient name","Flags":[]},{"Name":"RecipientAddress","Type":"string","Docs":"Message recipient address","Flags":[]},{"Name":"Type","Type":"string","Docs":"Message type\n\n\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\"sms-cdma\" and \"mms\"\n\n\t\tuint64 Size [readonly]\n\n\t\t\tMessage size in bytes","Flags":[]},{"Name":"Status","Type":"string","Docs":"Message reception status\n\n\t\t\tPossible values: \"complete\",\n\t\t\t\"fractioned\" and \"notification\"","Flags":[]},{"Name":"Priority","Type":"boolean","Docs":"Message priority flag","Flags":[]},{"Name":"Read","Type":"boolean","Docs":"Message read flag","Flags":[3]},{"Name":"Deleted","Type":"boolean","Docs":"Message deleted flag","Flags":[]},{"Name":"Sent","Type":"boolean","Docs":"Message sent flag","Flags":[]},{"Name":"Protected","Type":"boolean","Docs":"Message protected flag","Flags":[]}]}]},{"FileName":"profile-api.txt","Name":"BlueZ D-Bus Profile API description","Description":"\n","Api":[{"Title":"Profile Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ProfileManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"},{"Type":"string","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers a profile implementation.\n\t\t\tIf an application disconnects from the bus all\n\t\t\tits registered profiles will be removed.\n\t\t\tSome predefined services:\n\t\t\tHFP AG UUID: 0000111f-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.7, profile Features\n\t\t\t\tis 0b001001 and RFCOMM channel is 13.\n\t\t\t\tAuthentication is required.\n\t\t\tHFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.7, profile Features\n\t\t\t\tis 0b000000 and RFCOMM channel is 7.\n\t\t\t\tAuthentication is required.\n\t\t\tHSP AG UUID: 00001112-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.2, RFCOMM channel\n\t\t\t\tis 12 and Authentication is required. Does not\n\t\t\t\tsupport any Features, option is ignored.\n\t\t\tHSP HS UUID: 00001108-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.2, profile Features\n\t\t\t\tis 0b0 and RFCOMM channel is 6. Authentication\n\t\t\t\tis required. Features is one bit value, specify\n\t\t\t\tcapability of Remote Audio Volume Control\n\t\t\t\t(by default turned off).\n\t\t\tAvailable options:\n\t\t\t\tstring Name\n\t\t\t\t\tHuman readable name for the profile\n\t\t\t\tstring Service\n\t\t\t\t\tThe primary service class UUID\n\t\t\t\t\t(if different from the actual\n\t\t\t\t\t profile UUID)\n\t\t\t\tstring Role\n\t\t\t\t\tFor asymmetric profiles that do not\n\t\t\t\t\thave UUIDs available to uniquely\n\t\t\t\t\tidentify each side this\n\t\t\t\t\tparameter allows specifying the\n\t\t\t\t\tprecise local role.\n\t\t\t\t\tPossible values: \"client\", \"server\"\n\t\t\t\tuint16 Channel\n\t\t\t\t\tRFCOMM channel number that is used\n\t\t\t\t\tfor client and server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tuint16 PSM\n\t\t\t\t\tPSM number that is used for client\n\t\t\t\t\tand server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tboolean RequireAuthentication\n\t\t\t\t\tPairing is required before connections\n\t\t\t\t\twill be established. No devices will\n\t\t\t\t\tbe connected if not paired.\n\t\t\t\tboolean RequireAuthorization\n\t\t\t\t\tRequest authorization before any\n\t\t\t\t\tconnection will be established.\n\t\t\t\tboolean AutoConnect\n\t\t\t\t\tIn case of a client UUID this will\n\t\t\t\t\tforce connection of the RFCOMM or\n\t\t\t\t\tL2CAP channels when a remote device\n\t\t\t\t\tis connected.\n\t\t\t\tstring ServiceRecord\n\t\t\t\t\tProvide a manual SDP record.\n\t\t\t\tuint16 Version\n\t\t\t\t\tProfile version (for SDP record)\n\t\t\t\tuint16 Features\n\t\t\t\t\tProfile features (for SDP record)\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the profile that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Profile hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Profile1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. A profile can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"NewConnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"int32","Name":"fd"},{"Type":"dict","Name":"fd_properties"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a new service level\n\t\t\tconnection has been made and authorized.\n\t\t\tCommon fd_properties:\n\t\t\tuint16 Version\t\tProfile version (optional)\n\t\t\tuint16 Features\t\tProfile features (optional)\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestDisconnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a profile gets\n\t\t\tdisconnected.\n\t\t\tThe file descriptor is no longer owned by the service\n\t\t\tdaemon and the profile implementation needs to take\n\t\t\tcare of cleaning up all connections.\n\t\t\tIf multiple file descriptors are indicated via\n\t\t\tNewConnection, it is expected that all of them\n\t\t\tare disconnected before returning from this\n\t\t\tmethod call.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"}],"Signals":[],"Properties":[]}]},{"FileName":"sap-api.txt","Name":"BlueZ D-Bus Sim Access API description","Description":"\n","Api":[{"Title":"Sim Access Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.SimAccess1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnects SAP client from the server.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if SAP client is connected to the server.","Flags":[]}]}]},{"FileName":"thermometer-api.txt","Name":"BlueZ D-Bus Thermometer API description","Description":"\tSantiago Carot-Nemesio \u003csancane@gmail.com\u003e\n\n","Api":[{"Title":"Health Thermometer Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ThermometerManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a watcher to monitor scanned measurements.\n\t\t\tThis agent will be notified about final temperature\n\t\t\tmeasurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"UnregisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tUnregisters a watcher.\n"},{"Name":"EnableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tEnables intermediate measurement notifications\n\t\t\tfor this agent. Intermediate measurements will\n\t\t\tbe enabled only for thermometers which support it.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DisableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDisables intermediate measurement notifications\n\t\t\tfor this agent. It will disable notifications in\n\t\t\tthermometers when the last agent removes the\n\t\t\twatcher for intermediate measurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\torg.bluez.Error.NotFound\n"}],"Signals":[],"Properties":[]},{"Title":"Health Thermometer Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Thermometer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Intermediate","Type":"boolean","Docs":"True if the thermometer supports intermediate\n\t\t\tmeasurement notifications.","Flags":[]},{"Name":"Interval","Type":"uint16","Docs":"(optional) The Measurement Interval defines the time (in\n\t\t\tseconds) between measurements. This interval is\n\t\t\tnot related to the intermediate measurements and\n\t\t\tmust be defined into a valid range. Setting it\n\t\t\tto zero means that no periodic measurements will\n\t\t\tbe taken.","Flags":[5]},{"Name":"Maximum","Type":"uint16","Docs":"(optional) Defines the maximum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]},{"Name":"Minimum","Type":"uint16","Docs":"(optional) Defines the minimum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]}]},{"Title":"Health Thermometer Watcher hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.ThermometerWatcher1","ObjectPath":"freely definable","Methods":[{"Name":"MeasurementReceived","ReturnType":"void","Args":[{"Type":"dict","Name":"measurement"}],"Errors":null,"Docs":"\t\t\tThis callback gets called when a measurement has been\n\t\t\tscanned in the thermometer.\n\t\t\tMeasurement:\n\t\t\t\tint16 Exponent:\n\t\t\t\tint32 Mantissa:\n\t\t\t\t\tExponent and Mantissa values as\n\t\t\t\t\textracted from float value defined by\n\t\t\t\t\tIEEE-11073-20601.\n\t\t\t\t\tMeasurement value is calculated as\n\t\t\t\t\t(Mantissa) * (10^Exponent)\n\t\t\t\t\tFor special cases Exponent is\n\t\t\t\t\tset to 0 and Mantissa is set to\n\t\t\t\t\tone of following values:\n\t\t\t\t\t+(2^23 - 1)\tNaN (invalid or\n\t\t\t\t\t\t\tmissing data)\n\t\t\t\t\t-(2^23)\t\tNRes\n\t\t\t\t\t+(2^23 - 2)\t+Infinity\n\t\t\t\t\t-(2^23 - 2)\t-Infinity\n\t\t\t\tstring Unit:\n\t\t\t\t\tPossible values: \"celsius\" or\n\t\t\t\t\t\t\t\"fahrenheit\"\n\t\t\t\tuint64 Time (optional):\n\t\t\t\t\tTime of measurement, if\n\t\t\t\t\tsupported by device.\n\t\t\t\t\tExpressed in seconds since epoch.\n\t\t\t\tstring Type (optional):\n\t\t\t\t\tOnly present if measurement type\n\t\t\t\t\tis known.\n\t\t\t\t\tPossible values: \"armpit\", \"body\",\n\t\t\t\t\t\t\"ear\", \"finger\", \"intestines\",\n\t\t\t\t\t\t\"mouth\", \"rectum\", \"toe\",\n\t\t\t\t\t\t\"tympanum\"\n\t\t\t\tstring Measurement:\n\t\t\t\t\tPossible values: \"final\" or\n\t\t\t\t\t\t\t\"intermediate\"\n"}],"Signals":[],"Properties":[]}]}]}go-bluetooth-bluez-5.60/bluez-5.60.json000077500000000000000000005360531420407601400176120ustar00rootroot00000000000000{"Version":"5.60","Api":[{"FileName":"adapter-api.txt","Name":"BlueZ D-Bus Adapter API description","Description":"\n","Api":[{"Title":"Adapter hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Adapter1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"StartDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method starts the device discovery session. This\n\t\t\tincludes an inquiry procedure and remote device name\n\t\t\tresolving. Use StopDiscovery to release the sessions\n\t\t\tacquired.\n\t\t\tThis process will start creating Device objects as\n\t\t\tnew devices are discovered.\n\t\t\tDuring discovery RSSI delta-threshold is imposed.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n"},{"Name":"StopDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method will cancel any previous StartDiscovery\n\t\t\ttransaction.\n\t\t\tNote that a discovery procedure is shared between all\n\t\t\tdiscovery sessions thus calling StopDiscovery will only\n\t\t\trelease a single session.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n"},{"Name":"RemoveDevice","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis removes the remote device object at the given\n\t\t\tpath. It will remove also the pairing information.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"SetDiscoveryFilter","ReturnType":"void","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method sets the device discovery filter for the\n\t\t\tcaller. When this method is called with no filter\n\t\t\tparameter, filter is removed.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tarray{string} UUIDs\n\t\t\t\tFilter by service UUIDs, empty means match\n\t\t\t\t_any_ UUID.\n\t\t\t\tWhen a remote device is found that advertises\n\t\t\t\tany UUID from UUIDs, it will be reported if:\n\t\t\t\t- Pathloss and RSSI are both empty.\n\t\t\t\t- only Pathloss param is set, device advertise\n\t\t\t\t TX pwer, and computed pathloss is less than\n\t\t\t\t Pathloss param.\n\t\t\t\t- only RSSI param is set, and received RSSI is\n\t\t\t\t higher than RSSI param.\n\t\t\tint16 RSSI\n\t\t\t\tRSSI threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated RSSI value. If one or more discovery\n\t\t\t\tfilters have been set, the RSSI delta-threshold,\n\t\t\t\tthat is imposed by StartDiscovery by default,\n\t\t\t\twill not be applied.\n\t\t\tuint16 Pathloss\n\t\t\t\tPathloss threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated Pathloss value.\n\t\t\tstring Transport (Default \"auto\")\n\t\t\t\tTransport parameter determines the type of\n\t\t\t\tscan.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"auto\"\t- interleaved scan\n\t\t\t\t\t\"bredr\"\t- BR/EDR inquiry\n\t\t\t\t\t\"le\"\t- LE scan only\n\t\t\t\tIf \"le\" or \"bredr\" Transport is requested,\n\t\t\t\tand the controller doesn't support it,\n\t\t\t\torg.bluez.Error.Failed error will be returned.\n\t\t\t\tIf \"auto\" transport is requested, scan will use\n\t\t\t\tLE, BREDR, or both, depending on what's\n\t\t\t\tcurrently enabled on the controller.\n\t\t\tbool DuplicateData (Default: true)\n\t\t\t\tDisables duplicate detection of advertisement\n\t\t\t\tdata.\n\t\t\t\tWhen enabled PropertiesChanged signals will be\n\t\t\t\tgenerated for either ManufacturerData and\n\t\t\t\tServiceData everytime they are discovered.\n\t\t\tbool Discoverable (Default: false)\n\t\t\t\tMake adapter discoverable while discovering,\n\t\t\t\tif the adapter is already discoverable setting\n\t\t\t\tthis filter won't do anything.\n\t\t\tstring Pattern (Default: none)\n\t\t\t\tDiscover devices where the pattern matches\n\t\t\t\teither the prefix of the address or\n\t\t\t\tdevice name which is convenient way to limited\n\t\t\t\tthe number of device objects created during a\n\t\t\t\tdiscovery.\n\t\t\t\tWhen set disregards device discoverable flags.\n\t\t\t\tNote: The pattern matching is ignored if there\n\t\t\t\tare other client that don't set any pattern as\n\t\t\t\tit work as a logical OR, also setting empty\n\t\t\t\tstring \"\" pattern will match any device found.\n\t\t\tWhen discovery filter is set, Device objects will be\n\t\t\tcreated as new devices with matching criteria are\n\t\t\tdiscovered regardless of they are connectable or\n\t\t\tdiscoverable which enables listening to\n\t\t\tnon-connectable and non-discoverable devices.\n\t\t\tWhen multiple clients call SetDiscoveryFilter, their\n\t\t\tfilters are internally merged, and notifications about\n\t\t\tnew devices are sent to all clients. Therefore, each\n\t\t\tclient must check that device updates actually match\n\t\t\tits filter.\n\t\t\tWhen SetDiscoveryFilter is called multiple times by the\n\t\t\tsame client, last filter passed will be active for\n\t\t\tgiven client.\n\t\t\tSetDiscoveryFilter can be called before StartDiscovery.\n\t\t\tIt is useful when client will create first discovery\n\t\t\tsession, to ensure that proper scan will be started\n\t\t\tright after call to StartDiscovery.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"GetDiscoveryFilters","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn available filters that can be given to\n\t\t\tSetDiscoveryFilter.\n\t\t\tPossible errors: None\n"},{"Name":"ConnectDevice","ReturnType":"object","Args":[{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method connects to device without need of\n\t\t\tperforming General Discovery. Connection mechanism is\n\t\t\tsimilar to Connect method from Device1 interface with\n\t\t\texception that this method returns success when physical\n\t\t\tconnection is established. After this method returns,\n\t\t\tservices discovery will continue and any supported\n\t\t\tprofile will be connected. There is no need for calling\n\t\t\tConnect on Device1 after this call. If connection was\n\t\t\tsuccessful this method returns object path to created\n\t\t\tdevice object.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tstring Address\n\t\t\t\tThe Bluetooth device address of the remote\n\t\t\t\tdevice. This parameter is mandatory.\n\t\t\tstring AddressType\n\t\t\t\tThe Bluetooth device Address Type. This is\n\t\t\t\taddress type that should be used for initial\n\t\t\t\tconnection. If this parameter is not present\n\t\t\t\tBR/EDR device is created.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"public\" - Public address\n\t\t\t\t\t\"random\" - Random address\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth Address Type. For dual-mode and BR/EDR\n\t\t\tonly adapter this defaults to \"public\". Single mode LE\n\t\t\tadapters may have either value. With privacy enabled\n\t\t\tthis contains type of Identity Address and not type of\n\t\t\taddress used for connection.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth system name (pretty hostname).\n\n\t\t\tThis property is either a static system default\n\t\t\tor controlled by an external daemon providing\n\t\t\taccess to the pretty hostname configuration.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The Bluetooth friendly name. This value can be\n\t\t\tchanged.\n\n\t\t\tIn case no alias is set, it will return the system\n\t\t\tprovided name. Setting an empty string as alias will\n\t\t\tconvert it back to the system provided name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to system name.\n\n\t\t\tOn a well configured system, this property never\n\t\t\tneeds to be changed since it defaults to the system\n\t\t\tname and provides the pretty hostname. Only if the\n\t\t\tlocal name needs to be different from the pretty\n\t\t\thostname, this property should be used as last\n\t\t\tresort.","Flags":[]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device.\n\n\t\t\tThis property represents the value that is either\n\t\t\tautomatically configured by DMI/ACPI information\n\t\t\tor provided as static configuration.","Flags":[]},{"Name":"Powered","Type":"boolean","Docs":"Switch an adapter on or off. This will also set the\n\t\t\tappropriate connectable state of the controller.\n\n\t\t\tThe value of this property is not persistent. After\n\t\t\trestart or unplugging of the adapter it will reset\n\t\t\tback to false.","Flags":[]},{"Name":"Discoverable","Type":"boolean","Docs":"Switch an adapter to discoverable or non-discoverable\n\t\t\tto either make it visible or hide it. This is a global\n\t\t\tsetting and should only be used by the settings\n\t\t\tapplication.\n\n\t\t\tIf the DiscoverableTimeout is set to a non-zero\n\t\t\tvalue then the system will set this value back to\n\t\t\tfalse after the timer expired.\n\n\t\t\tIn case the adapter is switched off, setting this\n\t\t\tvalue will fail.\n\n\t\t\tWhen changing the Powered property the new state of\n\t\t\tthis property will be updated via a PropertiesChanged\n\t\t\tsignal.\n\n\t\t\tFor any new adapter this settings defaults to false.","Flags":[]},{"Name":"Pairable","Type":"boolean","Docs":"Switch an adapter to pairable or non-pairable. This is\n\t\t\ta global setting and should only be used by the\n\t\t\tsettings application.\n\n\t\t\tNote that this property only affects incoming pairing\n\t\t\trequests.\n\n\t\t\tFor any new adapter this settings defaults to true.","Flags":[]},{"Name":"PairableTimeout","Type":"uint32","Docs":"The pairable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tpairable mode forever.\n\n\t\t\tThe default value for pairable timeout should be\n\t\t\tdisabled (value 0).","Flags":[]},{"Name":"DiscoverableTimeout","Type":"uint32","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tThe default value for the discoverable timeout should\n\t\t\tbe 180 seconds (3 minutes).","Flags":[]},{"Name":"Discovering","Type":"boolean","Docs":"Indicates that a device discovery procedure is active.","Flags":[]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tlocal services.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Local Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"Roles","Type":"array{string}","Docs":"List of supported roles. Possible values:\n\t\t\t\t\"central\": Supports the central role.\n\t\t\t\t\"peripheral\": Supports the peripheral role.\n\t\t\t\t\"central-peripheral\": Supports both roles\n\t\t\t\t\t\t concurrently.","Flags":[]}]}]},{"FileName":"advertisement-monitor-api.txt","Name":"BlueZ D-Bus Advertisement Monitor API Description","Description":"This API allows an client to specify a job of monitoring advertisements by\nregistering the root of hierarchy and then exposing advertisement monitors\nunder the root with filtering conditions, thresholds of RSSI and timers\nof RSSI thresholds.\n\nOnce a monitoring job is activated by BlueZ, the client can expect to get\nnotified on the targeted advertisements no matter if there is an ongoing\ndiscovery session (a discovery session is started/stopped with methods in\norg.bluez.Adapter1 interface).\n\n","Api":[{"Title":"Advertisement Monitor hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdvertisementMonitor1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis gets called as a signal for a client to perform\n\t\t\tclean-up when (1)a monitor cannot be activated after it\n\t\t\twas exposed or (2)a monitor has been deactivated.\n"},{"Name":"Activate","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAfter a monitor was exposed, this gets called as a\n\t\t\tsignal for client to get acknowledged when a monitor\n\t\t\thas been activated, so the client can expect to receive\n\t\t\tcalls on DeviceFound() or DeviceLost().\n"},{"Name":"DeviceFound","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":null,"Docs":"\t\t\tThis gets called to notify the client of finding the\n\t\t\ttargeted device. Once receiving the call, the client\n\t\t\tshould start to monitor the corresponding device to\n\t\t\tretrieve the changes on RSSI and advertisement content.\n"},{"Name":"DeviceLost","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":null,"Docs":"\t\t\tThis gets called to notify the client of losing the\n\t\t\ttargeted device. Once receiving this call, the client\n\t\t\tshould stop monitoring the corresponding device.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The type of the monitor. See SupportedMonitorTypes in\n\t\t\torg.bluez.AdvertisementMonitorManager1 for the available\n\t\t\toptions.","Flags":[1]},{"Name":"RSSILowThreshold","Type":"Int16","Docs":"Used in conjunction with RSSILowTimeout to determine\n\t\t\twhether a device becomes out-of-range. Valid range is\n\t\t\t-127 to 20 (dBm), while 127 indicates unset.","Flags":[1,5]},{"Name":"RSSIHighThreshold","Type":"Int16","Docs":"Used in conjunction with RSSIHighTimeout to determine\n\t\t\twhether a device becomes in-range. Valid range is\n\t\t\t-127 to 20 (dBm), while 127 indicates unset.","Flags":[1,5]},{"Name":"RSSILowTimeout","Type":"Uint16","Docs":"The time it takes to consider a device as out-of-range.\n\t\t\tIf this many seconds elapses without receiving any\n\t\t\tsignal at least as strong as RSSILowThreshold, a\n\t\t\tcurrently in-range device will be considered as\n\t\t\tout-of-range (lost). Valid range is 1 to 300 (seconds),\n\t\t\twhile 0 indicates unset.","Flags":[1,5]},{"Name":"RSSIHighTimeout","Type":"Uint16","Docs":"The time it takes to consider a device as in-range.\n\t\t\tIf this many seconds elapses while we continuously\n\t\t\treceive signals at least as strong as RSSIHighThreshold,\n\t\t\ta currently out-of-range device will be considered as\n\t\t\tin-range (found). Valid range is 1 to 300 (seconds),\n\t\t\twhile 0 indicates unset.","Flags":[1,5]},{"Name":"RSSISamplingPeriod","Type":"Uint16","Docs":"Grouping rules on how to propagate the received\n\t\t\tadvertisement packets to the client. Valid range is 0 to\n\t\t\t255 while 256 indicates unset.\n\n\t\t\tThe meaning of this property is as follows:\n\t\t\t0:\n\t\t\t\tAll advertisement packets from in-range devices\n\t\t\t\twould be propagated.\n\t\t\t255:\n\t\t\t\tOnly the first advertisement packet of in-range\n\t\t\t\tdevices would be propagated. If the device\n\t\t\t\tbecomes lost, then the first packet when it is\n\t\t\t\tfound again will also be propagated.\n\t\t\t1 to 254:\n\t\t\t\tAdvertisement packets would be grouped into\n\t\t\t\t100ms * N time period. Packets in the same group\n\t\t\t\twill only be reported once, with the RSSI value\n\t\t\t\tbeing averaged out.\n\n\t\t\tCurrently this is unimplemented in user space, so the\n\t\t\tvalue is only used to be forwarded to the kernel.","Flags":[1,5]},{"Name":"Patterns","Type":"array{(uint8, uint8, array{byte})}","Docs":"If the Type property is set to \"or_patterns\", then this\n\t\t\tproperty must exist and have at least one entry in the\n\t\t\tarray.\n\n\t\t\tThe structure of a pattern contains the following:\n\t\t\tuint8 start_position\n\t\t\t\tThe index in an AD data field where the search\n\t\t\t\tshould start. The beginning of an AD data field\n\t\t\t\tis index 0.\n\t\t\tuint8 AD_data_type\n\t\t\t\tSee https://www.bluetooth.com/specifications/\n\t\t\t\tassigned-numbers/generic-access-profile/ for\n\t\t\t\tthe possible allowed value.","Flags":[1,5]}]},{"Title":"Advertisement Monitor Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdvertisementMonitorManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterMonitor","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers the root path of a hierarchy of\n\t\t\tadvertisement monitors.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering advertisement monitors.\n\t\t\tOnce a root path is registered by a client via this\n\t\t\tmethod, the client can freely expose/unexpose\n\t\t\tadvertisement monitors without re-registering the root\n\t\t\tpath again. After use, the client should call\n\t\t\tUnregisterMonitor() method to invalidate the\n\t\t\tadvertisement monitors.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"UnregisterMonitor","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters a hierarchy of advertisement monitors\n\t\t\tthat has been previously registered. The object path\n\t\t\tparameter must match the same value that has been used\n\t\t\ton registration. Upon unregistration, the advertisement\n\t\t\tmonitor(s) should expect to receive Release() method as\n\t\t\tthe signal that the advertisement monitor(s) has been\n\t\t\tdeactivated.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"SupportedMonitorTypes","Type":"array{string}","Docs":"This lists the supported types of advertisement\n\t\t\tmonitors. An application should check this before\n\t\t\tinstantiate and expose an object of\n\t\t\torg.bluez.AdvertisementMonitor1.\n\n\t\t\tPossible values for monitor types:\n\n\t\t\t\"or_patterns\"\n\t\t\t\tPatterns with logic OR applied. With this type,\n\t\t\t\tproperty \"Patterns\" must exist and has at least\n\t\t\t\tone pattern.","Flags":[1]},{"Name":"SupportedFeatures","Type":"array{string}","Docs":"This lists the features of advertisement monitoring\n\t\t\tsupported by BlueZ.\n\n\t\t\tPossible values for features:\n\n\t\t\t\"controller-patterns\"\n\t\t\t\tIf the controller is capable of performing\n\t\t\t\tadvertisement monitoring by patterns, BlueZ\n\t\t\t\twould offload the patterns to the controller to\n\t\t\t\treduce power consumption.","Flags":[1]}]}]},{"FileName":"advertising-api.txt","Name":"BlueZ D-Bus LE Advertising API Description","Description":"Advertising packets are structured data which is broadcast on the LE Advertising\nchannels and available for all devices in range. Because of the limited space\navailable in LE Advertising packets (31 bytes), each packet's contents must be\ncarefully controlled.\n\nBlueZ acts as a store for the Advertisement Data which is meant to be sent.\nIt constructs the correct Advertisement Data from the structured\ndata and configured the kernel to send the correct advertisement.\n\nAdvertisement Data objects are registered freely and then referenced by BlueZ\nwhen constructing the data sent to the kernel.\n\n","Api":[{"Title":"LE Advertisement Data hierarchy","Description":"\nSpecifies the Advertisement Data to be broadcast and some advertising\nparameters. Properties which are not present will not be included in the\ndata. Required advertisement data types will always be included.\nAll UUIDs are 128-bit versions in the API, and 16 or 32-bit\nversions of the same UUID will be used in the advertising data as appropriate.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisement1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tremoves the Advertisement. A client can use it to do\n\t\t\tcleanup tasks. There is no need to call\n\t\t\tUnregisterAdvertisement because when this method gets\n\t\t\tcalled it has already been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"Determines the type of advertising packet requested.\n\n\t\t\tPossible values: \"broadcast\" or \"peripheral\"","Flags":[]},{"Name":"ServiceUUIDs","Type":"array{string}","Docs":"List of UUIDs to include in the \"Service UUID\" field of\n\t\t\tthe Advertising Data.","Flags":[]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufactuer Data fields to include in\n\t\t\tthe Advertising Data. Keys are the Manufacturer ID\n\t\t\tto associate with the data.","Flags":[]},{"Name":"SolicitUUIDs","Type":"array{string}","Docs":"Array of UUIDs to include in \"Service Solicitation\"\n\t\t\tAdvertisement Data.","Flags":[]},{"Name":"ServiceData","Type":"dict","Docs":"Service Data elements to include. The keys are the\n\t\t\tUUID to associate with the data.","Flags":[]},{"Name":"Data","Type":"dict","Docs":"Advertising Type to include in the Advertising\n\t\t\tData. Key is the advertising type and value is the\n\t\t\tdata as byte array.\n\n\t\t\tNote: Types already handled by other properties shall\n\t\t\tnot be used.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[4]},{"Name":"Discoverable","Type":"bool","Docs":"Advertise as general discoverable. When present this\n\t\t\twill override adapter Discoverable property.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"DiscoverableTimeout","Type":"uint16","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"Includes","Type":"array{string}","Docs":"List of features to be included in the advertising\n\t\t\tpacket.\n\n\t\t\tPossible values: as found on\n\t\t\t\t\tLEAdvertisingManager.SupportedIncludes","Flags":[]},{"Name":"LocalName","Type":"string","Docs":"Local name to be used in the advertising report. If the\n\t\t\tstring is too big to fit into the packet it will be\n\t\t\ttruncated.\n\n\t\t\tIf this property is available 'local-name' cannot be\n\t\t\tpresent in the Includes.","Flags":[]},{"Name":"Appearance","Type":"uint16","Docs":"Appearance to be used in the advertising report.\n\n\t\t\tPossible values: as found on GAP Service.","Flags":[]},{"Name":"Duration","Type":"uint16_t","Docs":"Duration of the advertisement in seconds. If there are\n\t\t\tother applications advertising no duration is set the\n\t\t\tdefault is 2 seconds.","Flags":[]},{"Name":"Timeout","Type":"uint16_t","Docs":"Timeout of the advertisement in seconds. This defines\n\t\t\tthe lifetime of the advertisement.","Flags":[]},{"Name":"SecondaryChannel","Type":"string","Docs":"Secondary channel to be used. Primary channel is\n\t\t\talways set to \"1M\" except when \"Coded\" is set.\n\n\t\t\tPossible value: \"1M\" (default)\n\t\t\t\t\t\"2M\"\n\t\t\t\t\t\"Coded\"","Flags":[4]},{"Name":"MinInterval","Type":"uint32","Docs":"Minimum advertising interval to be used by the\n\t\t\tadvertising set, in milliseconds. Acceptable values\n\t\t\tare in the range [20ms, 10,485s]. If the provided\n\t\t\tMinInterval is larger than the provided MaxInterval,\n\t\t\tthe registration will return failure.","Flags":[4]},{"Name":"MaxInterval","Type":"uint32","Docs":"Maximum advertising interval to be used by the\n\t\t\tadvertising set, in milliseconds. Acceptable values\n\t\t\tare in the range [20ms, 10,485s]. If the provided\n\t\t\tMinInterval is larger than the provided MaxInterval,\n\t\t\tthe registration will return failure.","Flags":[4]},{"Name":"TxPower","Type":"int16","Docs":"Requested transmission power of this advertising set.\n\t\t\tThe provided value is used only if the \"CanSetTxPower\"\n\t\t\tfeature is enabled on the Advertising Manager. The\n\t\t\tprovided value must be in range [-127 to +20], where\n\t\t\tunits are in dBm.","Flags":[4]}]},{"Title":"LE Advertising Manager hierarchy","Description":"\nThe Advertising Manager allows external applications to register Advertisement\nData which should be broadcast to devices. Advertisement Data elements must\nfollow the API for LE Advertisement Data described above.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisingManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters an advertisement object to be sent over the LE\n\t\t\tAdvertising channel. The service must be exported\n\t\t\tunder interface LEAdvertisement1.\n\t\t\tInvalidArguments error indicates that the object has\n\t\t\tinvalid or conflicting properties.\n\t\t\tInvalidLength error indicates that the data\n\t\t\tprovided generates a data packet which is too long.\n\t\t\tThe properties of this object are parsed when it is\n\t\t\tregistered, and any changes are ignored.\n\t\t\tIf the same object is registered twice it will result in\n\t\t\tan AlreadyExists error.\n\t\t\tIf the maximum number of advertisement instances is\n\t\t\treached it will result in NotPermitted error.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.InvalidLength\n\t\t\t\t\t org.bluez.Error.NotPermitted\n"},{"Name":"UnregisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters an advertisement that has been\n\t\t\tpreviously registered. The object path parameter must\n\t\t\tmatch the same value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"ActiveInstances","Type":"byte","Docs":"Number of active advertising instances.","Flags":[]},{"Name":"SupportedInstances","Type":"byte","Docs":"Number of available advertising instances.","Flags":[]},{"Name":"SupportedIncludes","Type":"array{string}","Docs":"List of supported system includes.\n\n\t\t\tPossible values: \"tx-power\"\n\t\t\t\t\t \"appearance\"\n\t\t\t\t\t \"local-name\"","Flags":[]},{"Name":"SupportedSecondaryChannels","Type":"array{string}","Docs":"List of supported Secondary channels. Secondary\n\t\t\tchannels can be used to advertise with the\n\t\t\tcorresponding PHY.\n\n\t\t\tPossible values: \"1M\"\n\t\t\t\t\t \"2M\"\n\t\t\t\t\t \"Coded\"","Flags":[4]},{"Name":"SupportedCapabilities","Type":"dict","Docs":"Enumerates Advertising-related controller capabilities\n\t\t\tuseful to the client.\n\n\t\t\tPossible Values:","Flags":[4]},{"Name":"MaxAdvLen","Type":"byte","Docs":"Max advertising data length","Flags":[]},{"Name":"MaxScnRspLen","Type":"byte","Docs":"Max advertising scan response length","Flags":[]},{"Name":"MinTxPower","Type":"int16","Docs":"Min advertising tx power (dBm)","Flags":[]},{"Name":"MaxTxPower","Type":"int16","Docs":"Max advertising tx power (dBm)","Flags":[]},{"Name":"SupportedFeatures","Type":"array{string}","Docs":"List of supported platform features. If no features\n\t\t\tare available on the platform, the SupportedFeatures\n\t\t\tarray will be empty.\n\n\t\t\tPossible values: \"CanSetTxPower\"\n\n\t\t\t\t\t\tIndicates whether platform can\n\t\t\t\t\t\tspecify tx power on each\n\t\t\t\t\t\tadvertising instance.\n\n\t\t\t\t\t \"HardwareOffload\"\n\n\t\t\t\t\t\tIndicates whether multiple\n\t\t\t\t\t\tadvertising will be offloaded\n\t\t\t\t\t\tto the controller.","Flags":[5,4]}]}]},{"FileName":"agent-api.txt","Name":"BlueZ D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AgentManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"},{"Type":"string","Name":"capability"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers an agent handler.\n\t\t\tThe object path defines the path of the agent\n\t\t\tthat will be called when user input is needed.\n\t\t\tEvery application can register its own agent and\n\t\t\tfor all actions triggered by that application its\n\t\t\tagent is used.\n\t\t\tIt is not required by an application to register\n\t\t\tan agent. If an application does chooses to not\n\t\t\tregister an agent, the default agent is used. This\n\t\t\tis on most cases a good idea. Only application\n\t\t\tlike a pairing wizard should register their own\n\t\t\tagent.\n\t\t\tAn application can only register one agent. Multiple\n\t\t\tagents per application is not supported.\n\t\t\tThe capability parameter can have the values\n\t\t\t\"DisplayOnly\", \"DisplayYesNo\", \"KeyboardOnly\",\n\t\t\t\"NoInputNoOutput\" and \"KeyboardDisplay\" which\n\t\t\treflects the input and output capabilities of the\n\t\t\tagent.\n\t\t\tIf an empty string is used it will fallback to\n\t\t\t\"KeyboardDisplay\".\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"},{"Name":"RequestDefaultAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis requests is to make the application agent\n\t\t\tthe default agent. The application is required\n\t\t\tto register an agent.\n\t\t\tSpecial permission might be required to become\n\t\t\tthe default agent.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"RequestPinCode","ReturnType":"string","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a string of 1-16 characters\n\t\t\tlength. The string can be alphanumeric.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPinCode","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"pincode"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a pincode for an authentication.\n\t\t\tAn empty reply should be returned. When the pincode\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tThis is used during the pairing process of keyboards\n\t\t\tthat don't support Bluetooth 2.1 Secure Simple Pairing,\n\t\t\tin contrast to DisplayPasskey which is used for those\n\t\t\tthat do.\n\t\t\tThis method will only ever be called once since\n\t\t\tolder keyboards do not support typing notification.\n\t\t\tNote that the PIN will always be a 6-digit number,\n\t\t\tzero-padded to 6 digits. This is for harmony with\n\t\t\tthe later specification.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestPasskey","ReturnType":"uint32","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a numeric value\n\t\t\tbetween 0-999999.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPasskey","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"},{"Type":"uint16","Name":"entered"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a passkey for an authentication.\n\t\t\tThe entered parameter indicates the number of already\n\t\t\ttyped keys on the remote side.\n\t\t\tAn empty reply should be returned. When the passkey\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tDuring the pairing process this method might be\n\t\t\tcalled multiple times to update the entered value.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n"},{"Name":"RequestConfirmation","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to confirm a passkey for an authentication.\n\t\t\tTo confirm the value it should return an empty reply\n\t\t\tor an error in case the passkey is invalid.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestAuthorization","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called to request the user to\n\t\t\tauthorize an incoming pairing attempt which\n\t\t\twould in other circumstances trigger the just-works\n\t\t\tmodel, or when the user plugged in a device that\n\t\t\timplements cable pairing. In the latter case, the\n\t\t\tdevice would not be connected to the adapter via\n\t\t\tBluetooth yet.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"AuthorizeService","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to authorize a connection/service request.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"battery-api.txt","Name":"BlueZ D-Bus Battery API description","Description":"\n","Api":[{"Title":"Battery hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Battery1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Percentage","Type":"byte","Docs":"The percentage of battery left as an unsigned 8-bit integer.","Flags":[]},{"Name":"Source","Type":"string","Docs":"Describes where the battery information comes from\n\t\t\tThis property is informational only and may be useful\n\t\t\tfor debugging purposes.\n\t\t\tProviders from BatteryProvider1 may make use of this\n\t\t\tproperty to indicate where the battery report comes from\n\t\t\t(e.g. \"HFP 1.7\", \"HID\", or the profile UUID).","Flags":[5]}]},{"Title":"Battery Provider Manager hierarchy","Description":"A battery provider starts by registering itself as a battery provider with the\nRegisterBatteryProvider method passing an object path as the provider ID. Then,\nit can start exposing org.bluez.BatteryProvider1 objects having the path\nstarting with the given provider ID. It can also remove objects at any time.\nThe objects and their properties exposed by battery providers will be reflected\non org.bluez.Battery1 interface.\n\nBlueZ will stop monitoring these exposed and removed objects after\nUnregisterBatteryProvider is called for that provider ID.\n","Service":"org.bluez","Interface":"org.bluez.BatteryProviderManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterBatteryProvider","ReturnType":"void","Args":[{"Type":"object","Name":"provider"}],"Errors":null,"Docs":"\t\t\tThis registers a battery provider. A registered\n\t\t\tbattery provider can then expose objects with\n\t\t\torg.bluez.BatteryProvider1 interface described below.\n"},{"Name":"UnregisterBatteryProvider","ReturnType":"void","Args":[{"Type":"object","Name":"provider"}],"Errors":null,"Docs":"\t\t\tThis unregisters a battery provider. After\n\t\t\tunregistration, the BatteryProvider1 objects provided\n\t\t\tby this client are ignored by BlueZ.\n"}],"Signals":[],"Properties":[]},{"Title":"Battery Provider hierarchy","Description":"","Service":"\u003cclient D-Bus address\u003e","Interface":"org.bluez.BatteryProvider1","ObjectPath":"{provider_root}/{unique battery object path}","Methods":[],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"The object path of the device that has this battery.","Flags":[]}]}]},{"FileName":"device-api.txt","Name":"BlueZ D-Bus Device API description","Description":"\n","Api":[{"Title":"Device hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Device1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis is a generic method to connect any profiles\n\t\t\tthe remote device supports that can be connected\n\t\t\tto and have been flagged as auto-connectable on\n\t\t\tour side. If only subset of profiles is already\n\t\t\tconnected it will try to connect currently disconnected\n\t\t\tones.\n\t\t\tIf at least one profile was connected successfully this\n\t\t\tmethod will indicate success.\n\t\t\tFor dual-mode devices only one bearer is connected at\n\t\t\ttime, the conditions are in the following order:\n\t\t\t\t1. Connect the disconnected bearer if already\n\t\t\t\tconnected.\n\t\t\t\t2. Connect first the bonded bearer. If no\n\t\t\t\tbearers are bonded or both are skip and check\n\t\t\t\tlatest seen bearer.\n\t\t\t\t3. Connect last seen bearer, in case the\n\t\t\t\ttimestamps are the same BR/EDR takes\n\t\t\t\tprecedence.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.AlreadyConnected\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tThis method gracefully disconnects all connected\n\t\t\tprofiles and then terminates low-level ACL connection.\n\t\t\tACL connection will be terminated even if some profiles\n\t\t\twere not disconnected properly e.g. due to misbehaving\n\t\t\tdevice.\n\t\t\tThis method can be also used to cancel a preceding\n\t\t\tConnect call before a reply to it has been received.\n\t\t\tFor non-trusted devices connected over LE bearer calling\n\t\t\tthis method will disable incoming connections until\n\t\t\tConnect method is called again.\n\t\t\tPossible errors: org.bluez.Error.NotConnected\n"},{"Name":"ConnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method connects a specific profile of this\n\t\t\tdevice. The UUID provided is the remote service\n\t\t\tUUID for the profile.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotAvailable\n\t\t\t\t\t org.bluez.Error.NotReady\n"},{"Name":"DisconnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method disconnects a specific profile of\n\t\t\tthis device. The profile needs to be registered\n\t\t\tclient profile.\n\t\t\tThere is no connection tracking for a profile, so\n\t\t\tas long as the profile is registered this will always\n\t\t\tsucceed.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"Pair","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method will connect to the remote device,\n\t\t\tinitiate pairing and then retrieve all SDP records\n\t\t\t(or GATT primary services).\n\t\t\tIf the application has registered its own agent,\n\t\t\tthen that specific agent will be used. Otherwise\n\t\t\tit will use the default agent.\n\t\t\tOnly for applications like a pairing wizard it\n\t\t\twould make sense to have its own agent. In almost\n\t\t\tall other cases the default agent will handle\n\t\t\tthis just fine.\n\t\t\tIn case there is no application agent and also\n\t\t\tno default agent present, this method will fail.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.AuthenticationCanceled\n\t\t\t\t\t org.bluez.Error.AuthenticationFailed\n\t\t\t\t\t org.bluez.Error.AuthenticationRejected\n\t\t\t\t\t org.bluez.Error.AuthenticationTimeout\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"CancelPairing","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis method can be used to cancel a pairing\n\t\t\toperation initiated by the Pair method.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address of the remote device.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth device Address Type. For dual-mode and\n\t\t\tBR/EDR only devices this defaults to \"public\". Single\n\t\t\tmode LE devices may have either value. If remote device\n\t\t\tuses privacy than before pairing this represents address\n\t\t\ttype used for connection and Identity Address after\n\t\t\tpairing.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth remote name. This value can not be\n\t\t\tchanged. Use the Alias property instead.\n\n\t\t\tThis value is only present for completeness. It is\n\t\t\tbetter to always use the Alias property when\n\t\t\tdisplaying the devices name.\n\n\t\t\tIf the Alias property is unset, it will reflect\n\t\t\tthis value which makes it more convenient.","Flags":[5]},{"Name":"Icon","Type":"string","Docs":"Proposed icon name according to the freedesktop.org\n\t\t\ticon naming specification.","Flags":[5]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device of the remote device.","Flags":[5]},{"Name":"Appearance","Type":"uint16","Docs":"External appearance of device, as found on GAP service.","Flags":[5]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tremote services.","Flags":[5]},{"Name":"Paired","Type":"boolean","Docs":"Indicates if the remote device is paired.","Flags":[]},{"Name":"Connected","Type":"boolean","Docs":"Indicates if the remote device is currently connected.\n\t\t\tA PropertiesChanged signal indicate changes to this\n\t\t\tstatus.","Flags":[]},{"Name":"Trusted","Type":"boolean","Docs":"Indicates if the remote is seen as trusted. This\n\t\t\tsetting can be changed by the application.","Flags":[]},{"Name":"Blocked","Type":"boolean","Docs":"If set to true any incoming connections from the\n\t\t\tdevice will be immediately rejected. Any device\n\t\t\tdrivers will also be removed and no new ones will\n\t\t\tbe probed as long as the device is blocked.","Flags":[]},{"Name":"WakeAllowed","Type":"boolean","Docs":"If set to true this device will be allowed to wake the\n\t\t\thost from system suspend.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The name alias for the remote device. The alias can\n\t\t\tbe used to have a different friendly name for the\n\t\t\tremote device.\n\n\t\t\tIn case no alias is set, it will return the remote\n\t\t\tdevice name. Setting an empty string as alias will\n\t\t\tconvert it back to the remote device name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to the remote name.","Flags":[]},{"Name":"Adapter","Type":"object","Docs":"The object path of the adapter the device belongs to.","Flags":[]},{"Name":"LegacyPairing","Type":"boolean","Docs":"Set to true if the device only supports the pre-2.1\n\t\t\tpairing mechanism. This property is useful during\n\t\t\tdevice discovery to anticipate whether legacy or\n\t\t\tsimple pairing will occur if pairing is initiated.\n\n\t\t\tNote that this property can exhibit false-positives\n\t\t\tin the case of Bluetooth 2.1 (or newer) devices that\n\t\t\thave disabled Extended Inquiry Response support.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Remote Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"RSSI","Type":"int16","Docs":"Received Signal Strength Indicator of the remote\n\t\t\tdevice (inquiry or advertising).","Flags":[5]},{"Name":"TxPower","Type":"int16","Docs":"Advertised transmitted power level (inquiry or\n\t\t\tadvertising).","Flags":[5]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufacturer specific advertisement data. Keys are\n\t\t\t16 bits Manufacturer ID followed by its byte array\n\t\t\tvalue.","Flags":[5]},{"Name":"ServiceData","Type":"dict","Docs":"Service advertisement data. Keys are the UUIDs in\n\t\t\tstring format followed by its byte array value.","Flags":[5]},{"Name":"ServicesResolved","Type":"bool","Docs":"Indicate whether or not service discovery has been\n\t\t\tresolved.","Flags":[]},{"Name":"AdvertisingFlags","Type":"array{byte}","Docs":"The Advertising Data Flags of the remote device.","Flags":[]},{"Name":"AdvertisingData","Type":"dict","Docs":"The Advertising Data of the remote device. Keys are\n\t\t\tare 8 bits AD Type followed by data as byte array.\n\n\t\t\tNote: Only types considered safe to be handled by\n\t\t\tapplication are exposed.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[]}]}]},{"FileName":"gatt-api.txt","Name":"BlueZ D-Bus GATT API description","Description":"GATT local and remote services share the same high-level D-Bus API. Local\nrefers to GATT based service exported by a BlueZ plugin or an external\napplication. Remote refers to GATT services exported by the peer.\n\nBlueZ acts as a proxy, translating ATT operations to D-Bus method calls and\nProperties (or the opposite). Support for D-Bus Object Manager is mandatory for\nexternal services to allow seamless GATT declarations (Service, Characteristic\nand Descriptors) discovery. Each GATT service tree is required to export a D-Bus\nObject Manager at its root that is solely responsible for the objects that\nbelong to that service.\n\nReleasing a registered GATT service is not defined yet. Any API extension\nshould avoid breaking the defined API, and if possible keep an unified GATT\nremote and local services representation.\n\n","Api":[{"Title":"Service hierarchy","Description":"\nGATT remote and local service representation. Object path for local services\nis freely definable.\n\nExternal applications implementing local services must register the services\nusing GattManager1 registration method and must implement the methods and\nproperties defined in GattService1 interface.\n","Service":"org.bluez","Interface":"org.bluez.GattService1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX","Methods":[],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit service UUID.","Flags":[1]},{"Name":"Primary","Type":"boolean","Docs":"Indicates whether or not this GATT service is a\n\t\t\tprimary service. If false, the service is secondary.","Flags":[1]},{"Name":"Device","Type":"object","Docs":"Object path of the Bluetooth device the service\n\t\t\tbelongs to. Only present on services from remote\n\t\t\tdevices.","Flags":[1,5]},{"Name":"Includes","Type":"array{object}","Docs":"Array of object paths representing the included\n\t\t\tservices of this service.","Flags":[1,5]},{"Name":"Handle","Type":"uint16","Docs":"Service handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic hierarchy","Description":"\nFor local GATT defined services, the object paths need to follow the service\npath hierarchy and are freely definable.\n","Service":"org.bluez","Interface":"org.bluez.GattCharacteristic1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": uint16 offset\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Object Device (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.InvalidOffset\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"type\": string\n\t\t\t\t\t\tPossible values:\n\t\t\t\t\t\t\"command\": Write without\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\"request\": Write with response\n\t\t\t\t\t\t\"reliable\": Reliable Write\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": True if prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireWrite","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for writing. Only\n\t\t\tsockets are supported. Usage of WriteValue will be\n\t\t\tlocked causing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tFor client it only works with characteristic that has\n\t\t\tWriteAcquired property which relies on\n\t\t\twrite-without-response Flag.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireNotify","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for notify. Only\n\t\t\tsockets are support. Usage of StartNotify will be locked\n\t\t\tcausing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tOnly works with characteristic that has NotifyAcquired\n\t\t\twhich relies on notify Flag and no other client have\n\t\t\tcalled StartNotify.\n\t\t\tNotification are enabled during this procedure so\n\t\t\tStartNotify shall not be called, any notification\n\t\t\twill be dispatched via file descriptor therefore the\n\t\t\tValue property is not affected during the time where\n\t\t\tnotify has been acquired.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StartNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tStarts a notification session from this characteristic\n\t\t\tif it supports value notifications or indications.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StopNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method will cancel any previous StartNotify\n\t\t\ttransaction. Note that notifications from a\n\t\t\tcharacteristic are shared between sessions thus\n\t\t\tcalling StopNotify will release a single session.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"},{"Name":"Confirm","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method doesn't expect a reply so it is just a\n\t\t\tconfirmation that value was received.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit characteristic UUID.","Flags":[1]},{"Name":"Service","Type":"object","Docs":"Object path of the GATT service the characteristic\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the characteristic. This property\n\t\t\tgets updated only after a successful read request and\n\t\t\twhen a notification or indication is received, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"WriteAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireWrite.\n\n\t\t\tFor client properties is ommited in case\n\t\t\t'write-without-response' flag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireWrite is supported.","Flags":[1,5]},{"Name":"NotifyAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireNotify.\n\n\t\t\tFor client this properties is ommited in case 'notify'\n\t\t\tflag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireNotify is supported.","Flags":[1,5]},{"Name":"Notifying","Type":"boolean","Docs":"True, if notifications or indications on this\n\t\t\tcharacteristic are currently enabled.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the characteristic value can be used. See\n\t\t\tCore spec \"Table 3.5: Characteristic Properties bit\n\t\t\tfield\", and \"Table 3.8: Characteristic Extended\n\t\t\tProperties bit field\". Allowed values:\n\n\t\t\t\t\"broadcast\"\n\t\t\t\t\"read\"\n\t\t\t\t\"write-without-response\"\n\t\t\t\t\"write\"\n\t\t\t\t\"notify\"\n\t\t\t\t\"indicate\"\n\t\t\t\t\"authenticated-signed-writes\"\n\t\t\t\t\"extended-properties\"\n\t\t\t\t\"reliable-write\"\n\t\t\t\t\"writable-auxiliaries\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server only)\n\t\t\t\t\"secure-write\" (Server only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic Descriptors hierarchy","Description":"\nLocal or remote GATT characteristic descriptors hierarchy.\n","Service":"org.bluez","Interface":"org.bluez.GattDescriptor1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": boolean Is prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit descriptor UUID.","Flags":[1]},{"Name":"Characteristic","Type":"object","Docs":"Object path of the GATT characteristic the descriptor\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the descriptor. This property\n\t\t\tgets updated only after a successful read request, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the descriptor value can be used.\n\n\t\t\tPossible values:\n\n\t\t\t\t\"read\"\n\t\t\t\t\"write\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server Only)\n\t\t\t\t\"secure-write\" (Server Only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"GATT Profile hierarchy","Description":"\nLocal profile (GATT client) instance. By registering this type of object\nan application effectively indicates support for a specific GATT profile\nand requests automatic connections to be established to devices\nsupporting it.\n","Service":"\u003capplication dependent\u003e","Interface":"org.bluez.GattProfile1","ObjectPath":"\u003capplication dependent\u003e","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. The profile can use it to\n\t\t\tdo cleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUIDs","Type":"array{string}","Docs":"128-bit GATT service UUIDs to auto connect.","Flags":[1]}]},{"Title":"GATT Manager hierarchy","Description":"\nGATT Manager allows external applications to register GATT services and\nprofiles.\n\nRegistering a profile allows applications to subscribe to *remote* services.\nThese must implement the GattProfile1 interface defined above.\n\nRegistering a service allows applications to publish a *local* GATT service,\nwhich then becomes available to remote devices. A GATT service is represented by\na D-Bus object hierarchy where the root node corresponds to a service and the\nchild nodes represent characteristics and descriptors that belong to that\nservice. Each node must implement one of GattService1, GattCharacteristic1,\nor GattDescriptor1 interfaces described above, based on the attribute it\nrepresents. Each node must also implement the standard D-Bus Properties\ninterface to expose their properties. These objects collectively represent a\nGATT service definition.\n\nTo make service registration simple, BlueZ requires that all objects that belong\nto a GATT service be grouped under a D-Bus Object Manager that solely manages\nthe objects of that service. Hence, the standard DBus.ObjectManager interface\nmust be available on the root service path. An example application hierarchy\ncontaining two separate GATT services may look like this:\n\n-\u003e /com/example\n | - org.freedesktop.DBus.ObjectManager\n |\n -\u003e /com/example/service0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattService1\n | |\n | -\u003e /com/example/service0/char0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1/desc0\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattDescriptor1\n |\n -\u003e /com/example/service1\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattService1\n |\n -\u003e /com/example/service1/char0\n - org.freedesktop.DBus.Properties\n - org.bluez.GattCharacteristic1\n\nWhen a service is registered, BlueZ will automatically obtain information about\nall objects using the service's Object Manager. Once a service has been\nregistered, the objects of a service should not be removed. If BlueZ receives an\nInterfacesRemoved signal from a service's Object Manager, it will immediately\nunregister the service. Similarly, if the application disconnects from the bus,\nall of its registered services will be automatically unregistered.\nInterfacesAdded signals will be ignored.\n\nExamples:\n\t- Client\n\t\ttest/example-gatt-client\n\t\tclient/bluetoothctl\n\t- Server\n\t\ttest/example-gatt-server\n\t\ttools/gatt-service\n\n","Service":"org.bluez","Interface":"org.bluez.GattManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a local GATT services hierarchy as described\n\t\t\tabove (GATT Server) and/or GATT profiles (GATT Client).\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering a GATT based\n\t\t\tservice or profile.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]}]},{"FileName":"health-api.txt","Name":"BlueZ D-Bus Health API description","Description":"\n","Api":[{"Title":"HealthManager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthManager1","ObjectPath":"/org/bluez/","Methods":[{"Name":"CreateApplication","ReturnType":"object","Args":[{"Type":"dict","Name":"config"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturns the path of the new registered application.\n\t\t\tApplication will be closed by the call or implicitly\n\t\t\twhen the programs leaves the bus.\n\t\t\tconfig:\n\t\t\t\tuint16 DataType:\n\t\t\t\t\tMandatory\n\t\t\t\tstring Role:\n\t\t\t\t\tMandatory. Possible values: \"source\",\n\t\t\t\t\t\t\t\t\t\"sink\"\n\t\t\t\tstring Description:\n\t\t\t\t\tOptional\n\t\t\t\tChannelType:\n\t\t\t\t\tOptional, just for sources. Possible\n\t\t\t\t\tvalues: \"reliable\", \"streaming\"\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DestroyApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCloses the HDP application identified by the object\n\t\t\tpath. Also application will be closed if the process\n\t\t\tthat started it leaves the bus. Only the creator of the\n\t\t\tapplication will be able to destroy it.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[]},{"Title":"HealthDevice hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthDevice1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Echo","ReturnType":"boolean","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tSends an echo petition to the remote service. Returns\n\t\t\tTrue if response matches with the buffer sent. If some\n\t\t\terror is detected False value is returned.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.OutOfRange\n"},{"Name":"CreateChannel","ReturnType":"object","Args":[{"Type":"object","Name":"application"},{"Type":"string","Name":"configuration"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCreates a new data channel. The configuration should\n\t\t\tindicate the channel quality of service using one of\n\t\t\tthis values \"reliable\", \"streaming\", \"any\".\n\t\t\tReturns the object path that identifies the data\n\t\t\tchannel that is already connected.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.HealthError\n"},{"Name":"DestroyChannel","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDestroys the data channel object. Only the creator of\n\t\t\tthe channel or the creator of the HealthApplication\n\t\t\tthat received the data channel will be able to destroy\n\t\t\tit.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[{"Name":"ChannelConnected","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a new data channel is\n\t\t\tcreated or when a known data channel is reconnected.\n\n"},{"Name":"ChannelDeleted","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a data channel is deleted.\n\n\t\t\tAfter this signal the data channel path will not be\n\t\t\tvalid and its path can be reused for future data\n\t\t\tchannels."}],"Properties":[{"Name":"MainChannel","Type":"object","Docs":"The first reliable channel opened. It is needed by\n\t\t\tupper applications in order to send specific protocol\n\t\t\tdata units. The first reliable can change after a\n\t\t\treconnection.","Flags":[]}]},{"Title":"HealthChannel hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthChannel1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/chanZZZ","Methods":[{"Name":"Acquire","ReturnType":"fd","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tReturns the file descriptor for this data channel. If\n\t\t\tthe data channel is not connected it will also\n\t\t\treconnect.\n\t\t\tPossible Errors: org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotAcquired","org.bluez.Error.NotAcquired"],"Docs":"\t\t\tReleases the fd. Application should also need to\n\t\t\tclose() it.\n\t\t\tPossible Errors: org.bluez.Error.NotAcquired\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The quality of service of the data channel. (\"reliable\"\n\t\t\tor \"streaming\")","Flags":[]},{"Name":"Device","Type":"object","Docs":"Identifies the Remote Device that is connected with.\n\t\t\tMaps with a HealthDevice object.","Flags":[]},{"Name":"Application","Type":"object","Docs":"Identifies the HealthApplication to which this channel\n\t\t\tis related to (which indirectly defines its role and\n\t\t\tdata type).","Flags":[]}]}]},{"FileName":"input-api.txt","Name":"BlueZ D-Bus Input API description","Description":"","Api":[{"Title":"Input hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Input1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"ReconnectMode","Type":"string","Docs":"Determines the Connectability mode of the HID device as\n\t\t\tdefined by the HID Profile specification, Section 5.4.2.\n\n\t\t\tThis mode is based in the two properties\n\t\t\tHIDReconnectInitiate (see Section 5.3.4.6) and\n\t\t\tHIDNormallyConnectable (see Section 5.3.4.14) which\n\t\t\tdefine the following four possible values:\n\n\t\t\t\"none\"\t\tDevice and host are not required to\n\t\t\t\t\tautomatically restore the connection.\n\n\t\t\t\"host\"\t\tBluetooth HID host restores connection.\n\n\t\t\t\"device\"\tBluetooth HID device restores\n\t\t\t\t\tconnection.\n\n\t\t\t\"any\"\t\tBluetooth HID device shall attempt to\n\t\t\t\t\trestore the lost connection, but\n\t\t\t\t\tBluetooth HID Host may also restore the\n\t\t\t\t\tconnection.","Flags":[]}]}]},{"FileName":"media-api.txt","Name":"BlueZ D-Bus Media API description","Description":"\n","Api":[{"Title":"Media hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Media1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a local end point to sender, the sender can\n\t\t\tregister as many end points as it likes.\n\t\t\tNote: If the sender disconnects the end points are\n\t\t\tautomatically unregistered.\n\t\t\tpossible properties:\n\t\t\t\tstring UUID:\n\t\t\t\t\tUUID of the profile which the endpoint\n\t\t\t\t\tis for.\n\t\t\t\tbyte Codec:\n\t\t\t\t\tAssigned number of codec that the\n\t\t\t\t\tendpoint implements. The values should\n\t\t\t\t\tmatch the profile specification which\n\t\t\t\t\tis indicated by the UUID.\n\t\t\t\tarray{byte} Capabilities:\n\t\t\t\t\tCapabilities blob, it is used as it is\n\t\t\t\t\tso the size and byte order must match.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported - emitted\n\t\t\t\t\t when interface for the end-point is\n\t\t\t\t\t disabled.\n"},{"Name":"UnregisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"}],"Errors":null,"Docs":"\t\t\tUnregister sender end point.\n"},{"Name":"RegisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a media player object to sender, the sender\n\t\t\tcan register as many objects as it likes.\n\t\t\tObject must implement at least\n\t\t\torg.mpris.MediaPlayer2.Player as defined in MPRIS 2.2\n\t\t\tspec:\n\t\t\thttp://specifications.freedesktop.org/mpris-spec/latest/\n\t\t\tNote: If the sender disconnects its objects are\n\t\t\tautomatically unregistered.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"UnregisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"}],"Errors":null,"Docs":"\t\t\tUnregister sender media player.\n"},{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"root"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister endpoints an player objects within root\n\t\t\tobject which must implement ObjectManager.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Media Control hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaControl1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume playback.\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPause playback.\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStop playback.\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tNext item.\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPrevious item.\n"},{"Name":"VolumeUp","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step up\n"},{"Name":"VolumeDown","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step down\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"","Flags":[]},{"Name":"Player","Type":"object","Docs":"Addressed Player object path.","Flags":[5]}]},{"Title":"MediaPlayer1 hierarchy","Description":"","Service":"org.bluez (Controller role)","Interface":"org.bluez.MediaPlayer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tResume playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPause playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tStop playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tNext item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPrevious item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Press","ReturnType":"void","Args":[{"Type":"byte","Name":"avc_key"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tPress a specific key to send as passthrough command.\n\t\t\tThe key will be released automatically. Use Hold()\n\t\t\tinstead if the intention is to hold down the key.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Hold","ReturnType":"void","Args":[{"Type":"byte","Name":"avc_key"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tPress and hold a specific key to send as passthrough\n\t\t\tcommand. It is your responsibility to make sure that\n\t\t\tRelease() is called after calling this method. The held\n\t\t\tkey will also be released when any other method in this\n\t\t\tinterface is called.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRelease the previously held key invoked using Hold().\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Equalizer","Type":"string","Docs":"Possible values: \"off\" or \"on\"","Flags":[]},{"Name":"Repeat","Type":"string","Docs":"Possible values: \"off\", \"singletrack\", \"alltracks\" or\n\t\t\t\t\t\"group\"","Flags":[]},{"Name":"Shuffle","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Scan","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Status","Type":"string","Docs":"Possible status: \"playing\", \"stopped\", \"paused\",\n\t\t\t\t\t\"forward-seek\", \"reverse-seek\"\n\t\t\t\t\tor \"error\"","Flags":[]},{"Name":"Position","Type":"uint32","Docs":"Playback position in milliseconds. Changing the\n\t\t\tposition may generate additional events that will be\n\t\t\tsent to the remote device. When position is 0 it means\n\t\t\tthe track is starting and when it's greater than or\n\t\t\tequal to track's duration the track has ended. Note\n\t\t\tthat even if duration is not available in metadata it's\n\t\t\tpossible to signal its end by setting position to the\n\t\t\tmaximum uint32 value.","Flags":[]},{"Name":"Track","Type":"dict","Docs":"Track metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title:","Type":"string","Docs":"Track title name","Flags":[]},{"Name":"Artist:","Type":"string","Docs":"Track artist name","Flags":[]},{"Name":"Album:","Type":"string","Docs":"Track album name","Flags":[]},{"Name":"Genre:","Type":"string","Docs":"Track genre name","Flags":[]},{"Name":"NumberOfTracks:","Type":"uint32","Docs":"Number of tracks in total","Flags":[]},{"Name":"TrackNumber:","Type":"uint32","Docs":"Track number","Flags":[]},{"Name":"Duration:","Type":"uint32","Docs":"Track duration in milliseconds","Flags":[]},{"Name":"Device","Type":"object","Docs":"Device object path.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Player name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Player type\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio\"\n\t\t\t\t\"Video\"\n\t\t\t\t\"Audio Broadcasting\"\n\t\t\t\t\"Video Broadcasting\"","Flags":[]},{"Name":"Subtype","Type":"string","Docs":"Player subtype\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio Book\"\n\t\t\t\t\"Podcast\"","Flags":[]},{"Name":"Browsable","Type":"boolean","Docs":"If present indicates the player can be browsed using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Searchable","Type":"boolean","Docs":"If present indicates the player can be searched using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Playlist","Type":"object","Docs":"Playlist object path.","Flags":[]}]},{"Title":"MediaFolder1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaFolder1","ObjectPath":"freely definable (Target role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX\n\t\t(Controller role)","Methods":[{"Name":"Search","ReturnType":"object","Args":[{"Type":"string","Name":"value"},{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tReturn a folder object containing the search result.\n\t\t\tTo list the items found use the folder object returned\n\t\t\tand pass to ChangeFolder.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ListItems","ReturnType":"array{objects, properties}","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturn a list of items found\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"object","Name":"folder"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tChange current folder.\n\t\t\tNote: By changing folder the items of previous folder\n\t\t\tmight be destroyed and have to be listed again, the\n\t\t\texception is NowPlaying folder which should be always\n\t\t\tpresent while the player is active.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"NumberOfItems","Type":"uint32","Docs":"Number of items in the folder","Flags":[]},{"Name":"Name","Type":"string","Docs":"Folder name:\n\n\t\t\tPossible values:\n\t\t\t\t\"/Filesystem/...\": Filesystem scope\n\t\t\t\t\"/NowPlaying/...\": NowPlaying scope\n\n\t\t\tNote: /NowPlaying folder might not be listed if player\n\t\t\tis stopped, folders created by Search are virtual so\n\t\t\tonce another Search is perform or the folder is\n\t\t\tchanged using ChangeFolder it will no longer be listed.\n\nFilters","Flags":[]},{"Name":"Start:","Type":"uint32","Docs":"Offset of the first item.\n\n\t\t\tDefault value: 0","Flags":[]},{"Name":"End:","Type":"uint32","Docs":"Offset of the last item.\n\n\t\t\tDefault value: NumbeOfItems","Flags":[]},{"Name":"Attributes","Type":"array{string}","Docs":"Item properties that should be included in the list.\n\n\t\t\tPossible Values:\n\n\t\t\t\t\"title\", \"artist\", \"album\", \"genre\",\n\t\t\t\t\"number-of-tracks\", \"number\", \"duration\"\n\n\t\t\tDefault Value: All","Flags":[]}]},{"Title":"MediaItem1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaItem1","ObjectPath":"freely definable (Target role)\n\t\t[variable\n\t\tprefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX\n\t\t(Controller role)","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPlay item\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"AddtoNowPlaying","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tAdd item to now playing list\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Player","Type":"object","Docs":"Player object path the item belongs to","Flags":[]},{"Name":"Name","Type":"string","Docs":"Item displayable name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Item type\n\n\t\t\tPossible values: \"video\", \"audio\", \"folder\"","Flags":[]},{"Name":"FolderType","Type":"string","Docs":"Folder type.\n\n\t\t\tPossible values: \"mixed\", \"titles\", \"albums\", \"artists\"\n\n\t\t\tAvailable if property Type is \"Folder\"","Flags":[5]},{"Name":"Playable","Type":"boolean","Docs":"Indicates if the item can be played\n\n\t\t\tAvailable if property Type is \"folder\"","Flags":[5]},{"Name":"Metadata","Type":"dict","Docs":"Item metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title","Type":"string","Docs":"Item title name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Artist","Type":"string","Docs":"Item artist name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Album","Type":"string","Docs":"Item album name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Genre","Type":"string","Docs":"Item genre name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"NumberOfTracks","Type":"uint32","Docs":"Item album number of tracks in total\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Number","Type":"uint32","Docs":"Item album number\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Duration","Type":"uint32","Docs":"Item duration in milliseconds\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]}]},{"Title":"MediaEndpoint1 hierarchy","Description":"","Service":"unique name (Server role)\n\t\torg.bluez (Client role)","Interface":"org.bluez.MediaEndpoint1","ObjectPath":"freely definable (Server role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX\n\t\t(Client role)","Methods":[{"Name":"SetConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"},{"Type":"dict","Name":"properties"}],"Errors":null,"Docs":"\t\t\tSet configuration for the transport.\n\t\t\tFor client role transport must be set with a server\n\t\t\tendpoint oject which will be configured and the\n\t\t\tproperties must contain the following properties:\n\t\t\t\tarray{byte} Capabilities\n"},{"Name":"SelectConfiguration","ReturnType":"array{byte}","Args":[{"Type":"array{byte}","Name":"capabilities"}],"Errors":null,"Docs":"\t\t\tSelect preferable configuration from the supported\n\t\t\tcapabilities.\n\t\t\tReturns a configuration which can be used to setup\n\t\t\ta transport.\n\t\t\tNote: There is no need to cache the selected\n\t\t\tconfiguration since on success the configuration is\n\t\t\tsend back as parameter of SetConfiguration.\n"},{"Name":"ClearConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"}],"Errors":null,"Docs":"\t\t\tClear transport configuration.\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the endpoint. An endpoint can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tendpoint, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the endpoint is for.","Flags":[5]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the endpoint implements.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[5]},{"Name":"Capabilities","Type":"array{byte}","Docs":"Capabilities blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[5]},{"Name":"Device","Type":"object","Docs":"Device object which the endpoint is belongs to.","Flags":[5]},{"Name":"DelayReporting","Type":"bool","Docs":"Indicates if endpoint supports Delay Reporting.","Flags":[5]}]},{"Title":"MediaTransport1 hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaTransport1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX","Methods":[{"Name":"Acquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAuthorized","org.bluez.Error.NotAuthorized"],"Docs":"\t\t\tAcquire transport file descriptor and the MTU for read\n\t\t\tand write respectively.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"TryAcquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAvailable","org.bluez.Error.NotAvailable"],"Docs":"\t\t\tAcquire transport file descriptor only if the transport\n\t\t\tis in \"pending\" state at the time the message is\n\t\t\treceived by BlueZ. Otherwise no request will be sent\n\t\t\tto the remote device and the function will just fail\n\t\t\twith org.bluez.Error.NotAvailable.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAvailable\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tReleases file descriptor.\n"}],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"Device object which the transport is connected to.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the transport is for.","Flags":[]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the transport support.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[]},{"Name":"Configuration","Type":"array{byte}","Docs":"Configuration blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[]},{"Name":"State","Type":"string","Docs":"Indicates the state of the transport. Possible\n\t\t\tvalues are:\n\t\t\t\t\"idle\": not streaming\n\t\t\t\t\"pending\": streaming but not acquired\n\t\t\t\t\"active\": streaming and acquired","Flags":[]},{"Name":"Delay","Type":"uint16","Docs":"Optional. Transport delay in 1/10 of millisecond, this\n\t\t\tproperty is only writeable when the transport was\n\t\t\tacquired by the sender.","Flags":[]},{"Name":"Volume","Type":"uint16","Docs":"Optional. Indicates volume level of the transport,\n\t\t\tthis property is only writeable when the transport was\n\t\t\tacquired by the sender.\n\n\t\t\tPossible Values: 0-127","Flags":[]},{"Name":"Endpoint","Type":"object","Docs":"Endpoint object which the transport is associated\n\t\t\twith.","Flags":[5]}]}]},{"FileName":"mesh-api.txt","Name":"BlueZ D-Bus Mesh API description","Description":"","Api":[{"Title":"Mesh Network Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Network1","ObjectPath":"/org/bluez/mesh","Methods":[{"Name":"Join","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application has to call to\n\t\tbecome a provisioned node on a mesh network. The call will\n\t\tinitiate broadcasting of Unprovisioned Device Beacon.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The application hierarchy\n\t\talso contains a provision agent object that implements\n\t\torg.bluez.mesh.ProvisionAgent1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error. The composition of the UUID\n\t\toctets must be in compliance with RFC 4122.\n\t\tWhen provisioning finishes, the daemon will call either\n\t\tJoinComplete or JoinFailed method on object implementing\n\t\torg.bluez.mesh.Application1 interface.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Cancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"Attach","ReturnType":"object node, array{byte, array{(uint16, dict)}} configuration","Args":[{"Type":"object","Name":"app_root"},{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis is the first method that an application must call to get\n\t\taccess to mesh node functionalities.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe token parameter is a 64-bit number that has been assigned to\n\t\tthe application when it first got provisioned/joined mesh\n\t\tnetwork, i.e. upon receiving JoinComplete() method. The daemon\n\t\tuses the token to verify whether the application is authorized\n\t\tto assume the mesh node identity.\n\t\tIn case of success, the method call returns mesh node object\n\t\t(see Mesh Node Hierarchy section) and current configuration\n\t\tsettings. The return value of configuration parameter is an\n\t\tarray, where each entry is a structure that contains element\n\t\tconfiguration. The element configuration structure is organized\n\t\tas follows:\n\t\tbyte\n\t\t\tElement index, identifies the element to which this\n\t\t\tconfiguration entry pertains.\n\t\tarray{struct}\n\t\t\tModels array where each entry is a structure with the\n\t\t\tfollowing members:\n\t\t\tuint16\n\t\t\t\tEither a SIG Model Identifier or, if Vendor key\n\t\t\t\tis present in model configuration dictionary, a\n\t\t\t\t16-bit vendor-assigned Model Identifier\n\t\t\tdict\n\t\t\t\tA dictionary that contains model configuration\n\t\t\t\twith the following keys defined:\n\t\t\t\tarray{uint16} Bindings\n\t\t\t\t\tIndices of application keys bound to the\n\t\t\t\t\tmodel\n\t\t\t\tuint32 PublicationPeriod\n\t\t\t\t\tModel publication period in milliseconds\n\t\t\t\tuint16 Vendor\n\t\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\t\tBluetooth SIG\n\t\t\t\tarray{variant} Subscriptions\n\t\t\t\t\tAddresses the model is subscribed to.\n\t\t\t\t\tEach address is provided either as\n\t\t\t\t\tuint16 for group addresses, or\n\t\t\t\t\tas array{byte} for virtual labels.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.Busy,\n\t\t\torg.bluez.mesh.Error.Failed\n"},{"Name":"Leave","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis removes the configuration information about the mesh node\n\t\tidentified by the 64-bit token parameter. The token parameter\n\t\thas been obtained as a result of successful Join() method call.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"CreateNetwork","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application calls to become\n\t\ta Provisioner node, and a Configuration Client on a newly\n\t\tcreated Mesh Network.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface, and a org.bluez.mesh.Provisioner1 interface. The\n\t\tapplication represents a node where child mesh elements have\n\t\ttheir own objects that implement org.bluez.mesh.Element1\n\t\tinterface. The application hierarchy also contains a provision\n\t\tagent object that implements org.bluez.mesh.ProvisionAgent1\n\t\tinterface. The standard DBus.ObjectManager interface must be\n\t\tavailable on the app_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error. The composition of the UUID\n\t\toctets must be in compliance with RFC 4122.\n\t\tThe other information the bluetooth-meshd daemon will preserve\n\t\tabout the initial node, is to give it the initial primary\n\t\tunicast address (0x0001), and create and assign a net_key as the\n\t\tprimary network net_index (0x000).\n\t\tUpon successful processing of Create() method, the daemon\n\t\twill call JoinComplete method on object implementing\n\t\torg.bluez.mesh.Application1.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Import","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"array{byte}[16]","Name":"dev_key"},{"Type":"array{byte}[16]","Name":"net_key"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"flags"},{"Type":"uint32","Name":"iv_index"},{"Type":"uint16","Name":"unicast"}],"Errors":null,"Docs":"\t\tThis method creates a local mesh node based on node\n\t\tconfiguration that has been generated outside bluetooth-meshd.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error. The composition of the UUID\n\t\toctets must be in compliance with RFC 4122.\n\t\tThe dev_key parameter is the 16-byte value of the dev key of\n\t\tthe imported mesh node.\n\t\tRemaining parameters correspond to provisioning data:\n\t\tThe net_key and net_index parameters describe the network (or a\n\t\tsubnet, if net_index is not 0) the imported mesh node belongs\n\t\tto.\n\t\tThe flags parameter is a dictionary containing provisioning\n\t\tflags. Supported values are:\n\t\t\tboolean IvUpdate\n\t\t\t\tWhen true, indicates that the network is in the\n\t\t\t\tmiddle of IV Index Update procedure.\n\t\t\tboolean KeyRefresh\n\t\t\t\tWhen true, indicates that the specified net key\n\t\t\t\tis in the middle of a key refresh procedure.\n\t\tThe iv_index parameter is the current IV Index value used by\n\t\tthe network. This value is known by the provisioner.\n\t\tThe unicast parameter is the primary unicast address of the\n\t\timported node.\n\t\tUpon successful processing of Import() method, the daemon will\n\t\tcall JoinComplete method on object implementing\n\t\torg.bluez.mesh.Application1 interface.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.NotSupported,\n\t\t\torg.bluez.mesh.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Node Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Node1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"Send","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"key_index"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe key_index parameter determines which application key to use\n\t\tfor encrypting the message. The key_index must be valid for that\n\t\telement, i.e., the application key must be bound to a model on\n\t\tthis element. Otherwise, org.bluez.mesh.Error.NotAuthorized will\n\t\tbe returned.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tbluetooth-meshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"DevKeySend","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel encoded with the device key of the remote node.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe remote parameter, if true, looks up the device key by the\n\t\tdestination address in the key database to encrypt the message.\n\t\tIf remote is true, but requested key does not exist, a NotFound\n\t\terror will be returned. If set to false, the local node's\n\t\tdevice key is used.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddNetKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"subnet_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe subnet_index parameter refers to the subnet index of the\n\t\tnetwork that is being added or updated. This key must exist in\n\t\tthe local key database.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddAppKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"app_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe app_index parameter refers to the application key which is\n\t\tbeing added or updated. This key must exist in the local key\n\t\tdatabase.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"Publish","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"model"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a publication originated by a local\n\t\tmodel. If the model does not exist, or it has no publication\n\t\trecord, the method returns org.bluez.mesh.Error.DoesNotExist\n\t\terror.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe model parameter contains a model ID, as defined by the\n\t\tBluetooth SIG. If the options dictionary contains a \"Vendor\"\n\t\tkey, then this ID is defined by the specified vendor.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\t\tuint16 Vendor\n\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\tBluetooth SIG. This key should only exist when\n\t\t\t\tpublishing on a Vendor defined model.\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tSince only one Publish record may exist per element-model, the\n\t\tdestination and key_index are obtained from the Publication\n\t\trecord cached by the daemon.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[{"Name":"Features","Type":"dict","Docs":"The dictionary that contains information about feature support.\n\t\tThe following keys are defined:","Flags":[1]},{"Name":"Friend","Type":"boolean","Docs":"Indicates the ability to establish a friendship with a\n\t\t\tLow Power node","Flags":[]},{"Name":"LowPower","Type":"boolean","Docs":"Indicates support for operating in Low Power node mode","Flags":[]},{"Name":"Proxy","Type":"boolean","Docs":"Indicates support for GATT proxy","Flags":[]},{"Name":"Relay","Type":"boolean","Docs":"Indicates support for relaying messages\n\n\tIf a key is absent from the dictionary, the feature is not supported.\n\tOtherwise, true means that the feature is enabled and false means that\n\tthe feature is disabled.","Flags":[]},{"Name":"Beacon","Type":"boolean","Docs":"This property indicates whether the periodic beaconing is\n\t\tenabled (true) or disabled (false).","Flags":[1]},{"Name":"IvUpdate","Type":"boolean","Docs":"When true, indicates that the network is in the middle of IV\n\t\tIndex Update procedure. This information is only useful for\n\t\tprovisioning.","Flags":[1]},{"Name":"IvIndex","Type":"uint32","Docs":"This property may be read at any time to determine the IV_Index\n\t\tthat the current network is on. This information is only useful\n\t\tfor provisioning.","Flags":[1]},{"Name":"SecondsSinceLastHeard","Type":"uint32","Docs":"This property may be read at any time to determine the number of\n\t\tseconds since mesh network layer traffic was last detected on\n\t\tthis node's network.","Flags":[1]},{"Name":"Addresses","Type":"array{uint16}","Docs":"This property contains unicast addresses of node's elements.","Flags":[1]},{"Name":"SequenceNumber","Type":"uint32","Docs":"This property may be read at any time to determine the\n\t\tsequence number.","Flags":[1]}]},{"Title":"Mesh Provisioning Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Management1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"UnprovisionedScan","ReturnType":"void","Args":[{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to start listening\n\t\t(scanning) for unprovisioned devices in the area.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tuint16 Seconds\n\t\t\tSpecifies number of seconds for scanning to be active.\n\t\t\tIf set to 0 or if this key is not present, then the\n\t\t\tscanning will continue until UnprovisionedScanCancel()\n\t\t\tor AddNode() methods are called.\n\t\tEach time a unique unprovisioned beacon is heard, the\n\t\tScanResult() method on the app will be called with the result.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"UnprovisionedScanCancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"AddNode","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to add the\n\t\tunprovisioned device specified by uuid, to the Network.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID\n\t\tof the unprovisioned device to be added to the network.\n\t\tThe options parameter is a dictionary that may contain\n\t\tadditional configuration info (currently an empty placeholder\n\t\tfor forward compatibility).\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n"},{"Name":"CreateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tnetwork subnet key.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"ImportSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}[16]","Name":"net_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add a network subnet\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThe net_key parameter is the 16-byte value of the net key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"UpdateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new network\n\t\tsubnet key, and set it's key refresh state to Phase 1.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to update. Note that the subnet must\n\t\texist prior to updating.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"DeleteSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application that to delete a subnet.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to delete. The primary net key (0x000)\n\t\tmay not be deleted.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"SetKeyPhase","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint8","Name":"phase"}],"Errors":null,"Docs":"\t\tThis method is used to set the master key update phase of the\n\t\tgiven subnet. When finalizing the procedure, it is important\n\t\tto CompleteAppKeyUpdate() on all app keys that have been\n\t\tupdated during the procedure prior to setting phase 3.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which subnet phase to set.\n\t\tThe phase parameter is used to cycle the local key database\n\t\tthrough the phases as defined by the Mesh Profile Specification.\n\t\tAllowed values:\n\t\t\t0 - Cancel Key Refresh (May only be called from Phase 1,\n\t\t\t\tand should never be called once the new key has\n\t\t\t\tstarted propagating)\n\t\t\t1 - Invalid Argument (see NetKeyUpdate method)\n\t\t\t2 - Go to Phase 2 (May only be called from Phase 1)\n\t\t\t3 - Complete Key Refresh procedure (May only be called\n\t\t\t\tfrom Phase 2)\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is the responsibility of the application to maintain the key\n\t\trefresh phases per the Mesh Profile Specification.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"CreateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tapplication key.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"ImportAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"},{"Type":"array{byte}[16]","Name":"app_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add an application\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to import.\n\t\tThe app_key parameter is the 16-byte value of the key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"UpdateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new\n\t\tapplication key.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to update. Note that the subnet that\n\t\tthe key is bound to must exist and be in Phase 1.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InProgress\n"},{"Name":"DeleteAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete an application\n\t\tkey.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to delete.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"ImportRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"},{"Type":"array{byte}[16]","Name":"device_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to import a remote node\n\t\tthat has been provisioned by an external process.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being imported.\n\t\tThe count parameter specifies the number of elements that are\n\t\tassigned to this remote node.\n\t\tThe device_key parameter is the access layer key that will be\n\t\twill used to decrypt privledged messages from this remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"DeleteRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete a remote node\n\t\tfrom the local device key database.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being deleted.\n\t\tThe count parameter specifies the number of elements that were\n\t\tassigned to the remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Application Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Application1","ObjectPath":"\u003capp_root\u003e","Methods":[{"Name":"JoinComplete","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby a Join() method call successfully completed.\n\t\tThe token parameter serves as a unique identifier of the\n\t\tparticular node. The token must be preserved by the application\n\t\tin order to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n\t\tIf this method returns an error, the daemon will assume that the\n\t\tapplication failed to preserve the token, and will remove the\n\t\tfreshly created node.\n"},{"Name":"JoinFailed","ReturnType":"void","Args":[{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tJoin() has failed.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"timeout\", \"bad-pdu\",\n\t\t\"confirmation-failed\", \"out-of-resources\", \"decryption-error\",\n\t\t\"unexpected-error\", \"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[{"Name":"CompanyID","Type":"uint16","Docs":"A 16-bit Bluetooth-assigned Company Identifier of the vendor as\n\t\tdefined by Bluetooth SIG","Flags":[1]},{"Name":"ProductID","Type":"uint16","Docs":"A 16-bit vendor-assigned product identifier","Flags":[1]},{"Name":"VersionID","Type":"uint16","Docs":"A 16-bit vendor-assigned product version identifier","Flags":[1]},{"Name":"CRPL","Type":"uint16","Docs":"A 16-bit minimum number of replay protection list entries","Flags":[1,5]}]},{"Title":"Mesh Element Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Element1","ObjectPath":"\u003capp_defined_element_path\u003e","Methods":[{"Name":"MessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"uint16","Name":"key_index"},{"Type":"variant","Name":"destination"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a message\n\t\tarrives addressed to the application.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe key_index parameter indicates which application key has been\n\t\tused to decode the incoming message. The same key_index should\n\t\tbe used by the application when sending a response to this\n\t\tmessage (in case a response is expected).\n\t\tThe destination parameter contains the destination address of\n\t\treceived message. Underlying variant types are:\n\t\tuint16\n\t\t\tDestination is an unicast address, or a well known\n\t\t\tgroup address\n\t\tarray{byte}\n\t\t\tDestination is a virtual address label\n\t\tThe data parameter is the incoming message.\n"},{"Name":"DevKeyMessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by meshd daemon when a message arrives\n\t\taddressed to the application, which was sent with the remote\n\t\tnode's device key.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe remote parameter if true indicates that the device key\n\t\tused to decrypt the message was from the sender. False\n\t\tindicates that the local nodes device key was used, and the\n\t\tmessage has permissions to modify local states.\n\t\tThe net_index parameter indicates what subnet the message was\n\t\treceived on, and if a response is required, the same subnet\n\t\tmust be used to send the response.\n\t\tThe data parameter is the incoming message.\n"},{"Name":"UpdateModelConfiguration","ReturnType":"void","Args":[{"Type":"uint16","Name":"model_id"},{"Type":"dict","Name":"config"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a model's\n\t\tconfiguration is updated.\n\t\tThe model_id parameter contains BT SIG Model Identifier or, if\n\t\tVendor key is present in config dictionary, a 16-bit\n\t\tvendor-assigned Model Identifier.\n\t\tThe config parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tarray{uint16} Bindings\n\t\t\tIndices of application keys bound to the model\n\t\tuint32 PublicationPeriod\n\t\t\tModel publication period in milliseconds\n\t\tuint16 Vendor\n\t\t\tA 16-bit Bluetooth-assigned Company Identifier of the\n\t\t\tvendor as defined by Bluetooth SIG\n\t\tarray{variant} Subscriptions\n\t\t\tAddresses the model is subscribed to.\n\t\t\tEach address is provided either as uint16 for group\n\t\t\taddresses, or as array{byte} for virtual labels.\n"}],"Signals":[],"Properties":[{"Name":"Models","Type":"array{(uint16 id, dict caps)}","Docs":"An array of SIG Models:\n\n\t\t\tid - SIG Model Identifier\n\n\t\t\toptions - a dictionary that may contain additional model\n\t\t\tinfo. The following keys are defined:","Flags":[1]},{"Name":"Publish","Type":"boolean","Docs":"supports publication mechanism. If not\n\t\t\t\t\tpresent, publication is enabled.","Flags":[]},{"Name":"Subscribe","Type":"boolean","Docs":"supports subscription mechanism. If not\n\t\t\t\t\tpresent, subscriptons are enabled.\n\n\t\tThe array may be empty.","Flags":[]},{"Name":"VendorModels","Type":"array{(uint16 vendor, uint16 id, dict options)}","Docs":"An array of Vendor Models:\n\n\t\t\tvendor - a 16-bit Bluetooth-assigned Company ID as\n\t\t\tdefined by Bluetooth SIG.\n\n\t\t\tid - a 16-bit vendor-assigned Model Identifier\n\n\t\t\toptions - a dictionary that may contain additional model\n\t\t\tinfo. The following keys are defined:","Flags":[1]},{"Name":"Publish","Type":"boolean","Docs":"supports publication mechanism","Flags":[]},{"Name":"Subscribe","Type":"boolean","Docs":"supports subscription mechanism\n\n\t\tThe array may be empty.","Flags":[]},{"Name":"Location","Type":"uint16","Docs":"Location descriptor as defined in the GATT Bluetooth Namespace\n\t\tDescriptors section of the Bluetooth SIG Assigned Numbers","Flags":[1,5]}]},{"Title":"Mesh Attention Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Attention1","ObjectPath":"freely definable","Methods":[{"Name":"SetTimer","ReturnType":"void","Args":[{"Type":"uint8","Name":"element_index"},{"Type":"uint16","Name":"time"}],"Errors":null,"Docs":"\t\tThe element_index parameter is the element's index within the\n\t\tnode where the health server model is hosted.\n\t\tThe time parameter indicates how many seconds the attention\n\t\tstate shall be on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"},{"Name":"GetTimer","ReturnType":"uint16","Args":[{"Type":"uint16","Name":"element"}],"Errors":null,"Docs":"\t\tThe element parameter is the unicast address within the node\n\t\twhere the health server model is hosted.\n\t\tReturns the number of seconds for how long the attention action\n\t\tremains staying on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Provisioner Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Provisioner1","ObjectPath":"freely definable","Methods":[{"Name":"ScanResult","ReturnType":"void","Args":[{"Type":"int16","Name":"rssi"},{"Type":"array{byte}","Name":"data"},{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThe method is called from the bluetooth-meshd daemon when a\n\t\tunique UUID has been seen during UnprovisionedScan() for\n\t\tunprovsioned devices.\n\t\tThe rssi parameter is a signed, normalized measurement of the\n\t\tsignal strength of the recieved unprovisioned beacon.\n\t\tThe data parameter is a variable length byte array, that may\n\t\thave 1, 2 or 3 distinct fields contained in it including the 16\n\t\tbyte remote device UUID (always), a 16 bit mask of OOB\n\t\tauthentication flags (optional), and a 32 bit URI hash (if URI\n\t\tbit set in OOB mask). Whether these fields exist or not is a\n\t\tdecision of the remote device.\n\t\tThe options parameter is a dictionary that may contain\n\t\tadditional scan result info (currently an empty placeholder for\n\t\tforward compatibility).\n\t\tIf a beacon with a UUID that has already been reported is\n\t\trecieved by the daemon, it will be silently discarded unless it\n\t\twas recieved at a higher rssi power level.\n"},{"Name":"RequestProvData","ReturnType":"uint16 net_index, uint16 unicast","Args":[{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is implemented by a Provisioner capable application\n\t\tand is called when the remote device has been fully\n\t\tauthenticated and confirmed.\n\t\tThe count parameter is the number of consecutive unicast\n\t\taddresses the remote device is requesting.\n\t\tReturn Parameters are from the Mesh Profile Spec:\n\t\tnet_index - Subnet index of the net_key\n\t\tunicast - Primary Unicast address of the new node\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Abort\n"},{"Name":"AddNodeComplete","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"uint16","Name":"unicast"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby an AddNode() method call successfully completed.\n\t\tThe unicast parameter is the primary address that has been\n\t\tassigned to the new node, and the address of it's config server.\n\t\tThe count parameter is the number of unicast addresses assigned\n\t\tto the new node.\n\t\tThe new node may now be sent messages using the credentials\n\t\tsupplied by the RequestProvData method.\n"},{"Name":"AddNodeFailed","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tAddNode() has failed. Depending on how far Provisioning\n\t\tproceeded before failing, some cleanup of cached data may be\n\t\trequired.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"aborted\", \"timeout\",\n\t\t\"bad-pdu\", \"confirmation-failed\", \"out-of-resources\",\n\t\t\"decryption-error\", \"unexpected-error\",\n\t\t\"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[]},{"Title":"Provisioning Agent Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.ProvisionAgent1","ObjectPath":"freely definable","Methods":[{"Name":"PrivateKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the Provisioner\n\t\thas requested Out-Of-Band ECC key exchange. The Private key is\n\t\treturned to the Daemon, and the Public Key is delivered to the\n\t\tremote Provisioner using a method that does not involve the\n\t\tBluetooth Mesh system. The Private Key returned must be 32\n\t\toctets in size, or the Provisioning procedure will fail and be\n\t\tcanceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Unprovisioned device.\n"},{"Name":"PublicKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the local device is\n\t\tthe Provisioner, and is requestng Out-Of-Band ECC key exchange.\n\t\tThe Public key is returned to the Daemon that is the matched\n\t\tpair of the Private key of the remote device. The Public Key\n\t\treturned must be 64 octets in size, or the Provisioning\n\t\tprocedure will fail and be canceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Provisioner.\n"},{"Name":"DisplayString","ReturnType":"void","Args":[{"Type":"string","Name":"value"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter \"ABCDE\" on remote device\".\n"},{"Name":"DisplayNumeric","ReturnType":"void","Args":[{"Type":"string","Name":"type"},{"Type":"uint32","Name":"number"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter 14939264 on remote device\".\n\t\tThe type parameter indicates the display method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Locally blink LED\n\t\t\t\"beep\" - Locally make a noise\n\t\t\t\"vibrate\" - Locally vibrate\n\t\t\t\"out-numeric\" - Display value to enter remotely\n\t\t\t\"push\" - Request pushes on remote button\n\t\t\t\"twist\" - Request twists on remote knob\n\t\tThe number parameter is the specific value represented by the\n\t\tPrompt.\n"},{"Name":"PromptNumeric","ReturnType":"uint32","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requests the user to\n\t\tenter a decimal value between 1-99999999.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Enter times remote LED blinked\n\t\t\t\"beep\" - Enter times remote device beeped\n\t\t\t\"vibrate\" - Enter times remote device vibrated\n\t\t\t\"in-numeric\" - Enter remotely displayed value\n\t\t\t\"push\" - Push local button remotely requested times\n\t\t\t\"twist\" - Twist local knob remotely requested times\n\t\tThis agent should prompt the user for specific input. For\n\t\tinstance: \"Enter value being displayed by remote device\".\n"},{"Name":"PromptStatic","ReturnType":"array{byte}[16]","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requires a 16 octet byte\n\t\tarray, as an Out-of-Band authentication.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"static-oob\" - return 16 octet array\n\t\t\t\"in-alpha\" - return 16 octet alpha array\n\t\tThe Static data returned must be 16 octets in size, or the\n\t\tProvisioning procedure will fail and be canceled. If input type\n\t\tis \"in-alpha\", the printable characters should be\n\t\tleft-justified, with trailing 0x00 octets filling the remaining\n\t\tbytes.\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\tThis method gets called by the daemon to cancel any existing\n\t\tAgent Requests. When called, any pending user input should be\n\t\tcanceled, and any display requests removed.\n"}],"Signals":[],"Properties":[{"Name":"Capabilities","Type":"array{string}","Docs":"An array of strings with the following allowed values:\n\t\t\t\"blink\"\n\t\t\t\"beep\"\n\t\t\t\"vibrate\"\n\t\t\t\"out-numeric\"\n\t\t\t\"out-alpha\"\n\t\t\t\"push\"\n\t\t\t\"twist\"\n\t\t\t\"in-numeric\"\n\t\t\t\"in-alpha\"\n\t\t\t\"static-oob\"\n\t\t\t\"public-oob\"","Flags":[1]},{"Name":"OutOfBandInfo","Type":"array{string}","Docs":"Indicates availability of OOB data. An array of strings with the\n\t\tfollowing allowed values:\n\t\t\t\"other\"\n\t\t\t\"uri\"\n\t\t\t\"machine-code-2d\"\n\t\t\t\"bar-code\"\n\t\t\t\"nfc\"\n\t\t\t\"number\"\n\t\t\t\"string\"\n\t\t\t\"on-box\"\n\t\t\t\"in-box\"\n\t\t\t\"on-paper\",\n\t\t\t\"in-manual\"\n\t\t\t\"on-device\"","Flags":[1,5]},{"Name":"URI","Type":"string","Docs":"Uniform Resource Identifier points to out-of-band (OOB)\n\t\tinformation (e.g., a public key)","Flags":[1,5]}]}]},{"FileName":"network-api.txt","Name":"BlueZ D-Bus Network API description","Description":"\n","Api":[{"Title":"Network hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Network1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"string","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.AlreadyConnected","org.bluez.Error.AlreadyConnected"],"Docs":"\t\t\tConnect to the network device and return the network\n\t\t\tinterface name. Examples of the interface name are\n\t\t\tbnep0, bnep1 etc.\n\t\t\tuuid can be either one of \"gn\", \"panu\" or \"nap\" (case\n\t\t\tinsensitive) or a traditional string representation of\n\t\t\tUUID or a hexadecimal number.\n\t\t\tThe connection will be closed and network device\n\t\t\treleased either upon calling Disconnect() or when\n\t\t\tthe client disappears from the message bus.\n\t\t\tPossible errors: org.bluez.Error.AlreadyConnected\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnect from the network device.\n\t\t\tTo abort a connection attempt in case of errors or\n\t\t\ttimeouts in the client it is fine to call this method.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if the device is connected.","Flags":[]},{"Name":"Interface","Type":"string","Docs":"Indicates the network interface name when available.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"Indicates the connection role when available.","Flags":[]}]},{"Title":"Network server hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.NetworkServer1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"Register","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"},{"Type":"string","Name":"bridge"}],"Errors":null,"Docs":"\t\t\tRegister server for the provided UUID. Every new\n\t\t\tconnection to this server will be added the bridge\n\t\t\tinterface.\n\t\t\tValid UUIDs are \"gn\", \"panu\" or \"nap\".\n\t\t\tInitially no network server SDP is provided. Only\n\t\t\tafter this method a SDP record will be available\n\t\t\tand the BNEP server will be ready for incoming\n\t\t\tconnections.\n"},{"Name":"Unregister","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":null,"Docs":"\t\t\tUnregister the server for provided UUID.\n\t\t\tAll servers will be automatically unregistered when\n\t\t\tthe calling application terminates.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-agent-api.txt","Name":"OBEX D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.AgentManager1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tRegister an agent to request authorization of\n\t\t\tthe user to accept/reject objects. Object push\n\t\t\tservice needs to authorize each received object.\n\t\t\tPossible errors: org.bluez.obex.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.obex.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.obex.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"AuthorizePush","ReturnType":"string","Args":[{"Type":"object","Name":"transfer"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to accept/reject a Bluetooth object push request.\n\t\t\tReturns the full path (including the filename) where\n\t\t\tthe object shall be stored. The tranfer object will\n\t\t\tcontain a Filename property that contains the default\n\t\t\tlocation and name that can be returned.\n\t\t\tPossible errors: org.bluez.obex.Error.Rejected\n\t\t\t org.bluez.obex.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned. It cancels\n\t\t\tthe previous request.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-api.txt","Name":"OBEX D-Bus API description","Description":"\n","Api":[{"Title":"Client hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Client1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"CreateSession","ReturnType":"object","Args":[{"Type":"string","Name":"destination"},{"Type":"dict","Name":"args"}],"Errors":null,"Docs":"\t\t\tCreate a new OBEX session for the given remote address.\n\t\t\tThe last parameter is a dictionary to hold optional or\n\t\t\ttype-specific parameters. Typical parameters that can\n\t\t\tbe set in this dictionary include the following:\n\t\t\t\tstring \"Target\" : type of session to be created\n\t\t\t\tstring \"Source\" : local address to be used\n\t\t\t\tbyte \"Channel\"\n\t\t\tThe currently supported targets are the following:\n\t\t\t\t\"ftp\"\n\t\t\t\t\"map\"\n\t\t\t\t\"opp\"\n\t\t\t\t\"pbap\"\n\t\t\t\t\"sync\"\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"RemoveSession","ReturnType":"void","Args":[{"Type":"object","Name":"session"}],"Errors":null,"Docs":"\t\t\tUnregister session and abort pending transfers.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.NotAuthorized\n"}],"Signals":[],"Properties":[]},{"Title":"Session hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Session1","ObjectPath":"/org/bluez/obex/server/session{0, 1, 2, ...} or\n\t\t/org/bluez/obex/client/session{0, 1, 2, ...}","Methods":[{"Name":"GetCapabilities","ReturnType":"string","Args":[],"Errors":null,"Docs":"\t\t\tGet remote device capabilities.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Source","Type":"string","Docs":"Bluetooth adapter address","Flags":[]},{"Name":"Destination","Type":"string","Docs":"Bluetooth device address","Flags":[]},{"Name":"Channel","Type":"byte","Docs":"Bluetooth channel","Flags":[]},{"Name":"Target","Type":"string","Docs":"Target UUID","Flags":[]},{"Name":"Root","Type":"string","Docs":"Root path","Flags":[]}]},{"Title":"Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Transfer1","ObjectPath":"[Session object path]/transfer{0, 1, 2, ...}","Methods":[{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStops the current transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.InProgress\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Suspend","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tSuspend transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to suspend transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"},{"Name":"Resume","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to resume transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"}],"Signals":[],"Properties":[{"Name":"Status","Type":"string","Docs":"Inform the current status of the transfer.\n\n\t\t\tPossible values: \"queued\", \"active\", \"suspended\",\n\t\t\t\t\t\"complete\" or \"error\"","Flags":[]},{"Name":"Session","Type":"object","Docs":"The object path of the session the transfer belongs\n\t\t\tto.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Name of the transferred object. Either Name or Type\n\t\t\tor both will be present.","Flags":[]},{"Name":"Type","Type":"string","Docs":"Type of the transferred object. Either Name or Type\n\t\t\tor both will be present.\n\n\t\tuint64 Time [readonly, optional]\n\n\t\t\tTime of the transferred object if this is\n\t\t\tprovided by the remote party.\n\n\t\tuint64 Size [readonly, optional]\n\n\t\t\tSize of the transferred object. If the size is\n\t\t\tunknown, then this property will not be present.\n\n\t\tuint64 Transferred [readonly, optional]\n\n\t\t\tNumber of bytes transferred. For queued transfers, this\n\t\t\tvalue will not be present.","Flags":[]},{"Name":"Filename","Type":"string","Docs":"Complete name of the file being received or sent.\n\n\t\t\tFor incoming object push transaction, this will be\n\t\t\tthe proposed default location and name. It can be\n\t\t\toverwritten by the AuthorizePush agent callback\n\t\t\tand will be then updated accordingly.","Flags":[5]}]},{"Title":"Object Push hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.ObjectPush1","ObjectPath":"[Session object path]","Methods":[{"Name":"SendFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend one local file to the remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullBusinessCard","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRequest the business card from a remote device and\n\t\t\tstore it in the local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ExchangeBusinessCards","ReturnType":"object, dict","Args":[{"Type":"string","Name":"clientfile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tPush the client's business card to the remote device\n\t\t\tand then retrieve the remote business card and store\n\t\t\tit in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"File Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.FileTransfer","ObjectPath":"[Session object path]","Methods":[{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tChange the current folder of the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CreateFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tCreate a new folder in the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolder","ReturnType":"array{dict}","Args":[],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Object name in UTF-8 format\n\t\t\t\tstring Type : Either \"folder\" or \"file\"\n\t\t\t\tuint64 Size : Object size or number of items in\n\t\t\t\t\t\tfolder\n\t\t\t\tstring Permission : Group, owner and other\n\t\t\t\t\t\t\tpermission\n\t\t\t\tuint64 Modified : Last change\n\t\t\t\tuint64 Accessed : Last access\n\t\t\t\tuint64 Created : Creation date\n\t\t\tPossible errors: org.bluez.obex.Error.Failed\n"},{"Name":"GetFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from remote device) to the\n\t\t\ttarget file (on local filesystem).\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from local filesystem) to the\n\t\t\ttarget file (on remote device).\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CopyFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy a file within the remote device from source file\n\t\t\tto target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"MoveFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tMove a file within the remote device from source file\n\t\t\tto the target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Delete","ReturnType":"void","Args":[{"Type":"string","Name":"file"}],"Errors":null,"Docs":"\t\t\tDeletes the specified file/folder.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Phonebook Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.PhonebookAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"Select","ReturnType":"void","Args":[{"Type":"string","Name":"location"},{"Type":"string","Name":"phonebook"}],"Errors":null,"Docs":"\t\t\tSelect the phonebook object for other operations. Should\n\t\t\tbe call before all the other operations.\n\t\t\tlocation : Where the phonebook is stored, possible\n\t\t\tinputs :\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim\" ( \"sim1\" )\n\t\t\t\t\"sim2\"\n\t\t\t\t...\n\t\t\tphonebook : Possible inputs :\n\t\t\t\t\"pb\" :\tphonebook for the saved contacts\n\t\t\t\t\"ich\":\tincoming call history\n\t\t\t\t\"och\":\toutgoing call history\n\t\t\t\t\"mch\":\tmissing call history\n\t\t\t\t\"cch\":\tcombination of ich och mch\n\t\t\t\t\"spd\":\tspeed dials entry ( only for \"internal\" )\n\t\t\t\t\"fav\":\tfavorites entry ( only for \"internal\" )\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullAll","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn the entire phonebook object from the PSE server\n\t\t\tin plain string with vcard format, and store it in\n\t\t\ta local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible filters: Format, Order, Offset, MaxCount and\n\t\t\tFields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\torg.bluez.obex.Forbidden\n"},{"Name":"List","ReturnType":"array{string vcard, string name}","Args":[{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name. For example:\n\t\t\t\t\"1.vcf\" : \"John\"\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Forbidden\n"},{"Name":"Pull","ReturnType":"object, dict","Args":[{"Type":"string","Name":"vcard"},{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tGiven a vcard handle, retrieve the vcard in the current\n\t\t\tphonebook object and store it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossbile filters: Format and Fields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Search","ReturnType":"array{string vcard, string name}","Args":[{"Type":"string","Name":"field"},{"Type":"string","Name":"value"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tSearch for entries matching the given condition and\n\t\t\treturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name.\n\t\t\tvcard : name paired string match the search condition.\n\t\t\tfield : the field in the vcard to search with\n\t\t\t\t{ \"name\" (default) | \"number\" | \"sound\" }\n\t\t\tvalue : the string value to search for\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"GetSize","ReturnType":"uint16","Args":[],"Errors":null,"Docs":"\t\t\tReturn the number of entries in the selected phonebook\n\t\t\tobject that are actually used (i.e. indexes that\n\t\t\tcorrespond to non-NULL entries).\n\t\t\tPossible errors: org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateVersion","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAttempt to update PrimaryCounter and SecondaryCounter.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn All Available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Current folder.","Flags":[]},{"Name":"DatabaseIdentifier","Type":"string","Docs":"128 bits persistent database identifier.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"PrimaryCounter","Type":"string","Docs":"128 bits primary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"SecondaryCounter","Type":"string","Docs":"128 bits secondary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"FixedImageSize","Type":"bool","Docs":"Indicate support for fixed image size.\n\n\t\t\tPossible values: True if image is JPEG 300x300 pixels\n\t\t\totherwise False.","Flags":[5]}]},{"Title":"Synchronization hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Synchronization1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetLocation","ReturnType":"void","Args":[{"Type":"string","Name":"location"}],"Errors":null,"Docs":"\t\t\tSet the phonebook object store location for other\n\t\t\toperations. Should be called before all the other\n\t\t\toperations.\n\t\t\tlocation: Where the phonebook is stored, possible\n\t\t\tvalues:\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim1\"\n\t\t\t\t\"sim2\"\n\t\t\t\t......\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n"},{"Name":"GetPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRetrieve an entire Phonebook Object store from remote\n\t\t\tdevice, and stores it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend an entire Phonebook Object store to remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Message Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.MessageAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetFolder","ReturnType":"void","Args":[{"Type":"string","Name":"name"}],"Errors":null,"Docs":"\t\t\tSet working directory for current session, *name* may\n\t\t\tbe the directory name or '..[/dir]'.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolders","ReturnType":"array{dict}","Args":[{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Folder name\n\t\t\tPossible filters: Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn all available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"},{"Name":"ListMessages","ReturnType":"array{object, dict}","Args":[{"Type":"string","Name":"folder"},{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns an array containing the messages found in the\n\t\t\tgiven subfolder of the current folder, or in the\n\t\t\tcurrent folder if folder is empty.\n\t\t\tPossible Filters: Offset, MaxCount, SubjectLength, Fields,\n\t\t\tType, PeriodStart, PeriodEnd, Status, Recipient, Sender,\n\t\t\tPriority\n\t\t\tEach message is represented by an object path followed\n\t\t\tby a dictionary of the properties.\n\t\t\tProperties:\n\t\t\t\tstring Subject:\n\t\t\t\t\tMessage subject\n\t\t\t\tstring Timestamp:\n\t\t\t\t\tMessage timestamp\n\t\t\t\tstring Sender:\n\t\t\t\t\tMessage sender name\n\t\t\t\tstring SenderAddress:\n\t\t\t\t\tMessage sender address\n\t\t\t\tstring ReplyTo:\n\t\t\t\t\tMessage Reply-To address\n\t\t\t\tstring Recipient:\n\t\t\t\t\tMessage recipient name\n\t\t\t\tstring RecipientAddress:\n\t\t\t\t\tMessage recipient address\n\t\t\t\tstring Type:\n\t\t\t\t\tMessage type\n\t\t\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\t\t\"sms-cdma\" and \"mms\"\n\t\t\t\tuint64 Size:\n\t\t\t\t\tMessage size in bytes\n\t\t\t\tboolean Text:\n\t\t\t\t\tMessage text flag\n\t\t\t\t\tSpecifies whether message has textual\n\t\t\t\t\tcontent or is binary only\n\t\t\t\tstring Status:\n\t\t\t\t\tMessage status\n\t\t\t\t\tPossible values for received messages:\n\t\t\t\t\t\"complete\", \"fractioned\", \"notification\"\n\t\t\t\t\tPossible values for sent messages:\n\t\t\t\t\t\"delivery-success\", \"sending-success\",\n\t\t\t\t\t\"delivery-failure\", \"sending-failure\"\n\t\t\t\tuint64 AttachmentSize:\n\t\t\t\t\tMessage overall attachment size in bytes\n\t\t\t\tboolean Priority:\n\t\t\t\t\tMessage priority flag\n\t\t\t\tboolean Read:\n\t\t\t\t\tMessage read flag\n\t\t\t\tboolean Sent:\n\t\t\t\t\tMessage sent flag\n\t\t\t\tboolean Protected:\n\t\t\t\t\tMessage protected flag\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateInbox","ReturnType":"void","Args":null,"Errors":null,"Docs":""}],"Signals":[],"Properties":[]},{"Title":"Message hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Message1","ObjectPath":"[Session object path]/{message0,...}","Methods":[{"Name":"Get","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"boolean","Name":"attachment"}],"Errors":null,"Docs":"\t\t\tDownload message and store it in the target file.\n\t\t\tIf an empty target file is given, a temporary file\n\t\t\twill be automatically generated.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Folder which the message belongs to","Flags":[]},{"Name":"Subject","Type":"string","Docs":"Message subject","Flags":[]},{"Name":"Timestamp","Type":"string","Docs":"Message timestamp","Flags":[]},{"Name":"Sender","Type":"string","Docs":"Message sender name","Flags":[]},{"Name":"SenderAddress","Type":"string","Docs":"Message sender address","Flags":[]},{"Name":"ReplyTo","Type":"string","Docs":"Message Reply-To address","Flags":[]},{"Name":"Recipient","Type":"string","Docs":"Message recipient name","Flags":[]},{"Name":"RecipientAddress","Type":"string","Docs":"Message recipient address","Flags":[]},{"Name":"Type","Type":"string","Docs":"Message type\n\n\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\"sms-cdma\" and \"mms\"\n\n\t\tuint64 Size [readonly]\n\n\t\t\tMessage size in bytes","Flags":[]},{"Name":"Status","Type":"string","Docs":"Message reception status\n\n\t\t\tPossible values: \"complete\",\n\t\t\t\"fractioned\" and \"notification\"","Flags":[]},{"Name":"Priority","Type":"boolean","Docs":"Message priority flag","Flags":[]},{"Name":"Read","Type":"boolean","Docs":"Message read flag","Flags":[3]},{"Name":"Deleted","Type":"boolean","Docs":"Message deleted flag","Flags":[]},{"Name":"Sent","Type":"boolean","Docs":"Message sent flag","Flags":[]},{"Name":"Protected","Type":"boolean","Docs":"Message protected flag","Flags":[]}]}]},{"FileName":"profile-api.txt","Name":"BlueZ D-Bus Profile API description","Description":"\n","Api":[{"Title":"Profile Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ProfileManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"},{"Type":"string","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers a profile implementation.\n\t\t\tIf an application disconnects from the bus all\n\t\t\tits registered profiles will be removed.\n\t\t\tSome predefined services:\n\t\t\tHFP AG UUID: 0000111f-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.7, profile Features\n\t\t\t\tis 0b001001 and RFCOMM channel is 13.\n\t\t\t\tAuthentication is required.\n\t\t\tHFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.7, profile Features\n\t\t\t\tis 0b000000 and RFCOMM channel is 7.\n\t\t\t\tAuthentication is required.\n\t\t\tHSP AG UUID: 00001112-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.2, RFCOMM channel\n\t\t\t\tis 12 and Authentication is required. Does not\n\t\t\t\tsupport any Features, option is ignored.\n\t\t\tHSP HS UUID: 00001108-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.2, profile Features\n\t\t\t\tis 0b0 and RFCOMM channel is 6. Authentication\n\t\t\t\tis required. Features is one bit value, specify\n\t\t\t\tcapability of Remote Audio Volume Control\n\t\t\t\t(by default turned off).\n\t\t\tAvailable options:\n\t\t\t\tstring Name\n\t\t\t\t\tHuman readable name for the profile\n\t\t\t\tstring Service\n\t\t\t\t\tThe primary service class UUID\n\t\t\t\t\t(if different from the actual\n\t\t\t\t\t profile UUID)\n\t\t\t\tstring Role\n\t\t\t\t\tFor asymmetric profiles that do not\n\t\t\t\t\thave UUIDs available to uniquely\n\t\t\t\t\tidentify each side this\n\t\t\t\t\tparameter allows specifying the\n\t\t\t\t\tprecise local role.\n\t\t\t\t\tPossible values: \"client\", \"server\"\n\t\t\t\tuint16 Channel\n\t\t\t\t\tRFCOMM channel number that is used\n\t\t\t\t\tfor client and server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tuint16 PSM\n\t\t\t\t\tPSM number that is used for client\n\t\t\t\t\tand server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tboolean RequireAuthentication\n\t\t\t\t\tPairing is required before connections\n\t\t\t\t\twill be established. No devices will\n\t\t\t\t\tbe connected if not paired.\n\t\t\t\tboolean RequireAuthorization\n\t\t\t\t\tRequest authorization before any\n\t\t\t\t\tconnection will be established.\n\t\t\t\tboolean AutoConnect\n\t\t\t\t\tIn case of a client UUID this will\n\t\t\t\t\tforce connection of the RFCOMM or\n\t\t\t\t\tL2CAP channels when a remote device\n\t\t\t\t\tis connected.\n\t\t\t\tstring ServiceRecord\n\t\t\t\t\tProvide a manual SDP record.\n\t\t\t\tuint16 Version\n\t\t\t\t\tProfile version (for SDP record)\n\t\t\t\tuint16 Features\n\t\t\t\t\tProfile features (for SDP record)\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the profile that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Profile hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Profile1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. A profile can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"NewConnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"int32","Name":"fd"},{"Type":"dict","Name":"fd_properties"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a new service level\n\t\t\tconnection has been made and authorized.\n\t\t\tCommon fd_properties:\n\t\t\tuint16 Version\t\tProfile version (optional)\n\t\t\tuint16 Features\t\tProfile features (optional)\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestDisconnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a profile gets\n\t\t\tdisconnected.\n\t\t\tThe file descriptor is no longer owned by the service\n\t\t\tdaemon and the profile implementation needs to take\n\t\t\tcare of cleaning up all connections.\n\t\t\tIf multiple file descriptors are indicated via\n\t\t\tNewConnection, it is expected that all of them\n\t\t\tare disconnected before returning from this\n\t\t\tmethod call.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"}],"Signals":[],"Properties":[]}]},{"FileName":"sap-api.txt","Name":"BlueZ D-Bus Sim Access API description","Description":"\n","Api":[{"Title":"Sim Access Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.SimAccess1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnects SAP client from the server.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if SAP client is connected to the server.","Flags":[]}]}]},{"FileName":"thermometer-api.txt","Name":"BlueZ D-Bus Thermometer API description","Description":"\tSantiago Carot-Nemesio \u003csancane@gmail.com\u003e\n\n","Api":[{"Title":"Health Thermometer Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ThermometerManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a watcher to monitor scanned measurements.\n\t\t\tThis agent will be notified about final temperature\n\t\t\tmeasurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"UnregisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tUnregisters a watcher.\n"},{"Name":"EnableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tEnables intermediate measurement notifications\n\t\t\tfor this agent. Intermediate measurements will\n\t\t\tbe enabled only for thermometers which support it.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DisableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDisables intermediate measurement notifications\n\t\t\tfor this agent. It will disable notifications in\n\t\t\tthermometers when the last agent removes the\n\t\t\twatcher for intermediate measurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\torg.bluez.Error.NotFound\n"}],"Signals":[],"Properties":[]},{"Title":"Health Thermometer Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Thermometer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Intermediate","Type":"boolean","Docs":"True if the thermometer supports intermediate\n\t\t\tmeasurement notifications.","Flags":[]},{"Name":"Interval","Type":"uint16","Docs":"(optional) The Measurement Interval defines the time (in\n\t\t\tseconds) between measurements. This interval is\n\t\t\tnot related to the intermediate measurements and\n\t\t\tmust be defined into a valid range. Setting it\n\t\t\tto zero means that no periodic measurements will\n\t\t\tbe taken.","Flags":[5]},{"Name":"Maximum","Type":"uint16","Docs":"(optional) Defines the maximum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]},{"Name":"Minimum","Type":"uint16","Docs":"(optional) Defines the minimum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]}]},{"Title":"Health Thermometer Watcher hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.ThermometerWatcher1","ObjectPath":"freely definable","Methods":[{"Name":"MeasurementReceived","ReturnType":"void","Args":[{"Type":"dict","Name":"measurement"}],"Errors":null,"Docs":"\t\t\tThis callback gets called when a measurement has been\n\t\t\tscanned in the thermometer.\n\t\t\tMeasurement:\n\t\t\t\tint16 Exponent:\n\t\t\t\tint32 Mantissa:\n\t\t\t\t\tExponent and Mantissa values as\n\t\t\t\t\textracted from float value defined by\n\t\t\t\t\tIEEE-11073-20601.\n\t\t\t\t\tMeasurement value is calculated as\n\t\t\t\t\t(Mantissa) * (10^Exponent)\n\t\t\t\t\tFor special cases Exponent is\n\t\t\t\t\tset to 0 and Mantissa is set to\n\t\t\t\t\tone of following values:\n\t\t\t\t\t+(2^23 - 1)\tNaN (invalid or\n\t\t\t\t\t\t\tmissing data)\n\t\t\t\t\t-(2^23)\t\tNRes\n\t\t\t\t\t+(2^23 - 2)\t+Infinity\n\t\t\t\t\t-(2^23 - 2)\t-Infinity\n\t\t\t\tstring Unit:\n\t\t\t\t\tPossible values: \"celsius\" or\n\t\t\t\t\t\t\t\"fahrenheit\"\n\t\t\t\tuint64 Time (optional):\n\t\t\t\t\tTime of measurement, if\n\t\t\t\t\tsupported by device.\n\t\t\t\t\tExpressed in seconds since epoch.\n\t\t\t\tstring Type (optional):\n\t\t\t\t\tOnly present if measurement type\n\t\t\t\t\tis known.\n\t\t\t\t\tPossible values: \"armpit\", \"body\",\n\t\t\t\t\t\t\"ear\", \"finger\", \"intestines\",\n\t\t\t\t\t\t\"mouth\", \"rectum\", \"toe\",\n\t\t\t\t\t\t\"tympanum\"\n\t\t\t\tstring Measurement:\n\t\t\t\t\tPossible values: \"final\" or\n\t\t\t\t\t\t\t\"intermediate\"\n"}],"Signals":[],"Properties":[]}]}]}go-bluetooth-bluez-5.60/bluez-5.62.json000077500000000000000000005444131420407601400176130ustar00rootroot00000000000000{"Version":"5.62","Api":[{"FileName":"adapter-api.txt","Name":"BlueZ D-Bus Adapter API description","Description":"\n","Api":[{"Title":"Adapter hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Adapter1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"StartDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method starts the device discovery session. This\n\t\t\tincludes an inquiry procedure and remote device name\n\t\t\tresolving. Use StopDiscovery to release the sessions\n\t\t\tacquired.\n\t\t\tThis process will start creating Device objects as\n\t\t\tnew devices are discovered.\n\t\t\tDuring discovery RSSI delta-threshold is imposed.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n"},{"Name":"StopDiscovery","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis method will cancel any previous StartDiscovery\n\t\t\ttransaction.\n\t\t\tNote that a discovery procedure is shared between all\n\t\t\tdiscovery sessions thus calling StopDiscovery will only\n\t\t\trelease a single session.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n"},{"Name":"RemoveDevice","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis removes the remote device object at the given\n\t\t\tpath. It will remove also the pairing information.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"SetDiscoveryFilter","ReturnType":"void","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method sets the device discovery filter for the\n\t\t\tcaller. When this method is called with no filter\n\t\t\tparameter, filter is removed.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tarray{string} UUIDs\n\t\t\t\tFilter by service UUIDs, empty means match\n\t\t\t\t_any_ UUID.\n\t\t\t\tWhen a remote device is found that advertises\n\t\t\t\tany UUID from UUIDs, it will be reported if:\n\t\t\t\t- Pathloss and RSSI are both empty.\n\t\t\t\t- only Pathloss param is set, device advertise\n\t\t\t\t TX pwer, and computed pathloss is less than\n\t\t\t\t Pathloss param.\n\t\t\t\t- only RSSI param is set, and received RSSI is\n\t\t\t\t higher than RSSI param.\n\t\t\tint16 RSSI\n\t\t\t\tRSSI threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated RSSI value. If one or more discovery\n\t\t\t\tfilters have been set, the RSSI delta-threshold,\n\t\t\t\tthat is imposed by StartDiscovery by default,\n\t\t\t\twill not be applied.\n\t\t\tuint16 Pathloss\n\t\t\t\tPathloss threshold value.\n\t\t\t\tPropertiesChanged signals will be emitted\n\t\t\t\tfor already existing Device objects, with\n\t\t\t\tupdated Pathloss value.\n\t\t\tstring Transport (Default \"auto\")\n\t\t\t\tTransport parameter determines the type of\n\t\t\t\tscan.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"auto\"\t- interleaved scan\n\t\t\t\t\t\"bredr\"\t- BR/EDR inquiry\n\t\t\t\t\t\"le\"\t- LE scan only\n\t\t\t\tIf \"le\" or \"bredr\" Transport is requested,\n\t\t\t\tand the controller doesn't support it,\n\t\t\t\torg.bluez.Error.Failed error will be returned.\n\t\t\t\tIf \"auto\" transport is requested, scan will use\n\t\t\t\tLE, BREDR, or both, depending on what's\n\t\t\t\tcurrently enabled on the controller.\n\t\t\tbool DuplicateData (Default: true)\n\t\t\t\tDisables duplicate detection of advertisement\n\t\t\t\tdata.\n\t\t\t\tWhen enabled PropertiesChanged signals will be\n\t\t\t\tgenerated for either ManufacturerData and\n\t\t\t\tServiceData everytime they are discovered.\n\t\t\tbool Discoverable (Default: false)\n\t\t\t\tMake adapter discoverable while discovering,\n\t\t\t\tif the adapter is already discoverable setting\n\t\t\t\tthis filter won't do anything.\n\t\t\tstring Pattern (Default: none)\n\t\t\t\tDiscover devices where the pattern matches\n\t\t\t\teither the prefix of the address or\n\t\t\t\tdevice name which is convenient way to limited\n\t\t\t\tthe number of device objects created during a\n\t\t\t\tdiscovery.\n\t\t\t\tWhen set disregards device discoverable flags.\n\t\t\t\tNote: The pattern matching is ignored if there\n\t\t\t\tare other client that don't set any pattern as\n\t\t\t\tit work as a logical OR, also setting empty\n\t\t\t\tstring \"\" pattern will match any device found.\n\t\t\tWhen discovery filter is set, Device objects will be\n\t\t\tcreated as new devices with matching criteria are\n\t\t\tdiscovered regardless of they are connectable or\n\t\t\tdiscoverable which enables listening to\n\t\t\tnon-connectable and non-discoverable devices.\n\t\t\tWhen multiple clients call SetDiscoveryFilter, their\n\t\t\tfilters are internally merged, and notifications about\n\t\t\tnew devices are sent to all clients. Therefore, each\n\t\t\tclient must check that device updates actually match\n\t\t\tits filter.\n\t\t\tWhen SetDiscoveryFilter is called multiple times by the\n\t\t\tsame client, last filter passed will be active for\n\t\t\tgiven client.\n\t\t\tSetDiscoveryFilter can be called before StartDiscovery.\n\t\t\tIt is useful when client will create first discovery\n\t\t\tsession, to ensure that proper scan will be started\n\t\t\tright after call to StartDiscovery.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"GetDiscoveryFilters","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn available filters that can be given to\n\t\t\tSetDiscoveryFilter.\n\t\t\tPossible errors: None\n"},{"Name":"ConnectDevice","ReturnType":"object","Args":[{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method connects to device without need of\n\t\t\tperforming General Discovery. Connection mechanism is\n\t\t\tsimilar to Connect method from Device1 interface with\n\t\t\texception that this method returns success when physical\n\t\t\tconnection is established. After this method returns,\n\t\t\tservices discovery will continue and any supported\n\t\t\tprofile will be connected. There is no need for calling\n\t\t\tConnect on Device1 after this call. If connection was\n\t\t\tsuccessful this method returns object path to created\n\t\t\tdevice object.\n\t\t\tParameters that may be set in the filter dictionary\n\t\t\tinclude the following:\n\t\t\tstring Address\n\t\t\t\tThe Bluetooth device address of the remote\n\t\t\t\tdevice. This parameter is mandatory.\n\t\t\tstring AddressType\n\t\t\t\tThe Bluetooth device Address Type. This is\n\t\t\t\taddress type that should be used for initial\n\t\t\t\tconnection. If this parameter is not present\n\t\t\t\tBR/EDR device is created.\n\t\t\t\tPossible values:\n\t\t\t\t\t\"public\" - Public address\n\t\t\t\t\t\"random\" - Random address\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth Address Type. For dual-mode and BR/EDR\n\t\t\tonly adapter this defaults to \"public\". Single mode LE\n\t\t\tadapters may have either value. With privacy enabled\n\t\t\tthis contains type of Identity Address and not type of\n\t\t\taddress used for connection.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth system name (pretty hostname).\n\n\t\t\tThis property is either a static system default\n\t\t\tor controlled by an external daemon providing\n\t\t\taccess to the pretty hostname configuration.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The Bluetooth friendly name. This value can be\n\t\t\tchanged.\n\n\t\t\tIn case no alias is set, it will return the system\n\t\t\tprovided name. Setting an empty string as alias will\n\t\t\tconvert it back to the system provided name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to system name.\n\n\t\t\tOn a well configured system, this property never\n\t\t\tneeds to be changed since it defaults to the system\n\t\t\tname and provides the pretty hostname. Only if the\n\t\t\tlocal name needs to be different from the pretty\n\t\t\thostname, this property should be used as last\n\t\t\tresort.","Flags":[]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device.\n\n\t\t\tThis property represents the value that is either\n\t\t\tautomatically configured by DMI/ACPI information\n\t\t\tor provided as static configuration.","Flags":[]},{"Name":"Powered","Type":"boolean","Docs":"Switch an adapter on or off. This will also set the\n\t\t\tappropriate connectable state of the controller.\n\n\t\t\tThe value of this property is not persistent. After\n\t\t\trestart or unplugging of the adapter it will reset\n\t\t\tback to false.","Flags":[]},{"Name":"Discoverable","Type":"boolean","Docs":"Switch an adapter to discoverable or non-discoverable\n\t\t\tto either make it visible or hide it. This is a global\n\t\t\tsetting and should only be used by the settings\n\t\t\tapplication.\n\n\t\t\tIf the DiscoverableTimeout is set to a non-zero\n\t\t\tvalue then the system will set this value back to\n\t\t\tfalse after the timer expired.\n\n\t\t\tIn case the adapter is switched off, setting this\n\t\t\tvalue will fail.\n\n\t\t\tWhen changing the Powered property the new state of\n\t\t\tthis property will be updated via a PropertiesChanged\n\t\t\tsignal.\n\n\t\t\tFor any new adapter this settings defaults to false.","Flags":[]},{"Name":"Pairable","Type":"boolean","Docs":"Switch an adapter to pairable or non-pairable. This is\n\t\t\ta global setting and should only be used by the\n\t\t\tsettings application.\n\n\t\t\tNote that this property only affects incoming pairing\n\t\t\trequests.\n\n\t\t\tFor any new adapter this settings defaults to true.","Flags":[]},{"Name":"PairableTimeout","Type":"uint32","Docs":"The pairable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tpairable mode forever.\n\n\t\t\tThe default value for pairable timeout should be\n\t\t\tdisabled (value 0).","Flags":[]},{"Name":"DiscoverableTimeout","Type":"uint32","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tThe default value for the discoverable timeout should\n\t\t\tbe 180 seconds (3 minutes).","Flags":[]},{"Name":"Discovering","Type":"boolean","Docs":"Indicates that a device discovery procedure is active.","Flags":[]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tlocal services.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Local Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"Roles","Type":"array{string}","Docs":"List of supported roles. Possible values:\n\t\t\t\t\"central\": Supports the central role.\n\t\t\t\t\"peripheral\": Supports the peripheral role.\n\t\t\t\t\"central-peripheral\": Supports both roles\n\t\t\t\t\t\t concurrently.","Flags":[]},{"Name":"ExperimentalFeatures","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the experimental\n\t\t\tfeatures currently enabled.","Flags":[5]}]}]},{"FileName":"admin-policy-api.txt","Name":"BlueZ D-Bus Admin Policy API description","Description":"This API provides methods to control the behavior of bluez as an administrator.\n\nInterface AdminPolicySet1 provides methods to set policies. Once the policy is\nset successfully, it will affect all clients and stay persistently even after\nrestarting Bluetooth Daemon. The only way to clear it is to overwrite the\npolicy with the same method.\n\nInterface AdminPolicyStatus1 provides readonly properties to indicate the\ncurrent values of admin policy.\n\n\n","Api":[{"Title":"Admin Policy Set hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdminPolicySet1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"SetServiceAllowList","ReturnType":"void","Args":[{"Type":"array{string}","Name":"UUIDs"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method sets the service allowlist by specifying\n\t\t\tservice UUIDs.\n\t\t\tWhen SetServiceAllowList is called, bluez will block\n\t\t\tincoming and outgoing connections to the service not in\n\t\t\tUUIDs for all of the clients.\n\t\t\tAny subsequent calls to this method will supersede any\n\t\t\tpreviously set allowlist values. Calling this method\n\t\t\twith an empty array will allow any service UUIDs to be\n\t\t\tused.\n\t\t\tThe default value is an empty array.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Admin Policy Status hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdminPolicyStatus1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[],"Signals":[],"Properties":[{"Name":"ServiceAllowList","Type":"array{string}","Docs":"Current value of service allow list.","Flags":[]}]},{"Title":"Admin Policy Status hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdminPolicyStatus1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"IsAffectedByPolicy","Type":"bool","Docs":"Indicate if there is any auto-connect profile in this\n\t\t\tdevice is not allowed by admin policy.","Flags":[]}]}]},{"FileName":"advertisement-monitor-api.txt","Name":"BlueZ D-Bus Advertisement Monitor API Description","Description":"This API allows an client to specify a job of monitoring advertisements by\nregistering the root of hierarchy and then exposing advertisement monitors\nunder the root with filtering conditions, thresholds of RSSI and timers\nof RSSI thresholds.\n\nOnce a monitoring job is activated by BlueZ, the client can expect to get\nnotified on the targeted advertisements no matter if there is an ongoing\ndiscovery session (a discovery session is started/stopped with methods in\norg.bluez.Adapter1 interface).\n\n","Api":[{"Title":"Advertisement Monitor hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdvertisementMonitor1 [experimental]","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis gets called as a signal for a client to perform\n\t\t\tclean-up when (1)a monitor cannot be activated after it\n\t\t\twas exposed or (2)a monitor has been deactivated.\n"},{"Name":"Activate","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAfter a monitor was exposed, this gets called as a\n\t\t\tsignal for client to get acknowledged when a monitor\n\t\t\thas been activated, so the client can expect to receive\n\t\t\tcalls on DeviceFound() or DeviceLost().\n"},{"Name":"DeviceFound","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":null,"Docs":"\t\t\tThis gets called to notify the client of finding the\n\t\t\ttargeted device. Once receiving the call, the client\n\t\t\tshould start to monitor the corresponding device to\n\t\t\tretrieve the changes on RSSI and advertisement content.\n"},{"Name":"DeviceLost","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":null,"Docs":"\t\t\tThis gets called to notify the client of losing the\n\t\t\ttargeted device. Once receiving this call, the client\n\t\t\tshould stop monitoring the corresponding device.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The type of the monitor. See SupportedMonitorTypes in\n\t\t\torg.bluez.AdvertisementMonitorManager1 for the available\n\t\t\toptions.\n\n\t\tInt16 RSSILowThreshold [read-only, optional]\n\n\t\t\tUsed in conjunction with RSSILowTimeout to determine\n\t\t\twhether a device becomes out-of-range. Valid range is\n\t\t\t-127 to 20 (dBm), while 127 indicates unset.\n\n\t\tInt16 RSSIHighThreshold [read-only, optional]\n\n\t\t\tUsed in conjunction with RSSIHighTimeout to determine\n\t\t\twhether a device becomes in-range. Valid range is\n\t\t\t-127 to 20 (dBm), while 127 indicates unset.\n\n\t\tU","Flags":[1]},{"Name":"RSSILowTimeout","Type":"int16","Docs":"The time it takes to consider a device as out-of-range.\n\t\t\tIf this many seconds elapses without receiving any\n\t\t\tsignal at least as strong as RSSILowThreshold, a\n\t\t\tcurrently in-range device will be considered as\n\t\t\tout-of-range (lost). Valid range is 1 to 300 (seconds),\n\t\t\twhile 0 indicates unset.\n\n\t\tU","Flags":[1,5]},{"Name":"RSSIHighTimeout","Type":"int16","Docs":"The time it takes to consider a device as in-range.\n\t\t\tIf this many seconds elapses while we continuously\n\t\t\treceive signals at least as strong as RSSIHighThreshold,\n\t\t\ta currently out-of-range device will be considered as\n\t\t\tin-range (found). Valid range is 1 to 300 (seconds),\n\t\t\twhile 0 indicates unset.\n\n\t\tU","Flags":[1,5]},{"Name":"RSSISamplingPeriod","Type":"int16","Docs":"Grouping rules on how to propagate the received\n\t\t\tadvertisement packets to the client. Valid range is 0 to\n\t\t\t255 while 256 indicates unset.\n\n\t\t\tThe meaning of this property is as follows:\n\t\t\t0:\n\t\t\t\tAll advertisement packets from in-range devices\n\t\t\t\twould be propagated.\n\t\t\t255:\n\t\t\t\tOnly the first advertisement packet of in-range\n\t\t\t\tdevices would be propagated. If the device\n\t\t\t\tbecomes lost, then the first packet when it is\n\t\t\t\tfound again will also be propagated.\n\t\t\t1 to 254:\n\t\t\t\tAdvertisement packets would be grouped into\n\t\t\t\t100ms * N time period. Packets in the same group\n\t\t\t\twill only be reported once, with the RSSI value\n\t\t\t\tbeing averaged out.\n\n\t\t\tCurrently this is unimplemented in user space, so the\n\t\t\tvalue is only used to be forwarded to the kernel.","Flags":[1,5]},{"Name":"Patterns","Type":"array{(uint8, uint8, array{byte})}","Docs":"If the Type property is set to \"or_patterns\", then this\n\t\t\tproperty must exist and have at least one entry in the\n\t\t\tarray.\n\n\t\t\tThe structure of a pattern contains the following:\n\t\t\tuint8 start_position\n\t\t\t\tThe index in an AD data field where the search\n\t\t\t\tshould start. The beginning of an AD data field\n\t\t\t\tis index 0.\n\t\t\tuint8 AD_data_type\n\t\t\t\tSee https://www.bluetooth.com/specifications/\n\t\t\t\tassigned-numbers/generic-access-profile/ for\n\t\t\t\tthe possible allowed value.","Flags":[1,5]}]},{"Title":"Advertisement Monitor Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AdvertisementMonitorManager1 [experimental]","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterMonitor","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers the root path of a hierarchy of\n\t\t\tadvertisement monitors.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering advertisement monitors.\n\t\t\tOnce a root path is registered by a client via this\n\t\t\tmethod, the client can freely expose/unexpose\n\t\t\tadvertisement monitors without re-registering the root\n\t\t\tpath again. After use, the client should call\n\t\t\tUnregisterMonitor() method to invalidate the\n\t\t\tadvertisement monitors.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"UnregisterMonitor","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters a hierarchy of advertisement monitors\n\t\t\tthat has been previously registered. The object path\n\t\t\tparameter must match the same value that has been used\n\t\t\ton registration. Upon unregistration, the advertisement\n\t\t\tmonitor(s) should expect to receive Release() method as\n\t\t\tthe signal that the advertisement monitor(s) has been\n\t\t\tdeactivated.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"SupportedMonitorTypes","Type":"array{string}","Docs":"This lists the supported types of advertisement\n\t\t\tmonitors. An application should check this before\n\t\t\tinstantiate and expose an object of\n\t\t\torg.bluez.AdvertisementMonitor1.\n\n\t\t\tPossible values for monitor types:\n\n\t\t\t\"or_patterns\"\n\t\t\t\tPatterns with logic OR applied. With this type,\n\t\t\t\tproperty \"Patterns\" must exist and has at least\n\t\t\t\tone pattern.","Flags":[1]},{"Name":"SupportedFeatures","Type":"array{string}","Docs":"This lists the features of advertisement monitoring\n\t\t\tsupported by BlueZ.\n\n\t\t\tPossible values for features:\n\n\t\t\t\"controller-patterns\"\n\t\t\t\tIf the controller is capable of performing\n\t\t\t\tadvertisement monitoring by patterns, BlueZ\n\t\t\t\twould offload the patterns to the controller to\n\t\t\t\treduce power consumption.","Flags":[1]}]}]},{"FileName":"advertising-api.txt","Name":"BlueZ D-Bus LE Advertising API Description","Description":"Advertising packets are structured data which is broadcast on the LE Advertising\nchannels and available for all devices in range. Because of the limited space\navailable in LE Advertising packets (31 bytes), each packet's contents must be\ncarefully controlled.\n\nBlueZ acts as a store for the Advertisement Data which is meant to be sent.\nIt constructs the correct Advertisement Data from the structured\ndata and configured the kernel to send the correct advertisement.\n\nAdvertisement Data objects are registered freely and then referenced by BlueZ\nwhen constructing the data sent to the kernel.\n\n","Api":[{"Title":"LE Advertisement Data hierarchy","Description":"\nSpecifies the Advertisement Data to be broadcast and some advertising\nparameters. Properties which are not present will not be included in the\ndata. Required advertisement data types will always be included.\nAll UUIDs are 128-bit versions in the API, and 16 or 32-bit\nversions of the same UUID will be used in the advertising data as appropriate.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisement1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tremoves the Advertisement. A client can use it to do\n\t\t\tcleanup tasks. There is no need to call\n\t\t\tUnregisterAdvertisement because when this method gets\n\t\t\tcalled it has already been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"Determines the type of advertising packet requested.\n\n\t\t\tPossible values: \"broadcast\" or \"peripheral\"","Flags":[]},{"Name":"ServiceUUIDs","Type":"array{string}","Docs":"List of UUIDs to include in the \"Service UUID\" field of\n\t\t\tthe Advertising Data.","Flags":[]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufactuer Data fields to include in\n\t\t\tthe Advertising Data. Keys are the Manufacturer ID\n\t\t\tto associate with the data.","Flags":[]},{"Name":"SolicitUUIDs","Type":"array{string}","Docs":"Array of UUIDs to include in \"Service Solicitation\"\n\t\t\tAdvertisement Data.","Flags":[]},{"Name":"ServiceData","Type":"dict","Docs":"Service Data elements to include. The keys are the\n\t\t\tUUID to associate with the data.","Flags":[]},{"Name":"Data","Type":"dict","Docs":"Advertising Type to include in the Advertising\n\t\t\tData. Key is the advertising type and value is the\n\t\t\tdata as byte array.\n\n\t\t\tNote: Types already handled by other properties shall\n\t\t\tnot be used.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[4]},{"Name":"Discoverable","Type":"bool","Docs":"Advertise as general discoverable. When present this\n\t\t\twill override adapter Discoverable property.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"DiscoverableTimeout","Type":"uint16","Docs":"The discoverable timeout in seconds. A value of zero\n\t\t\tmeans that the timeout is disabled and it will stay in\n\t\t\tdiscoverable/limited mode forever.\n\n\t\t\tNote: This property shall not be set when Type is set\n\t\t\tto broadcast.","Flags":[4]},{"Name":"Includes","Type":"array{string}","Docs":"List of features to be included in the advertising\n\t\t\tpacket.\n\n\t\t\tPossible values: as found on\n\t\t\t\t\tLEAdvertisingManager.SupportedIncludes","Flags":[]},{"Name":"LocalName","Type":"string","Docs":"Local name to be used in the advertising report. If the\n\t\t\tstring is too big to fit into the packet it will be\n\t\t\ttruncated.\n\n\t\t\tIf this property is available 'local-name' cannot be\n\t\t\tpresent in the Includes.","Flags":[]},{"Name":"Appearance","Type":"uint16","Docs":"Appearance to be used in the advertising report.\n\n\t\t\tPossible values: as found on GAP Service.","Flags":[]},{"Name":"Duration","Type":"uint16_t","Docs":"Duration of the advertisement in seconds. If there are\n\t\t\tother applications advertising no duration is set the\n\t\t\tdefault is 2 seconds.","Flags":[]},{"Name":"Timeout","Type":"uint16_t","Docs":"Timeout of the advertisement in seconds. This defines\n\t\t\tthe lifetime of the advertisement.","Flags":[]},{"Name":"SecondaryChannel","Type":"string","Docs":"Secondary channel to be used. Primary channel is\n\t\t\talways set to \"1M\" except when \"Coded\" is set.\n\n\t\t\tPossible value: \"1M\" (default)\n\t\t\t\t\t\"2M\"\n\t\t\t\t\t\"Coded\"","Flags":[4]},{"Name":"MinInterval","Type":"uint32","Docs":"Minimum advertising interval to be used by the\n\t\t\tadvertising set, in milliseconds. Acceptable values\n\t\t\tare in the range [20ms, 10,485s]. If the provided\n\t\t\tMinInterval is larger than the provided MaxInterval,\n\t\t\tthe registration will return failure.","Flags":[4]},{"Name":"MaxInterval","Type":"uint32","Docs":"Maximum advertising interval to be used by the\n\t\t\tadvertising set, in milliseconds. Acceptable values\n\t\t\tare in the range [20ms, 10,485s]. If the provided\n\t\t\tMinInterval is larger than the provided MaxInterval,\n\t\t\tthe registration will return failure.","Flags":[4]},{"Name":"TxPower","Type":"int16","Docs":"Requested transmission power of this advertising set.\n\t\t\tThe provided value is used only if the \"CanSetTxPower\"\n\t\t\tfeature is enabled on the Advertising Manager. The\n\t\t\tprovided value must be in range [-127 to +20], where\n\t\t\tunits are in dBm.","Flags":[4]}]},{"Title":"LE Advertising Manager hierarchy","Description":"\nThe Advertising Manager allows external applications to register Advertisement\nData which should be broadcast to devices. Advertisement Data elements must\nfollow the API for LE Advertisement Data described above.\n","Service":"org.bluez","Interface":"org.bluez.LEAdvertisingManager1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters an advertisement object to be sent over the LE\n\t\t\tAdvertising channel. The service must be exported\n\t\t\tunder interface LEAdvertisement1.\n\t\t\tInvalidArguments error indicates that the object has\n\t\t\tinvalid or conflicting properties.\n\t\t\tInvalidLength error indicates that the data\n\t\t\tprovided generates a data packet which is too long.\n\t\t\tThe properties of this object are parsed when it is\n\t\t\tregistered, and any changes are ignored.\n\t\t\tIf the same object is registered twice it will result in\n\t\t\tan AlreadyExists error.\n\t\t\tIf the maximum number of advertisement instances is\n\t\t\treached it will result in NotPermitted error.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.InvalidLength\n\t\t\t\t\t org.bluez.Error.NotPermitted\n"},{"Name":"UnregisterAdvertisement","ReturnType":"","Args":[{"Type":"object","Name":"advertisement"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters an advertisement that has been\n\t\t\tpreviously registered. The object path parameter must\n\t\t\tmatch the same value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[{"Name":"ActiveInstances","Type":"byte","Docs":"Number of active advertising instances.","Flags":[]},{"Name":"SupportedInstances","Type":"byte","Docs":"Number of available advertising instances.","Flags":[]},{"Name":"SupportedIncludes","Type":"array{string}","Docs":"List of supported system includes.\n\n\t\t\tPossible values: \"tx-power\"\n\t\t\t\t\t \"appearance\"\n\t\t\t\t\t \"local-name\"","Flags":[]},{"Name":"SupportedSecondaryChannels","Type":"array{string}","Docs":"List of supported Secondary channels. Secondary\n\t\t\tchannels can be used to advertise with the\n\t\t\tcorresponding PHY.\n\n\t\t\tPossible values: \"1M\"\n\t\t\t\t\t \"2M\"\n\t\t\t\t\t \"Coded\"","Flags":[4]},{"Name":"SupportedCapabilities","Type":"dict","Docs":"Enumerates Advertising-related controller capabilities\n\t\t\tuseful to the client.\n\n\t\t\tPossible Values:","Flags":[4]},{"Name":"MaxAdvLen","Type":"byte","Docs":"Max advertising data length","Flags":[]},{"Name":"MaxScnRspLen","Type":"byte","Docs":"Max advertising scan response length","Flags":[]},{"Name":"MinTxPower","Type":"int16","Docs":"Min advertising tx power (dBm)","Flags":[]},{"Name":"MaxTxPower","Type":"int16","Docs":"Max advertising tx power (dBm)","Flags":[]},{"Name":"SupportedFeatures","Type":"array{string}","Docs":"List of supported platform features. If no features\n\t\t\tare available on the platform, the SupportedFeatures\n\t\t\tarray will be empty.\n\n\t\t\tPossible values: \"CanSetTxPower\"\n\n\t\t\t\t\t\tIndicates whether platform can\n\t\t\t\t\t\tspecify tx power on each\n\t\t\t\t\t\tadvertising instance.\n\n\t\t\t\t\t \"HardwareOffload\"\n\n\t\t\t\t\t\tIndicates whether multiple\n\t\t\t\t\t\tadvertising will be offloaded\n\t\t\t\t\t\tto the controller.","Flags":[5,4]}]}]},{"FileName":"agent-api.txt","Name":"BlueZ D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.AgentManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"},{"Type":"string","Name":"capability"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers an agent handler.\n\t\t\tThe object path defines the path of the agent\n\t\t\tthat will be called when user input is needed.\n\t\t\tEvery application can register its own agent and\n\t\t\tfor all actions triggered by that application its\n\t\t\tagent is used.\n\t\t\tIt is not required by an application to register\n\t\t\tan agent. If an application does chooses to not\n\t\t\tregister an agent, the default agent is used. This\n\t\t\tis on most cases a good idea. Only application\n\t\t\tlike a pairing wizard should register their own\n\t\t\tagent.\n\t\t\tAn application can only register one agent. Multiple\n\t\t\tagents per application is not supported.\n\t\t\tThe capability parameter can have the values\n\t\t\t\"DisplayOnly\", \"DisplayYesNo\", \"KeyboardOnly\",\n\t\t\t\"NoInputNoOutput\" and \"KeyboardDisplay\" which\n\t\t\treflects the input and output capabilities of the\n\t\t\tagent.\n\t\t\tIf an empty string is used it will fallback to\n\t\t\t\"KeyboardDisplay\".\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"},{"Name":"RequestDefaultAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis requests is to make the application agent\n\t\t\tthe default agent. The application is required\n\t\t\tto register an agent.\n\t\t\tSpecial permission might be required to become\n\t\t\tthe default agent.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"RequestPinCode","ReturnType":"string","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a string of 1-16 characters\n\t\t\tlength. The string can be alphanumeric.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPinCode","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"pincode"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a pincode for an authentication.\n\t\t\tAn empty reply should be returned. When the pincode\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tThis is used during the pairing process of keyboards\n\t\t\tthat don't support Bluetooth 2.1 Secure Simple Pairing,\n\t\t\tin contrast to DisplayPasskey which is used for those\n\t\t\tthat do.\n\t\t\tThis method will only ever be called once since\n\t\t\tolder keyboards do not support typing notification.\n\t\t\tNote that the PIN will always be a 6-digit number,\n\t\t\tzero-padded to 6 digits. This is for harmony with\n\t\t\tthe later specification.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestPasskey","ReturnType":"uint32","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to get the passkey for an authentication.\n\t\t\tThe return value should be a numeric value\n\t\t\tbetween 0-999999.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"DisplayPasskey","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"},{"Type":"uint16","Name":"entered"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to display a passkey for an authentication.\n\t\t\tThe entered parameter indicates the number of already\n\t\t\ttyped keys on the remote side.\n\t\t\tAn empty reply should be returned. When the passkey\n\t\t\tneeds no longer to be displayed, the Cancel method\n\t\t\tof the agent will be called.\n\t\t\tDuring the pairing process this method might be\n\t\t\tcalled multiple times to update the entered value.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n"},{"Name":"RequestConfirmation","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"uint32","Name":"passkey"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to confirm a passkey for an authentication.\n\t\t\tTo confirm the value it should return an empty reply\n\t\t\tor an error in case the passkey is invalid.\n\t\t\tNote that the passkey will always be a 6-digit number,\n\t\t\tso the display should be zero-padded at the start if\n\t\t\tthe value contains less than 6 digits.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestAuthorization","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called to request the user to\n\t\t\tauthorize an incoming pairing attempt which\n\t\t\twould in other circumstances trigger the just-works\n\t\t\tmodel, or when the user plugged in a device that\n\t\t\timplements cable pairing. In the latter case, the\n\t\t\tdevice would not be connected to the adapter via\n\t\t\tBluetooth yet.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"AuthorizeService","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to authorize a connection/service request.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"battery-api.txt","Name":"BlueZ D-Bus Battery API description","Description":"\n","Api":[{"Title":"Battery hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Battery1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Percentage","Type":"byte","Docs":"The percentage of battery left as an unsigned 8-bit integer.","Flags":[]},{"Name":"Source","Type":"string","Docs":"Describes where the battery information comes from\n\t\t\tThis property is informational only and may be useful\n\t\t\tfor debugging purposes.\n\t\t\tProviders from BatteryProvider1 may make use of this\n\t\t\tproperty to indicate where the battery report comes from\n\t\t\t(e.g. \"HFP 1.7\", \"HID\", or the profile UUID).","Flags":[5]}]},{"Title":"Battery Provider Manager hierarchy","Description":"A battery provider starts by registering itself as a battery provider with the\nRegisterBatteryProvider method passing an object path as the provider ID. Then,\nit can start exposing org.bluez.BatteryProvider1 objects having the path\nstarting with the given provider ID. It can also remove objects at any time.\nThe objects and their properties exposed by battery providers will be reflected\non org.bluez.Battery1 interface.\n\nBlueZ will stop monitoring these exposed and removed objects after\nUnregisterBatteryProvider is called for that provider ID.\n","Service":"org.bluez","Interface":"org.bluez.BatteryProviderManager1 [experimental]","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"RegisterBatteryProvider","ReturnType":"void","Args":[{"Type":"object","Name":"provider"}],"Errors":null,"Docs":"\t\t\tThis registers a battery provider. A registered\n\t\t\tbattery provider can then expose objects with\n\t\t\torg.bluez.BatteryProvider1 interface described below.\n"},{"Name":"UnregisterBatteryProvider","ReturnType":"void","Args":[{"Type":"object","Name":"provider"}],"Errors":null,"Docs":"\t\t\tThis unregisters a battery provider. After\n\t\t\tunregistration, the BatteryProvider1 objects provided\n\t\t\tby this client are ignored by BlueZ.\n"}],"Signals":[],"Properties":[]},{"Title":"Battery Provider hierarchy","Description":"","Service":"\u003cclient D-Bus address\u003e","Interface":"org.bluez.BatteryProvider1 [experimental]","ObjectPath":"{provider_root}/{unique battery object path}","Methods":[],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"The object path of the device that has this battery.","Flags":[]}]}]},{"FileName":"device-api.txt","Name":"BlueZ D-Bus Device API description","Description":"\n","Api":[{"Title":"Device hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Device1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotReady","org.bluez.Error.NotReady"],"Docs":"\t\t\tThis is a generic method to connect any profiles\n\t\t\tthe remote device supports that can be connected\n\t\t\tto and have been flagged as auto-connectable on\n\t\t\tour side. If only subset of profiles is already\n\t\t\tconnected it will try to connect currently disconnected\n\t\t\tones.\n\t\t\tIf at least one profile was connected successfully this\n\t\t\tmethod will indicate success.\n\t\t\tFor dual-mode devices only one bearer is connected at\n\t\t\ttime, the conditions are in the following order:\n\t\t\t\t1. Connect the disconnected bearer if already\n\t\t\t\tconnected.\n\t\t\t\t2. Connect first the bonded bearer. If no\n\t\t\t\tbearers are bonded or both are skip and check\n\t\t\t\tlatest seen bearer.\n\t\t\t\t3. Connect last seen bearer, in case the\n\t\t\t\ttimestamps are the same BR/EDR takes\n\t\t\t\tprecedence.\n\t\t\tPossible errors: org.bluez.Error.NotReady\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.AlreadyConnected\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tThis method gracefully disconnects all connected\n\t\t\tprofiles and then terminates low-level ACL connection.\n\t\t\tACL connection will be terminated even if some profiles\n\t\t\twere not disconnected properly e.g. due to misbehaving\n\t\t\tdevice.\n\t\t\tThis method can be also used to cancel a preceding\n\t\t\tConnect call before a reply to it has been received.\n\t\t\tFor non-trusted devices connected over LE bearer calling\n\t\t\tthis method will disable incoming connections until\n\t\t\tConnect method is called again.\n\t\t\tPossible errors: org.bluez.Error.NotConnected\n"},{"Name":"ConnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method connects a specific profile of this\n\t\t\tdevice. The UUID provided is the remote service\n\t\t\tUUID for the profile.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotAvailable\n\t\t\t\t\t org.bluez.Error.NotReady\n"},{"Name":"DisconnectProfile","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method disconnects a specific profile of\n\t\t\tthis device. The profile needs to be registered\n\t\t\tclient profile.\n\t\t\tThere is no connection tracking for a profile, so\n\t\t\tas long as the profile is registered this will always\n\t\t\tsucceed.\n\t\t\tPossible errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"Pair","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis method will connect to the remote device,\n\t\t\tinitiate pairing and then retrieve all SDP records\n\t\t\t(or GATT primary services).\n\t\t\tIf the application has registered its own agent,\n\t\t\tthen that specific agent will be used. Otherwise\n\t\t\tit will use the default agent.\n\t\t\tOnly for applications like a pairing wizard it\n\t\t\twould make sense to have its own agent. In almost\n\t\t\tall other cases the default agent will handle\n\t\t\tthis just fine.\n\t\t\tIn case there is no application agent and also\n\t\t\tno default agent present, this method will fail.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n\t\t\t\t\t org.bluez.Error.AuthenticationCanceled\n\t\t\t\t\t org.bluez.Error.AuthenticationFailed\n\t\t\t\t\t org.bluez.Error.AuthenticationRejected\n\t\t\t\t\t org.bluez.Error.AuthenticationTimeout\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"CancelPairing","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis method can be used to cancel a pairing\n\t\t\toperation initiated by the Pair method.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Address","Type":"string","Docs":"The Bluetooth device address of the remote device.","Flags":[]},{"Name":"AddressType","Type":"string","Docs":"The Bluetooth device Address Type. For dual-mode and\n\t\t\tBR/EDR only devices this defaults to \"public\". Single\n\t\t\tmode LE devices may have either value. If remote device\n\t\t\tuses privacy than before pairing this represents address\n\t\t\ttype used for connection and Identity Address after\n\t\t\tpairing.\n\n\t\t\tPossible values:\n\t\t\t\t\"public\" - Public address\n\t\t\t\t\"random\" - Random address","Flags":[]},{"Name":"Name","Type":"string","Docs":"The Bluetooth remote name. This value can not be\n\t\t\tchanged. Use the Alias property instead.\n\n\t\t\tThis value is only present for completeness. It is\n\t\t\tbetter to always use the Alias property when\n\t\t\tdisplaying the devices name.\n\n\t\t\tIf the Alias property is unset, it will reflect\n\t\t\tthis value which makes it more convenient.","Flags":[5]},{"Name":"Icon","Type":"string","Docs":"Proposed icon name according to the freedesktop.org\n\t\t\ticon naming specification.","Flags":[5]},{"Name":"Class","Type":"uint32","Docs":"The Bluetooth class of device of the remote device.","Flags":[5]},{"Name":"Appearance","Type":"uint16","Docs":"External appearance of device, as found on GAP service.","Flags":[5]},{"Name":"UUIDs","Type":"array{string}","Docs":"List of 128-bit UUIDs that represents the available\n\t\t\tremote services.","Flags":[5]},{"Name":"Paired","Type":"boolean","Docs":"Indicates if the remote device is paired.","Flags":[]},{"Name":"Connected","Type":"boolean","Docs":"Indicates if the remote device is currently connected.\n\t\t\tA PropertiesChanged signal indicate changes to this\n\t\t\tstatus.","Flags":[]},{"Name":"Trusted","Type":"boolean","Docs":"Indicates if the remote is seen as trusted. This\n\t\t\tsetting can be changed by the application.","Flags":[]},{"Name":"Blocked","Type":"boolean","Docs":"If set to true any incoming connections from the\n\t\t\tdevice will be immediately rejected. Any device\n\t\t\tdrivers will also be removed and no new ones will\n\t\t\tbe probed as long as the device is blocked.","Flags":[]},{"Name":"WakeAllowed","Type":"boolean","Docs":"If set to true this device will be allowed to wake the\n\t\t\thost from system suspend.","Flags":[]},{"Name":"Alias","Type":"string","Docs":"The name alias for the remote device. The alias can\n\t\t\tbe used to have a different friendly name for the\n\t\t\tremote device.\n\n\t\t\tIn case no alias is set, it will return the remote\n\t\t\tdevice name. Setting an empty string as alias will\n\t\t\tconvert it back to the remote device name.\n\n\t\t\tWhen resetting the alias with an empty string, the\n\t\t\tproperty will default back to the remote name.","Flags":[]},{"Name":"Adapter","Type":"object","Docs":"The object path of the adapter the device belongs to.","Flags":[]},{"Name":"LegacyPairing","Type":"boolean","Docs":"Set to true if the device only supports the pre-2.1\n\t\t\tpairing mechanism. This property is useful during\n\t\t\tdevice discovery to anticipate whether legacy or\n\t\t\tsimple pairing will occur if pairing is initiated.\n\n\t\t\tNote that this property can exhibit false-positives\n\t\t\tin the case of Bluetooth 2.1 (or newer) devices that\n\t\t\thave disabled Extended Inquiry Response support.","Flags":[]},{"Name":"Modalias","Type":"string","Docs":"Remote Device ID information in modalias format\n\t\t\tused by the kernel and udev.","Flags":[5]},{"Name":"RSSI","Type":"int16","Docs":"Received Signal Strength Indicator of the remote\n\t\t\tdevice (inquiry or advertising).","Flags":[5]},{"Name":"TxPower","Type":"int16","Docs":"Advertised transmitted power level (inquiry or\n\t\t\tadvertising).","Flags":[5]},{"Name":"ManufacturerData","Type":"dict","Docs":"Manufacturer specific advertisement data. Keys are\n\t\t\t16 bits Manufacturer ID followed by its byte array\n\t\t\tvalue.","Flags":[5]},{"Name":"ServiceData","Type":"dict","Docs":"Service advertisement data. Keys are the UUIDs in\n\t\t\tstring format followed by its byte array value.","Flags":[5]},{"Name":"ServicesResolved","Type":"bool","Docs":"Indicate whether or not service discovery has been\n\t\t\tresolved.","Flags":[]},{"Name":"AdvertisingFlags","Type":"array{byte}","Docs":"The Advertising Data Flags of the remote device.","Flags":[]},{"Name":"AdvertisingData","Type":"dict","Docs":"The Advertising Data of the remote device. Keys are\n\t\t\tare 8 bits AD Type followed by data as byte array.\n\n\t\t\tNote: Only types considered safe to be handled by\n\t\t\tapplication are exposed.\n\n\t\t\tPossible values:\n\t\t\t\t\u003ctype\u003e \u003cbyte array\u003e\n\t\t\t\t...\n\n\t\t\tExample:\n\t\t\t\t\u003cTransport Discovery\u003e \u003cOrganization Flags...\u003e\n\t\t\t\t0x26 0x01 0x01...","Flags":[]}]}]},{"FileName":"gatt-api.txt","Name":"BlueZ D-Bus GATT API description","Description":"GATT local and remote services share the same high-level D-Bus API. Local\nrefers to GATT based service exported by a BlueZ plugin or an external\napplication. Remote refers to GATT services exported by the peer.\n\nBlueZ acts as a proxy, translating ATT operations to D-Bus method calls and\nProperties (or the opposite). Support for D-Bus Object Manager is mandatory for\nexternal services to allow seamless GATT declarations (Service, Characteristic\nand Descriptors) discovery. Each GATT service tree is required to export a D-Bus\nObject Manager at its root that is solely responsible for the objects that\nbelong to that service.\n\nReleasing a registered GATT service is not defined yet. Any API extension\nshould avoid breaking the defined API, and if possible keep an unified GATT\nremote and local services representation.\n\n","Api":[{"Title":"Service hierarchy","Description":"\nGATT remote and local service representation. Object path for local services\nis freely definable.\n\nExternal applications implementing local services must register the services\nusing GattManager1 registration method and must implement the methods and\nproperties defined in GattService1 interface.\n","Service":"org.bluez","Interface":"org.bluez.GattService1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX","Methods":[],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit service UUID.","Flags":[1]},{"Name":"Primary","Type":"boolean","Docs":"Indicates whether or not this GATT service is a\n\t\t\tprimary service. If false, the service is secondary.","Flags":[1]},{"Name":"Device","Type":"object","Docs":"Object path of the Bluetooth device the service\n\t\t\tbelongs to. Only present on services from remote\n\t\t\tdevices.","Flags":[1,5]},{"Name":"Includes","Type":"array{object}","Docs":"Array of object paths representing the included\n\t\t\tservices of this service.","Flags":[1,5]},{"Name":"Handle","Type":"uint16","Docs":"Service handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"Characteristic hierarchy","Description":"\nFor local GATT defined services, the object paths need to follow the service\npath hierarchy and are freely definable.\n","Service":"org.bluez","Interface":"org.bluez.GattCharacteristic1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": uint16 offset\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Object Device (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.InvalidOffset\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"type\": string\n\t\t\t\t\t\tPossible values:\n\t\t\t\t\t\t\"command\": Write without\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\"request\": Write with response\n\t\t\t\t\t\t\"reliable\": Reliable Write\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": True if prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireWrite","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for writing. Only\n\t\t\tsockets are supported. Usage of WriteValue will be\n\t\t\tlocked causing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tFor client it only works with characteristic that has\n\t\t\tWriteAcquired property which relies on\n\t\t\twrite-without-response Flag.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"AcquireNotify","ReturnType":"fd, uint16","Args":[{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tAcquire file descriptor and MTU for notify. Only\n\t\t\tsockets are support. Usage of StartNotify will be locked\n\t\t\tcausing it to return NotPermitted error.\n\t\t\tFor server the MTU returned shall be equal or smaller\n\t\t\tthan the negotiated MTU.\n\t\t\tOnly works with characteristic that has NotifyAcquired\n\t\t\twhich relies on notify Flag and no other client have\n\t\t\tcalled StartNotify.\n\t\t\tNotification are enabled during this procedure so\n\t\t\tStartNotify shall not be called, any notification\n\t\t\twill be dispatched via file descriptor therefore the\n\t\t\tValue property is not affected during the time where\n\t\t\tnotify has been acquired.\n\t\t\tTo release the lock the client shall close the file\n\t\t\tdescriptor, a HUP is generated in case the device\n\t\t\tis disconnected.\n\t\t\tNote: the MTU can only be negotiated once and is\n\t\t\tsymmetric therefore this method may be delayed in\n\t\t\torder to have the exchange MTU completed, because of\n\t\t\tthat the file descriptor is closed during\n\t\t\treconnections as the MTU has to be renegotiated.\n\t\t\tPossible options: \"device\": Object Device (Server only)\n\t\t\t\t\t \"mtu\": Exchanged MTU (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StartNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tStarts a notification session from this characteristic\n\t\t\tif it supports value notifications or indications.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"StopNotify","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method will cancel any previous StartNotify\n\t\t\ttransaction. Note that notifications from a\n\t\t\tcharacteristic are shared between sessions thus\n\t\t\tcalling StopNotify will release a single session.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"},{"Name":"Confirm","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tThis method doesn't expect a reply so it is just a\n\t\t\tconfirmation that value was received.\n\t\t\tPossible Errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit characteristic UUID.","Flags":[1]},{"Name":"Service","Type":"object","Docs":"Object path of the GATT service the characteristic\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the characteristic. This property\n\t\t\tgets updated only after a successful read request and\n\t\t\twhen a notification or indication is received, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"WriteAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireWrite.\n\n\t\t\tFor client properties is ommited in case\n\t\t\t'write-without-response' flag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireWrite is supported.","Flags":[1,5]},{"Name":"NotifyAcquired","Type":"boolean","Docs":"True, if this characteristic has been acquired by any\n\t\t\tclient using AcquireNotify.\n\n\t\t\tFor client this properties is ommited in case 'notify'\n\t\t\tflag is not set.\n\n\t\t\tFor server the presence of this property indicates\n\t\t\tthat AcquireNotify is supported.","Flags":[1,5]},{"Name":"Notifying","Type":"boolean","Docs":"True, if notifications or indications on this\n\t\t\tcharacteristic are currently enabled.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the characteristic value can be used. See\n\t\t\tCore spec \"Table 3.5: Characteristic Properties bit\n\t\t\tfield\", and \"Table 3.8: Characteristic Extended\n\t\t\tProperties bit field\".\n\n\t\t\tThe \"x-notify\" and \"x-indicate\" flags restrict access\n\t\t\tto notifications and indications by imposing write\n\t\t\trestrictions on a characteristic's client\n\t\t\tcharacteristic configuration descriptor.\n\n\t\t\tAllowed values:\n\n\t\t\t\t\"broadcast\"\n\t\t\t\t\"read\"\n\t\t\t\t\"write-without-response\"\n\t\t\t\t\"write\"\n\t\t\t\t\"notify\"\n\t\t\t\t\"indicate\"\n\t\t\t\t\"authenticated-signed-writes\"\n\t\t\t\t\"extended-properties\"\n\t\t\t\t\"reliable-write\"\n\t\t\t\t\"writable-auxiliaries\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-notify\" (Server only)\n\t\t\t\t\"encrypt-indicate\" (Server only)\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"encrypt-authenticated-notify\" (Server only)\n\t\t\t\t\"encrypt-authenticated-indicate\" (Server only)\n\t\t\t\t\"secure-read\" (Server only)\n\t\t\t\t\"secure-write\" (Server only)\n\t\t\t\t\"secure-notify\" (Server only)\n\t\t\t\t\"secure-indicate\" (Server only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]},{"Name":"MTU","Type":"uint16","Docs":"Characteristic MTU, this is valid both for ReadValue\n\t\t\tand WriteValue but either method can use long\n\t\t\tprocedures when supported.","Flags":[1]}]},{"Title":"Characteristic Descriptors hierarchy","Description":"\nLocal or remote GATT characteristic descriptors hierarchy.\n","Service":"org.bluez","Interface":"org.bluez.GattDescriptor1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ","Methods":[{"Name":"ReadValue","ReturnType":"array{byte}","Args":[{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to read the value of the\n\t\t\tcharacteristic and returns the value if the\n\t\t\toperation was successful.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"WriteValue","ReturnType":"void","Args":[{"Type":"array{byte}","Name":"value"},{"Type":"dict","Name":"flags"}],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tIssues a request to write the value of the\n\t\t\tcharacteristic.\n\t\t\tPossible options: \"offset\": Start offset\n\t\t\t\t\t \"device\": Device path (Server only)\n\t\t\t\t\t \"link\": Link type (Server only)\n\t\t\t\t\t \"prepare-authorize\": boolean Is prepare\n\t\t\t\t\t\t\t authorization\n\t\t\t\t\t\t\t request\n\t\t\tPossible Errors: org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.InProgress\n\t\t\t\t\t org.bluez.Error.NotPermitted\n\t\t\t\t\t org.bluez.Error.InvalidValueLength\n\t\t\t\t\t org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.NotSupported\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"128-bit descriptor UUID.","Flags":[1]},{"Name":"Characteristic","Type":"object","Docs":"Object path of the GATT characteristic the descriptor\n\t\t\tbelongs to.","Flags":[1]},{"Name":"Value","Type":"array{byte}","Docs":"The cached value of the descriptor. This property\n\t\t\tgets updated only after a successful read request, upon\n\t\t\twhich a PropertiesChanged signal will be emitted.","Flags":[1,5]},{"Name":"Flags","Type":"array{string}","Docs":"Defines how the descriptor value can be used.\n\n\t\t\tPossible values:\n\n\t\t\t\t\"read\"\n\t\t\t\t\"write\"\n\t\t\t\t\"encrypt-read\"\n\t\t\t\t\"encrypt-write\"\n\t\t\t\t\"encrypt-authenticated-read\"\n\t\t\t\t\"encrypt-authenticated-write\"\n\t\t\t\t\"secure-read\" (Server Only)\n\t\t\t\t\"secure-write\" (Server Only)\n\t\t\t\t\"authorize\"","Flags":[1]},{"Name":"Handle","Type":"uint16","Docs":"Characteristic handle. When available in the server it\n\t\t\twould attempt to use to allocate into the database\n\t\t\twhich may fail, to auto allocate the value 0x0000\n\t\t\tshall be used which will cause the allocated handle to\n\t\t\tbe set once registered.","Flags":[6,5]}]},{"Title":"GATT Profile hierarchy","Description":"\nLocal profile (GATT client) instance. By registering this type of object\nan application effectively indicates support for a specific GATT profile\nand requests automatic connections to be established to devices\nsupporting it.\n","Service":"\u003capplication dependent\u003e","Interface":"org.bluez.GattProfile1","ObjectPath":"\u003capplication dependent\u003e","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. The profile can use it to\n\t\t\tdo cleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUIDs","Type":"array{string}","Docs":"128-bit GATT service UUIDs to auto connect.","Flags":[1]}]},{"Title":"GATT Manager hierarchy","Description":"\nGATT Manager allows external applications to register GATT services and\nprofiles.\n\nRegistering a profile allows applications to subscribe to *remote* services.\nThese must implement the GattProfile1 interface defined above.\n\nRegistering a service allows applications to publish a *local* GATT service,\nwhich then becomes available to remote devices. A GATT service is represented by\na D-Bus object hierarchy where the root node corresponds to a service and the\nchild nodes represent characteristics and descriptors that belong to that\nservice. Each node must implement one of GattService1, GattCharacteristic1,\nor GattDescriptor1 interfaces described above, based on the attribute it\nrepresents. Each node must also implement the standard D-Bus Properties\ninterface to expose their properties. These objects collectively represent a\nGATT service definition.\n\nTo make service registration simple, BlueZ requires that all objects that belong\nto a GATT service be grouped under a D-Bus Object Manager that solely manages\nthe objects of that service. Hence, the standard DBus.ObjectManager interface\nmust be available on the root service path. An example application hierarchy\ncontaining two separate GATT services may look like this:\n\n-\u003e /com/example\n | - org.freedesktop.DBus.ObjectManager\n |\n -\u003e /com/example/service0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattService1\n | |\n | -\u003e /com/example/service0/char0\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1\n | | - org.freedesktop.DBus.Properties\n | | - org.bluez.GattCharacteristic1\n | |\n | -\u003e /com/example/service0/char1/desc0\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattDescriptor1\n |\n -\u003e /com/example/service1\n | - org.freedesktop.DBus.Properties\n | - org.bluez.GattService1\n |\n -\u003e /com/example/service1/char0\n - org.freedesktop.DBus.Properties\n - org.bluez.GattCharacteristic1\n\nWhen a service is registered, BlueZ will automatically obtain information about\nall objects using the service's Object Manager. Once a service has been\nregistered, the objects of a service should not be removed. If BlueZ receives an\nInterfacesRemoved signal from a service's Object Manager, it will immediately\nunregister the service. Similarly, if the application disconnects from the bus,\nall of its registered services will be automatically unregistered.\nInterfacesAdded signals will be ignored.\n\nExamples:\n\t- Client\n\t\ttest/example-gatt-client\n\t\tclient/bluetoothctl\n\t- Server\n\t\ttest/example-gatt-server\n\t\ttools/gatt-service\n\n","Service":"org.bluez","Interface":"org.bluez.GattManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a local GATT services hierarchy as described\n\t\t\tabove (GATT Server) and/or GATT profiles (GATT Client).\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application registering a GATT based\n\t\t\tservice or profile.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]}]},{"FileName":"health-api.txt","Name":"BlueZ D-Bus Health API description","Description":"\n","Api":[{"Title":"HealthManager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthManager1","ObjectPath":"/org/bluez/","Methods":[{"Name":"CreateApplication","ReturnType":"object","Args":[{"Type":"dict","Name":"config"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturns the path of the new registered application.\n\t\t\tApplication will be closed by the call or implicitly\n\t\t\twhen the programs leaves the bus.\n\t\t\tconfig:\n\t\t\t\tuint16 DataType:\n\t\t\t\t\tMandatory\n\t\t\t\tstring Role:\n\t\t\t\t\tMandatory. Possible values: \"source\",\n\t\t\t\t\t\t\t\t\t\"sink\"\n\t\t\t\tstring Description:\n\t\t\t\t\tOptional\n\t\t\t\tChannelType:\n\t\t\t\t\tOptional, just for sources. Possible\n\t\t\t\t\tvalues: \"reliable\", \"streaming\"\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DestroyApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCloses the HDP application identified by the object\n\t\t\tpath. Also application will be closed if the process\n\t\t\tthat started it leaves the bus. Only the creator of the\n\t\t\tapplication will be able to destroy it.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[]},{"Title":"HealthDevice hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthDevice1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Echo","ReturnType":"boolean","Args":[],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tSends an echo petition to the remote service. Returns\n\t\t\tTrue if response matches with the buffer sent. If some\n\t\t\terror is detected False value is returned.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.OutOfRange\n"},{"Name":"CreateChannel","ReturnType":"object","Args":[{"Type":"object","Name":"application"},{"Type":"string","Name":"configuration"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tCreates a new data channel. The configuration should\n\t\t\tindicate the channel quality of service using one of\n\t\t\tthis values \"reliable\", \"streaming\", \"any\".\n\t\t\tReturns the object path that identifies the data\n\t\t\tchannel that is already connected.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.HealthError\n"},{"Name":"DestroyChannel","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDestroys the data channel object. Only the creator of\n\t\t\tthe channel or the creator of the HealthApplication\n\t\t\tthat received the data channel will be able to destroy\n\t\t\tit.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotFound\n\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[{"Name":"ChannelConnected","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a new data channel is\n\t\t\tcreated or when a known data channel is reconnected.\n\n"},{"Name":"ChannelDeleted","ReturnType":"void","Args":[{"Type":"object","Name":"channel"}],"Errors":null,"Docs":"\n\t\t\tThis signal is launched when a data channel is deleted.\n\n\t\t\tAfter this signal the data channel path will not be\n\t\t\tvalid and its path can be reused for future data\n\t\t\tchannels."}],"Properties":[{"Name":"MainChannel","Type":"object","Docs":"The first reliable channel opened. It is needed by\n\t\t\tupper applications in order to send specific protocol\n\t\t\tdata units. The first reliable can change after a\n\t\t\treconnection.","Flags":[]}]},{"Title":"HealthChannel hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.HealthChannel1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/chanZZZ","Methods":[{"Name":"Acquire","ReturnType":"fd","Args":[],"Errors":["org.bluez.Error.NotConnected","org.bluez.Error.NotConnected"],"Docs":"\t\t\tReturns the file descriptor for this data channel. If\n\t\t\tthe data channel is not connected it will also\n\t\t\treconnect.\n\t\t\tPossible Errors: org.bluez.Error.NotConnected\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotAcquired","org.bluez.Error.NotAcquired"],"Docs":"\t\t\tReleases the fd. Application should also need to\n\t\t\tclose() it.\n\t\t\tPossible Errors: org.bluez.Error.NotAcquired\n\t\t\t\t\t org.bluez.Error.NotAllowed\n"}],"Signals":[],"Properties":[{"Name":"Type","Type":"string","Docs":"The quality of service of the data channel. (\"reliable\"\n\t\t\tor \"streaming\")","Flags":[]},{"Name":"Device","Type":"object","Docs":"Identifies the Remote Device that is connected with.\n\t\t\tMaps with a HealthDevice object.","Flags":[]},{"Name":"Application","Type":"object","Docs":"Identifies the HealthApplication to which this channel\n\t\t\tis related to (which indirectly defines its role and\n\t\t\tdata type).","Flags":[]}]}]},{"FileName":"input-api.txt","Name":"BlueZ D-Bus Input API description","Description":"","Api":[{"Title":"Input hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Input1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"ReconnectMode","Type":"string","Docs":"Determines the Connectability mode of the HID device as\n\t\t\tdefined by the HID Profile specification, Section 5.4.2.\n\n\t\t\tThis mode is based in the two properties\n\t\t\tHIDReconnectInitiate (see Section 5.3.4.6) and\n\t\t\tHIDNormallyConnectable (see Section 5.3.4.14) which\n\t\t\tdefine the following four possible values:\n\n\t\t\t\"none\"\t\tDevice and host are not required to\n\t\t\t\t\tautomatically restore the connection.\n\n\t\t\t\"host\"\t\tBluetooth HID host restores connection.\n\n\t\t\t\"device\"\tBluetooth HID device restores\n\t\t\t\t\tconnection.\n\n\t\t\t\"any\"\t\tBluetooth HID device shall attempt to\n\t\t\t\t\trestore the lost connection, but\n\t\t\t\t\tBluetooth HID Host may also restore the\n\t\t\t\t\tconnection.","Flags":[]}]}]},{"FileName":"media-api.txt","Name":"BlueZ D-Bus Media API description","Description":"\n","Api":[{"Title":"Media hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Media1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a local end point to sender, the sender can\n\t\t\tregister as many end points as it likes.\n\t\t\tNote: If the sender disconnects the end points are\n\t\t\tautomatically unregistered.\n\t\t\tpossible properties:\n\t\t\t\tstring UUID:\n\t\t\t\t\tUUID of the profile which the endpoint\n\t\t\t\t\tis for.\n\t\t\t\tbyte Codec:\n\t\t\t\t\tAssigned number of codec that the\n\t\t\t\t\tendpoint implements. The values should\n\t\t\t\t\tmatch the profile specification which\n\t\t\t\t\tis indicated by the UUID.\n\t\t\t\tarray{byte} Capabilities:\n\t\t\t\t\tCapabilities blob, it is used as it is\n\t\t\t\t\tso the size and byte order must match.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported - emitted\n\t\t\t\t\t when interface for the end-point is\n\t\t\t\t\t disabled.\n"},{"Name":"UnregisterEndpoint","ReturnType":"void","Args":[{"Type":"object","Name":"endpoint"}],"Errors":null,"Docs":"\t\t\tUnregister sender end point.\n"},{"Name":"RegisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"},{"Type":"dict","Name":"properties"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister a media player object to sender, the sender\n\t\t\tcan register as many objects as it likes.\n\t\t\tObject must implement at least\n\t\t\torg.mpris.MediaPlayer2.Player as defined in MPRIS 2.2\n\t\t\tspec:\n\t\t\thttp://specifications.freedesktop.org/mpris-spec/latest/\n\t\t\tNote: If the sender disconnects its objects are\n\t\t\tautomatically unregistered.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n"},{"Name":"UnregisterPlayer","ReturnType":"void","Args":[{"Type":"object","Name":"player"}],"Errors":null,"Docs":"\t\t\tUnregister sender media player.\n"},{"Name":"RegisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"root"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegister endpoints an player objects within root\n\t\t\tobject which must implement ObjectManager.\n\t\t\tThe application object path together with the D-Bus\n\t\t\tsystem bus connection ID define the identification of\n\t\t\tthe application.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterApplication","ReturnType":"void","Args":[{"Type":"object","Name":"application"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis unregisters the services that has been\n\t\t\tpreviously registered. The object path parameter\n\t\t\tmust match the same value that has been used\n\t\t\ton registration.\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Media Control hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaControl1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume playback.\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPause playback.\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStop playback.\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tNext item.\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tPrevious item.\n"},{"Name":"VolumeUp","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step up\n"},{"Name":"VolumeDown","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAdjust remote volume one step down\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"","Flags":[]},{"Name":"Player","Type":"object","Docs":"Addressed Player object path.","Flags":[5]}]},{"Title":"MediaPlayer1 hierarchy","Description":"","Service":"org.bluez (Controller role)","Interface":"org.bluez.MediaPlayer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tResume playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Pause","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPause playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Stop","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tStop playback.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Next","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tNext item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Previous","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPrevious item.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"FastForward","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tFast forward playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Rewind","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRewind playback, this action is only stopped\n\t\t\twhen another method in this interface is called.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Press","ReturnType":"void","Args":[{"Type":"byte","Name":"avc_key"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tPress a specific key to send as passthrough command.\n\t\t\tThe key will be released automatically. Use Hold()\n\t\t\tinstead if the intention is to hold down the key.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Hold","ReturnType":"void","Args":[{"Type":"byte","Name":"avc_key"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tPress and hold a specific key to send as passthrough\n\t\t\tcommand. It is your responsibility to make sure that\n\t\t\tRelease() is called after calling this method. The held\n\t\t\tkey will also be released when any other method in this\n\t\t\tinterface is called.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tRelease the previously held key invoked using Hold().\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Equalizer","Type":"string","Docs":"Possible values: \"off\" or \"on\"","Flags":[]},{"Name":"Repeat","Type":"string","Docs":"Possible values: \"off\", \"singletrack\", \"alltracks\" or\n\t\t\t\t\t\"group\"","Flags":[]},{"Name":"Shuffle","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Scan","Type":"string","Docs":"Possible values: \"off\", \"alltracks\" or \"group\"","Flags":[]},{"Name":"Status","Type":"string","Docs":"Possible status: \"playing\", \"stopped\", \"paused\",\n\t\t\t\t\t\"forward-seek\", \"reverse-seek\"\n\t\t\t\t\tor \"error\"","Flags":[]},{"Name":"Position","Type":"uint32","Docs":"Playback position in milliseconds. Changing the\n\t\t\tposition may generate additional events that will be\n\t\t\tsent to the remote device. When position is 0 it means\n\t\t\tthe track is starting and when it's greater than or\n\t\t\tequal to track's duration the track has ended. Note\n\t\t\tthat even if duration is not available in metadata it's\n\t\t\tpossible to signal its end by setting position to the\n\t\t\tmaximum uint32 value.","Flags":[]},{"Name":"Track","Type":"dict","Docs":"Track metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title:","Type":"string","Docs":"Track title name","Flags":[]},{"Name":"Artist:","Type":"string","Docs":"Track artist name","Flags":[]},{"Name":"Album:","Type":"string","Docs":"Track album name","Flags":[]},{"Name":"Genre:","Type":"string","Docs":"Track genre name","Flags":[]},{"Name":"NumberOfTracks:","Type":"uint32","Docs":"Number of tracks in total","Flags":[]},{"Name":"TrackNumber:","Type":"uint32","Docs":"Track number","Flags":[]},{"Name":"Duration:","Type":"uint32","Docs":"Track duration in milliseconds","Flags":[]},{"Name":"Device","Type":"object","Docs":"Device object path.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Player name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Player type\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio\"\n\t\t\t\t\"Video\"\n\t\t\t\t\"Audio Broadcasting\"\n\t\t\t\t\"Video Broadcasting\"","Flags":[]},{"Name":"Subtype","Type":"string","Docs":"Player subtype\n\n\t\t\tPossible values:\n\n\t\t\t\t\"Audio Book\"\n\t\t\t\t\"Podcast\"","Flags":[]},{"Name":"Browsable","Type":"boolean","Docs":"If present indicates the player can be browsed using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Searchable","Type":"boolean","Docs":"If present indicates the player can be searched using\n\t\t\tMediaFolder interface.\n\n\t\t\tPossible values:\n\n\t\t\t\tTrue: Supported and active\n\t\t\t\tFalse: Supported but inactive\n\n\t\t\tNote: If supported but inactive clients can enable it\n\t\t\tby using MediaFolder interface but it might interfere\n\t\t\tin the playback of other players.","Flags":[]},{"Name":"Playlist","Type":"object","Docs":"Playlist object path.","Flags":[]}]},{"Title":"MediaFolder1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaFolder1","ObjectPath":"freely definable (Target role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX\n\t\t(Controller role)","Methods":[{"Name":"Search","ReturnType":"object","Args":[{"Type":"string","Name":"value"},{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tReturn a folder object containing the search result.\n\t\t\tTo list the items found use the folder object returned\n\t\t\tand pass to ChangeFolder.\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ListItems","ReturnType":"array{objects, properties}","Args":[{"Type":"dict","Name":"filter"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tReturn a list of items found\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"object","Name":"folder"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tChange current folder.\n\t\t\tNote: By changing folder the items of previous folder\n\t\t\tmight be destroyed and have to be listed again, the\n\t\t\texception is NowPlaying folder which should be always\n\t\t\tpresent while the player is active.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\t org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"NumberOfItems","Type":"uint32","Docs":"Number of items in the folder","Flags":[]},{"Name":"Name","Type":"string","Docs":"Folder name:\n\n\t\t\tPossible values:\n\t\t\t\t\"/Filesystem/...\": Filesystem scope\n\t\t\t\t\"/NowPlaying/...\": NowPlaying scope\n\n\t\t\tNote: /NowPlaying folder might not be listed if player\n\t\t\tis stopped, folders created by Search are virtual so\n\t\t\tonce another Search is perform or the folder is\n\t\t\tchanged using ChangeFolder it will no longer be listed.\n\nFilters","Flags":[]},{"Name":"Start:","Type":"uint32","Docs":"Offset of the first item.\n\n\t\t\tDefault value: 0","Flags":[]},{"Name":"End:","Type":"uint32","Docs":"Offset of the last item.\n\n\t\t\tDefault value: NumbeOfItems","Flags":[]},{"Name":"Attributes","Type":"array{string}","Docs":"Item properties that should be included in the list.\n\n\t\t\tPossible Values:\n\n\t\t\t\t\"title\", \"artist\", \"album\", \"genre\",\n\t\t\t\t\"number-of-tracks\", \"number\", \"duration\"\n\n\t\t\tDefault Value: All","Flags":[]}]},{"Title":"MediaItem1 hierarchy","Description":"","Service":"unique name (Target role)\n\t\torg.bluez (Controller role)","Interface":"org.bluez.MediaItem1","ObjectPath":"freely definable (Target role)\n\t\t[variable\n\t\tprefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX\n\t\t(Controller role)","Methods":[{"Name":"Play","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tPlay item\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"AddtoNowPlaying","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.NotSupported","org.bluez.Error.NotSupported"],"Docs":"\t\t\tAdd item to now playing list\n\t\t\tPossible Errors: org.bluez.Error.NotSupported\n\t\t\t\t\t org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Player","Type":"object","Docs":"Player object path the item belongs to","Flags":[]},{"Name":"Name","Type":"string","Docs":"Item displayable name","Flags":[]},{"Name":"Type","Type":"string","Docs":"Item type\n\n\t\t\tPossible values: \"video\", \"audio\", \"folder\"","Flags":[]},{"Name":"FolderType","Type":"string","Docs":"Folder type.\n\n\t\t\tPossible values: \"mixed\", \"titles\", \"albums\", \"artists\"\n\n\t\t\tAvailable if property Type is \"Folder\"","Flags":[5]},{"Name":"Playable","Type":"boolean","Docs":"Indicates if the item can be played\n\n\t\t\tAvailable if property Type is \"folder\"","Flags":[5]},{"Name":"Metadata","Type":"dict","Docs":"Item metadata.\n\n\t\t\tPossible values:","Flags":[]},{"Name":"Title","Type":"string","Docs":"Item title name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Artist","Type":"string","Docs":"Item artist name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Album","Type":"string","Docs":"Item album name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Genre","Type":"string","Docs":"Item genre name\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"NumberOfTracks","Type":"uint32","Docs":"Item album number of tracks in total\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Number","Type":"uint32","Docs":"Item album number\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]},{"Name":"Duration","Type":"uint32","Docs":"Item duration in milliseconds\n\n\t\t\t\t\tAvailable if property Type is \"audio\"\n\t\t\t\t\tor \"video\"","Flags":[]}]},{"Title":"MediaEndpoint1 hierarchy","Description":"","Service":"unique name (Server role)\n\t\torg.bluez (Client role)","Interface":"org.bluez.MediaEndpoint1","ObjectPath":"freely definable (Server role)\n\t\t[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX\n\t\t(Client role)","Methods":[{"Name":"SetConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"},{"Type":"dict","Name":"properties"}],"Errors":null,"Docs":"\t\t\tSet configuration for the transport.\n\t\t\tFor client role transport must be set with a server\n\t\t\tendpoint oject which will be configured and the\n\t\t\tproperties must contain the following properties:\n\t\t\t\tarray{byte} Capabilities\n"},{"Name":"SelectConfiguration","ReturnType":"array{byte}","Args":[{"Type":"array{byte}","Name":"capabilities"}],"Errors":null,"Docs":"\t\t\tSelect preferable configuration from the supported\n\t\t\tcapabilities.\n\t\t\tReturns a configuration which can be used to setup\n\t\t\ta transport.\n\t\t\tNote: There is no need to cache the selected\n\t\t\tconfiguration since on success the configuration is\n\t\t\tsend back as parameter of SetConfiguration.\n"},{"Name":"ClearConfiguration","ReturnType":"void","Args":[{"Type":"object","Name":"transport"}],"Errors":null,"Docs":"\t\t\tClear transport configuration.\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the endpoint. An endpoint can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tendpoint, because when this method gets called it has\n\t\t\talready been unregistered.\n"}],"Signals":[],"Properties":[{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the endpoint is for.","Flags":[5]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the endpoint implements.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[5]},{"Name":"Capabilities","Type":"array{byte}","Docs":"Capabilities blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[5]},{"Name":"Device","Type":"object","Docs":"Device object which the endpoint is belongs to.","Flags":[5]},{"Name":"DelayReporting","Type":"bool","Docs":"Indicates if endpoint supports Delay Reporting.","Flags":[5]}]},{"Title":"MediaTransport1 hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.MediaTransport1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX","Methods":[{"Name":"Acquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAuthorized","org.bluez.Error.NotAuthorized"],"Docs":"\t\t\tAcquire transport file descriptor and the MTU for read\n\t\t\tand write respectively.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n"},{"Name":"TryAcquire","ReturnType":"fd, uint16, uint16","Args":[],"Errors":["org.bluez.Error.NotAvailable","org.bluez.Error.NotAvailable"],"Docs":"\t\t\tAcquire transport file descriptor only if the transport\n\t\t\tis in \"pending\" state at the time the message is\n\t\t\treceived by BlueZ. Otherwise no request will be sent\n\t\t\tto the remote device and the function will just fail\n\t\t\twith org.bluez.Error.NotAvailable.\n\t\t\tPossible Errors: org.bluez.Error.NotAuthorized\n\t\t\t\t\t org.bluez.Error.Failed\n\t\t\t\t\t org.bluez.Error.NotAvailable\n"},{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tReleases file descriptor.\n"}],"Signals":[],"Properties":[{"Name":"Device","Type":"object","Docs":"Device object which the transport is connected to.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"UUID of the profile which the transport is for.","Flags":[]},{"Name":"Codec","Type":"byte","Docs":"Assigned number of codec that the transport support.\n\t\t\tThe values should match the profile specification which\n\t\t\tis indicated by the UUID.","Flags":[]},{"Name":"Configuration","Type":"array{byte}","Docs":"Configuration blob, it is used as it is so the size and\n\t\t\tbyte order must match.","Flags":[]},{"Name":"State","Type":"string","Docs":"Indicates the state of the transport. Possible\n\t\t\tvalues are:\n\t\t\t\t\"idle\": not streaming\n\t\t\t\t\"pending\": streaming but not acquired\n\t\t\t\t\"active\": streaming and acquired","Flags":[]},{"Name":"Delay","Type":"uint16","Docs":"Optional. Transport delay in 1/10 of millisecond, this\n\t\t\tproperty is only writeable when the transport was\n\t\t\tacquired by the sender.","Flags":[]},{"Name":"Volume","Type":"uint16","Docs":"Optional. Indicates volume level of the transport,\n\t\t\tthis property is only writeable when the transport was\n\t\t\tacquired by the sender.\n\n\t\t\tPossible Values: 0-127","Flags":[]},{"Name":"Endpoint","Type":"object","Docs":"Endpoint object which the transport is associated\n\t\t\twith.","Flags":[5]}]}]},{"FileName":"mesh-api.txt","Name":"BlueZ D-Bus Mesh API description","Description":"","Api":[{"Title":"Mesh Network Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Network1","ObjectPath":"/org/bluez/mesh","Methods":[{"Name":"Join","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application has to call to\n\t\tbecome a provisioned node on a mesh network. The call will\n\t\tinitiate broadcasting of Unprovisioned Device Beacon.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The application hierarchy\n\t\talso contains a provision agent object that implements\n\t\torg.bluez.mesh.ProvisionAgent1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error. The composition of the UUID\n\t\toctets must be in compliance with RFC 4122.\n\t\tWhen provisioning finishes, the daemon will call either\n\t\tJoinComplete or JoinFailed method on object implementing\n\t\torg.bluez.mesh.Application1 interface.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Cancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"Attach","ReturnType":"object node, array{byte, array{(uint16, dict)}} configuration","Args":[{"Type":"object","Name":"app_root"},{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis is the first method that an application must call to get\n\t\taccess to mesh node functionalities.\n\t\tThe app_root parameter is a D-Bus object root path of\n\t\tthe application that implements org.bluez.mesh.Application1\n\t\tinterface. The application represents a node where child mesh\n\t\telements have their own objects that implement\n\t\torg.bluez.mesh.Element1 interface. The standard\n\t\tDBus.ObjectManager interface must be available on the\n\t\tapp_root path.\n\t\tThe token parameter is a 64-bit number that has been assigned to\n\t\tthe application when it first got provisioned/joined mesh\n\t\tnetwork, i.e. upon receiving JoinComplete() method. The daemon\n\t\tuses the token to verify whether the application is authorized\n\t\tto assume the mesh node identity.\n\t\tIn case of success, the method call returns mesh node object\n\t\t(see Mesh Node Hierarchy section) and current configuration\n\t\tsettings. The return value of configuration parameter is an\n\t\tarray, where each entry is a structure that contains element\n\t\tconfiguration. The element configuration structure is organized\n\t\tas follows:\n\t\tbyte\n\t\t\tElement index, identifies the element to which this\n\t\t\tconfiguration entry pertains.\n\t\tarray{struct}\n\t\t\tModels array where each entry is a structure with the\n\t\t\tfollowing members:\n\t\t\tuint16\n\t\t\t\tEither a SIG Model Identifier or, if Vendor key\n\t\t\t\tis present in model configuration dictionary, a\n\t\t\t\t16-bit vendor-assigned Model Identifier\n\t\t\tdict\n\t\t\t\tA dictionary that contains model configuration\n\t\t\t\twith the following keys defined:\n\t\t\t\tarray{uint16} Bindings\n\t\t\t\t\tIndices of application keys bound to the\n\t\t\t\t\tmodel\n\t\t\t\tuint32 PublicationPeriod\n\t\t\t\t\tModel publication period in milliseconds\n\t\t\t\tuint16 Vendor\n\t\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\t\tBluetooth SIG\n\t\t\t\tarray{variant} Subscriptions\n\t\t\t\t\tAddresses the model is subscribed to.\n\t\t\t\t\tEach address is provided either as\n\t\t\t\t\tuint16 for group addresses, or\n\t\t\t\t\tas array{byte} for virtual labels.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.Busy,\n\t\t\torg.bluez.mesh.Error.Failed\n"},{"Name":"Leave","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis removes the configuration information about the mesh node\n\t\tidentified by the 64-bit token parameter. The token parameter\n\t\thas been obtained as a result of successful Join() method call.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"CreateNetwork","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"}],"Errors":null,"Docs":"\t\tThis is the first method that an application calls to become\n\t\ta Provisioner node, and a Configuration Client on a newly\n\t\tcreated Mesh Network.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface, and a org.bluez.mesh.Provisioner1 interface. The\n\t\tapplication represents a node where child mesh elements have\n\t\ttheir own objects that implement org.bluez.mesh.Element1\n\t\tinterface. The application hierarchy also contains a provision\n\t\tagent object that implements org.bluez.mesh.ProvisionAgent1\n\t\tinterface. The standard DBus.ObjectManager interface must be\n\t\tavailable on the app_root path.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error. The composition of the UUID\n\t\toctets must be in compliance with RFC 4122.\n\t\tThe other information the bluetooth-meshd daemon will preserve\n\t\tabout the initial node, is to give it the initial primary\n\t\tunicast address (0x0001), and create and assign a net_key as the\n\t\tprimary network net_index (0x000).\n\t\tUpon successful processing of Create() method, the daemon\n\t\twill call JoinComplete method on object implementing\n\t\torg.bluez.mesh.Application1.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n"},{"Name":"Import","ReturnType":"void","Args":[{"Type":"object","Name":"app_root"},{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"array{byte}[16]","Name":"dev_key"},{"Type":"array{byte}[16]","Name":"net_key"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"flags"},{"Type":"uint32","Name":"iv_index"},{"Type":"uint16","Name":"unicast"}],"Errors":null,"Docs":"\t\tThis method creates a local mesh node based on node\n\t\tconfiguration that has been generated outside bluetooth-meshd.\n\t\tThe app_root parameter is a D-Bus object root path of the\n\t\tapplication that implements org.bluez.mesh.Application1\n\t\tinterface.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID.\n\t\tThis UUID must be unique (at least from the daemon perspective),\n\t\ttherefore attempting to call this function using already\n\t\tregistered UUID results in an error. The composition of the UUID\n\t\toctets must be in compliance with RFC 4122.\n\t\tThe dev_key parameter is the 16-byte value of the dev key of\n\t\tthe imported mesh node.\n\t\tRemaining parameters correspond to provisioning data:\n\t\tThe net_key and net_index parameters describe the network (or a\n\t\tsubnet, if net_index is not 0) the imported mesh node belongs\n\t\tto.\n\t\tThe flags parameter is a dictionary containing provisioning\n\t\tflags. Supported values are:\n\t\t\tboolean IvUpdate\n\t\t\t\tWhen true, indicates that the network is in the\n\t\t\t\tmiddle of IV Index Update procedure.\n\t\t\tboolean KeyRefresh\n\t\t\t\tWhen true, indicates that the specified net key\n\t\t\t\tis in the middle of a key refresh procedure.\n\t\tThe iv_index parameter is the current IV Index value used by\n\t\tthe network. This value is known by the provisioner.\n\t\tThe unicast parameter is the primary unicast address of the\n\t\timported node.\n\t\tUpon successful processing of Import() method, the daemon will\n\t\tcall JoinComplete method on object implementing\n\t\torg.bluez.mesh.Application1 interface.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments,\n\t\t\torg.bluez.mesh.Error.AlreadyExists,\n\t\t\torg.bluez.mesh.Error.NotSupported,\n\t\t\torg.bluez.mesh.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Node Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Node1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"Send","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"key_index"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe key_index parameter determines which application key to use\n\t\tfor encrypting the message. The key_index must be valid for that\n\t\telement, i.e., the application key must be bound to a model on\n\t\tthis element. Otherwise, org.bluez.mesh.Error.NotAuthorized will\n\t\tbe returned.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tbluetooth-meshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"DevKeySend","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a message originated by a local\n\t\tmodel encoded with the device key of the remote node.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a unicast address, or a well\n\t\tknown group address.\n\t\tThe remote parameter, if true, looks up the device key by the\n\t\tdestination address in the key database to encrypt the message.\n\t\tIf remote is true, but requested key does not exist, a NotFound\n\t\terror will be returned. If set to false, the local node's\n\t\tdevice key is used.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddNetKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"subnet_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe subnet_index parameter refers to the subnet index of the\n\t\tnetwork that is being added or updated. This key must exist in\n\t\tthe local key database.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"AddAppKey","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"destination"},{"Type":"uint16","Name":"app_index"},{"Type":"uint16","Name":"net_index"},{"Type":"boolean","Name":"update"}],"Errors":null,"Docs":"\t\tThis method is used to send add or update network key originated\n\t\tby the local configuration client to a remote configuration\n\t\tserver.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe destination parameter contains the destination address. This\n\t\tdestination must be a uint16 to a nodes primary unicast address.\n\t\tThe app_index parameter refers to the application key which is\n\t\tbeing added or updated. This key must exist in the local key\n\t\tdatabase.\n\t\tThe net_index parameter is the subnet index of the network on\n\t\twhich the message is to be sent.\n\t\tThe update parameter indicates if this is an addition or an\n\t\tupdate. If true, the subnet key must be in the phase 1 state of\n\t\tthe key update procedure.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotFound\n"},{"Name":"Publish","ReturnType":"void","Args":[{"Type":"object","Name":"element_path"},{"Type":"uint16","Name":"model"},{"Type":"dict","Name":"options"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is used to send a publication originated by a local\n\t\tmodel. If the model does not exist, or it has no publication\n\t\trecord, the method returns org.bluez.mesh.Error.DoesNotExist\n\t\terror.\n\t\tThe element_path parameter is the object path of an element from\n\t\ta collection of the application elements (see Mesh Application\n\t\tHierarchy section).\n\t\tThe model parameter contains a model ID, as defined by the\n\t\tBluetooth SIG. If the options dictionary contains a \"Vendor\"\n\t\tkey, then this ID is defined by the specified vendor.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\t\tbool ForceSegmented\n\t\t\t\tSpecifies whether to force sending of a short\n\t\t\t\tmessage as one-segment payload. If not present,\n\t\t\t\tthe default setting is \"false\".\n\t\t\tuint16 Vendor\n\t\t\t\tA 16-bit Company ID as defined by the\n\t\t\t\tBluetooth SIG. This key should only exist when\n\t\t\t\tpublishing on a Vendor defined model.\n\t\tThe data parameter is an outgoing message to be encypted by the\n\t\tmeshd daemon and sent on.\n\t\tSince only one Publish record may exist per element-model, the\n\t\tdestination and key_index are obtained from the Publication\n\t\trecord cached by the daemon.\n\t\tPossible errors:\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"}],"Signals":[],"Properties":[{"Name":"Features","Type":"dict","Docs":"The dictionary that contains information about feature support.\n\t\tThe following keys are defined:","Flags":[1]},{"Name":"Friend","Type":"boolean","Docs":"Indicates the ability to establish a friendship with a\n\t\t\tLow Power node","Flags":[]},{"Name":"LowPower","Type":"boolean","Docs":"Indicates support for operating in Low Power node mode","Flags":[]},{"Name":"Proxy","Type":"boolean","Docs":"Indicates support for GATT proxy","Flags":[]},{"Name":"Relay","Type":"boolean","Docs":"Indicates support for relaying messages\n\n\tIf a key is absent from the dictionary, the feature is not supported.\n\tOtherwise, true means that the feature is enabled and false means that\n\tthe feature is disabled.","Flags":[]},{"Name":"Beacon","Type":"boolean","Docs":"This property indicates whether the periodic beaconing is\n\t\tenabled (true) or disabled (false).","Flags":[1]},{"Name":"IvUpdate","Type":"boolean","Docs":"When true, indicates that the network is in the middle of IV\n\t\tIndex Update procedure. This information is only useful for\n\t\tprovisioning.","Flags":[1]},{"Name":"IvIndex","Type":"uint32","Docs":"This property may be read at any time to determine the IV_Index\n\t\tthat the current network is on. This information is only useful\n\t\tfor provisioning.","Flags":[1]},{"Name":"SecondsSinceLastHeard","Type":"uint32","Docs":"This property may be read at any time to determine the number of\n\t\tseconds since mesh network layer traffic was last detected on\n\t\tthis node's network.","Flags":[1]},{"Name":"Addresses","Type":"array{uint16}","Docs":"This property contains unicast addresses of node's elements.","Flags":[1]},{"Name":"SequenceNumber","Type":"uint32","Docs":"This property may be read at any time to determine the\n\t\tsequence number.","Flags":[1]}]},{"Title":"Mesh Provisioning Hierarchy","Description":"","Service":"org.bluez.mesh","Interface":"org.bluez.mesh.Management1","ObjectPath":"/org/bluez/mesh/node\u003cuuid\u003e\n\t\twhere \u003cuuid\u003e is the Device UUID passed to Join(),\n\t\tCreateNetwork() or Import()","Methods":[{"Name":"UnprovisionedScan","ReturnType":"void","Args":[{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to start listening\n\t\t(scanning) for unprovisioned devices in the area.\n\t\tThe options parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tuint16 Seconds\n\t\t\tSpecifies number of seconds for scanning to be active.\n\t\t\tIf set to 0 or if this key is not present, then the\n\t\t\tscanning will continue until UnprovisionedScanCancel()\n\t\t\tor AddNode() methods are called.\n\t\tEach time a unique unprovisioned beacon is heard, the\n\t\tScanResult() method on the app will be called with the result.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"UnprovisionedScanCancel","ReturnType":"void","Args":null,"Errors":null,"Docs":""},{"Name":"AddNode","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThis method is used by the application that supports\n\t\torg.bluez.mesh.Provisioner1 interface to add the\n\t\tunprovisioned device specified by uuid, to the Network.\n\t\tThe uuid parameter is a 16-byte array that contains Device UUID\n\t\tof the unprovisioned device to be added to the network.\n\t\tThe options parameter is a dictionary that may contain\n\t\tadditional configuration info (currently an empty placeholder\n\t\tfor forward compatibility).\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.NotAuthorized\n"},{"Name":"CreateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tnetwork subnet key.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"ImportSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}[16]","Name":"net_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add a network subnet\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to add.\n\t\tThe net_key parameter is the 16-byte value of the net key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n"},{"Name":"UpdateSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new network\n\t\tsubnet key, and set it's key refresh state to Phase 1.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to update. Note that the subnet must\n\t\texist prior to updating.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.Busy\n"},{"Name":"DeleteSubnet","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application that to delete a subnet.\n\t\tThe net_index parameter is a 12-bit value (0x001-0xFFF)\n\t\tspecifying which net key to delete. The primary net key (0x000)\n\t\tmay not be deleted.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"SetKeyPhase","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint8","Name":"phase"}],"Errors":null,"Docs":"\t\tThis method is used to set the flooding key update phase of the\n\t\tgiven subnet. When finalizing the procedure, it is important\n\t\tto CompleteAppKeyUpdate() on all app keys that have been\n\t\tupdated during the procedure prior to setting phase 3.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which subnet phase to set.\n\t\tThe phase parameter is used to cycle the local key database\n\t\tthrough the phases as defined by the Mesh Profile Specification.\n\t\tAllowed values:\n\t\t\t0 - Cancel Key Refresh (May only be called from Phase 1,\n\t\t\t\tand should never be called once the new key has\n\t\t\t\tstarted propagating)\n\t\t\t1 - Invalid Argument (see NetKeyUpdate method)\n\t\t\t2 - Go to Phase 2 (May only be called from Phase 1)\n\t\t\t3 - Complete Key Refresh procedure (May only be called\n\t\t\t\tfrom Phase 2)\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is the responsibility of the application to maintain the key\n\t\trefresh phases per the Mesh Profile Specification.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"CreateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate and add a new\n\t\tapplication key.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to add.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"ImportAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"net_index"},{"Type":"uint16","Name":"app_index"},{"Type":"array{byte}[16]","Name":"app_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to add an application\n\t\tkey, that was originally generated by a remote Config Client.\n\t\tThe net_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which net key to bind the application key to.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to import.\n\t\tThe app_key parameter is the 16-byte value of the key being\n\t\timported.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.AlreadyExists\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n"},{"Name":"UpdateAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to generate a new\n\t\tapplication key.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to update. Note that the subnet that\n\t\tthe key is bound to must exist and be in Phase 1.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n\t\t\torg.bluez.mesh.Error.DoesNotExist\n\t\t\torg.bluez.mesh.Error.InProgress\n"},{"Name":"DeleteAppKey","ReturnType":"void","Args":[{"Type":"uint16","Name":"app_index"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete an application\n\t\tkey.\n\t\tThe app_index parameter is a 12-bit value (0x000-0xFFF)\n\t\tspecifying which app key to delete.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"ImportRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"},{"Type":"array{byte}[16]","Name":"device_key"}],"Errors":null,"Docs":"\t\tThis method is used by the application to import a remote node\n\t\tthat has been provisioned by an external process.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being imported.\n\t\tThe count parameter specifies the number of elements that are\n\t\tassigned to this remote node.\n\t\tThe device_key parameter is the access layer key that will be\n\t\twill used to decrypt privledged messages from this remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Failed\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"DeleteRemoteNode","ReturnType":"void","Args":[{"Type":"uint16","Name":"primary"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is used by the application to delete a remote node\n\t\tfrom the local device key database.\n\t\tThe primary parameter specifies the unicast address of the\n\t\tthe node being deleted.\n\t\tThe count parameter specifies the number of elements that were\n\t\tassigned to the remote node.\n\t\tThis call affects the local bluetooth-meshd key database only.\n\t\tIt is an error to call this with address range overlapping\n\t\twith local element addresses.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.InvalidArguments\n"},{"Name":"ExportKeys","ReturnType":"dict","Args":null,"Errors":null,"Docs":""}],"Signals":[],"Properties":[]},{"Title":"Mesh Application Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Application1","ObjectPath":"\u003capp_root\u003e","Methods":[{"Name":"JoinComplete","ReturnType":"void","Args":[{"Type":"uint64","Name":"token"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby a Join() method call successfully completed.\n\t\tThe token parameter serves as a unique identifier of the\n\t\tparticular node. The token must be preserved by the application\n\t\tin order to authenticate itself to the mesh daemon and attach to\n\t\tthe network as a mesh node by calling Attach() method or\n\t\tpermanently remove the identity of the mesh node by calling\n\t\tLeave() method.\n\t\tIf this method returns an error, the daemon will assume that the\n\t\tapplication failed to preserve the token, and will remove the\n\t\tfreshly created node.\n"},{"Name":"JoinFailed","ReturnType":"void","Args":[{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tJoin() has failed.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"timeout\", \"bad-pdu\",\n\t\t\"confirmation-failed\", \"out-of-resources\", \"decryption-error\",\n\t\t\"unexpected-error\", \"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[{"Name":"CompanyID","Type":"uint16","Docs":"A 16-bit Bluetooth-assigned Company Identifier of the vendor as\n\t\tdefined by Bluetooth SIG","Flags":[1]},{"Name":"ProductID","Type":"uint16","Docs":"A 16-bit vendor-assigned product identifier","Flags":[1]},{"Name":"VersionID","Type":"uint16","Docs":"A 16-bit vendor-assigned product version identifier","Flags":[1]},{"Name":"CRPL","Type":"uint16","Docs":"A 16-bit minimum number of replay protection list entries","Flags":[1,5]}]},{"Title":"Mesh Element Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Element1","ObjectPath":"\u003capp_defined_element_path\u003e","Methods":[{"Name":"MessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"uint16","Name":"key_index"},{"Type":"variant","Name":"destination"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a message\n\t\tarrives addressed to the application.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe key_index parameter indicates which application key has been\n\t\tused to decode the incoming message. The same key_index should\n\t\tbe used by the application when sending a response to this\n\t\tmessage (in case a response is expected).\n\t\tThe destination parameter contains the destination address of\n\t\treceived message. Underlying variant types are:\n\t\tuint16\n\t\t\tDestination is an unicast address, or a well known\n\t\t\tgroup address\n\t\tarray{byte}\n\t\t\tDestination is a virtual address label\n\t\tThe data parameter is the incoming message.\n"},{"Name":"DevKeyMessageReceived","ReturnType":"void","Args":[{"Type":"uint16","Name":"source"},{"Type":"boolean","Name":"remote"},{"Type":"uint16","Name":"net_index"},{"Type":"array{byte}","Name":"data"}],"Errors":null,"Docs":"\t\tThis method is called by meshd daemon when a message arrives\n\t\taddressed to the application, which was sent with the remote\n\t\tnode's device key.\n\t\tThe source parameter is unicast address of the remote\n\t\tnode-element that sent the message.\n\t\tThe remote parameter if true indicates that the device key\n\t\tused to decrypt the message was from the sender. False\n\t\tindicates that the local nodes device key was used, and the\n\t\tmessage has permissions to modify local states.\n\t\tThe net_index parameter indicates what subnet the message was\n\t\treceived on, and if a response is required, the same subnet\n\t\tmust be used to send the response.\n\t\tThe data parameter is the incoming message.\n"},{"Name":"UpdateModelConfiguration","ReturnType":"void","Args":[{"Type":"uint16","Name":"model_id"},{"Type":"dict","Name":"config"}],"Errors":null,"Docs":"\t\tThis method is called by bluetooth-meshd daemon when a model's\n\t\tconfiguration is updated.\n\t\tThe model_id parameter contains BT SIG Model Identifier or, if\n\t\tVendor key is present in config dictionary, a 16-bit\n\t\tvendor-assigned Model Identifier.\n\t\tThe config parameter is a dictionary with the following keys\n\t\tdefined:\n\t\tarray{uint16} Bindings\n\t\t\tIndices of application keys bound to the model\n\t\tuint32 PublicationPeriod\n\t\t\tModel publication period in milliseconds\n\t\tuint16 Vendor\n\t\t\tA 16-bit Bluetooth-assigned Company Identifier of the\n\t\t\tvendor as defined by Bluetooth SIG\n\t\tarray{variant} Subscriptions\n\t\t\tAddresses the model is subscribed to.\n\t\t\tEach address is provided either as uint16 for group\n\t\t\taddresses, or as array{byte} for virtual labels.\n"}],"Signals":[],"Properties":[{"Name":"Models","Type":"array{(uint16 id, dict caps)}","Docs":"An array of SIG Models:\n\n\t\t\tid - SIG Model Identifier\n\n\t\t\toptions - a dictionary that may contain additional model\n\t\t\tinfo. The following keys are defined:","Flags":[1]},{"Name":"Publish","Type":"boolean","Docs":"supports publication mechanism. If not\n\t\t\t\t\tpresent, publication is enabled.","Flags":[]},{"Name":"Subscribe","Type":"boolean","Docs":"supports subscription mechanism. If not\n\t\t\t\t\tpresent, subscriptons are enabled.\n\n\t\tThe array may be empty.","Flags":[]},{"Name":"VendorModels","Type":"array{(uint16 vendor, uint16 id, dict options)}","Docs":"An array of Vendor Models:\n\n\t\t\tvendor - a 16-bit Bluetooth-assigned Company ID as\n\t\t\tdefined by Bluetooth SIG.\n\n\t\t\tid - a 16-bit vendor-assigned Model Identifier\n\n\t\t\toptions - a dictionary that may contain additional model\n\t\t\tinfo. The following keys are defined:","Flags":[1]},{"Name":"Publish","Type":"boolean","Docs":"supports publication mechanism","Flags":[]},{"Name":"Subscribe","Type":"boolean","Docs":"supports subscription mechanism\n\n\t\tThe array may be empty.","Flags":[]},{"Name":"Location","Type":"uint16","Docs":"Location descriptor as defined in the GATT Bluetooth Namespace\n\t\tDescriptors section of the Bluetooth SIG Assigned Numbers","Flags":[1,5]}]},{"Title":"Mesh Attention Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Attention1","ObjectPath":"freely definable","Methods":[{"Name":"SetTimer","ReturnType":"void","Args":[{"Type":"uint8","Name":"element_index"},{"Type":"uint16","Name":"time"}],"Errors":null,"Docs":"\t\tThe element_index parameter is the element's index within the\n\t\tnode where the health server model is hosted.\n\t\tThe time parameter indicates how many seconds the attention\n\t\tstate shall be on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"},{"Name":"GetTimer","ReturnType":"uint16","Args":[{"Type":"uint16","Name":"element"}],"Errors":null,"Docs":"\t\tThe element parameter is the unicast address within the node\n\t\twhere the health server model is hosted.\n\t\tReturns the number of seconds for how long the attention action\n\t\tremains staying on.\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.NotSupported\n"}],"Signals":[],"Properties":[]},{"Title":"Mesh Provisioner Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.Provisioner1","ObjectPath":"freely definable","Methods":[{"Name":"ScanResult","ReturnType":"void","Args":[{"Type":"int16","Name":"rssi"},{"Type":"array{byte}","Name":"data"},{"Type":"dict","Name":"options"}],"Errors":null,"Docs":"\t\tThe method is called from the bluetooth-meshd daemon when a\n\t\tunique UUID has been seen during UnprovisionedScan() for\n\t\tunprovsioned devices.\n\t\tThe rssi parameter is a signed, normalized measurement of the\n\t\tsignal strength of the recieved unprovisioned beacon.\n\t\tThe data parameter is a variable length byte array, that may\n\t\thave 1, 2 or 3 distinct fields contained in it including the 16\n\t\tbyte remote device UUID (always), a 16 bit mask of OOB\n\t\tauthentication flags (optional), and a 32 bit URI hash (if URI\n\t\tbit set in OOB mask). Whether these fields exist or not is a\n\t\tdecision of the remote device.\n\t\tThe options parameter is a dictionary that may contain\n\t\tadditional scan result info (currently an empty placeholder for\n\t\tforward compatibility).\n\t\tIf a beacon with a UUID that has already been reported is\n\t\trecieved by the daemon, it will be silently discarded unless it\n\t\twas recieved at a higher rssi power level.\n"},{"Name":"RequestProvData","ReturnType":"uint16 net_index, uint16 unicast","Args":[{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is implemented by a Provisioner capable application\n\t\tand is called when the remote device has been fully\n\t\tauthenticated and confirmed.\n\t\tThe count parameter is the number of consecutive unicast\n\t\taddresses the remote device is requesting.\n\t\tReturn Parameters are from the Mesh Profile Spec:\n\t\tnet_index - Subnet index of the net_key\n\t\tunicast - Primary Unicast address of the new node\n\t\tPossibleErrors:\n\t\t\torg.bluez.mesh.Error.Abort\n"},{"Name":"AddNodeComplete","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"uint16","Name":"unicast"},{"Type":"uint8","Name":"count"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated\n\t\tby an AddNode() method call successfully completed.\n\t\tThe unicast parameter is the primary address that has been\n\t\tassigned to the new node, and the address of it's config server.\n\t\tThe count parameter is the number of unicast addresses assigned\n\t\tto the new node.\n\t\tThe new node may now be sent messages using the credentials\n\t\tsupplied by the RequestProvData method.\n"},{"Name":"AddNodeFailed","ReturnType":"void","Args":[{"Type":"array{byte}[16]","Name":"uuid"},{"Type":"string","Name":"reason"}],"Errors":null,"Docs":"\t\tThis method is called when the node provisioning initiated by\n\t\tAddNode() has failed. Depending on how far Provisioning\n\t\tproceeded before failing, some cleanup of cached data may be\n\t\trequired.\n\t\tThe reason parameter identifies the reason for provisioning\n\t\tfailure. The defined values are: \"aborted\", \"timeout\",\n\t\t\"bad-pdu\", \"confirmation-failed\", \"out-of-resources\",\n\t\t\"decryption-error\", \"unexpected-error\",\n\t\t\"cannot-assign-addresses\".\n"}],"Signals":[],"Properties":[]},{"Title":"Provisioning Agent Hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.mesh.ProvisionAgent1","ObjectPath":"freely definable","Methods":[{"Name":"PrivateKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the Provisioner\n\t\thas requested Out-Of-Band ECC key exchange. The Private key is\n\t\treturned to the Daemon, and the Public Key is delivered to the\n\t\tremote Provisioner using a method that does not involve the\n\t\tBluetooth Mesh system. The Private Key returned must be 32\n\t\toctets in size, or the Provisioning procedure will fail and be\n\t\tcanceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Unprovisioned device.\n"},{"Name":"PublicKey","ReturnType":"array{byte}","Args":[],"Errors":null,"Docs":"\t\tThis method is called during provisioning if the local device is\n\t\tthe Provisioner, and is requestng Out-Of-Band ECC key exchange.\n\t\tThe Public key is returned to the Daemon that is the matched\n\t\tpair of the Private key of the remote device. The Public Key\n\t\treturned must be 64 octets in size, or the Provisioning\n\t\tprocedure will fail and be canceled.\n\t\tThis function will only be called if the Provisioner has\n\t\trequested pre-determined keys to be exchanged Out-of-Band, and\n\t\tthe local role is Provisioner.\n"},{"Name":"DisplayString","ReturnType":"void","Args":[{"Type":"string","Name":"value"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter \"ABCDE\" on remote device\".\n"},{"Name":"DisplayNumeric","ReturnType":"void","Args":[{"Type":"string","Name":"type"},{"Type":"uint32","Name":"number"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon has something important\n\t\tfor the Agent to Display, but does not require any additional\n\t\tinput locally. For instance: \"Enter 14939264 on remote device\".\n\t\tThe type parameter indicates the display method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Locally blink LED\n\t\t\t\"beep\" - Locally make a noise\n\t\t\t\"vibrate\" - Locally vibrate\n\t\t\t\"out-numeric\" - Display value to enter remotely\n\t\t\t\"push\" - Request pushes on remote button\n\t\t\t\"twist\" - Request twists on remote knob\n\t\tThe number parameter is the specific value represented by the\n\t\tPrompt.\n"},{"Name":"PromptNumeric","ReturnType":"uint32","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requests the user to\n\t\tenter a decimal value between 1-99999999.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"blink\" - Enter times remote LED blinked\n\t\t\t\"beep\" - Enter times remote device beeped\n\t\t\t\"vibrate\" - Enter times remote device vibrated\n\t\t\t\"in-numeric\" - Enter remotely displayed value\n\t\t\t\"push\" - Push local button remotely requested times\n\t\t\t\"twist\" - Twist local knob remotely requested times\n\t\tThis agent should prompt the user for specific input. For\n\t\tinstance: \"Enter value being displayed by remote device\".\n"},{"Name":"PromptStatic","ReturnType":"array{byte}[16]","Args":[{"Type":"string","Name":"type"}],"Errors":null,"Docs":"\t\tThis method is called when the Daemon requires a 16 octet byte\n\t\tarray, as an Out-of-Band authentication.\n\t\tThe type parameter indicates the input method. Allowed values\n\t\tare:\n\t\t\t\"static-oob\" - return 16 octet array\n\t\t\t\"in-alpha\" - return 16 octet alpha array\n\t\tThe Static data returned must be 16 octets in size, or the\n\t\tProvisioning procedure will fail and be canceled. If input type\n\t\tis \"in-alpha\", the printable characters should be\n\t\tleft-justified, with trailing 0x00 octets filling the remaining\n\t\tbytes.\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\tThis method gets called by the daemon to cancel any existing\n\t\tAgent Requests. When called, any pending user input should be\n\t\tcanceled, and any display requests removed.\n"}],"Signals":[],"Properties":[{"Name":"Capabilities","Type":"array{string}","Docs":"An array of strings with the following allowed values:\n\t\t\t\"blink\"\n\t\t\t\"beep\"\n\t\t\t\"vibrate\"\n\t\t\t\"out-numeric\"\n\t\t\t\"out-alpha\"\n\t\t\t\"push\"\n\t\t\t\"twist\"\n\t\t\t\"in-numeric\"\n\t\t\t\"in-alpha\"\n\t\t\t\"static-oob\"\n\t\t\t\"public-oob\"","Flags":[1]},{"Name":"OutOfBandInfo","Type":"array{string}","Docs":"Indicates availability of OOB data. An array of strings with the\n\t\tfollowing allowed values:\n\t\t\t\"other\"\n\t\t\t\"uri\"\n\t\t\t\"machine-code-2d\"\n\t\t\t\"bar-code\"\n\t\t\t\"nfc\"\n\t\t\t\"number\"\n\t\t\t\"string\"\n\t\t\t\"on-box\"\n\t\t\t\"in-box\"\n\t\t\t\"on-paper\",\n\t\t\t\"in-manual\"\n\t\t\t\"on-device\"","Flags":[1,5]},{"Name":"URI","Type":"string","Docs":"Uniform Resource Identifier points to out-of-band (OOB)\n\t\tinformation (e.g., a public key)","Flags":[1,5]}]}]},{"FileName":"network-api.txt","Name":"BlueZ D-Bus Network API description","Description":"\n","Api":[{"Title":"Network hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Network1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[{"Name":"Connect","ReturnType":"string","Args":[{"Type":"string","Name":"uuid"}],"Errors":["org.bluez.Error.AlreadyConnected","org.bluez.Error.AlreadyConnected"],"Docs":"\t\t\tConnect to the network device and return the network\n\t\t\tinterface name. Examples of the interface name are\n\t\t\tbnep0, bnep1 etc.\n\t\t\tuuid can be either one of \"gn\", \"panu\" or \"nap\" (case\n\t\t\tinsensitive) or a traditional string representation of\n\t\t\tUUID or a hexadecimal number.\n\t\t\tThe connection will be closed and network device\n\t\t\treleased either upon calling Disconnect() or when\n\t\t\tthe client disappears from the message bus.\n\t\t\tPossible errors: org.bluez.Error.AlreadyConnected\n\t\t\t\t\t org.bluez.Error.ConnectionAttemptFailed\n"},{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnect from the network device.\n\t\t\tTo abort a connection attempt in case of errors or\n\t\t\ttimeouts in the client it is fine to call this method.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if the device is connected.","Flags":[]},{"Name":"Interface","Type":"string","Docs":"Indicates the network interface name when available.","Flags":[]},{"Name":"UUID","Type":"string","Docs":"Indicates the connection role when available.","Flags":[]}]},{"Title":"Network server hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.NetworkServer1","ObjectPath":"/org/bluez/{hci0,hci1,...}","Methods":[{"Name":"Register","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"},{"Type":"string","Name":"bridge"}],"Errors":null,"Docs":"\t\t\tRegister server for the provided UUID. Every new\n\t\t\tconnection to this server will be added the bridge\n\t\t\tinterface.\n\t\t\tValid UUIDs are \"gn\", \"panu\" or \"nap\".\n\t\t\tInitially no network server SDP is provided. Only\n\t\t\tafter this method a SDP record will be available\n\t\t\tand the BNEP server will be ready for incoming\n\t\t\tconnections.\n"},{"Name":"Unregister","ReturnType":"void","Args":[{"Type":"string","Name":"uuid"}],"Errors":null,"Docs":"\t\t\tUnregister the server for provided UUID.\n\t\t\tAll servers will be automatically unregistered when\n\t\t\tthe calling application terminates.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-agent-api.txt","Name":"OBEX D-Bus Agent API description","Description":"\n","Api":[{"Title":"Agent Manager hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.AgentManager1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"RegisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tRegister an agent to request authorization of\n\t\t\tthe user to accept/reject objects. Object push\n\t\t\tservice needs to authorize each received object.\n\t\t\tPossible errors: org.bluez.obex.Error.AlreadyExists\n"},{"Name":"UnregisterAgent","ReturnType":"void","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tThis unregisters the agent that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.obex.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Agent hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.obex.Agent1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the agent. An agent can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tagent, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"AuthorizePush","ReturnType":"string","Args":[{"Type":"object","Name":"transfer"}],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tneeds to accept/reject a Bluetooth object push request.\n\t\t\tReturns the full path (including the filename) where\n\t\t\tthe object shall be stored. The tranfer object will\n\t\t\tcontain a Filename property that contains the default\n\t\t\tlocation and name that can be returned.\n\t\t\tPossible errors: org.bluez.obex.Error.Rejected\n\t\t\t org.bluez.obex.Error.Canceled\n"},{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called to indicate that the agent\n\t\t\trequest failed before a reply was returned. It cancels\n\t\t\tthe previous request.\n"}],"Signals":[],"Properties":[]}]},{"FileName":"obex-api.txt","Name":"OBEX D-Bus API description","Description":"\n","Api":[{"Title":"Client hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Client1","ObjectPath":"/org/bluez/obex","Methods":[{"Name":"CreateSession","ReturnType":"object","Args":[{"Type":"string","Name":"destination"},{"Type":"dict","Name":"args"}],"Errors":null,"Docs":"\t\t\tCreate a new OBEX session for the given remote address.\n\t\t\tThe last parameter is a dictionary to hold optional or\n\t\t\ttype-specific parameters. Typical parameters that can\n\t\t\tbe set in this dictionary include the following:\n\t\t\t\tstring \"Target\" : type of session to be created\n\t\t\t\tstring \"Source\" : local address to be used\n\t\t\t\tbyte \"Channel\"\n\t\t\tThe currently supported targets are the following:\n\t\t\t\t\"ftp\"\n\t\t\t\t\"map\"\n\t\t\t\t\"opp\"\n\t\t\t\t\"pbap\"\n\t\t\t\t\"sync\"\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"RemoveSession","ReturnType":"void","Args":[{"Type":"object","Name":"session"}],"Errors":null,"Docs":"\t\t\tUnregister session and abort pending transfers.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.NotAuthorized\n"}],"Signals":[],"Properties":[]},{"Title":"Session hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Session1","ObjectPath":"/org/bluez/obex/server/session{0, 1, 2, ...} or\n\t\t/org/bluez/obex/client/session{0, 1, 2, ...}","Methods":[{"Name":"GetCapabilities","ReturnType":"string","Args":[],"Errors":null,"Docs":"\t\t\tGet remote device capabilities.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Source","Type":"string","Docs":"Bluetooth adapter address","Flags":[]},{"Name":"Destination","Type":"string","Docs":"Bluetooth device address","Flags":[]},{"Name":"Channel","Type":"byte","Docs":"Bluetooth channel","Flags":[]},{"Name":"Target","Type":"string","Docs":"Target UUID","Flags":[]},{"Name":"Root","Type":"string","Docs":"Root path","Flags":[]}]},{"Title":"Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Transfer1","ObjectPath":"[Session object path]/transfer{0, 1, 2, ...}","Methods":[{"Name":"Cancel","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tStops the current transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.InProgress\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Suspend","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tSuspend transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to suspend transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"},{"Name":"Resume","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tResume transference.\n\t\t\tPossible errors: org.bluez.obex.Error.NotAuthorized\n\t\t\t\t\t org.bluez.obex.Error.NotInProgress\n\t\t\tNote that it is not possible to resume transfers\n\t\t\twhich are queued which is why NotInProgress is listed\n\t\t\tas possible error.\n"}],"Signals":[],"Properties":[{"Name":"Status","Type":"string","Docs":"Inform the current status of the transfer.\n\n\t\t\tPossible values: \"queued\", \"active\", \"suspended\",\n\t\t\t\t\t\"complete\" or \"error\"","Flags":[]},{"Name":"Session","Type":"object","Docs":"The object path of the session the transfer belongs\n\t\t\tto.","Flags":[]},{"Name":"Name","Type":"string","Docs":"Name of the transferred object. Either Name or Type\n\t\t\tor both will be present.","Flags":[]},{"Name":"Type","Type":"string","Docs":"Type of the transferred object. Either Name or Type\n\t\t\tor both will be present.\n\n\t\tuint64 Time [readonly, optional]\n\n\t\t\tTime of the transferred object if this is\n\t\t\tprovided by the remote party.\n\n\t\tuint64 Size [readonly, optional]\n\n\t\t\tSize of the transferred object. If the size is\n\t\t\tunknown, then this property will not be present.\n\n\t\tuint64 Transferred [readonly, optional]\n\n\t\t\tNumber of bytes transferred. For queued transfers, this\n\t\t\tvalue will not be present.","Flags":[]},{"Name":"Filename","Type":"string","Docs":"Complete name of the file being received or sent.\n\n\t\t\tFor incoming object push transaction, this will be\n\t\t\tthe proposed default location and name. It can be\n\t\t\toverwritten by the AuthorizePush agent callback\n\t\t\tand will be then updated accordingly.","Flags":[5]}]},{"Title":"Object Push hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.ObjectPush1","ObjectPath":"[Session object path]","Methods":[{"Name":"SendFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend one local file to the remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullBusinessCard","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRequest the business card from a remote device and\n\t\t\tstore it in the local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ExchangeBusinessCards","ReturnType":"object, dict","Args":[{"Type":"string","Name":"clientfile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tPush the client's business card to the remote device\n\t\t\tand then retrieve the remote business card and store\n\t\t\tit in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"File Transfer hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.FileTransfer","ObjectPath":"[Session object path]","Methods":[{"Name":"ChangeFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tChange the current folder of the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CreateFolder","ReturnType":"void","Args":[{"Type":"string","Name":"folder"}],"Errors":null,"Docs":"\t\t\tCreate a new folder in the remote device.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolder","ReturnType":"array{dict}","Args":[],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Object name in UTF-8 format\n\t\t\t\tstring Type : Either \"folder\" or \"file\"\n\t\t\t\tuint64 Size : Object size or number of items in\n\t\t\t\t\t\tfolder\n\t\t\t\tstring Permission : Group, owner and other\n\t\t\t\t\t\t\tpermission\n\t\t\t\tuint64 Modified : Last change\n\t\t\t\tuint64 Accessed : Last access\n\t\t\t\tuint64 Created : Creation date\n\t\t\tPossible errors: org.bluez.obex.Error.Failed\n"},{"Name":"GetFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from remote device) to the\n\t\t\ttarget file (on local filesystem).\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutFile","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy the source file (from local filesystem) to the\n\t\t\ttarget file (on remote device).\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"CopyFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tCopy a file within the remote device from source file\n\t\t\tto target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"MoveFile","ReturnType":"void","Args":[{"Type":"string","Name":"sourcefile"},{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tMove a file within the remote device from source file\n\t\t\tto the target file.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Delete","ReturnType":"void","Args":[{"Type":"string","Name":"file"}],"Errors":null,"Docs":"\t\t\tDeletes the specified file/folder.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Phonebook Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.PhonebookAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"Select","ReturnType":"void","Args":[{"Type":"string","Name":"location"},{"Type":"string","Name":"phonebook"}],"Errors":null,"Docs":"\t\t\tSelect the phonebook object for other operations. Should\n\t\t\tbe call before all the other operations.\n\t\t\tlocation : Where the phonebook is stored, possible\n\t\t\tinputs :\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim\" ( \"sim1\" )\n\t\t\t\t\"sim2\"\n\t\t\t\t...\n\t\t\tphonebook : Possible inputs :\n\t\t\t\t\"pb\" :\tphonebook for the saved contacts\n\t\t\t\t\"ich\":\tincoming call history\n\t\t\t\t\"och\":\toutgoing call history\n\t\t\t\t\"mch\":\tmissing call history\n\t\t\t\t\"cch\":\tcombination of ich och mch\n\t\t\t\t\"spd\":\tspeed dials entry ( only for \"internal\" )\n\t\t\t\t\"fav\":\tfavorites entry ( only for \"internal\" )\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PullAll","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn the entire phonebook object from the PSE server\n\t\t\tin plain string with vcard format, and store it in\n\t\t\ta local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible filters: Format, Order, Offset, MaxCount and\n\t\t\tFields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\torg.bluez.obex.Forbidden\n"},{"Name":"List","ReturnType":"array{string vcard, string name}","Args":[{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tReturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name. For example:\n\t\t\t\t\"1.vcf\" : \"John\"\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Forbidden\n"},{"Name":"Pull","ReturnType":"object, dict","Args":[{"Type":"string","Name":"vcard"},{"Type":"string","Name":"targetfile"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tGiven a vcard handle, retrieve the vcard in the current\n\t\t\tphonebook object and store it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossbile filters: Format and Fields\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"Search","ReturnType":"array{string vcard, string name}","Args":[{"Type":"string","Name":"field"},{"Type":"string","Name":"value"},{"Type":"dict","Name":"filters"}],"Errors":null,"Docs":"\t\t\tSearch for entries matching the given condition and\n\t\t\treturn an array of vcard-listing data where every entry\n\t\t\tconsists of a pair of strings containing the vcard\n\t\t\thandle and the contact name.\n\t\t\tvcard : name paired string match the search condition.\n\t\t\tfield : the field in the vcard to search with\n\t\t\t\t{ \"name\" (default) | \"number\" | \"sound\" }\n\t\t\tvalue : the string value to search for\n\t\t\tPossible filters: Order, Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"GetSize","ReturnType":"uint16","Args":[],"Errors":null,"Docs":"\t\t\tReturn the number of entries in the selected phonebook\n\t\t\tobject that are actually used (i.e. indexes that\n\t\t\tcorrespond to non-NULL entries).\n\t\t\tPossible errors: org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateVersion","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tAttempt to update PrimaryCounter and SecondaryCounter.\n\t\t\tPossible errors: org.bluez.obex.Error.NotSupported\n\t\t\t\t\t org.bluez.obex.Error.Forbidden\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn All Available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Current folder.","Flags":[]},{"Name":"DatabaseIdentifier","Type":"string","Docs":"128 bits persistent database identifier.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"PrimaryCounter","Type":"string","Docs":"128 bits primary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"SecondaryCounter","Type":"string","Docs":"128 bits secondary version counter.\n\n\t\t\tPossible values: 32-character hexadecimal such\n\t\t\tas A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6","Flags":[5]},{"Name":"FixedImageSize","Type":"bool","Docs":"Indicate support for fixed image size.\n\n\t\t\tPossible values: True if image is JPEG 300x300 pixels\n\t\t\totherwise False.","Flags":[5]}]},{"Title":"Synchronization hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Synchronization1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetLocation","ReturnType":"void","Args":[{"Type":"string","Name":"location"}],"Errors":null,"Docs":"\t\t\tSet the phonebook object store location for other\n\t\t\toperations. Should be called before all the other\n\t\t\toperations.\n\t\t\tlocation: Where the phonebook is stored, possible\n\t\t\tvalues:\n\t\t\t\t\"int\" ( \"internal\" which is default )\n\t\t\t\t\"sim1\"\n\t\t\t\t\"sim2\"\n\t\t\t\t......\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n"},{"Name":"GetPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"}],"Errors":null,"Docs":"\t\t\tRetrieve an entire Phonebook Object store from remote\n\t\t\tdevice, and stores it in a local file.\n\t\t\tIf an empty target file is given, a name will be\n\t\t\tautomatically calculated for the temporary file.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"PutPhonebook","ReturnType":"object, dict","Args":[{"Type":"string","Name":"sourcefile"}],"Errors":null,"Docs":"\t\t\tSend an entire Phonebook Object store to remote device.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[]},{"Title":"Message Access hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.MessageAccess1","ObjectPath":"[Session object path]","Methods":[{"Name":"SetFolder","ReturnType":"void","Args":[{"Type":"string","Name":"name"}],"Errors":null,"Docs":"\t\t\tSet working directory for current session, *name* may\n\t\t\tbe the directory name or '..[/dir]'.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFolders","ReturnType":"array{dict}","Args":[{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns a dictionary containing information about\n\t\t\tthe current folder content.\n\t\t\tThe following keys are defined:\n\t\t\t\tstring Name : Folder name\n\t\t\tPossible filters: Offset and MaxCount\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"ListFilterFields","ReturnType":"array{string}","Args":[],"Errors":null,"Docs":"\t\t\tReturn all available fields that can be used in Fields\n\t\t\tfilter.\n\t\t\tPossible errors: None\n"},{"Name":"ListMessages","ReturnType":"array{object, dict}","Args":[{"Type":"string","Name":"folder"},{"Type":"dict","Name":"filter"}],"Errors":null,"Docs":"\t\t\tReturns an array containing the messages found in the\n\t\t\tgiven subfolder of the current folder, or in the\n\t\t\tcurrent folder if folder is empty.\n\t\t\tPossible Filters: Offset, MaxCount, SubjectLength, Fields,\n\t\t\tType, PeriodStart, PeriodEnd, Status, Recipient, Sender,\n\t\t\tPriority\n\t\t\tEach message is represented by an object path followed\n\t\t\tby a dictionary of the properties.\n\t\t\tProperties:\n\t\t\t\tstring Subject:\n\t\t\t\t\tMessage subject\n\t\t\t\tstring Timestamp:\n\t\t\t\t\tMessage timestamp\n\t\t\t\tstring Sender:\n\t\t\t\t\tMessage sender name\n\t\t\t\tstring SenderAddress:\n\t\t\t\t\tMessage sender address\n\t\t\t\tstring ReplyTo:\n\t\t\t\t\tMessage Reply-To address\n\t\t\t\tstring Recipient:\n\t\t\t\t\tMessage recipient name\n\t\t\t\tstring RecipientAddress:\n\t\t\t\t\tMessage recipient address\n\t\t\t\tstring Type:\n\t\t\t\t\tMessage type\n\t\t\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\t\t\"sms-cdma\" and \"mms\"\n\t\t\t\tuint64 Size:\n\t\t\t\t\tMessage size in bytes\n\t\t\t\tboolean Text:\n\t\t\t\t\tMessage text flag\n\t\t\t\t\tSpecifies whether message has textual\n\t\t\t\t\tcontent or is binary only\n\t\t\t\tstring Status:\n\t\t\t\t\tMessage status\n\t\t\t\t\tPossible values for received messages:\n\t\t\t\t\t\"complete\", \"fractioned\", \"notification\"\n\t\t\t\t\tPossible values for sent messages:\n\t\t\t\t\t\"delivery-success\", \"sending-success\",\n\t\t\t\t\t\"delivery-failure\", \"sending-failure\"\n\t\t\t\tuint64 AttachmentSize:\n\t\t\t\t\tMessage overall attachment size in bytes\n\t\t\t\tboolean Priority:\n\t\t\t\t\tMessage priority flag\n\t\t\t\tboolean Read:\n\t\t\t\t\tMessage read flag\n\t\t\t\tboolean Sent:\n\t\t\t\t\tMessage sent flag\n\t\t\t\tboolean Protected:\n\t\t\t\t\tMessage protected flag\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"},{"Name":"UpdateInbox","ReturnType":"void","Args":null,"Errors":null,"Docs":""}],"Signals":[],"Properties":[]},{"Title":"Message hierarchy","Description":"","Service":"org.bluez.obex","Interface":"org.bluez.obex.Message1","ObjectPath":"[Session object path]/{message0,...}","Methods":[{"Name":"Get","ReturnType":"object, dict","Args":[{"Type":"string","Name":"targetfile"},{"Type":"boolean","Name":"attachment"}],"Errors":null,"Docs":"\t\t\tDownload message and store it in the target file.\n\t\t\tIf an empty target file is given, a temporary file\n\t\t\twill be automatically generated.\n\t\t\tThe returned path represents the newly created transfer,\n\t\t\twhich should be used to find out if the content has been\n\t\t\tsuccessfully transferred or if the operation fails.\n\t\t\tThe properties of this transfer are also returned along\n\t\t\twith the object path, to avoid a call to GetProperties.\n\t\t\tPossible errors: org.bluez.obex.Error.InvalidArguments\n\t\t\t\t\t org.bluez.obex.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Folder","Type":"string","Docs":"Folder which the message belongs to","Flags":[]},{"Name":"Subject","Type":"string","Docs":"Message subject","Flags":[]},{"Name":"Timestamp","Type":"string","Docs":"Message timestamp","Flags":[]},{"Name":"Sender","Type":"string","Docs":"Message sender name","Flags":[]},{"Name":"SenderAddress","Type":"string","Docs":"Message sender address","Flags":[]},{"Name":"ReplyTo","Type":"string","Docs":"Message Reply-To address","Flags":[]},{"Name":"Recipient","Type":"string","Docs":"Message recipient name","Flags":[]},{"Name":"RecipientAddress","Type":"string","Docs":"Message recipient address","Flags":[]},{"Name":"Type","Type":"string","Docs":"Message type\n\n\t\t\tPossible values: \"email\", \"sms-gsm\",\n\t\t\t\"sms-cdma\" and \"mms\"\n\n\t\tuint64 Size [readonly]\n\n\t\t\tMessage size in bytes","Flags":[]},{"Name":"Status","Type":"string","Docs":"Message reception status\n\n\t\t\tPossible values: \"complete\",\n\t\t\t\"fractioned\" and \"notification\"","Flags":[]},{"Name":"Priority","Type":"boolean","Docs":"Message priority flag","Flags":[]},{"Name":"Read","Type":"boolean","Docs":"Message read flag","Flags":[3]},{"Name":"Deleted","Type":"boolean","Docs":"Message deleted flag","Flags":[]},{"Name":"Sent","Type":"boolean","Docs":"Message sent flag","Flags":[]},{"Name":"Protected","Type":"boolean","Docs":"Message protected flag","Flags":[]}]}]},{"FileName":"profile-api.txt","Name":"BlueZ D-Bus Profile API description","Description":"\n","Api":[{"Title":"Profile Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ProfileManager1","ObjectPath":"/org/bluez","Methods":[{"Name":"RegisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"},{"Type":"string","Name":"uuid"},{"Type":"dict","Name":"options"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tThis registers a profile implementation.\n\t\t\tIf an application disconnects from the bus all\n\t\t\tits registered profiles will be removed.\n\t\t\tSome predefined services:\n\t\t\tHFP AG UUID: 0000111f-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.7, profile Features\n\t\t\t\tis 0b001001 and RFCOMM channel is 13.\n\t\t\t\tAuthentication is required.\n\t\t\tHFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.7, profile Features\n\t\t\t\tis 0b000000 and RFCOMM channel is 7.\n\t\t\t\tAuthentication is required.\n\t\t\tHSP AG UUID: 00001112-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.2, RFCOMM channel\n\t\t\t\tis 12 and Authentication is required. Does not\n\t\t\t\tsupport any Features, option is ignored.\n\t\t\tHSP HS UUID: 00001108-0000-1000-8000-00805f9b34fb\n\t\t\t\tDefault profile Version is 1.2, profile Features\n\t\t\t\tis 0b0 and RFCOMM channel is 6. Authentication\n\t\t\t\tis required. Features is one bit value, specify\n\t\t\t\tcapability of Remote Audio Volume Control\n\t\t\t\t(by default turned off).\n\t\t\tAvailable options:\n\t\t\t\tstring Name\n\t\t\t\t\tHuman readable name for the profile\n\t\t\t\tstring Service\n\t\t\t\t\tThe primary service class UUID\n\t\t\t\t\t(if different from the actual\n\t\t\t\t\t profile UUID)\n\t\t\t\tstring Role\n\t\t\t\t\tFor asymmetric profiles that do not\n\t\t\t\t\thave UUIDs available to uniquely\n\t\t\t\t\tidentify each side this\n\t\t\t\t\tparameter allows specifying the\n\t\t\t\t\tprecise local role.\n\t\t\t\t\tPossible values: \"client\", \"server\"\n\t\t\t\tuint16 Channel\n\t\t\t\t\tRFCOMM channel number that is used\n\t\t\t\t\tfor client and server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tuint16 PSM\n\t\t\t\t\tPSM number that is used for client\n\t\t\t\t\tand server UUIDs.\n\t\t\t\t\tIf applicable it will be used in the\n\t\t\t\t\tSDP record as well.\n\t\t\t\tboolean RequireAuthentication\n\t\t\t\t\tPairing is required before connections\n\t\t\t\t\twill be established. No devices will\n\t\t\t\t\tbe connected if not paired.\n\t\t\t\tboolean RequireAuthorization\n\t\t\t\t\tRequest authorization before any\n\t\t\t\t\tconnection will be established.\n\t\t\t\tboolean AutoConnect\n\t\t\t\t\tIn case of a client UUID this will\n\t\t\t\t\tforce connection of the RFCOMM or\n\t\t\t\t\tL2CAP channels when a remote device\n\t\t\t\t\tis connected.\n\t\t\t\tstring ServiceRecord\n\t\t\t\t\tProvide a manual SDP record.\n\t\t\t\tuint16 Version\n\t\t\t\t\tProfile version (for SDP record)\n\t\t\t\tuint16 Features\n\t\t\t\t\tProfile features (for SDP record)\n\t\t\tPossible errors: org.bluez.Error.InvalidArguments\n\t\t\t org.bluez.Error.AlreadyExists\n"},{"Name":"UnregisterProfile","ReturnType":"void","Args":[{"Type":"object","Name":"profile"}],"Errors":["org.bluez.Error.DoesNotExist","org.bluez.Error.DoesNotExist"],"Docs":"\t\t\tThis unregisters the profile that has been previously\n\t\t\tregistered. The object path parameter must match the\n\t\t\tsame value that has been used on registration.\n\t\t\tPossible errors: org.bluez.Error.DoesNotExist\n"}],"Signals":[],"Properties":[]},{"Title":"Profile hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.Profile1","ObjectPath":"freely definable","Methods":[{"Name":"Release","ReturnType":"void","Args":[],"Errors":null,"Docs":"\t\t\tThis method gets called when the service daemon\n\t\t\tunregisters the profile. A profile can use it to do\n\t\t\tcleanup tasks. There is no need to unregister the\n\t\t\tprofile, because when this method gets called it has\n\t\t\talready been unregistered.\n"},{"Name":"NewConnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"},{"Type":"int32","Name":"fd"},{"Type":"dict","Name":"fd_properties"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a new service level\n\t\t\tconnection has been made and authorized.\n\t\t\tCommon fd_properties:\n\t\t\tuint16 Version\t\tProfile version (optional)\n\t\t\tuint16 Features\t\tProfile features (optional)\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"},{"Name":"RequestDisconnection","ReturnType":"void","Args":[{"Type":"object","Name":"device"}],"Errors":["org.bluez.Error.Rejected","org.bluez.Error.Rejected"],"Docs":"\t\t\tThis method gets called when a profile gets\n\t\t\tdisconnected.\n\t\t\tThe file descriptor is no longer owned by the service\n\t\t\tdaemon and the profile implementation needs to take\n\t\t\tcare of cleaning up all connections.\n\t\t\tIf multiple file descriptors are indicated via\n\t\t\tNewConnection, it is expected that all of them\n\t\t\tare disconnected before returning from this\n\t\t\tmethod call.\n\t\t\tPossible errors: org.bluez.Error.Rejected\n\t\t\t org.bluez.Error.Canceled\n"}],"Signals":[],"Properties":[]}]},{"FileName":"sap-api.txt","Name":"BlueZ D-Bus Sim Access API description","Description":"\n","Api":[{"Title":"Sim Access Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.SimAccess1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"Disconnect","ReturnType":"void","Args":[],"Errors":["org.bluez.Error.Failed","org.bluez.Error.Failed"],"Docs":"\t\t\tDisconnects SAP client from the server.\n\t\t\tPossible errors: org.bluez.Error.Failed\n"}],"Signals":[],"Properties":[{"Name":"Connected","Type":"boolean","Docs":"Indicates if SAP client is connected to the server.","Flags":[]}]}]},{"FileName":"thermometer-api.txt","Name":"BlueZ D-Bus Thermometer API description","Description":"\tSantiago Carot-Nemesio \u003csancane@gmail.com\u003e\n\n","Api":[{"Title":"Health Thermometer Manager hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.ThermometerManager1","ObjectPath":"[variable prefix]/{hci0,hci1,...}","Methods":[{"Name":"RegisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tRegisters a watcher to monitor scanned measurements.\n\t\t\tThis agent will be notified about final temperature\n\t\t\tmeasurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"UnregisterWatcher","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":null,"Docs":"\t\t\tUnregisters a watcher.\n"},{"Name":"EnableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tEnables intermediate measurement notifications\n\t\t\tfor this agent. Intermediate measurements will\n\t\t\tbe enabled only for thermometers which support it.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n"},{"Name":"DisableIntermediateMeasurement","ReturnType":"","Args":[{"Type":"object","Name":"agent"}],"Errors":["org.bluez.Error.InvalidArguments","org.bluez.Error.InvalidArguments"],"Docs":"\t\t\tDisables intermediate measurement notifications\n\t\t\tfor this agent. It will disable notifications in\n\t\t\tthermometers when the last agent removes the\n\t\t\twatcher for intermediate measurements.\n\t\t\tPossible Errors: org.bluez.Error.InvalidArguments\n\t\t\t\t\torg.bluez.Error.NotFound\n"}],"Signals":[],"Properties":[]},{"Title":"Health Thermometer Profile hierarchy","Description":"","Service":"org.bluez","Interface":"org.bluez.Thermometer1","ObjectPath":"[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX","Methods":[],"Signals":[],"Properties":[{"Name":"Intermediate","Type":"boolean","Docs":"True if the thermometer supports intermediate\n\t\t\tmeasurement notifications.","Flags":[]},{"Name":"Interval","Type":"uint16","Docs":"(optional) The Measurement Interval defines the time (in\n\t\t\tseconds) between measurements. This interval is\n\t\t\tnot related to the intermediate measurements and\n\t\t\tmust be defined into a valid range. Setting it\n\t\t\tto zero means that no periodic measurements will\n\t\t\tbe taken.","Flags":[5]},{"Name":"Maximum","Type":"uint16","Docs":"(optional) Defines the maximum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]},{"Name":"Minimum","Type":"uint16","Docs":"(optional) Defines the minimum value allowed for the interval\n\t\t\tbetween periodic measurements.","Flags":[5]}]},{"Title":"Health Thermometer Watcher hierarchy","Description":"","Service":"unique name","Interface":"org.bluez.ThermometerWatcher1","ObjectPath":"freely definable","Methods":[{"Name":"MeasurementReceived","ReturnType":"void","Args":[{"Type":"dict","Name":"measurement"}],"Errors":null,"Docs":"\t\t\tThis callback gets called when a measurement has been\n\t\t\tscanned in the thermometer.\n\t\t\tMeasurement:\n\t\t\t\tint16 Exponent:\n\t\t\t\tint32 Mantissa:\n\t\t\t\t\tExponent and Mantissa values as\n\t\t\t\t\textracted from float value defined by\n\t\t\t\t\tIEEE-11073-20601.\n\t\t\t\t\tMeasurement value is calculated as\n\t\t\t\t\t(Mantissa) * (10^Exponent)\n\t\t\t\t\tFor special cases Exponent is\n\t\t\t\t\tset to 0 and Mantissa is set to\n\t\t\t\t\tone of following values:\n\t\t\t\t\t+(2^23 - 1)\tNaN (invalid or\n\t\t\t\t\t\t\tmissing data)\n\t\t\t\t\t-(2^23)\t\tNRes\n\t\t\t\t\t+(2^23 - 2)\t+Infinity\n\t\t\t\t\t-(2^23 - 2)\t-Infinity\n\t\t\t\tstring Unit:\n\t\t\t\t\tPossible values: \"celsius\" or\n\t\t\t\t\t\t\t\"fahrenheit\"\n\t\t\t\tuint64 Time (optional):\n\t\t\t\t\tTime of measurement, if\n\t\t\t\t\tsupported by device.\n\t\t\t\t\tExpressed in seconds since epoch.\n\t\t\t\tstring Type (optional):\n\t\t\t\t\tOnly present if measurement type\n\t\t\t\t\tis known.\n\t\t\t\t\tPossible values: \"armpit\", \"body\",\n\t\t\t\t\t\t\"ear\", \"finger\", \"intestines\",\n\t\t\t\t\t\t\"mouth\", \"rectum\", \"toe\",\n\t\t\t\t\t\t\"tympanum\"\n\t\t\t\tstring Measurement:\n\t\t\t\t\tPossible values: \"final\" or\n\t\t\t\t\t\t\t\"intermediate\"\n"}],"Signals":[],"Properties":[]}]}]}go-bluetooth-bluez-5.60/bluez/000077500000000000000000000000001420407601400163125ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/bluez.go000066400000000000000000000042111420407601400177600ustar00rootroot00000000000000package bluez import "github.com/godbus/dbus/v5/introspect" const ( OrgBluezPath = "/org/bluez" OrgBluezInterface = "org.bluez" //ObjectManagerInterface the dbus object manager interface ObjectManagerInterface = "org.freedesktop.DBus.ObjectManager" //InterfacesRemoved the DBus signal member for InterfacesRemoved InterfacesRemoved = "org.freedesktop.DBus.ObjectManager.InterfacesRemoved" //InterfacesAdded the DBus signal member for InterfacesAdded InterfacesAdded = "org.freedesktop.DBus.ObjectManager.InterfacesAdded" //PropertiesInterface the DBus properties interface PropertiesInterface = "org.freedesktop.DBus.Properties" //PropertiesChanged the DBus properties interface and member PropertiesChanged = "org.freedesktop.DBus.Properties.PropertiesChanged" // Introspectable introspectable interface Introspectable = "org.freedesktop.DBus.Introspectable" ) // ObjectManagerIntrospectDataString introspect ObjectManager description const ObjectManagerIntrospectDataString = ` ` // ObjectManagerIntrospectData introspect ObjectManager description var ObjectManagerIntrospectData = introspect.Interface{ Name: "org.freedesktop.DBus.ObjectManager", Methods: []introspect.Method{ { Name: "GetManagedObjects", Args: []introspect.Arg{ { Name: "objects", Type: "a{oa{sa{sv}}}", Direction: "out", }, }, }, }, Signals: []introspect.Signal{ { Name: "InterfacesAdded", Args: []introspect.Arg{ { Name: "object", Type: "o", }, { Name: "interfaces", Type: "a{sa{sv}}", }, }, }, { Name: "InterfacesRemoved", Args: []introspect.Arg{ { Name: "object", Type: "o", }, { Name: "interfaces", Type: "as", }, }, }, }, } go-bluetooth-bluez-5.60/bluez/client.go000066400000000000000000000072561420407601400201310ustar00rootroot00000000000000package bluez import ( "fmt" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/util" ) // NewClient create a new client func NewClient(config *Config) *Client { c := new(Client) c.Config = config return c } // Client implement a DBus client type Client struct { conn *dbus.Conn dbusObject dbus.BusObject Config *Config } func (c *Client) isConnected() bool { return c.conn != nil } //Disconnect from DBus func (c *Client) Disconnect() { // do not disconnect SystemBus // as it is a singleton from dbus package if c.Config.Bus == SystemBus { return } if c.isConnected() { c.conn.Close() c.conn = nil c.dbusObject = nil } } // Connect connects to DBus func (c *Client) Connect() error { dbusConn, err := GetConnection(c.Config.Bus) if err != nil { return err } c.conn = dbusConn c.dbusObject = c.conn.Object(c.Config.Name, dbus.ObjectPath(c.Config.Path)) return nil } // Call a DBus method func (c *Client) Call(method string, flags dbus.Flags, args ...interface{}) *dbus.Call { if !c.isConnected() { err := c.Connect() if err != nil { return &dbus.Call{ Err: err, } } } methodPath := fmt.Sprint(c.Config.Iface, ".", method) return c.dbusObject.Call(methodPath, flags, args...) } //GetConnection returns the Dbus connection func (c *Client) GetConnection() *dbus.Conn { return c.conn } //GetDbusObject returns the Dbus object func (c *Client) GetDbusObject() dbus.BusObject { return c.dbusObject } //GetProperty return a property value func (c *Client) GetProperty(p string) (dbus.Variant, error) { if !c.isConnected() { err := c.Connect() if err != nil { return dbus.Variant{}, err } } return c.dbusObject.GetProperty(c.Config.Iface + "." + p) } //SetProperty set a property value func (c *Client) SetProperty(p string, v interface{}) error { if !c.isConnected() { err := c.Connect() if err != nil { return err } } return c.dbusObject.Call("org.freedesktop.DBus.Properties.Set", 0, c.Config.Iface, p, dbus.MakeVariant(v)).Store() } //GetProperties load all the properties for an interface func (c *Client) GetProperties(props interface{}) error { if !c.isConnected() { err := c.Connect() if err != nil { return err } } result := make(map[string]dbus.Variant) err := c.dbusObject.Call("org.freedesktop.DBus.Properties.GetAll", 0, c.Config.Iface).Store(&result) if err != nil { return fmt.Errorf("Properties.GetAll %s: %s", c.Config.Iface, err) } err = util.MapToStruct(props, result) if err != nil { return fmt.Errorf("MapToStruct: %s", err) } return nil } func getMatchString(path dbus.ObjectPath, iface string) string { return fmt.Sprintf("type='signal',interface='%s',path='%s'", iface, path) } //Register for signals func (c *Client) Register(path dbus.ObjectPath, iface string) (chan *dbus.Signal, error) { if !c.isConnected() { err := c.Connect() if err != nil { return nil, err } } matchstr := getMatchString(path, iface) c.conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, matchstr) channel := make(chan *dbus.Signal, 1) c.conn.Signal(channel) return channel, nil } //Unregister for signals func (c *Client) Unregister(path dbus.ObjectPath, iface string, signal chan *dbus.Signal) error { if !c.isConnected() { err := c.Connect() if err != nil { return err } } matchstr := getMatchString(path, iface) c.conn.BusObject().Call("org.freedesktop.DBus.RemoveMatch", 0, matchstr) if signal != nil { c.conn.RemoveSignal(signal) } return nil } // Emit func (c *Client) Emit(path dbus.ObjectPath, name string, values ...interface{}) error { if !c.isConnected() { err := c.Connect() if err != nil { return err } } return c.conn.Emit(path, name, values...) } go-bluetooth-bluez-5.60/bluez/dbus.go000066400000000000000000000037601420407601400176040ustar00rootroot00000000000000package bluez import ( "errors" "github.com/godbus/dbus/v5" log "github.com/sirupsen/logrus" ) //Properties dbus serializable struct // Use struct tags to control how the field is handled by Properties interface // Example: field `dbus:writable,emit,myCallback` // See Prop in github.com/godbus/dbus/v5/prop for configuration details // Options: // - writable: set the property as writable (Set will updated it). Omit for read-only // - emit|invalidates: emit PropertyChanged, invalidates emit without disclosing the value. Omit for read-only // - callback: a callable function in the struct compatible with the signature of Prop.Callback. Omit for no callback type Properties interface { ToMap() (map[string]interface{}, error) Lock() Unlock() } //BusType a type of DBus connection type BusType int const ( // SessionBus uses the session bus SessionBus BusType = iota // SystemBus uses the system bus SystemBus ) var conns = make([]*dbus.Conn, 2) // Config pass configuration to a DBUS client type Config struct { Name string Iface string Path dbus.ObjectPath Bus BusType } // CloseConnections close all open connection to DBus func CloseConnections() (err error) { for _, conn := range conns { if conn != nil { err = conn.Close() if err != nil { log.Warnf("Close: %s", err) } } } conns = make([]*dbus.Conn, 2) return err } //GetConnection get a DBus connection func GetConnection(connType BusType) (*dbus.Conn, error) { switch connType { case SystemBus: if conns[SystemBus] == nil { // c.logger.Debug("Connecting to SystemBus") conn, err := dbus.SystemBus() if err != nil { return nil, err } conns[SystemBus] = conn } return conns[SystemBus], nil case SessionBus: if conns[SessionBus] == nil { // c.logger.Debug("Connecting to SessionBus") conn, err := dbus.SessionBus() if err != nil { return nil, err } conns[SessionBus] = conn } return conns[SessionBus], nil default: return nil, errors.New("Unmanged DBus type code") } } go-bluetooth-bluez-5.60/bluez/events.go000066400000000000000000000002411420407601400201420ustar00rootroot00000000000000package bluez // PropertyChanged indicates that a change is notified type PropertyChanged struct { Interface string Name string Value interface{} } go-bluetooth-bluez-5.60/bluez/introspect.go000066400000000000000000000075701420407601400210440ustar00rootroot00000000000000package bluez import "github.com/godbus/dbus/v5/introspect" // GattService1IntrospectDataString interface definition const GattService1IntrospectDataString = ` ` // GattDescriptor1IntrospectDataString interface definition const GattDescriptor1IntrospectDataString = ` ` //GattCharacteristic1IntrospectDataString interface definition const GattCharacteristic1IntrospectDataString = ` ` //Device1IntrospectDataString interface definition const Device1IntrospectDataString = ` ` // GattService1IntrospectData interface definition var GattService1IntrospectData = introspect.Interface{ Name: "org.bluez.GattService1", Properties: []introspect.Property{ { Name: "UUID", Access: "read", Type: "s", }, { Name: "Device", Access: "read", Type: "o", }, { Name: "Primary", Access: "read", Type: "b", }, { Name: "Characteristics", Access: "read", Type: "ao", }, }, } go-bluetooth-bluez-5.60/bluez/object_manager.go000066400000000000000000000041341420407601400216030ustar00rootroot00000000000000package bluez import ( "github.com/godbus/dbus/v5" ) var objectManager *ObjectManager // GetObjectManager return a client instance of the Bluez object manager func GetObjectManager() (*ObjectManager, error) { if objectManager != nil { return objectManager, nil } om, err := NewObjectManager(OrgBluezInterface, "/") if err != nil { return nil, err } objectManager = om return om, nil } // NewObjectManager create a new ObjectManager client func NewObjectManager(name string, path string) (*ObjectManager, error) { om := new(ObjectManager) om.client = NewClient( &Config{ Name: name, Iface: "org.freedesktop.DBus.ObjectManager", Path: dbus.ObjectPath(path), Bus: SystemBus, }, ) return om, nil } // ObjectManager manges the list of all available objects type ObjectManager struct { client *Client } // Close the connection func (o *ObjectManager) Close() { o.client.Disconnect() } // GetManagedObjects return a list of all available objects registered func (o *ObjectManager) GetManagedObjects() (map[dbus.ObjectPath]map[string]map[string]dbus.Variant, error) { var objs map[dbus.ObjectPath]map[string]map[string]dbus.Variant err := o.client.Call("GetManagedObjects", 0).Store(&objs) return objs, err } //Register watch for signal events func (o *ObjectManager) Register() (chan *dbus.Signal, error) { path := o.client.Config.Path iface := o.client.Config.Iface return o.client.Register(dbus.ObjectPath(path), iface) } //Unregister watch for signal events func (o *ObjectManager) Unregister(signal chan *dbus.Signal) error { path := o.client.Config.Path iface := o.client.Config.Iface return o.client.Unregister(dbus.ObjectPath(path), iface, signal) } // GetManagedObject return an up to date view of a single object state. // object is nil if the object path is not found func (o *ObjectManager) GetManagedObject(objpath dbus.ObjectPath) (map[string]map[string]dbus.Variant, error) { objects, err := o.GetManagedObjects() if err != nil { return nil, err } if p, ok := objects[objpath]; ok { return p, nil } // return nil, errors.New("Object not found") return nil, nil } go-bluetooth-bluez-5.60/bluez/profile/000077500000000000000000000000001420407601400177525ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/adapter/000077500000000000000000000000001420407601400213725ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/adapter/Adapter1_methods.go000066400000000000000000000002251420407601400251040ustar00rootroot00000000000000package adapter // GetAdapterID return the Id of the adapter func (a *Adapter1) GetAdapterID() (string, error) { return ParseAdapterID(a.Path()) } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter.go000066400000000000000000000041211420407601400233370ustar00rootroot00000000000000package adapter import ( "fmt" "strings" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/device" ) var defaultAdapterID = "hci0" // SetDefaultAdapterID set the default adapter func SetDefaultAdapterID(a string) { defaultAdapterID = a } // GetDefaultAdapterID get the default adapter func GetDefaultAdapterID() string { return defaultAdapterID } // ParseAdapterID read the adapterID from an object path in the form /org/bluez/hci[0-9]*[/...] func ParseAdapterID(path dbus.ObjectPath) (string, error) { spath := string(path) if !strings.HasPrefix(spath, bluez.OrgBluezPath) { return "", fmt.Errorf("Failed to parse adapterID from %s", path) } parts := strings.Split(spath[len(bluez.OrgBluezPath)+1:], "/") adapterID := parts[0] if adapterID[:3] != "hci" { return "", fmt.Errorf("adapterID missing hci* prefix from %s", path) } return adapterID, nil } // AdapterExists checks if an adapter is available func AdapterExists(adapterID string) (bool, error) { om, err := bluez.GetObjectManager() if err != nil { return false, err } objects, err := om.GetManagedObjects() if err != nil { return false, err } path := dbus.ObjectPath(fmt.Sprintf("%s/%s", bluez.OrgBluezPath, adapterID)) _, exists := objects[path] return exists, nil } func GetDefaultAdapter() (*Adapter1, error) { return GetAdapter(GetDefaultAdapterID()) } // GetAdapter return an adapter object instance func GetAdapter(adapterID string) (*Adapter1, error) { if exists, err := AdapterExists(adapterID); !exists { if err != nil { return nil, fmt.Errorf("AdapterExists: %s", err) } return nil, fmt.Errorf("Adapter %s not found", adapterID) } return NewAdapter1FromAdapterID(adapterID) } // GetAdapterFromDevicePath Return an adapter based on a device path func GetAdapterFromDevicePath(path dbus.ObjectPath) (*Adapter1, error) { d, err := device.NewDevice1(path) if err != nil { return nil, fmt.Errorf("Failed to load device %s", path) } a, err := NewAdapter1(d.Properties.Adapter) if err != nil { return nil, err } return a, nil } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_devices.go000066400000000000000000000051031420407601400250420ustar00rootroot00000000000000package adapter import ( "fmt" "strings" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/device" "github.com/muka/go-bluetooth/util" ) //GetDeviceByAddress return a Device object based on its address func (a *Adapter1) GetDeviceByAddress(address string) (*device.Device1, error) { list, err := a.GetDeviceList() if err != nil { return nil, err } for _, path := range list { dev, err := device.NewDevice1(path) if err != nil { return nil, err } if dev.Properties.Address == address { return dev, nil } } return nil, nil } //GetDevices returns a list of bluetooth discovered Devices func (a *Adapter1) GetDevices() ([]*device.Device1, error) { list, err := a.GetDeviceList() if err != nil { return nil, err } om, err := bluez.GetObjectManager() if err != nil { return nil, err } objects, err := om.GetManagedObjects() if err != nil { return nil, err } devices := []*device.Device1{} for _, path := range list { object, ok := objects[path] if !ok { return nil, fmt.Errorf("Path %s does not exists", path) } props := object[device.Device1Interface] dev, err := parseDevice(path, props) if err != nil { return nil, err } devices = append(devices, dev) } // log.Debugf("%d cached devices", len(devices)) return devices, nil } // GetDeviceList returns a list of cached device paths func (a *Adapter1) GetDeviceList() ([]dbus.ObjectPath, error) { om, err := bluez.GetObjectManager() if err != nil { return nil, err } objects, err := om.GetManagedObjects() if err != nil { return nil, err } devices := []dbus.ObjectPath{} for path, ifaces := range objects { for iface := range ifaces { switch iface { case device.Device1Interface: { if strings.Contains(string(path), string(a.Path())) { devices = append(devices, path) } } } } } return devices, nil } // FlushDevices removes device from bluez cache func (a *Adapter1) FlushDevices() error { devices, err := a.GetDevices() if err != nil { return err } for _, dev := range devices { err = a.RemoveDevice(dev.Path()) if err != nil { return fmt.Errorf("FlushDevices.RemoveDevice %s: %s", dev.Path(), err) } } return nil } // ParseDevice parse a Device from a ObjectManager map func parseDevice(path dbus.ObjectPath, propsMap map[string]dbus.Variant) (*device.Device1, error) { dev, err := device.NewDevice1(path) if err != nil { return nil, err } err = util.MapToStruct(dev.Properties, propsMap) if err != nil { return nil, err } return dev, nil } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_devices_test.go000066400000000000000000000015361420407601400261070ustar00rootroot00000000000000package adapter import ( "testing" "github.com/stretchr/testify/assert" ) func getDefaultAdapter(t *testing.T) *Adapter1 { a, err := GetDefaultAdapter() if err != nil { t.Fatal(err) } return a } func TestGetDeviceByAddress(t *testing.T) { a := getDefaultAdapter(t) list, err := a.GetDeviceByAddress("foobar") if err != nil { t.Fatal(err) } assert.Empty(t, list) } func TestGetDevices(t *testing.T) { a := getDefaultAdapter(t) _, err := a.GetDevices() if err != nil { t.Fatal(err) } } func TestGetDeviceList(t *testing.T) { a := getDefaultAdapter(t) _, err := a.GetDeviceList() if err != nil { t.Fatal(err) } } func TestFlushDevices(t *testing.T) { a := getDefaultAdapter(t) err := a.FlushDevices() if err != nil { t.Fatal(err) } list, err := a.GetDevices() if err != nil { t.Fatal(err) } assert.Zero(t, len(list)) } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_discovery.go000066400000000000000000000043341420407601400254340ustar00rootroot00000000000000package adapter import ( "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/device" log "github.com/sirupsen/logrus" ) const ( // DeviceRemoved a device has been removed from local cache DeviceRemoved DeviceActions = iota // DeviceAdded new device found, eg. via discovery DeviceAdded ) type DeviceActions uint8 // DeviceDiscovered event emitted when a device is added or removed from Object Manager type DeviceDiscovered struct { Path dbus.ObjectPath Type DeviceActions } // OnDeviceDiscovered monitor for new devices and send updates via channel. Use cancel to close the monitoring process func (a *Adapter1) OnDeviceDiscovered() (chan *DeviceDiscovered, func(), error) { signal, omSignalCancel, err := a.GetObjectManagerSignal() if err != nil { return nil, nil, err } var ( ch = make(chan *DeviceDiscovered) ) go func() { // Recover from panic on write to closed channel which happens // very often when there's too many BLE advertisements to process // in timly manner by bluez+dbus and advertising reports come in // after scanning was stopped defer func() { if err := recover(); err != nil { log.Warnf("Recovering from panic: %s", err) } }() for v := range signal { if v == nil { return } var op DeviceActions if v.Name == bluez.InterfacesAdded { op = DeviceAdded } else { if v.Name == bluez.InterfacesRemoved { op = DeviceRemoved } else { continue } } path := v.Body[0].(dbus.ObjectPath) if op == DeviceRemoved { ifaces := v.Body[1].([]string) for _, iface := range ifaces { if iface == device.Device1Interface { log.Tracef("Removed device %s", path) ch <- &DeviceDiscovered{path, op} } } continue } ifaces := v.Body[1].(map[string]map[string]dbus.Variant) if p, ok := ifaces[device.Device1Interface]; ok { if p == nil { continue } log.Tracef("Added device %s", path) if ch == nil { return } ch <- &DeviceDiscovered{path, op} } } }() cancel := func() { omSignalCancel() if ch != nil { close(ch) } ch = nil log.Trace("OnDeviceDiscovered: cancel() called") } return ch, cancel, nil } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_discovery_test.go000066400000000000000000000014321420407601400264670ustar00rootroot00000000000000package adapter import ( "fmt" "sync" "testing" "time" ) func TestDiscovery(t *testing.T) { a := getDefaultAdapter(t) err := a.StartDiscovery() if err != nil { t.Fatal(err) } defer func() { err := a.StopDiscovery() if err != nil { t.Error(err) } }() discovery, cancel, err := a.OnDeviceDiscovered() if err != nil { t.Fatal(err) } var ( wait = make(chan error, 2) wg sync.WaitGroup ) wg.Add(2) go func() { defer wg.Done() for dev := range discovery { if dev == nil { return } wait <- nil } }() go func() { defer wg.Done() sleep := 5 time.Sleep(time.Duration(sleep) * time.Second) wait <- fmt.Errorf("Discovery timeout exceeded (%ds)", sleep) }() err = <-wait cancel() if err != nil { t.Fatal(err) } wg.Wait() } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_filter.go000066400000000000000000000053111420407601400247060ustar00rootroot00000000000000package adapter import ( "github.com/muka/go-bluetooth/util" ) const ( DiscoveryFilterTransportAuto = "auto" DiscoveryFilterTransportBrEdr = "bredr" DiscoveryFilterTransportLE = "le" ) // Filter applied to discovery type DiscoveryFilter struct { // Filter by service UUIDs, empty means match // _any_ UUID. // // When a remote device is found that advertises // any UUID from UUIDs, it will be reported if: // - Pathloss and RSSI are both empty. // - only Pathloss param is set, device advertise // TX pwer, and computed pathloss is less than // Pathloss param. // - only RSSI param is set, and received RSSI is // higher than RSSI param. UUIDs []string // RSSI threshold value. // // PropertiesChanged signals will be emitted // for already existing Device objects, with // updated RSSI value. If one or more discovery // filters have been set, the RSSI delta-threshold, // that is imposed by StartDiscovery by default, // will not be applied. RSSI int16 // Pathloss threshold value. // // PropertiesChanged signals will be emitted // for already existing Device objects, with // updated Pathloss value. Pathloss uint16 // Transport parameter determines the type of // scan. // // Possible values: // "auto" - interleaved scan // "bredr" - BR/EDR inquiry // "le" - LE scan only // // If "le" or "bredr" Transport is requested, // and the controller doesn't support it, // org.bluez.Error.Failed error will be returned. // If "auto" transport is requested, scan will use // LE, BREDR, or both, depending on what's // currently enabled on the controller. Transport string // Disables duplicate detection of advertisement // data. // // When enabled PropertiesChanged signals will be // generated for either ManufacturerData and // ServiceData everytime they are discovered. DuplicateData bool } func (a *DiscoveryFilter) uuidExists(uuid string) bool { for _, uiid1 := range a.UUIDs { if uiid1 == uuid { return true } } return false } // Add an UUID to filter if it does not exists func (a *DiscoveryFilter) AddUUIDs(uuids ...string) { for _, uuid := range uuids { if !a.uuidExists(uuid) { a.UUIDs = append(a.UUIDs, uuid) } } } // ToMap convert to a format compatible with SetDiscoveryFilter method call func (a *DiscoveryFilter) ToMap() map[string]interface{} { m := make(map[string]interface{}) util.StructToMap(a, m) if len(a.UUIDs) == 0 { delete(m, "UUIDs") } if a.RSSI == 0 { delete(m, "RSSI") } if a.Pathloss == 0 { delete(m, "Pathloss") } return m } // initialize a new DiscoveryFilter func NewDiscoveryFilter() DiscoveryFilter { return DiscoveryFilter{ // defaults DuplicateData: true, Transport: DiscoveryFilterTransportAuto, } } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_filter_test.go000066400000000000000000000011111420407601400257370ustar00rootroot00000000000000package adapter import ( "testing" "github.com/stretchr/testify/assert" ) func TestDiscoveryFilter(t *testing.T) { f := NewDiscoveryFilter() f.AddUUIDs("AAAA", "BBBB") f.RSSI = 10 f.Pathloss = 1 f.DuplicateData = false f.Transport = DiscoveryFilterTransportLE m := f.ToMap() assert.EqualValues(t, m["UUIDs"].([]string), f.UUIDs) assert.EqualValues(t, m["RSSI"].(int16), f.RSSI) assert.EqualValues(t, m["Pathloss"].(uint16), f.Pathloss) assert.EqualValues(t, m["DuplicateData"].(bool), f.DuplicateData) assert.EqualValues(t, m["Transport"].(string), f.Transport) } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_gatt.go000066400000000000000000000005131420407601400243570ustar00rootroot00000000000000package adapter import ( "github.com/muka/go-bluetooth/bluez/profile/gatt" ) //GetGattManager return a GattManager1 instance func (a *Adapter1) GetGattManager() (*gatt.GattManager1, error) { adapterID, err := ParseAdapterID(a.Path()) if err != nil { return nil, err } return gatt.NewGattManager1FromAdapterID(adapterID) } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_gatt_test.go000066400000000000000000000003341420407601400254170ustar00rootroot00000000000000package adapter import "testing" //GetGattManager return a GattManager1 instance func TestGetGattManager(t *testing.T) { a := getDefaultAdapter(t) _, err := a.GetGattManager() if err != nil { t.Fatal(err) } } go-bluetooth-bluez-5.60/bluez/profile/adapter/adapter_test.go000066400000000000000000000043731420407601400244070ustar00rootroot00000000000000package adapter import ( "fmt" "log" "testing" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" ) func TestGetAdapterIDFromPath(t *testing.T) { hci := "hci999" path := fmt.Sprintf("%s/%s", bluez.OrgBluezPath, hci) adapterID, err := ParseAdapterID(dbus.ObjectPath(path)) if err != nil { t.Fatal(err) } if hci != adapterID { t.Fatal(fmt.Errorf("%s != %s", hci, adapterID)) } path += "/dev_AA_BB_CC" adapterID, err = ParseAdapterID(dbus.ObjectPath(path)) if err != nil { t.Fatal(err) } if hci != adapterID { t.Fatal(fmt.Errorf("%s != %s", hci, adapterID)) } } func TestGetAdapterIDFromPathFail(t *testing.T) { hci := "foo1234" path := fmt.Sprintf("%s/%s", bluez.OrgBluezPath, hci) _, err := ParseAdapterID(dbus.ObjectPath(path)) if err == nil { t.Fatal("Expected error parsing hci device name") } path = "foo/hci1" _, err = ParseAdapterID(dbus.ObjectPath(path)) if err == nil { t.Fatal("Expected error parsing bluez base path") } } func TestDefaultAdapterSetGet(t *testing.T) { testAdapterID := "hci1" SetDefaultAdapterID(testAdapterID) adapterID := GetDefaultAdapterID() if adapterID != testAdapterID { log.Fatal("Failed to set default adapter") } } func TestAdapterExists(t *testing.T) { adapterID := GetDefaultAdapterID() exists, err := AdapterExists(adapterID) if err != nil { t.Fatal(err) } if exists == false { t.Errorf("Expected %s to exists", adapterID) t.Fatal() } } func TestGetAdapterNotExists(t *testing.T) { _, err := GetAdapter("foobar") if err == nil { t.Fatal("adapter should not exists") } } func TestGetAdapterFromDevicePath(t *testing.T) { a := getDefaultAdapter(t) list, err := a.GetDeviceList() if err != nil { t.Fatal(err) } if len(list) == 0 { t.Log("Cannot test GetAdapterFromDevicePath, empty device list") return } _, err = GetAdapterFromDevicePath(list[0]) if err != nil { t.Fatal(err) } } func TestGetAdapterFromDevicePathFail(t *testing.T) { _, err := GetAdapterFromDevicePath(dbus.ObjectPath("foo/test/hci1/dev_AA_BB_CC_DD_EE_FF")) if err == nil { t.Fatal("Expected failure parsing device path") } } func TestGetAdapter(t *testing.T) { a := getDefaultAdapter(t) if a.Properties.Address == "" { log.Fatal("Properties should not be empty") } } go-bluetooth-bluez-5.60/bluez/profile/adapter/gen_Adapter1.go000066400000000000000000000502071420407601400242170ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package adapter import ( "fmt" "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Adapter1Interface = "org.bluez.Adapter1" // NewAdapter1 create a new instance of Adapter1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...} func NewAdapter1(objectPath dbus.ObjectPath) (*Adapter1, error) { a := new(Adapter1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Adapter1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Adapter1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } // NewAdapter1FromAdapterID create a new instance of Adapter1 // adapterID: ID of an adapter eg. hci0 func NewAdapter1FromAdapterID(adapterID string) (*Adapter1, error) { a := new(Adapter1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Adapter1Interface, Path: dbus.ObjectPath(fmt.Sprintf("/org/bluez/%s", adapterID)), Bus: bluez.SystemBus, }, ) a.Properties = new(Adapter1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Adapter1 Adapter hierarchy */ type Adapter1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Adapter1Properties watchPropertiesChannel chan *dbus.Signal } // Adapter1Properties contains the exposed properties of an interface type Adapter1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Address The Bluetooth device address. */ Address string /* AddressType The Bluetooth Address Type. For dual-mode and BR/EDR only adapter this defaults to "public". Single mode LE adapters may have either value. With privacy enabled this contains type of Identity Address and not type of address used for connection. Possible values: "public" - Public address "random" - Random address */ AddressType string /* Alias The Bluetooth friendly name. This value can be changed. In case no alias is set, it will return the system provided name. Setting an empty string as alias will convert it back to the system provided name. When resetting the alias with an empty string, the property will default back to system name. On a well configured system, this property never needs to be changed since it defaults to the system name and provides the pretty hostname. Only if the local name needs to be different from the pretty hostname, this property should be used as last resort. */ Alias string /* Class The Bluetooth class of device. This property represents the value that is either automatically configured by DMI/ACPI information or provided as static configuration. */ Class uint32 /* Discoverable Switch an adapter to discoverable or non-discoverable to either make it visible or hide it. This is a global setting and should only be used by the settings application. If the DiscoverableTimeout is set to a non-zero value then the system will set this value back to false after the timer expired. In case the adapter is switched off, setting this value will fail. When changing the Powered property the new state of this property will be updated via a PropertiesChanged signal. For any new adapter this settings defaults to false. */ Discoverable bool /* DiscoverableTimeout The discoverable timeout in seconds. A value of zero means that the timeout is disabled and it will stay in discoverable/limited mode forever. The default value for the discoverable timeout should be 180 seconds (3 minutes). */ DiscoverableTimeout uint32 /* Discovering Indicates that a device discovery procedure is active. */ Discovering bool /* Modalias Local Device ID information in modalias format used by the kernel and udev. */ Modalias string /* Name The Bluetooth system name (pretty hostname). This property is either a static system default or controlled by an external daemon providing access to the pretty hostname configuration. */ Name string /* Pairable Switch an adapter to pairable or non-pairable. This is a global setting and should only be used by the settings application. Note that this property only affects incoming pairing requests. For any new adapter this settings defaults to true. */ Pairable bool /* PairableTimeout The pairable timeout in seconds. A value of zero means that the timeout is disabled and it will stay in pairable mode forever. The default value for pairable timeout should be disabled (value 0). */ PairableTimeout uint32 /* Powered Switch an adapter on or off. This will also set the appropriate connectable state of the controller. The value of this property is not persistent. After restart or unplugging of the adapter it will reset back to false. */ Powered bool /* Roles List of supported roles. Possible values: "central": Supports the central role. "peripheral": Supports the peripheral role. "central-peripheral": Supports both roles concurrently. */ Roles []string /* UUIDs List of 128-bit UUIDs that represents the available local services. */ UUIDs []string } //Lock access to properties func (p *Adapter1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Adapter1Properties) Unlock() { p.lock.Unlock() } // SetAddress set Address value func (a *Adapter1) SetAddress(v string) error { return a.SetProperty("Address", v) } // GetAddress get Address value func (a *Adapter1) GetAddress() (string, error) { v, err := a.GetProperty("Address") if err != nil { return "", err } return v.Value().(string), nil } // SetAddressType set AddressType value func (a *Adapter1) SetAddressType(v string) error { return a.SetProperty("AddressType", v) } // GetAddressType get AddressType value func (a *Adapter1) GetAddressType() (string, error) { v, err := a.GetProperty("AddressType") if err != nil { return "", err } return v.Value().(string), nil } // SetAlias set Alias value func (a *Adapter1) SetAlias(v string) error { return a.SetProperty("Alias", v) } // GetAlias get Alias value func (a *Adapter1) GetAlias() (string, error) { v, err := a.GetProperty("Alias") if err != nil { return "", err } return v.Value().(string), nil } // SetClass set Class value func (a *Adapter1) SetClass(v uint32) error { return a.SetProperty("Class", v) } // GetClass get Class value func (a *Adapter1) GetClass() (uint32, error) { v, err := a.GetProperty("Class") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetDiscoverable set Discoverable value func (a *Adapter1) SetDiscoverable(v bool) error { return a.SetProperty("Discoverable", v) } // GetDiscoverable get Discoverable value func (a *Adapter1) GetDiscoverable() (bool, error) { v, err := a.GetProperty("Discoverable") if err != nil { return false, err } return v.Value().(bool), nil } // SetDiscoverableTimeout set DiscoverableTimeout value func (a *Adapter1) SetDiscoverableTimeout(v uint32) error { return a.SetProperty("DiscoverableTimeout", v) } // GetDiscoverableTimeout get DiscoverableTimeout value func (a *Adapter1) GetDiscoverableTimeout() (uint32, error) { v, err := a.GetProperty("DiscoverableTimeout") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetDiscovering set Discovering value func (a *Adapter1) SetDiscovering(v bool) error { return a.SetProperty("Discovering", v) } // GetDiscovering get Discovering value func (a *Adapter1) GetDiscovering() (bool, error) { v, err := a.GetProperty("Discovering") if err != nil { return false, err } return v.Value().(bool), nil } // SetModalias set Modalias value func (a *Adapter1) SetModalias(v string) error { return a.SetProperty("Modalias", v) } // GetModalias get Modalias value func (a *Adapter1) GetModalias() (string, error) { v, err := a.GetProperty("Modalias") if err != nil { return "", err } return v.Value().(string), nil } // SetName set Name value func (a *Adapter1) SetName(v string) error { return a.SetProperty("Name", v) } // GetName get Name value func (a *Adapter1) GetName() (string, error) { v, err := a.GetProperty("Name") if err != nil { return "", err } return v.Value().(string), nil } // SetPairable set Pairable value func (a *Adapter1) SetPairable(v bool) error { return a.SetProperty("Pairable", v) } // GetPairable get Pairable value func (a *Adapter1) GetPairable() (bool, error) { v, err := a.GetProperty("Pairable") if err != nil { return false, err } return v.Value().(bool), nil } // SetPairableTimeout set PairableTimeout value func (a *Adapter1) SetPairableTimeout(v uint32) error { return a.SetProperty("PairableTimeout", v) } // GetPairableTimeout get PairableTimeout value func (a *Adapter1) GetPairableTimeout() (uint32, error) { v, err := a.GetProperty("PairableTimeout") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetPowered set Powered value func (a *Adapter1) SetPowered(v bool) error { return a.SetProperty("Powered", v) } // GetPowered get Powered value func (a *Adapter1) GetPowered() (bool, error) { v, err := a.GetProperty("Powered") if err != nil { return false, err } return v.Value().(bool), nil } // SetRoles set Roles value func (a *Adapter1) SetRoles(v []string) error { return a.SetProperty("Roles", v) } // GetRoles get Roles value func (a *Adapter1) GetRoles() ([]string, error) { v, err := a.GetProperty("Roles") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetUUIDs set UUIDs value func (a *Adapter1) SetUUIDs(v []string) error { return a.SetProperty("UUIDs", v) } // GetUUIDs get UUIDs value func (a *Adapter1) GetUUIDs() ([]string, error) { v, err := a.GetProperty("UUIDs") if err != nil { return []string{}, err } return v.Value().([]string), nil } // Close the connection func (a *Adapter1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Adapter1 object path func (a *Adapter1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Adapter1 dbus client func (a *Adapter1) Client() *bluez.Client { return a.client } // Interface return Adapter1 interface func (a *Adapter1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Adapter1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Adapter1Properties to map func (a *Adapter1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Adapter1Properties func (a *Adapter1Properties) FromMap(props map[string]interface{}) (*Adapter1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Adapter1Properties func (a *Adapter1Properties) FromDBusMap(props map[string]dbus.Variant) (*Adapter1Properties, error) { s := new(Adapter1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Adapter1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Adapter1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Adapter1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Adapter1) GetProperties() (*Adapter1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Adapter1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Adapter1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Adapter1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Adapter1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Adapter1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Adapter1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* StartDiscovery This method starts the device discovery session. This includes an inquiry procedure and remote device name resolving. Use StopDiscovery to release the sessions acquired. This process will start creating Device objects as new devices are discovered. During discovery RSSI delta-threshold is imposed. Possible errors: org.bluez.Error.NotReady org.bluez.Error.Failed org.bluez.Error.InProgress */ func (a *Adapter1) StartDiscovery() error { return a.client.Call("StartDiscovery", 0).Store() } /* StopDiscovery This method will cancel any previous StartDiscovery transaction. Note that a discovery procedure is shared between all discovery sessions thus calling StopDiscovery will only release a single session. Possible errors: org.bluez.Error.NotReady org.bluez.Error.Failed org.bluez.Error.NotAuthorized */ func (a *Adapter1) StopDiscovery() error { return a.client.Call("StopDiscovery", 0).Store() } /* RemoveDevice This removes the remote device object at the given path. It will remove also the pairing information. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.Failed */ func (a *Adapter1) RemoveDevice(device dbus.ObjectPath) error { return a.client.Call("RemoveDevice", 0, device).Store() } /* SetDiscoveryFilter This method sets the device discovery filter for the caller. When this method is called with no filter parameter, filter is removed. Parameters that may be set in the filter dictionary include the following: array{string} UUIDs Filter by service UUIDs, empty means match _any_ UUID. When a remote device is found that advertises any UUID from UUIDs, it will be reported if: - Pathloss and RSSI are both empty. - only Pathloss param is set, device advertise TX pwer, and computed pathloss is less than Pathloss param. - only RSSI param is set, and received RSSI is higher than RSSI param. int16 RSSI RSSI threshold value. PropertiesChanged signals will be emitted for already existing Device objects, with updated RSSI value. If one or more discovery filters have been set, the RSSI delta-threshold, that is imposed by StartDiscovery by default, will not be applied. uint16 Pathloss Pathloss threshold value. PropertiesChanged signals will be emitted for already existing Device objects, with updated Pathloss value. string Transport (Default "auto") Transport parameter determines the type of scan. Possible values: "auto" - interleaved scan "bredr" - BR/EDR inquiry "le" - LE scan only If "le" or "bredr" Transport is requested, and the controller doesn't support it, org.bluez.Error.Failed error will be returned. If "auto" transport is requested, scan will use LE, BREDR, or both, depending on what's currently enabled on the controller. bool DuplicateData (Default: true) Disables duplicate detection of advertisement data. When enabled PropertiesChanged signals will be generated for either ManufacturerData and ServiceData everytime they are discovered. bool Discoverable (Default: false) Make adapter discoverable while discovering, if the adapter is already discoverable setting this filter won't do anything. string Pattern (Default: none) Discover devices where the pattern matches either the prefix of the address or device name which is convenient way to limited the number of device objects created during a discovery. When set disregards device discoverable flags. Note: The pattern matching is ignored if there are other client that don't set any pattern as it work as a logical OR, also setting empty string "" pattern will match any device found. When discovery filter is set, Device objects will be created as new devices with matching criteria are discovered regardless of they are connectable or discoverable which enables listening to non-connectable and non-discoverable devices. When multiple clients call SetDiscoveryFilter, their filters are internally merged, and notifications about new devices are sent to all clients. Therefore, each client must check that device updates actually match its filter. When SetDiscoveryFilter is called multiple times by the same client, last filter passed will be active for given client. SetDiscoveryFilter can be called before StartDiscovery. It is useful when client will create first discovery session, to ensure that proper scan will be started right after call to StartDiscovery. Possible errors: org.bluez.Error.NotReady org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *Adapter1) SetDiscoveryFilter(filter map[string]interface{}) error { return a.client.Call("SetDiscoveryFilter", 0, filter).Store() } /* GetDiscoveryFilters Return available filters that can be given to SetDiscoveryFilter. Possible errors: None */ func (a *Adapter1) GetDiscoveryFilters() ([]string, error) { val0 := []string{} err := a.client.Call("GetDiscoveryFilters", 0).Store(&val0) return val0, err } /* ConnectDevice This method connects to device without need of performing General Discovery. Connection mechanism is similar to Connect method from Device1 interface with exception that this method returns success when physical connection is established. After this method returns, services discovery will continue and any supported profile will be connected. There is no need for calling Connect on Device1 after this call. If connection was successful this method returns object path to created device object. Parameters that may be set in the filter dictionary include the following: string Address The Bluetooth device address of the remote device. This parameter is mandatory. string AddressType The Bluetooth device Address Type. This is address type that should be used for initial connection. If this parameter is not present BR/EDR device is created. Possible values: "public" - Public address "random" - Random address Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists org.bluez.Error.NotSupported org.bluez.Error.NotReady org.bluez.Error.Failed */ func (a *Adapter1) ConnectDevice(properties map[string]interface{}) (dbus.ObjectPath, error) { var val0 dbus.ObjectPath err := a.client.Call("ConnectDevice", 0, properties).Store(&val0) return val0, err } go-bluetooth-bluez-5.60/bluez/profile/adapter/gen_adapter.go000066400000000000000000000002101420407601400241630ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Adapter API description [adapter-api.txt] */ package adapter go-bluetooth-bluez-5.60/bluez/profile/advertisement_monitor/000077500000000000000000000000001420407601400243735ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/advertisement_monitor/advertisement_monitor.go000066400000000000000000000002271420407601400313440ustar00rootroot00000000000000package advertisement_monitor // array{(uint8, uint8, array{byte})} type Pattern struct { v1 uint8 v2 uint8 v3 []byte } type Patterns = []Pattern go-bluetooth-bluez-5.60/bluez/profile/advertisement_monitor/gen_AdvertisementMonitor1.go000066400000000000000000000257471420407601400320350ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package advertisement_monitor import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var AdvertisementMonitor1Interface = "org.bluez.AdvertisementMonitor1" // NewAdvertisementMonitor1 create a new instance of AdvertisementMonitor1 // // Args: // - objectPath: freely definable func NewAdvertisementMonitor1(objectPath dbus.ObjectPath) (*AdvertisementMonitor1, error) { a := new(AdvertisementMonitor1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: AdvertisementMonitor1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(AdvertisementMonitor1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* AdvertisementMonitor1 Advertisement Monitor hierarchy */ type AdvertisementMonitor1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *AdvertisementMonitor1Properties watchPropertiesChannel chan *dbus.Signal } // AdvertisementMonitor1Properties contains the exposed properties of an interface type AdvertisementMonitor1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Patterns If the Type property is set to "or_patterns", then this property must exist and have at least one entry in the array. The structure of a pattern contains the following: uint8 start_position The index in an AD data field where the search should start. The beginning of an AD data field is index 0. uint8 AD_data_type See https://www.bluetooth.com/specifications/ assigned-numbers/generic-access-profile/ for the possible allowed value. */ Patterns []Pattern /* RSSIHighThreshold Used in conjunction with RSSIHighTimeout to determine whether a device becomes in-range. Valid range is -127 to 20 (dBm), while 127 indicates unset. */ RSSIHighThreshold int16 /* RSSIHighTimeout The time it takes to consider a device as in-range. If this many seconds elapses while we continuously receive signals at least as strong as RSSIHighThreshold, a currently out-of-range device will be considered as in-range (found). Valid range is 1 to 300 (seconds), while 0 indicates unset. */ RSSIHighTimeout uint16 /* RSSILowThreshold Used in conjunction with RSSILowTimeout to determine whether a device becomes out-of-range. Valid range is -127 to 20 (dBm), while 127 indicates unset. */ RSSILowThreshold int16 /* RSSILowTimeout The time it takes to consider a device as out-of-range. If this many seconds elapses without receiving any signal at least as strong as RSSILowThreshold, a currently in-range device will be considered as out-of-range (lost). Valid range is 1 to 300 (seconds), while 0 indicates unset. */ RSSILowTimeout uint16 /* RSSISamplingPeriod Grouping rules on how to propagate the received advertisement packets to the client. Valid range is 0 to 255 while 256 indicates unset. The meaning of this property is as follows: 0: All advertisement packets from in-range devices would be propagated. 255: Only the first advertisement packet of in-range devices would be propagated. If the device becomes lost, then the first packet when it is found again will also be propagated. 1 to 254: Advertisement packets would be grouped into 100ms * N time period. Packets in the same group will only be reported once, with the RSSI value being averaged out. Currently this is unimplemented in user space, so the value is only used to be forwarded to the kernel. */ RSSISamplingPeriod uint16 /* Type The type of the monitor. See SupportedMonitorTypes in org.bluez.AdvertisementMonitorManager1 for the available options. */ Type string } //Lock access to properties func (p *AdvertisementMonitor1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *AdvertisementMonitor1Properties) Unlock() { p.lock.Unlock() } // GetPatterns get Patterns value func (a *AdvertisementMonitor1) GetPatterns() ([]Pattern, error) { v, err := a.GetProperty("Patterns") if err != nil { return []Pattern{}, err } return v.Value().([]Pattern), nil } // GetRSSIHighThreshold get RSSIHighThreshold value func (a *AdvertisementMonitor1) GetRSSIHighThreshold() (int16, error) { v, err := a.GetProperty("RSSIHighThreshold") if err != nil { return int16(0), err } return v.Value().(int16), nil } // GetRSSIHighTimeout get RSSIHighTimeout value func (a *AdvertisementMonitor1) GetRSSIHighTimeout() (uint16, error) { v, err := a.GetProperty("RSSIHighTimeout") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetRSSILowThreshold get RSSILowThreshold value func (a *AdvertisementMonitor1) GetRSSILowThreshold() (int16, error) { v, err := a.GetProperty("RSSILowThreshold") if err != nil { return int16(0), err } return v.Value().(int16), nil } // GetRSSILowTimeout get RSSILowTimeout value func (a *AdvertisementMonitor1) GetRSSILowTimeout() (uint16, error) { v, err := a.GetProperty("RSSILowTimeout") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetRSSISamplingPeriod get RSSISamplingPeriod value func (a *AdvertisementMonitor1) GetRSSISamplingPeriod() (uint16, error) { v, err := a.GetProperty("RSSISamplingPeriod") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetType get Type value func (a *AdvertisementMonitor1) GetType() (string, error) { v, err := a.GetProperty("Type") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *AdvertisementMonitor1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return AdvertisementMonitor1 object path func (a *AdvertisementMonitor1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return AdvertisementMonitor1 dbus client func (a *AdvertisementMonitor1) Client() *bluez.Client { return a.client } // Interface return AdvertisementMonitor1 interface func (a *AdvertisementMonitor1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *AdvertisementMonitor1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a AdvertisementMonitor1Properties to map func (a *AdvertisementMonitor1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an AdvertisementMonitor1Properties func (a *AdvertisementMonitor1Properties) FromMap(props map[string]interface{}) (*AdvertisementMonitor1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an AdvertisementMonitor1Properties func (a *AdvertisementMonitor1Properties) FromDBusMap(props map[string]dbus.Variant) (*AdvertisementMonitor1Properties, error) { s := new(AdvertisementMonitor1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *AdvertisementMonitor1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *AdvertisementMonitor1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *AdvertisementMonitor1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *AdvertisementMonitor1) GetProperties() (*AdvertisementMonitor1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *AdvertisementMonitor1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *AdvertisementMonitor1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *AdvertisementMonitor1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *AdvertisementMonitor1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *AdvertisementMonitor1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *AdvertisementMonitor1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Release This gets called as a signal for a client to perform clean-up when (1)a monitor cannot be activated after it was exposed or (2)a monitor has been deactivated. */ func (a *AdvertisementMonitor1) Release() error { return a.client.Call("Release", 0).Store() } /* Activate After a monitor was exposed, this gets called as a signal for client to get acknowledged when a monitor has been activated, so the client can expect to receive calls on DeviceFound() or DeviceLost(). */ func (a *AdvertisementMonitor1) Activate() error { return a.client.Call("Activate", 0).Store() } /* DeviceFound This gets called to notify the client of finding the targeted device. Once receiving the call, the client should start to monitor the corresponding device to retrieve the changes on RSSI and advertisement content. */ func (a *AdvertisementMonitor1) DeviceFound(device dbus.ObjectPath) error { return a.client.Call("DeviceFound", 0, device).Store() } /* DeviceLost This gets called to notify the client of losing the targeted device. Once receiving this call, the client should stop monitoring the corresponding device. */ func (a *AdvertisementMonitor1) DeviceLost(device dbus.ObjectPath) error { return a.client.Call("DeviceLost", 0, device).Store() } go-bluetooth-bluez-5.60/bluez/profile/advertisement_monitor/gen_AdvertisementMonitorManager1.go000066400000000000000000000211011420407601400333040ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package advertisement_monitor import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var AdvertisementMonitorManager1Interface = "org.bluez.AdvertisementMonitorManager1" // NewAdvertisementMonitorManager1 create a new instance of AdvertisementMonitorManager1 // // Args: // - objectPath: /org/bluez/{hci0,hci1,...} func NewAdvertisementMonitorManager1(objectPath dbus.ObjectPath) (*AdvertisementMonitorManager1, error) { a := new(AdvertisementMonitorManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: AdvertisementMonitorManager1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(AdvertisementMonitorManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* AdvertisementMonitorManager1 Advertisement Monitor Manager hierarchy */ type AdvertisementMonitorManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *AdvertisementMonitorManager1Properties watchPropertiesChannel chan *dbus.Signal } // AdvertisementMonitorManager1Properties contains the exposed properties of an interface type AdvertisementMonitorManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* SupportedFeatures This lists the features of advertisement monitoring supported by BlueZ. Possible values for features: "controller-patterns" If the controller is capable of performing advertisement monitoring by patterns, BlueZ would offload the patterns to the controller to reduce power consumption. */ SupportedFeatures []string /* SupportedMonitorTypes This lists the supported types of advertisement monitors. An application should check this before instantiate and expose an object of org.bluez.AdvertisementMonitor1. Possible values for monitor types: "or_patterns" Patterns with logic OR applied. With this type, property "Patterns" must exist and has at least one pattern. */ SupportedMonitorTypes []string } //Lock access to properties func (p *AdvertisementMonitorManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *AdvertisementMonitorManager1Properties) Unlock() { p.lock.Unlock() } // GetSupportedFeatures get SupportedFeatures value func (a *AdvertisementMonitorManager1) GetSupportedFeatures() ([]string, error) { v, err := a.GetProperty("SupportedFeatures") if err != nil { return []string{}, err } return v.Value().([]string), nil } // GetSupportedMonitorTypes get SupportedMonitorTypes value func (a *AdvertisementMonitorManager1) GetSupportedMonitorTypes() ([]string, error) { v, err := a.GetProperty("SupportedMonitorTypes") if err != nil { return []string{}, err } return v.Value().([]string), nil } // Close the connection func (a *AdvertisementMonitorManager1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return AdvertisementMonitorManager1 object path func (a *AdvertisementMonitorManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return AdvertisementMonitorManager1 dbus client func (a *AdvertisementMonitorManager1) Client() *bluez.Client { return a.client } // Interface return AdvertisementMonitorManager1 interface func (a *AdvertisementMonitorManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *AdvertisementMonitorManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a AdvertisementMonitorManager1Properties to map func (a *AdvertisementMonitorManager1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an AdvertisementMonitorManager1Properties func (a *AdvertisementMonitorManager1Properties) FromMap(props map[string]interface{}) (*AdvertisementMonitorManager1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an AdvertisementMonitorManager1Properties func (a *AdvertisementMonitorManager1Properties) FromDBusMap(props map[string]dbus.Variant) (*AdvertisementMonitorManager1Properties, error) { s := new(AdvertisementMonitorManager1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *AdvertisementMonitorManager1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *AdvertisementMonitorManager1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *AdvertisementMonitorManager1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *AdvertisementMonitorManager1) GetProperties() (*AdvertisementMonitorManager1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *AdvertisementMonitorManager1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *AdvertisementMonitorManager1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *AdvertisementMonitorManager1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *AdvertisementMonitorManager1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *AdvertisementMonitorManager1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *AdvertisementMonitorManager1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* RegisterMonitor This registers the root path of a hierarchy of advertisement monitors. The application object path together with the D-Bus system bus connection ID define the identification of the application registering advertisement monitors. Once a root path is registered by a client via this method, the client can freely expose/unexpose advertisement monitors without re-registering the root path again. After use, the client should call UnregisterMonitor() method to invalidate the advertisement monitors. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists org.bluez.Error.Failed */ func (a *AdvertisementMonitorManager1) RegisterMonitor(application dbus.ObjectPath) error { return a.client.Call("RegisterMonitor", 0, application).Store() } /* UnregisterMonitor This unregisters a hierarchy of advertisement monitors that has been previously registered. The object path parameter must match the same value that has been used on registration. Upon unregistration, the advertisement monitor(s) should expect to receive Release() method as the signal that the advertisement monitor(s) has been deactivated. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.DoesNotExist */ func (a *AdvertisementMonitorManager1) UnregisterMonitor(application dbus.ObjectPath) error { return a.client.Call("UnregisterMonitor", 0, application).Store() } go-bluetooth-bluez-5.60/bluez/profile/advertisement_monitor/gen_advertisement_monitor.go000066400000000000000000000012411420407601400321720ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Advertisement Monitor API Description [advertisement-monitor-api.txt] This API allows an client to specify a job of monitoring advertisements by registering the root of hierarchy and then exposing advertisement monitors under the root with filtering conditions, thresholds of RSSI and timers of RSSI thresholds. Once a monitoring job is activated by BlueZ, the client can expect to get notified on the targeted advertisements no matter if there is an ongoing discovery session (a discovery session is started/stopped with methods in org.bluez.Adapter1 interface). */ package advertisement_monitor go-bluetooth-bluez-5.60/bluez/profile/advertising/000077500000000000000000000000001420407601400222715ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/advertising/advertising.go000066400000000000000000000023701420407601400251410ustar00rootroot00000000000000package advertising const ( SecondaryChannel1M = "1M" SecondaryChannel2M = "2M" SecondaryChannelCoded = "Coded" ) // "tx-power" // "appearance" // "local-name" const ( SupportedIncludesTxPower = "tx-power" SupportedIncludesAppearance = "appearance" SupportedIncludesLocalName = "local-name" ) const ( AdvertisementTypeBroadcast = "broadcast" AdvertisementTypePeripheral = "peripheral" ) func (a *LEAdvertisement1Properties) AddServiceUUID(uuids ...string) { if a.ServiceUUIDs == nil { a.ServiceUUIDs = make([]string, 0) } for _, uuid := range uuids { for _, uuid1 := range a.ServiceUUIDs { if uuid1 == uuid { continue } } a.ServiceUUIDs = append(a.ServiceUUIDs, uuid) } } func (a *LEAdvertisement1Properties) AddData(code byte, data []uint8) { if a.Data == nil { a.Data = make(map[byte]interface{}) } a.Data[code] = data } func (a *LEAdvertisement1Properties) AddServiceData(code string, data []uint8) { if a.ServiceData == nil { a.ServiceData = make(map[string]interface{}) } a.ServiceData[code] = data } func (a *LEAdvertisement1Properties) AddManifacturerData(code uint16, data []uint8) { if a.ManufacturerData == nil { a.ManufacturerData = make(map[uint16]interface{}) } a.ManufacturerData[code] = data } go-bluetooth-bluez-5.60/bluez/profile/advertising/gen_LEAdvertisement1.go000066400000000000000000000372331420407601400265750ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package advertising import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var LEAdvertisement1Interface = "org.bluez.LEAdvertisement1" // NewLEAdvertisement1 create a new instance of LEAdvertisement1 // // Args: // - objectPath: freely definable func NewLEAdvertisement1(objectPath dbus.ObjectPath) (*LEAdvertisement1, error) { a := new(LEAdvertisement1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: LEAdvertisement1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(LEAdvertisement1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* LEAdvertisement1 LE Advertisement Data hierarchy Specifies the Advertisement Data to be broadcast and some advertising parameters. Properties which are not present will not be included in the data. Required advertisement data types will always be included. All UUIDs are 128-bit versions in the API, and 16 or 32-bit versions of the same UUID will be used in the advertising data as appropriate. */ type LEAdvertisement1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *LEAdvertisement1Properties watchPropertiesChannel chan *dbus.Signal } // LEAdvertisement1Properties contains the exposed properties of an interface type LEAdvertisement1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Appearance Appearance to be used in the advertising report. Possible values: as found on GAP Service. */ Appearance uint16 /* Data Advertising Type to include in the Advertising Data. Key is the advertising type and value is the data as byte array. Note: Types already handled by other properties shall not be used. Possible values: ... Example: 0x26 0x01 0x01... */ Data map[byte]interface{} /* Discoverable Advertise as general discoverable. When present this will override adapter Discoverable property. Note: This property shall not be set when Type is set to broadcast. */ Discoverable bool /* DiscoverableTimeout The discoverable timeout in seconds. A value of zero means that the timeout is disabled and it will stay in discoverable/limited mode forever. Note: This property shall not be set when Type is set to broadcast. */ DiscoverableTimeout uint16 /* Duration Duration of the advertisement in seconds. If there are other applications advertising no duration is set the default is 2 seconds. */ Duration uint16 /* Includes List of features to be included in the advertising packet. Possible values: as found on LEAdvertisingManager.SupportedIncludes */ Includes []string /* LocalName Local name to be used in the advertising report. If the string is too big to fit into the packet it will be truncated. If this property is available 'local-name' cannot be present in the Includes. */ LocalName string /* ManufacturerData Manufactuer Data fields to include in the Advertising Data. Keys are the Manufacturer ID to associate with the data. */ ManufacturerData map[uint16]interface{} /* MaxInterval Maximum advertising interval to be used by the advertising set, in milliseconds. Acceptable values are in the range [20ms, 10,485s]. If the provided MinInterval is larger than the provided MaxInterval, the registration will return failure. */ MaxInterval uint32 /* MinInterval Minimum advertising interval to be used by the advertising set, in milliseconds. Acceptable values are in the range [20ms, 10,485s]. If the provided MinInterval is larger than the provided MaxInterval, the registration will return failure. */ MinInterval uint32 /* SecondaryChannel Secondary channel to be used. Primary channel is always set to "1M" except when "Coded" is set. Possible value: "1M" (default) "2M" "Coded" */ SecondaryChannel string `dbus:"omitEmpty"` /* ServiceData Service Data elements to include. The keys are the UUID to associate with the data. */ ServiceData map[string]interface{} /* ServiceUUIDs List of UUIDs to include in the "Service UUID" field of the Advertising Data. */ ServiceUUIDs []string /* SolicitUUIDs Array of UUIDs to include in "Service Solicitation" Advertisement Data. */ SolicitUUIDs []string /* Timeout Timeout of the advertisement in seconds. This defines the lifetime of the advertisement. */ Timeout uint16 /* TxPower Requested transmission power of this advertising set. The provided value is used only if the "CanSetTxPower" feature is enabled on the Advertising Manager. The provided value must be in range [-127 to +20], where units are in dBm. */ TxPower int16 /* Type Determines the type of advertising packet requested. Possible values: "broadcast" or "peripheral" */ Type string } //Lock access to properties func (p *LEAdvertisement1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *LEAdvertisement1Properties) Unlock() { p.lock.Unlock() } // SetAppearance set Appearance value func (a *LEAdvertisement1) SetAppearance(v uint16) error { return a.SetProperty("Appearance", v) } // GetAppearance get Appearance value func (a *LEAdvertisement1) GetAppearance() (uint16, error) { v, err := a.GetProperty("Appearance") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetData set Data value func (a *LEAdvertisement1) SetData(v map[string]interface{}) error { return a.SetProperty("Data", v) } // GetData get Data value func (a *LEAdvertisement1) GetData() (map[string]interface{}, error) { v, err := a.GetProperty("Data") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetDiscoverable set Discoverable value func (a *LEAdvertisement1) SetDiscoverable(v bool) error { return a.SetProperty("Discoverable", v) } // GetDiscoverable get Discoverable value func (a *LEAdvertisement1) GetDiscoverable() (bool, error) { v, err := a.GetProperty("Discoverable") if err != nil { return false, err } return v.Value().(bool), nil } // SetDiscoverableTimeout set DiscoverableTimeout value func (a *LEAdvertisement1) SetDiscoverableTimeout(v uint16) error { return a.SetProperty("DiscoverableTimeout", v) } // GetDiscoverableTimeout get DiscoverableTimeout value func (a *LEAdvertisement1) GetDiscoverableTimeout() (uint16, error) { v, err := a.GetProperty("DiscoverableTimeout") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetDuration set Duration value func (a *LEAdvertisement1) SetDuration(v uint16) error { return a.SetProperty("Duration", v) } // GetDuration get Duration value func (a *LEAdvertisement1) GetDuration() (uint16, error) { v, err := a.GetProperty("Duration") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetIncludes set Includes value func (a *LEAdvertisement1) SetIncludes(v []string) error { return a.SetProperty("Includes", v) } // GetIncludes get Includes value func (a *LEAdvertisement1) GetIncludes() ([]string, error) { v, err := a.GetProperty("Includes") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetLocalName set LocalName value func (a *LEAdvertisement1) SetLocalName(v string) error { return a.SetProperty("LocalName", v) } // GetLocalName get LocalName value func (a *LEAdvertisement1) GetLocalName() (string, error) { v, err := a.GetProperty("LocalName") if err != nil { return "", err } return v.Value().(string), nil } // SetManufacturerData set ManufacturerData value func (a *LEAdvertisement1) SetManufacturerData(v map[string]interface{}) error { return a.SetProperty("ManufacturerData", v) } // GetManufacturerData get ManufacturerData value func (a *LEAdvertisement1) GetManufacturerData() (map[string]interface{}, error) { v, err := a.GetProperty("ManufacturerData") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetMaxInterval set MaxInterval value func (a *LEAdvertisement1) SetMaxInterval(v uint32) error { return a.SetProperty("MaxInterval", v) } // GetMaxInterval get MaxInterval value func (a *LEAdvertisement1) GetMaxInterval() (uint32, error) { v, err := a.GetProperty("MaxInterval") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetMinInterval set MinInterval value func (a *LEAdvertisement1) SetMinInterval(v uint32) error { return a.SetProperty("MinInterval", v) } // GetMinInterval get MinInterval value func (a *LEAdvertisement1) GetMinInterval() (uint32, error) { v, err := a.GetProperty("MinInterval") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetSecondaryChannel set SecondaryChannel value func (a *LEAdvertisement1) SetSecondaryChannel(v string) error { return a.SetProperty("SecondaryChannel", v) } // GetSecondaryChannel get SecondaryChannel value func (a *LEAdvertisement1) GetSecondaryChannel() (string, error) { v, err := a.GetProperty("SecondaryChannel") if err != nil { return "", err } return v.Value().(string), nil } // SetServiceData set ServiceData value func (a *LEAdvertisement1) SetServiceData(v map[string]interface{}) error { return a.SetProperty("ServiceData", v) } // GetServiceData get ServiceData value func (a *LEAdvertisement1) GetServiceData() (map[string]interface{}, error) { v, err := a.GetProperty("ServiceData") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetServiceUUIDs set ServiceUUIDs value func (a *LEAdvertisement1) SetServiceUUIDs(v []string) error { return a.SetProperty("ServiceUUIDs", v) } // GetServiceUUIDs get ServiceUUIDs value func (a *LEAdvertisement1) GetServiceUUIDs() ([]string, error) { v, err := a.GetProperty("ServiceUUIDs") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetSolicitUUIDs set SolicitUUIDs value func (a *LEAdvertisement1) SetSolicitUUIDs(v []string) error { return a.SetProperty("SolicitUUIDs", v) } // GetSolicitUUIDs get SolicitUUIDs value func (a *LEAdvertisement1) GetSolicitUUIDs() ([]string, error) { v, err := a.GetProperty("SolicitUUIDs") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetTimeout set Timeout value func (a *LEAdvertisement1) SetTimeout(v uint16) error { return a.SetProperty("Timeout", v) } // GetTimeout get Timeout value func (a *LEAdvertisement1) GetTimeout() (uint16, error) { v, err := a.GetProperty("Timeout") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetTxPower set TxPower value func (a *LEAdvertisement1) SetTxPower(v int16) error { return a.SetProperty("TxPower", v) } // GetTxPower get TxPower value func (a *LEAdvertisement1) GetTxPower() (int16, error) { v, err := a.GetProperty("TxPower") if err != nil { return int16(0), err } return v.Value().(int16), nil } // SetType set Type value func (a *LEAdvertisement1) SetType(v string) error { return a.SetProperty("Type", v) } // GetType get Type value func (a *LEAdvertisement1) GetType() (string, error) { v, err := a.GetProperty("Type") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *LEAdvertisement1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return LEAdvertisement1 object path func (a *LEAdvertisement1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return LEAdvertisement1 dbus client func (a *LEAdvertisement1) Client() *bluez.Client { return a.client } // Interface return LEAdvertisement1 interface func (a *LEAdvertisement1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *LEAdvertisement1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a LEAdvertisement1Properties to map func (a *LEAdvertisement1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an LEAdvertisement1Properties func (a *LEAdvertisement1Properties) FromMap(props map[string]interface{}) (*LEAdvertisement1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an LEAdvertisement1Properties func (a *LEAdvertisement1Properties) FromDBusMap(props map[string]dbus.Variant) (*LEAdvertisement1Properties, error) { s := new(LEAdvertisement1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *LEAdvertisement1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *LEAdvertisement1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *LEAdvertisement1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *LEAdvertisement1) GetProperties() (*LEAdvertisement1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *LEAdvertisement1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *LEAdvertisement1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *LEAdvertisement1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *LEAdvertisement1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *LEAdvertisement1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *LEAdvertisement1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Release This method gets called when the service daemon removes the Advertisement. A client can use it to do cleanup tasks. There is no need to call UnregisterAdvertisement because when this method gets called it has already been unregistered. */ func (a *LEAdvertisement1) Release() error { return a.client.Call("Release", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/advertising/gen_LEAdvertisingManager1.go000066400000000000000000000324671420407601400275410ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package advertising import ( "fmt" "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var LEAdvertisingManager1Interface = "org.bluez.LEAdvertisingManager1" // NewLEAdvertisingManager1 create a new instance of LEAdvertisingManager1 // // Args: // - objectPath: /org/bluez/{hci0,hci1,...} func NewLEAdvertisingManager1(objectPath dbus.ObjectPath) (*LEAdvertisingManager1, error) { a := new(LEAdvertisingManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: LEAdvertisingManager1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(LEAdvertisingManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } // NewLEAdvertisingManager1FromAdapterID create a new instance of LEAdvertisingManager1 // adapterID: ID of an adapter eg. hci0 func NewLEAdvertisingManager1FromAdapterID(adapterID string) (*LEAdvertisingManager1, error) { a := new(LEAdvertisingManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: LEAdvertisingManager1Interface, Path: dbus.ObjectPath(fmt.Sprintf("/org/bluez/%s", adapterID)), Bus: bluez.SystemBus, }, ) a.Properties = new(LEAdvertisingManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* LEAdvertisingManager1 LE Advertising Manager hierarchy The Advertising Manager allows external applications to register Advertisement Data which should be broadcast to devices. Advertisement Data elements must follow the API for LE Advertisement Data described above. */ type LEAdvertisingManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *LEAdvertisingManager1Properties watchPropertiesChannel chan *dbus.Signal } // LEAdvertisingManager1Properties contains the exposed properties of an interface type LEAdvertisingManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* ActiveInstances Number of active advertising instances. */ ActiveInstances byte /* MaxAdvLen Max advertising data length */ MaxAdvLen byte /* MaxScnRspLen Max advertising scan response length */ MaxScnRspLen byte /* MaxTxPower Max advertising tx power (dBm) */ MaxTxPower int16 /* MinTxPower Min advertising tx power (dBm) */ MinTxPower int16 /* SupportedCapabilities Enumerates Advertising-related controller capabilities useful to the client. Possible Values: */ SupportedCapabilities map[string]interface{} /* SupportedFeatures List of supported platform features. If no features are available on the platform, the SupportedFeatures array will be empty. Possible values: "CanSetTxPower" Indicates whether platform can specify tx power on each advertising instance. "HardwareOffload" Indicates whether multiple advertising will be offloaded to the controller. */ SupportedFeatures []string /* SupportedIncludes List of supported system includes. Possible values: "tx-power" "appearance" "local-name" */ SupportedIncludes []string /* SupportedInstances Number of available advertising instances. */ SupportedInstances byte /* SupportedSecondaryChannels List of supported Secondary channels. Secondary channels can be used to advertise with the corresponding PHY. Possible values: "1M" "2M" "Coded" */ SupportedSecondaryChannels []string } //Lock access to properties func (p *LEAdvertisingManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *LEAdvertisingManager1Properties) Unlock() { p.lock.Unlock() } // SetActiveInstances set ActiveInstances value func (a *LEAdvertisingManager1) SetActiveInstances(v byte) error { return a.SetProperty("ActiveInstances", v) } // GetActiveInstances get ActiveInstances value func (a *LEAdvertisingManager1) GetActiveInstances() (byte, error) { v, err := a.GetProperty("ActiveInstances") if err != nil { return byte(0), err } return v.Value().(byte), nil } // SetMaxAdvLen set MaxAdvLen value func (a *LEAdvertisingManager1) SetMaxAdvLen(v byte) error { return a.SetProperty("MaxAdvLen", v) } // GetMaxAdvLen get MaxAdvLen value func (a *LEAdvertisingManager1) GetMaxAdvLen() (byte, error) { v, err := a.GetProperty("MaxAdvLen") if err != nil { return byte(0), err } return v.Value().(byte), nil } // SetMaxScnRspLen set MaxScnRspLen value func (a *LEAdvertisingManager1) SetMaxScnRspLen(v byte) error { return a.SetProperty("MaxScnRspLen", v) } // GetMaxScnRspLen get MaxScnRspLen value func (a *LEAdvertisingManager1) GetMaxScnRspLen() (byte, error) { v, err := a.GetProperty("MaxScnRspLen") if err != nil { return byte(0), err } return v.Value().(byte), nil } // SetMaxTxPower set MaxTxPower value func (a *LEAdvertisingManager1) SetMaxTxPower(v int16) error { return a.SetProperty("MaxTxPower", v) } // GetMaxTxPower get MaxTxPower value func (a *LEAdvertisingManager1) GetMaxTxPower() (int16, error) { v, err := a.GetProperty("MaxTxPower") if err != nil { return int16(0), err } return v.Value().(int16), nil } // SetMinTxPower set MinTxPower value func (a *LEAdvertisingManager1) SetMinTxPower(v int16) error { return a.SetProperty("MinTxPower", v) } // GetMinTxPower get MinTxPower value func (a *LEAdvertisingManager1) GetMinTxPower() (int16, error) { v, err := a.GetProperty("MinTxPower") if err != nil { return int16(0), err } return v.Value().(int16), nil } // SetSupportedCapabilities set SupportedCapabilities value func (a *LEAdvertisingManager1) SetSupportedCapabilities(v map[string]interface{}) error { return a.SetProperty("SupportedCapabilities", v) } // GetSupportedCapabilities get SupportedCapabilities value func (a *LEAdvertisingManager1) GetSupportedCapabilities() (map[string]interface{}, error) { v, err := a.GetProperty("SupportedCapabilities") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetSupportedFeatures set SupportedFeatures value func (a *LEAdvertisingManager1) SetSupportedFeatures(v []string) error { return a.SetProperty("SupportedFeatures", v) } // GetSupportedFeatures get SupportedFeatures value func (a *LEAdvertisingManager1) GetSupportedFeatures() ([]string, error) { v, err := a.GetProperty("SupportedFeatures") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetSupportedIncludes set SupportedIncludes value func (a *LEAdvertisingManager1) SetSupportedIncludes(v []string) error { return a.SetProperty("SupportedIncludes", v) } // GetSupportedIncludes get SupportedIncludes value func (a *LEAdvertisingManager1) GetSupportedIncludes() ([]string, error) { v, err := a.GetProperty("SupportedIncludes") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetSupportedInstances set SupportedInstances value func (a *LEAdvertisingManager1) SetSupportedInstances(v byte) error { return a.SetProperty("SupportedInstances", v) } // GetSupportedInstances get SupportedInstances value func (a *LEAdvertisingManager1) GetSupportedInstances() (byte, error) { v, err := a.GetProperty("SupportedInstances") if err != nil { return byte(0), err } return v.Value().(byte), nil } // SetSupportedSecondaryChannels set SupportedSecondaryChannels value func (a *LEAdvertisingManager1) SetSupportedSecondaryChannels(v []string) error { return a.SetProperty("SupportedSecondaryChannels", v) } // GetSupportedSecondaryChannels get SupportedSecondaryChannels value func (a *LEAdvertisingManager1) GetSupportedSecondaryChannels() ([]string, error) { v, err := a.GetProperty("SupportedSecondaryChannels") if err != nil { return []string{}, err } return v.Value().([]string), nil } // Close the connection func (a *LEAdvertisingManager1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return LEAdvertisingManager1 object path func (a *LEAdvertisingManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return LEAdvertisingManager1 dbus client func (a *LEAdvertisingManager1) Client() *bluez.Client { return a.client } // Interface return LEAdvertisingManager1 interface func (a *LEAdvertisingManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *LEAdvertisingManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a LEAdvertisingManager1Properties to map func (a *LEAdvertisingManager1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an LEAdvertisingManager1Properties func (a *LEAdvertisingManager1Properties) FromMap(props map[string]interface{}) (*LEAdvertisingManager1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an LEAdvertisingManager1Properties func (a *LEAdvertisingManager1Properties) FromDBusMap(props map[string]dbus.Variant) (*LEAdvertisingManager1Properties, error) { s := new(LEAdvertisingManager1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *LEAdvertisingManager1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *LEAdvertisingManager1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *LEAdvertisingManager1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *LEAdvertisingManager1) GetProperties() (*LEAdvertisingManager1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *LEAdvertisingManager1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *LEAdvertisingManager1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *LEAdvertisingManager1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *LEAdvertisingManager1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *LEAdvertisingManager1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *LEAdvertisingManager1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* RegisterAdvertisement Registers an advertisement object to be sent over the LE Advertising channel. The service must be exported under interface LEAdvertisement1. InvalidArguments error indicates that the object has invalid or conflicting properties. InvalidLength error indicates that the data provided generates a data packet which is too long. The properties of this object are parsed when it is registered, and any changes are ignored. If the same object is registered twice it will result in an AlreadyExists error. If the maximum number of advertisement instances is reached it will result in NotPermitted error. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists org.bluez.Error.InvalidLength org.bluez.Error.NotPermitted */ func (a *LEAdvertisingManager1) RegisterAdvertisement(advertisement dbus.ObjectPath, options map[string]interface{}) error { return a.client.Call("RegisterAdvertisement", 0, advertisement, options).Store() } /* UnregisterAdvertisement This unregisters an advertisement that has been previously registered. The object path parameter must match the same value that has been used on registration. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.DoesNotExist */ func (a *LEAdvertisingManager1) UnregisterAdvertisement(advertisement dbus.ObjectPath) error { return a.client.Call("UnregisterAdvertisement", 0, advertisement).Store() } go-bluetooth-bluez-5.60/bluez/profile/advertising/gen_advertising.go000066400000000000000000000013521420407601400257710ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus LE Advertising API Description [advertising-api.txt] Advertising packets are structured data which is broadcast on the LE Advertising channels and available for all devices in range. Because of the limited space available in LE Advertising packets (31 bytes), each packet's contents must be carefully controlled. BlueZ acts as a store for the Advertisement Data which is meant to be sent. It constructs the correct Advertisement Data from the structured data and configured the kernel to send the correct advertisement. Advertisement Data objects are registered freely and then referenced by BlueZ when constructing the data sent to the kernel. */ package advertising go-bluetooth-bluez-5.60/bluez/profile/agent/000077500000000000000000000000001420407601400210505ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/agent/agent.go000066400000000000000000000077231420407601400225060ustar00rootroot00000000000000package agent import ( "fmt" "strings" "github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5/introspect" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/adapter" log "github.com/sirupsen/logrus" ) //All agent capabilities const ( CapDisplayOnly = "DisplayOnly" CapDisplayYesNo = "DisplayYesNo" CapKeyboardOnly = "KeyboardOnly" CapNoInputNoOutput = "NoInputNoOutput" CapKeyboardDisplay = "KeyboardDisplay" ) type Agent1Client interface { Release() *dbus.Error // Callback doesn't trigger on unregister RequestPinCode(device dbus.ObjectPath) (pincode string, err *dbus.Error) // Triggers for pairing when SSP is off and cap != CAP_NO_INPUT_NO_OUTPUT DisplayPinCode(device dbus.ObjectPath, pincode string) *dbus.Error RequestPasskey(device dbus.ObjectPath) (passkey uint32, err *dbus.Error) // SSP on, toolz.AGENT_CAP_KEYBOARD_ONLY DisplayPasskey(device dbus.ObjectPath, passkey uint32, entered uint16) *dbus.Error RequestConfirmation(device dbus.ObjectPath, passkey uint32) *dbus.Error RequestAuthorization(device dbus.ObjectPath) *dbus.Error AuthorizeService(device dbus.ObjectPath, uuid string) *dbus.Error Cancel() *dbus.Error Path() dbus.ObjectPath Interface() string } // SetTrusted lookup for a device by object path and set it to trusted func SetTrusted(adapterID string, devicePath dbus.ObjectPath) error { log.Tracef("Trust device %s on %s", devicePath, adapterID) a, err := adapter.GetAdapter(adapterID) if err != nil { return err } devices, err := a.GetDevices() if err != nil { return err } path := string(devicePath) for _, dev := range devices { if strings.Contains(string(dev.Path()), path) { log.Tracef("SetTrusted: Trust device at %s", path) err := dev.SetTrusted(true) if err != nil { return fmt.Errorf("SetTrusted error: %s", err) } log.Tracef("SetTrusted: OK") return nil } } return fmt.Errorf("Cannot trust device %s, not found", path) } // RemoveAgent remove an Agent1 implementation from AgentManager1 func RemoveAgent(ag Agent1Client) error { am, err := NewAgentManager1() if err != nil { return fmt.Errorf("NewAgentManager1: %s", err) } // Register the exported interface as application agent via AgenManager API err = am.UnregisterAgent(ag.Path()) if err != nil { return fmt.Errorf("UnregisterAgent %s: %s", ag.Path(), err) } return nil } // ExposeAgent expose an Agent1 implementation to DBus and set as default agent func ExposeAgent(conn *dbus.Conn, ag Agent1Client, caps string, setAsDefaultAgent bool) error { // Register agent am, err := NewAgentManager1() if err != nil { return fmt.Errorf("NewAgentManager1: %s", err) } // Export the Go interface to DBus err = exportAgent(conn, ag) if err != nil { return err } // Register the exported interface as application agent via AgenManager API err = am.RegisterAgent(ag.Path(), caps) if err != nil { return fmt.Errorf("RegisterAgent %s: %s", ag.Path(), err) } if setAsDefaultAgent { // Set the new application agent as Default Agent err = am.RequestDefaultAgent(ag.Path()) if err != nil { return err } } return nil } //ExportAgent exports the xml of a go agent to dbus func exportAgent(conn *dbus.Conn, ag Agent1Client) error { log.Tracef("Exposing Agent1 at %s", ag.Path()) //Export the given agent to the given path as interface "org.bluez.Agent1" err := conn.Export(ag, ag.Path(), ag.Interface()) if err != nil { return err } // Create Introspectable for the given agent instance node := &introspect.Node{ Interfaces: []introspect.Interface{ // Introspect introspect.IntrospectData, // Properties // prop.IntrospectData, // org.bluez.Agent1 { Name: ag.Interface(), Methods: introspect.Methods(ag), }, }, } // Export Introspectable for the given agent instance err = conn.Export(introspect.NewIntrospectable(node), ag.Path(), bluez.Introspectable) if err != nil { return err } return nil } go-bluetooth-bluez-5.60/bluez/profile/agent/agent_simple.go000066400000000000000000000076201420407601400240530ustar00rootroot00000000000000package agent import ( "fmt" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez/profile/adapter" log "github.com/sirupsen/logrus" ) var agentInstances = 0 const AgentBasePath = "/agent/simple%d" const SimpleAgentPinCode = "0000" const SimpleAgentPassKey uint32 = 1024 func NextAgentPath() dbus.ObjectPath { p := dbus.ObjectPath(fmt.Sprintf(AgentBasePath, agentInstances)) agentInstances += 1 return p } // NewDefaultSimpleAgent return a SimpleAgent instance with default pincode and passcode func NewDefaultSimpleAgent() *SimpleAgent { ag := &SimpleAgent{ path: NextAgentPath(), passKey: SimpleAgentPassKey, pinCode: SimpleAgentPinCode, } return ag } // NewSimpleAgent return a SimpleAgent instance func NewSimpleAgent() *SimpleAgent { ag := &SimpleAgent{ path: NextAgentPath(), } return ag } // SimpleAgent implement interface Agent1Client type SimpleAgent struct { path dbus.ObjectPath pinCode string passKey uint32 } func (self *SimpleAgent) SetPassKey(passkey uint32) { self.passKey = passkey } func (self *SimpleAgent) SetPassCode(pinCode string) { self.pinCode = pinCode } func (self *SimpleAgent) PassKey() uint32 { return self.passKey } func (self *SimpleAgent) PassCode() string { return self.pinCode } func (self *SimpleAgent) Path() dbus.ObjectPath { return self.path } func (self *SimpleAgent) Interface() string { return Agent1Interface } func (self *SimpleAgent) Release() *dbus.Error { return nil } func (self *SimpleAgent) RequestPinCode(path dbus.ObjectPath) (string, *dbus.Error) { log.Debugf("SimpleAgent: RequestPinCode: %s", path) adapterID, err := adapter.ParseAdapterID(path) if err != nil { log.Warnf("SimpleAgent.RequestPinCode: Failed to load adapter %s", err) return "", dbus.MakeFailedError(err) } err = SetTrusted(adapterID, path) if err != nil { log.Errorf("SimpleAgent.RequestPinCode SetTrusted failed: %s", err) return "", dbus.MakeFailedError(err) } log.Debugf("SimpleAgent: Returning pin code: %s", self.pinCode) return self.pinCode, nil } func (self *SimpleAgent) DisplayPinCode(device dbus.ObjectPath, pincode string) *dbus.Error { log.Info(fmt.Sprintf("SimpleAgent: DisplayPinCode (%s, %s)", device, pincode)) return nil } func (self *SimpleAgent) RequestPasskey(path dbus.ObjectPath) (uint32, *dbus.Error) { adapterID, err := adapter.ParseAdapterID(path) if err != nil { log.Warnf("SimpleAgent.RequestPassKey: Failed to load adapter %s", err) return 0, dbus.MakeFailedError(err) } err = SetTrusted(adapterID, path) if err != nil { log.Errorf("SimpleAgent.RequestPassKey: SetTrusted %s", err) return 0, dbus.MakeFailedError(err) } log.Debugf("RequestPasskey: returning %d", self.passKey) return self.passKey, nil } func (self *SimpleAgent) DisplayPasskey(device dbus.ObjectPath, passkey uint32, entered uint16) *dbus.Error { log.Debugf("SimpleAgent: DisplayPasskey %s, %06d entered %d", device, passkey, entered) return nil } func (self *SimpleAgent) RequestConfirmation(path dbus.ObjectPath, passkey uint32) *dbus.Error { log.Debugf("SimpleAgent: RequestConfirmation (%s, %06d)", path, passkey) adapterID, err := adapter.ParseAdapterID(path) if err != nil { log.Warnf("SimpleAgent: Failed to load adapter %s", err) return dbus.MakeFailedError(err) } err = SetTrusted(adapterID, path) if err != nil { log.Warnf("Failed to set trust for %s: %s", path, err) return dbus.MakeFailedError(err) } log.Debug("SimpleAgent: RequestConfirmation OK") return nil } func (self *SimpleAgent) RequestAuthorization(device dbus.ObjectPath) *dbus.Error { log.Debugf("SimpleAgent: RequestAuthorization (%s)", device) return nil } func (self *SimpleAgent) AuthorizeService(device dbus.ObjectPath, uuid string) *dbus.Error { log.Debugf("SimpleAgent: AuthorizeService (%s, %s)", device, uuid) // directly authorized return nil } func (self *SimpleAgent) Cancel() *dbus.Error { log.Debugf("SimpleAgent: Cancel") return nil } go-bluetooth-bluez-5.60/bluez/profile/agent/gen_Agent1.go000066400000000000000000000157101420407601400233530ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package agent import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" ) var Agent1Interface = "org.bluez.Agent1" // NewAgent1 create a new instance of Agent1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewAgent1(servicePath string, objectPath dbus.ObjectPath) (*Agent1, error) { a := new(Agent1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: Agent1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) return a, nil } /* Agent1 Agent hierarchy */ type Agent1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Agent1Properties watchPropertiesChannel chan *dbus.Signal } // Agent1Properties contains the exposed properties of an interface type Agent1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Agent1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Agent1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Agent1) Close() { a.client.Disconnect() } // Path return Agent1 object path func (a *Agent1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Agent1 dbus client func (a *Agent1) Client() *bluez.Client { return a.client } // Interface return Agent1 interface func (a *Agent1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Agent1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } /* Release This method gets called when the service daemon unregisters the agent. An agent can use it to do cleanup tasks. There is no need to unregister the agent, because when this method gets called it has already been unregistered. */ func (a *Agent1) Release() error { return a.client.Call("Release", 0).Store() } /* RequestPinCode This method gets called when the service daemon needs to get the passkey for an authentication. The return value should be a string of 1-16 characters length. The string can be alphanumeric. Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Agent1) RequestPinCode(device dbus.ObjectPath) (string, error) { var val0 string err := a.client.Call("RequestPinCode", 0, device).Store(&val0) return val0, err } /* DisplayPinCode This method gets called when the service daemon needs to display a pincode for an authentication. An empty reply should be returned. When the pincode needs no longer to be displayed, the Cancel method of the agent will be called. This is used during the pairing process of keyboards that don't support Bluetooth 2.1 Secure Simple Pairing, in contrast to DisplayPasskey which is used for those that do. This method will only ever be called once since older keyboards do not support typing notification. Note that the PIN will always be a 6-digit number, zero-padded to 6 digits. This is for harmony with the later specification. Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Agent1) DisplayPinCode(device dbus.ObjectPath, pincode string) error { return a.client.Call("DisplayPinCode", 0, device, pincode).Store() } /* RequestPasskey This method gets called when the service daemon needs to get the passkey for an authentication. The return value should be a numeric value between 0-999999. Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Agent1) RequestPasskey(device dbus.ObjectPath) (uint32, error) { var val0 uint32 err := a.client.Call("RequestPasskey", 0, device).Store(&val0) return val0, err } /* DisplayPasskey This method gets called when the service daemon needs to display a passkey for an authentication. The entered parameter indicates the number of already typed keys on the remote side. An empty reply should be returned. When the passkey needs no longer to be displayed, the Cancel method of the agent will be called. During the pairing process this method might be called multiple times to update the entered value. Note that the passkey will always be a 6-digit number, so the display should be zero-padded at the start if the value contains less than 6 digits. */ func (a *Agent1) DisplayPasskey(device dbus.ObjectPath, passkey uint32, entered uint16) error { return a.client.Call("DisplayPasskey", 0, device, passkey, entered).Store() } /* RequestConfirmation This method gets called when the service daemon needs to confirm a passkey for an authentication. To confirm the value it should return an empty reply or an error in case the passkey is invalid. Note that the passkey will always be a 6-digit number, so the display should be zero-padded at the start if the value contains less than 6 digits. Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Agent1) RequestConfirmation(device dbus.ObjectPath, passkey uint32) error { return a.client.Call("RequestConfirmation", 0, device, passkey).Store() } /* RequestAuthorization This method gets called to request the user to authorize an incoming pairing attempt which would in other circumstances trigger the just-works model, or when the user plugged in a device that implements cable pairing. In the latter case, the device would not be connected to the adapter via Bluetooth yet. Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Agent1) RequestAuthorization(device dbus.ObjectPath) error { return a.client.Call("RequestAuthorization", 0, device).Store() } /* AuthorizeService This method gets called when the service daemon needs to authorize a connection/service request. Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Agent1) AuthorizeService(device dbus.ObjectPath, uuid string) error { return a.client.Call("AuthorizeService", 0, device, uuid).Store() } /* Cancel This method gets called to indicate that the agent request failed before a reply was returned. */ func (a *Agent1) Cancel() error { return a.client.Call("Cancel", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/agent/gen_AgentManager1.go000066400000000000000000000103561420407601400246470ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package agent import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" ) var AgentManager1Interface = "org.bluez.AgentManager1" // NewAgentManager1 create a new instance of AgentManager1 // // Args: func NewAgentManager1() (*AgentManager1, error) { a := new(AgentManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: AgentManager1Interface, Path: dbus.ObjectPath("/org/bluez"), Bus: bluez.SystemBus, }, ) return a, nil } /* AgentManager1 Agent Manager hierarchy */ type AgentManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *AgentManager1Properties watchPropertiesChannel chan *dbus.Signal } // AgentManager1Properties contains the exposed properties of an interface type AgentManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *AgentManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *AgentManager1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *AgentManager1) Close() { a.client.Disconnect() } // Path return AgentManager1 object path func (a *AgentManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return AgentManager1 dbus client func (a *AgentManager1) Client() *bluez.Client { return a.client } // Interface return AgentManager1 interface func (a *AgentManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *AgentManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } /* RegisterAgent This registers an agent handler. The object path defines the path of the agent that will be called when user input is needed. Every application can register its own agent and for all actions triggered by that application its agent is used. It is not required by an application to register an agent. If an application does chooses to not register an agent, the default agent is used. This is on most cases a good idea. Only application like a pairing wizard should register their own agent. An application can only register one agent. Multiple agents per application is not supported. The capability parameter can have the values "DisplayOnly", "DisplayYesNo", "KeyboardOnly", "NoInputNoOutput" and "KeyboardDisplay" which reflects the input and output capabilities of the agent. If an empty string is used it will fallback to "KeyboardDisplay". Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists */ func (a *AgentManager1) RegisterAgent(agent dbus.ObjectPath, capability string) error { return a.client.Call("RegisterAgent", 0, agent, capability).Store() } /* UnregisterAgent This unregisters the agent that has been previously registered. The object path parameter must match the same value that has been used on registration. Possible errors: org.bluez.Error.DoesNotExist */ func (a *AgentManager1) UnregisterAgent(agent dbus.ObjectPath) error { return a.client.Call("UnregisterAgent", 0, agent).Store() } /* RequestDefaultAgent This requests is to make the application agent the default agent. The application is required to register an agent. Special permission might be required to become the default agent. Possible errors: org.bluez.Error.DoesNotExist */ func (a *AgentManager1) RequestDefaultAgent(agent dbus.ObjectPath) error { return a.client.Call("RequestDefaultAgent", 0, agent).Store() } go-bluetooth-bluez-5.60/bluez/profile/agent/gen_agent.go000066400000000000000000000002021420407601400233200ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Agent API description [agent-api.txt] */ package agent go-bluetooth-bluez-5.60/bluez/profile/battery/000077500000000000000000000000001420407601400214245ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/battery/gen_Battery1.go000066400000000000000000000137731420407601400243120ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package battery import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Battery1Interface = "org.bluez.Battery1" // NewBattery1 create a new instance of Battery1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX func NewBattery1(objectPath dbus.ObjectPath) (*Battery1, error) { a := new(Battery1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Battery1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Battery1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Battery1 Battery hierarchy */ type Battery1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Battery1Properties watchPropertiesChannel chan *dbus.Signal } // Battery1Properties contains the exposed properties of an interface type Battery1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Percentage The percentage of battery left as an unsigned 8-bit integer. */ Percentage byte /* Source Describes where the battery information comes from This property is informational only and may be useful for debugging purposes. Providers from BatteryProvider1 may make use of this property to indicate where the battery report comes from (e.g. "HFP 1.7", "HID", or the profile UUID). */ Source string } //Lock access to properties func (p *Battery1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Battery1Properties) Unlock() { p.lock.Unlock() } // SetPercentage set Percentage value func (a *Battery1) SetPercentage(v byte) error { return a.SetProperty("Percentage", v) } // GetPercentage get Percentage value func (a *Battery1) GetPercentage() (byte, error) { v, err := a.GetProperty("Percentage") if err != nil { return byte(0), err } return v.Value().(byte), nil } // SetSource set Source value func (a *Battery1) SetSource(v string) error { return a.SetProperty("Source", v) } // GetSource get Source value func (a *Battery1) GetSource() (string, error) { v, err := a.GetProperty("Source") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *Battery1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Battery1 object path func (a *Battery1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Battery1 dbus client func (a *Battery1) Client() *bluez.Client { return a.client } // Interface return Battery1 interface func (a *Battery1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Battery1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Battery1Properties to map func (a *Battery1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Battery1Properties func (a *Battery1Properties) FromMap(props map[string]interface{}) (*Battery1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Battery1Properties func (a *Battery1Properties) FromDBusMap(props map[string]dbus.Variant) (*Battery1Properties, error) { s := new(Battery1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Battery1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Battery1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Battery1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Battery1) GetProperties() (*Battery1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Battery1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Battery1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Battery1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Battery1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Battery1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Battery1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } go-bluetooth-bluez-5.60/bluez/profile/battery/gen_BatteryProvider1.go000066400000000000000000000134571420407601400260240ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package battery import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var BatteryProvider1Interface = "org.bluez.BatteryProvider1" // NewBatteryProvider1 create a new instance of BatteryProvider1 // // Args: // - servicePath: // - objectPath: {provider_root}/{unique battery object path} func NewBatteryProvider1(servicePath string, objectPath dbus.ObjectPath) (*BatteryProvider1, error) { a := new(BatteryProvider1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: BatteryProvider1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(BatteryProvider1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* BatteryProvider1 Battery Provider hierarchy */ type BatteryProvider1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *BatteryProvider1Properties watchPropertiesChannel chan *dbus.Signal } // BatteryProvider1Properties contains the exposed properties of an interface type BatteryProvider1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Device The object path of the device that has this battery. */ Device dbus.ObjectPath } //Lock access to properties func (p *BatteryProvider1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *BatteryProvider1Properties) Unlock() { p.lock.Unlock() } // SetDevice set Device value func (a *BatteryProvider1) SetDevice(v dbus.ObjectPath) error { return a.SetProperty("Device", v) } // GetDevice get Device value func (a *BatteryProvider1) GetDevice() (dbus.ObjectPath, error) { v, err := a.GetProperty("Device") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // Close the connection func (a *BatteryProvider1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return BatteryProvider1 object path func (a *BatteryProvider1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return BatteryProvider1 dbus client func (a *BatteryProvider1) Client() *bluez.Client { return a.client } // Interface return BatteryProvider1 interface func (a *BatteryProvider1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *BatteryProvider1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a BatteryProvider1Properties to map func (a *BatteryProvider1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an BatteryProvider1Properties func (a *BatteryProvider1Properties) FromMap(props map[string]interface{}) (*BatteryProvider1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an BatteryProvider1Properties func (a *BatteryProvider1Properties) FromDBusMap(props map[string]dbus.Variant) (*BatteryProvider1Properties, error) { s := new(BatteryProvider1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *BatteryProvider1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *BatteryProvider1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *BatteryProvider1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *BatteryProvider1) GetProperties() (*BatteryProvider1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *BatteryProvider1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *BatteryProvider1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *BatteryProvider1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *BatteryProvider1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *BatteryProvider1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *BatteryProvider1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } go-bluetooth-bluez-5.60/bluez/profile/battery/gen_BatteryProviderManager1.go000066400000000000000000000154621420407601400273150ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package battery import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var BatteryProviderManager1Interface = "org.bluez.BatteryProviderManager1" // NewBatteryProviderManager1 create a new instance of BatteryProviderManager1 // // Args: // - objectPath: /org/bluez/{hci0,hci1,...} func NewBatteryProviderManager1(objectPath dbus.ObjectPath) (*BatteryProviderManager1, error) { a := new(BatteryProviderManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: BatteryProviderManager1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(BatteryProviderManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* BatteryProviderManager1 Battery Provider Manager hierarchy A battery provider starts by registering itself as a battery provider with the RegisterBatteryProvider method passing an object path as the provider ID. Then, it can start exposing org.bluez.BatteryProvider1 objects having the path starting with the given provider ID. It can also remove objects at any time. The objects and their properties exposed by battery providers will be reflected on org.bluez.Battery1 interface. BlueZ will stop monitoring these exposed and removed objects after UnregisterBatteryProvider is called for that provider ID. */ type BatteryProviderManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *BatteryProviderManager1Properties watchPropertiesChannel chan *dbus.Signal } // BatteryProviderManager1Properties contains the exposed properties of an interface type BatteryProviderManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *BatteryProviderManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *BatteryProviderManager1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *BatteryProviderManager1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return BatteryProviderManager1 object path func (a *BatteryProviderManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return BatteryProviderManager1 dbus client func (a *BatteryProviderManager1) Client() *bluez.Client { return a.client } // Interface return BatteryProviderManager1 interface func (a *BatteryProviderManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *BatteryProviderManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a BatteryProviderManager1Properties to map func (a *BatteryProviderManager1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an BatteryProviderManager1Properties func (a *BatteryProviderManager1Properties) FromMap(props map[string]interface{}) (*BatteryProviderManager1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an BatteryProviderManager1Properties func (a *BatteryProviderManager1Properties) FromDBusMap(props map[string]dbus.Variant) (*BatteryProviderManager1Properties, error) { s := new(BatteryProviderManager1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *BatteryProviderManager1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *BatteryProviderManager1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *BatteryProviderManager1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *BatteryProviderManager1) GetProperties() (*BatteryProviderManager1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *BatteryProviderManager1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *BatteryProviderManager1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *BatteryProviderManager1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *BatteryProviderManager1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *BatteryProviderManager1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *BatteryProviderManager1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* RegisterBatteryProvider This registers a battery provider. A registered battery provider can then expose objects with org.bluez.BatteryProvider1 interface described below. */ func (a *BatteryProviderManager1) RegisterBatteryProvider(provider dbus.ObjectPath) error { return a.client.Call("RegisterBatteryProvider", 0, provider).Store() } /* UnregisterBatteryProvider This unregisters a battery provider. After unregistration, the BatteryProvider1 objects provided by this client are ignored by BlueZ. */ func (a *BatteryProviderManager1) UnregisterBatteryProvider(provider dbus.ObjectPath) error { return a.client.Call("UnregisterBatteryProvider", 0, provider).Store() } go-bluetooth-bluez-5.60/bluez/profile/battery/gen_battery.go000066400000000000000000000002101420407601400242470ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Battery API description [battery-api.txt] */ package battery go-bluetooth-bluez-5.60/bluez/profile/device/000077500000000000000000000000001420407601400212115ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/device/device.go000066400000000000000000000105061420407601400230010ustar00rootroot00000000000000package device import ( "errors" "fmt" "strings" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) func NewDevice(adapterID string, address string) (*Device1, error) { path := fmt.Sprintf("%s/%s/dev_%s", bluez.OrgBluezPath, adapterID, strings.Replace(address, ":", "_", -1)) return NewDevice1(dbus.ObjectPath(path)) } // GetCharacteristicsList return device characteristics object path list func (d *Device1) GetCharacteristicsList() ([]dbus.ObjectPath, error) { var chars []dbus.ObjectPath om, err := bluez.GetObjectManager() if err != nil { return nil, err } list, err := om.GetManagedObjects() if err != nil { return nil, err } for path := range list { spath := string(path) // log.Debugf("%s=%s", string(d.Path()), spath) if !strings.HasPrefix(spath, string(d.Path())) { continue } charPos := strings.Index(spath, "char") if charPos == -1 { continue } if strings.Contains(spath[charPos:], "desc") { continue } chars = append(chars, path) } return chars, nil } // GetDescriptorList returns all descriptors func (d *Device1) GetDescriptorList() ([]dbus.ObjectPath, error) { var descr []dbus.ObjectPath om, err := bluez.GetObjectManager() if err != nil { return nil, err } list, err := om.GetManagedObjects() if err != nil { return nil, err } for path := range list { spath := string(path) if !strings.HasPrefix(spath, string(d.Path())) { continue } charPos := strings.Index(spath, "char") if charPos == -1 { continue } if strings.Contains(spath[charPos:], "desc") { continue } descr = append(descr, path) } return descr, nil } //GetDescriptors returns all descriptors for a given characteristic func (d *Device1) GetDescriptors(char *gatt.GattCharacteristic1) ([]*gatt.GattDescriptor1, error) { descrPaths, err := d.GetDescriptorList() if err != nil { return nil, err } descrFound := []*gatt.GattDescriptor1{} for _, path := range descrPaths { descr, err := gatt.NewGattDescriptor1(path) if err != nil { return nil, err } if char.Path() == descr.Properties.Characteristic { descrFound = append(descrFound, descr) } } if len(descrFound) == 0 { return nil, errors.New("descriptors not found") } return descrFound, nil } //GetCharacteristics return a list of characteristics func (d *Device1) GetCharacteristics() ([]*gatt.GattCharacteristic1, error) { list, err := d.GetCharacteristicsList() if err != nil { return nil, err } chars := []*gatt.GattCharacteristic1{} for _, path := range list { char, err := gatt.NewGattCharacteristic1(path) if err != nil { return nil, err } chars = append(chars, char) } return chars, nil } //GetAllServicesAndUUID return a list of uuid's with their corresponding services func (d *Device1) GetAllServicesAndUUID() ([]string, error) { list, err := d.GetCharacteristicsList() if err != nil { return nil, err } chars := map[dbus.ObjectPath]*gatt.GattCharacteristic1{} var deviceFound []string var uuidAndService string for _, path := range list { char, err := gatt.NewGattCharacteristic1(path) if err != nil { return nil, err } chars[path] = char props := chars[path].Properties cuuid := strings.ToUpper(props.UUID) service := string(props.Service) uuidAndService = fmt.Sprint(cuuid, ":", service) deviceFound = append(deviceFound, uuidAndService) } return deviceFound, nil } //GetCharByUUID return a GattService by its uuid, return nil if not found func (d *Device1) GetCharByUUID(uuid string) (*gatt.GattCharacteristic1, error) { devices, err := d.GetCharsByUUID(uuid) if len(devices) > 0 { return devices[0], err } return nil, err } // GetCharsByUUID returns all characteristics that match the given UUID. func (d *Device1) GetCharsByUUID(uuid string) ([]*gatt.GattCharacteristic1, error) { uuid = strings.ToUpper(uuid) list, err := d.GetCharacteristicsList() if err != nil { return nil, err } charsFound := []*gatt.GattCharacteristic1{} for _, path := range list { char, err := gatt.NewGattCharacteristic1(path) if err != nil { return nil, err } cuuid := strings.ToUpper(char.Properties.UUID) if cuuid == uuid { charsFound = append(charsFound, char) } } if len(charsFound) == 0 { return nil, errors.New("characteristic not found") } return charsFound, nil } go-bluetooth-bluez-5.60/bluez/profile/device/gen_Device1.go000066400000000000000000000506021420407601400236540ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package device import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Device1Interface = "org.bluez.Device1" // NewDevice1 create a new instance of Device1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX func NewDevice1(objectPath dbus.ObjectPath) (*Device1, error) { a := new(Device1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Device1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Device1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Device1 Device hierarchy */ type Device1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Device1Properties watchPropertiesChannel chan *dbus.Signal } // Device1Properties contains the exposed properties of an interface type Device1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Adapter The object path of the adapter the device belongs to. */ Adapter dbus.ObjectPath /* Address The Bluetooth device address of the remote device. */ Address string /* AddressType The Bluetooth device Address Type. For dual-mode and BR/EDR only devices this defaults to "public". Single mode LE devices may have either value. If remote device uses privacy than before pairing this represents address type used for connection and Identity Address after pairing. Possible values: "public" - Public address "random" - Random address */ AddressType string /* AdvertisingData The Advertising Data of the remote device. Keys are are 8 bits AD Type followed by data as byte array. Note: Only types considered safe to be handled by application are exposed. Possible values: ... Example: 0x26 0x01 0x01... */ AdvertisingData map[string]interface{} /* AdvertisingFlags The Advertising Data Flags of the remote device. */ AdvertisingFlags []byte /* Alias The name alias for the remote device. The alias can be used to have a different friendly name for the remote device. In case no alias is set, it will return the remote device name. Setting an empty string as alias will convert it back to the remote device name. When resetting the alias with an empty string, the property will default back to the remote name. */ Alias string /* Appearance External appearance of device, as found on GAP service. */ Appearance uint16 /* Blocked If set to true any incoming connections from the device will be immediately rejected. Any device drivers will also be removed and no new ones will be probed as long as the device is blocked. */ Blocked bool /* Class The Bluetooth class of device of the remote device. */ Class uint32 /* Connected Indicates if the remote device is currently connected. A PropertiesChanged signal indicate changes to this status. */ Connected bool /* Icon Proposed icon name according to the freedesktop.org icon naming specification. */ Icon string /* LegacyPairing Set to true if the device only supports the pre-2.1 pairing mechanism. This property is useful during device discovery to anticipate whether legacy or simple pairing will occur if pairing is initiated. Note that this property can exhibit false-positives in the case of Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry Response support. */ LegacyPairing bool /* ManufacturerData Manufacturer specific advertisement data. Keys are 16 bits Manufacturer ID followed by its byte array value. */ ManufacturerData map[uint16]interface{} /* Modalias Remote Device ID information in modalias format used by the kernel and udev. */ Modalias string /* Name The Bluetooth remote name. This value can not be changed. Use the Alias property instead. This value is only present for completeness. It is better to always use the Alias property when displaying the devices name. If the Alias property is unset, it will reflect this value which makes it more convenient. */ Name string /* Paired Indicates if the remote device is paired. */ Paired bool /* RSSI Received Signal Strength Indicator of the remote device (inquiry or advertising). */ RSSI int16 /* ServiceData Service advertisement data. Keys are the UUIDs in string format followed by its byte array value. */ ServiceData map[string]interface{} /* ServicesResolved Indicate whether or not service discovery has been resolved. */ ServicesResolved bool /* Trusted Indicates if the remote is seen as trusted. This setting can be changed by the application. */ Trusted bool /* TxPower Advertised transmitted power level (inquiry or advertising). */ TxPower int16 /* UUIDs List of 128-bit UUIDs that represents the available remote services. */ UUIDs []string /* WakeAllowed If set to true this device will be allowed to wake the host from system suspend. */ WakeAllowed bool } //Lock access to properties func (p *Device1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Device1Properties) Unlock() { p.lock.Unlock() } // SetAdapter set Adapter value func (a *Device1) SetAdapter(v dbus.ObjectPath) error { return a.SetProperty("Adapter", v) } // GetAdapter get Adapter value func (a *Device1) GetAdapter() (dbus.ObjectPath, error) { v, err := a.GetProperty("Adapter") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetAddress set Address value func (a *Device1) SetAddress(v string) error { return a.SetProperty("Address", v) } // GetAddress get Address value func (a *Device1) GetAddress() (string, error) { v, err := a.GetProperty("Address") if err != nil { return "", err } return v.Value().(string), nil } // SetAddressType set AddressType value func (a *Device1) SetAddressType(v string) error { return a.SetProperty("AddressType", v) } // GetAddressType get AddressType value func (a *Device1) GetAddressType() (string, error) { v, err := a.GetProperty("AddressType") if err != nil { return "", err } return v.Value().(string), nil } // SetAdvertisingData set AdvertisingData value func (a *Device1) SetAdvertisingData(v map[string]interface{}) error { return a.SetProperty("AdvertisingData", v) } // GetAdvertisingData get AdvertisingData value func (a *Device1) GetAdvertisingData() (map[string]interface{}, error) { v, err := a.GetProperty("AdvertisingData") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetAdvertisingFlags set AdvertisingFlags value func (a *Device1) SetAdvertisingFlags(v []byte) error { return a.SetProperty("AdvertisingFlags", v) } // GetAdvertisingFlags get AdvertisingFlags value func (a *Device1) GetAdvertisingFlags() ([]byte, error) { v, err := a.GetProperty("AdvertisingFlags") if err != nil { return []byte{}, err } return v.Value().([]byte), nil } // SetAlias set Alias value func (a *Device1) SetAlias(v string) error { return a.SetProperty("Alias", v) } // GetAlias get Alias value func (a *Device1) GetAlias() (string, error) { v, err := a.GetProperty("Alias") if err != nil { return "", err } return v.Value().(string), nil } // SetAppearance set Appearance value func (a *Device1) SetAppearance(v uint16) error { return a.SetProperty("Appearance", v) } // GetAppearance get Appearance value func (a *Device1) GetAppearance() (uint16, error) { v, err := a.GetProperty("Appearance") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetBlocked set Blocked value func (a *Device1) SetBlocked(v bool) error { return a.SetProperty("Blocked", v) } // GetBlocked get Blocked value func (a *Device1) GetBlocked() (bool, error) { v, err := a.GetProperty("Blocked") if err != nil { return false, err } return v.Value().(bool), nil } // SetClass set Class value func (a *Device1) SetClass(v uint32) error { return a.SetProperty("Class", v) } // GetClass get Class value func (a *Device1) GetClass() (uint32, error) { v, err := a.GetProperty("Class") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetConnected set Connected value func (a *Device1) SetConnected(v bool) error { return a.SetProperty("Connected", v) } // GetConnected get Connected value func (a *Device1) GetConnected() (bool, error) { v, err := a.GetProperty("Connected") if err != nil { return false, err } return v.Value().(bool), nil } // SetIcon set Icon value func (a *Device1) SetIcon(v string) error { return a.SetProperty("Icon", v) } // GetIcon get Icon value func (a *Device1) GetIcon() (string, error) { v, err := a.GetProperty("Icon") if err != nil { return "", err } return v.Value().(string), nil } // SetLegacyPairing set LegacyPairing value func (a *Device1) SetLegacyPairing(v bool) error { return a.SetProperty("LegacyPairing", v) } // GetLegacyPairing get LegacyPairing value func (a *Device1) GetLegacyPairing() (bool, error) { v, err := a.GetProperty("LegacyPairing") if err != nil { return false, err } return v.Value().(bool), nil } // SetManufacturerData set ManufacturerData value func (a *Device1) SetManufacturerData(v map[string]interface{}) error { return a.SetProperty("ManufacturerData", v) } // GetManufacturerData get ManufacturerData value func (a *Device1) GetManufacturerData() (map[string]interface{}, error) { v, err := a.GetProperty("ManufacturerData") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetModalias set Modalias value func (a *Device1) SetModalias(v string) error { return a.SetProperty("Modalias", v) } // GetModalias get Modalias value func (a *Device1) GetModalias() (string, error) { v, err := a.GetProperty("Modalias") if err != nil { return "", err } return v.Value().(string), nil } // SetName set Name value func (a *Device1) SetName(v string) error { return a.SetProperty("Name", v) } // GetName get Name value func (a *Device1) GetName() (string, error) { v, err := a.GetProperty("Name") if err != nil { return "", err } return v.Value().(string), nil } // SetPaired set Paired value func (a *Device1) SetPaired(v bool) error { return a.SetProperty("Paired", v) } // GetPaired get Paired value func (a *Device1) GetPaired() (bool, error) { v, err := a.GetProperty("Paired") if err != nil { return false, err } return v.Value().(bool), nil } // SetRSSI set RSSI value func (a *Device1) SetRSSI(v int16) error { return a.SetProperty("RSSI", v) } // GetRSSI get RSSI value func (a *Device1) GetRSSI() (int16, error) { v, err := a.GetProperty("RSSI") if err != nil { return int16(0), err } return v.Value().(int16), nil } // SetServiceData set ServiceData value func (a *Device1) SetServiceData(v map[string]interface{}) error { return a.SetProperty("ServiceData", v) } // GetServiceData get ServiceData value func (a *Device1) GetServiceData() (map[string]interface{}, error) { v, err := a.GetProperty("ServiceData") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetServicesResolved set ServicesResolved value func (a *Device1) SetServicesResolved(v bool) error { return a.SetProperty("ServicesResolved", v) } // GetServicesResolved get ServicesResolved value func (a *Device1) GetServicesResolved() (bool, error) { v, err := a.GetProperty("ServicesResolved") if err != nil { return false, err } return v.Value().(bool), nil } // SetTrusted set Trusted value func (a *Device1) SetTrusted(v bool) error { return a.SetProperty("Trusted", v) } // GetTrusted get Trusted value func (a *Device1) GetTrusted() (bool, error) { v, err := a.GetProperty("Trusted") if err != nil { return false, err } return v.Value().(bool), nil } // SetTxPower set TxPower value func (a *Device1) SetTxPower(v int16) error { return a.SetProperty("TxPower", v) } // GetTxPower get TxPower value func (a *Device1) GetTxPower() (int16, error) { v, err := a.GetProperty("TxPower") if err != nil { return int16(0), err } return v.Value().(int16), nil } // SetUUIDs set UUIDs value func (a *Device1) SetUUIDs(v []string) error { return a.SetProperty("UUIDs", v) } // GetUUIDs get UUIDs value func (a *Device1) GetUUIDs() ([]string, error) { v, err := a.GetProperty("UUIDs") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetWakeAllowed set WakeAllowed value func (a *Device1) SetWakeAllowed(v bool) error { return a.SetProperty("WakeAllowed", v) } // GetWakeAllowed get WakeAllowed value func (a *Device1) GetWakeAllowed() (bool, error) { v, err := a.GetProperty("WakeAllowed") if err != nil { return false, err } return v.Value().(bool), nil } // Close the connection func (a *Device1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Device1 object path func (a *Device1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Device1 dbus client func (a *Device1) Client() *bluez.Client { return a.client } // Interface return Device1 interface func (a *Device1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Device1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Device1Properties to map func (a *Device1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Device1Properties func (a *Device1Properties) FromMap(props map[string]interface{}) (*Device1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Device1Properties func (a *Device1Properties) FromDBusMap(props map[string]dbus.Variant) (*Device1Properties, error) { s := new(Device1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Device1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Device1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Device1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Device1) GetProperties() (*Device1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Device1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Device1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Device1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Device1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Device1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Device1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Connect This is a generic method to connect any profiles the remote device supports that can be connected to and have been flagged as auto-connectable on our side. If only subset of profiles is already connected it will try to connect currently disconnected ones. If at least one profile was connected successfully this method will indicate success. For dual-mode devices only one bearer is connected at time, the conditions are in the following order: 1. Connect the disconnected bearer if already connected. 2. Connect first the bonded bearer. If no bearers are bonded or both are skip and check latest seen bearer. 3. Connect last seen bearer, in case the timestamps are the same BR/EDR takes precedence. Possible errors: org.bluez.Error.NotReady org.bluez.Error.Failed org.bluez.Error.InProgress org.bluez.Error.AlreadyConnected */ func (a *Device1) Connect() error { return a.client.Call("Connect", 0).Store() } /* Disconnect This method gracefully disconnects all connected profiles and then terminates low-level ACL connection. ACL connection will be terminated even if some profiles were not disconnected properly e.g. due to misbehaving device. This method can be also used to cancel a preceding Connect call before a reply to it has been received. For non-trusted devices connected over LE bearer calling this method will disable incoming connections until Connect method is called again. Possible errors: org.bluez.Error.NotConnected */ func (a *Device1) Disconnect() error { return a.client.Call("Disconnect", 0).Store() } /* ConnectProfile This method connects a specific profile of this device. The UUID provided is the remote service UUID for the profile. Possible errors: org.bluez.Error.Failed org.bluez.Error.InProgress org.bluez.Error.InvalidArguments org.bluez.Error.NotAvailable org.bluez.Error.NotReady */ func (a *Device1) ConnectProfile(uuid string) error { return a.client.Call("ConnectProfile", 0, uuid).Store() } /* DisconnectProfile This method disconnects a specific profile of this device. The profile needs to be registered client profile. There is no connection tracking for a profile, so as long as the profile is registered this will always succeed. Possible errors: org.bluez.Error.Failed org.bluez.Error.InProgress org.bluez.Error.InvalidArguments org.bluez.Error.NotSupported */ func (a *Device1) DisconnectProfile(uuid string) error { return a.client.Call("DisconnectProfile", 0, uuid).Store() } /* Pair This method will connect to the remote device, initiate pairing and then retrieve all SDP records (or GATT primary services). If the application has registered its own agent, then that specific agent will be used. Otherwise it will use the default agent. Only for applications like a pairing wizard it would make sense to have its own agent. In almost all other cases the default agent will handle this just fine. In case there is no application agent and also no default agent present, this method will fail. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.Failed org.bluez.Error.AlreadyExists org.bluez.Error.AuthenticationCanceled org.bluez.Error.AuthenticationFailed org.bluez.Error.AuthenticationRejected org.bluez.Error.AuthenticationTimeout org.bluez.Error.ConnectionAttemptFailed */ func (a *Device1) Pair() error { return a.client.Call("Pair", 0).Store() } /* CancelPairing This method can be used to cancel a pairing operation initiated by the Pair method. Possible errors: org.bluez.Error.DoesNotExist org.bluez.Error.Failed */ func (a *Device1) CancelPairing() error { return a.client.Call("CancelPairing", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/device/gen_device.go000066400000000000000000000002051420407601400236250ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Device API description [device-api.txt] */ package device go-bluetooth-bluez-5.60/bluez/profile/gatt/000077500000000000000000000000001420407601400207115ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/gatt/gatt.go000066400000000000000000000032401420407601400221760ustar00rootroot00000000000000package gatt // Defines how the characteristic value can be used. See // Core spec "Table 3.5: Characteristic Properties bit // field", and "Table 3.8: Characteristic Extended // Properties bit field" const ( FlagCharacteristicBroadcast = "broadcast" FlagCharacteristicRead = "read" FlagCharacteristicWriteWithoutResponse = "write-without-response" FlagCharacteristicWrite = "write" FlagCharacteristicNotify = "notify" FlagCharacteristicIndicate = "indicate" FlagCharacteristicAuthenticatedSignedWrites = "authenticated-signed-writes" FlagCharacteristicReliableWrite = "reliable-write" FlagCharacteristicWritableAuxiliaries = "writable-auxiliaries" FlagCharacteristicEncryptRead = "encrypt-read" FlagCharacteristicEncryptWrite = "encrypt-write" FlagCharacteristicEncryptAuthenticatedRead = "encrypt-authenticated-read" FlagCharacteristicEncryptAuthenticatedWrite = "encrypt-authenticated-write" FlagCharacteristicSecureRead = "secure-read" FlagCharacteristicSecureWrite = "secure-write" ) // Descriptor specific flags const ( FlagDescriptorRead = "read" FlagDescriptorWrite = "write" FlagDescriptorEncryptRead = "encrypt-read" FlagDescriptorEncryptWrite = "encrypt-write" FlagDescriptorEncryptAuthenticatedRead = "encrypt-authenticated-read" FlagDescriptorEncryptAuthenticatedWrite = "encrypt-authenticated-write" FlagDescriptorSecureRead = "secure-read" FlagDescriptorSecureWrite = "secure-write" ) go-bluetooth-bluez-5.60/bluez/profile/gatt/gen_GattCharacteristic1.go000066400000000000000000000361361420407601400257330ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package gatt import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var GattCharacteristic1Interface = "org.bluez.GattCharacteristic1" // NewGattCharacteristic1 create a new instance of GattCharacteristic1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY func NewGattCharacteristic1(objectPath dbus.ObjectPath) (*GattCharacteristic1, error) { a := new(GattCharacteristic1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: GattCharacteristic1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(GattCharacteristic1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* GattCharacteristic1 Characteristic hierarchy For local GATT defined services, the object paths need to follow the service path hierarchy and are freely definable. */ type GattCharacteristic1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *GattCharacteristic1Properties watchPropertiesChannel chan *dbus.Signal } // GattCharacteristic1Properties contains the exposed properties of an interface type GattCharacteristic1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Descriptors */ Descriptors []dbus.ObjectPath /* Flags Defines how the characteristic value can be used. See Core spec "Table 3.5: Characteristic Properties bit field", and "Table 3.8: Characteristic Extended Properties bit field". Allowed values: "broadcast" "read" "write-without-response" "write" "notify" "indicate" "authenticated-signed-writes" "extended-properties" "reliable-write" "writable-auxiliaries" "encrypt-read" "encrypt-write" "encrypt-authenticated-read" "encrypt-authenticated-write" "secure-read" (Server only) "secure-write" (Server only) "authorize" */ Flags []string /* Handle Characteristic handle. When available in the server it would attempt to use to allocate into the database which may fail, to auto allocate the value 0x0000 shall be used which will cause the allocated handle to be set once registered. */ Handle uint16 /* NotifyAcquired True, if this characteristic has been acquired by any client using AcquireNotify. For client this properties is ommited in case 'notify' flag is not set. For server the presence of this property indicates that AcquireNotify is supported. */ NotifyAcquired bool `dbus:"ignore"` /* Notifying True, if notifications or indications on this characteristic are currently enabled. */ Notifying bool /* Service Object path of the GATT service the characteristic belongs to. */ Service dbus.ObjectPath /* UUID 128-bit characteristic UUID. */ UUID string /* Value The cached value of the characteristic. This property gets updated only after a successful read request and when a notification or indication is received, upon which a PropertiesChanged signal will be emitted. */ Value []byte `dbus:"emit"` /* WriteAcquired True, if this characteristic has been acquired by any client using AcquireWrite. For client properties is ommited in case 'write-without-response' flag is not set. For server the presence of this property indicates that AcquireWrite is supported. */ WriteAcquired bool `dbus:"ignore"` } //Lock access to properties func (p *GattCharacteristic1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *GattCharacteristic1Properties) Unlock() { p.lock.Unlock() } // SetDescriptors set Descriptors value func (a *GattCharacteristic1) SetDescriptors(v []dbus.ObjectPath) error { return a.SetProperty("Descriptors", v) } // GetDescriptors get Descriptors value func (a *GattCharacteristic1) GetDescriptors() ([]dbus.ObjectPath, error) { v, err := a.GetProperty("Descriptors") if err != nil { return []dbus.ObjectPath{}, err } return v.Value().([]dbus.ObjectPath), nil } // GetFlags get Flags value func (a *GattCharacteristic1) GetFlags() ([]string, error) { v, err := a.GetProperty("Flags") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetHandle set Handle value func (a *GattCharacteristic1) SetHandle(v uint16) error { return a.SetProperty("Handle", v) } // GetHandle get Handle value func (a *GattCharacteristic1) GetHandle() (uint16, error) { v, err := a.GetProperty("Handle") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetNotifyAcquired get NotifyAcquired value func (a *GattCharacteristic1) GetNotifyAcquired() (bool, error) { v, err := a.GetProperty("NotifyAcquired") if err != nil { return false, err } return v.Value().(bool), nil } // GetNotifying get Notifying value func (a *GattCharacteristic1) GetNotifying() (bool, error) { v, err := a.GetProperty("Notifying") if err != nil { return false, err } return v.Value().(bool), nil } // GetService get Service value func (a *GattCharacteristic1) GetService() (dbus.ObjectPath, error) { v, err := a.GetProperty("Service") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // GetUUID get UUID value func (a *GattCharacteristic1) GetUUID() (string, error) { v, err := a.GetProperty("UUID") if err != nil { return "", err } return v.Value().(string), nil } // GetValue get Value value func (a *GattCharacteristic1) GetValue() ([]byte, error) { v, err := a.GetProperty("Value") if err != nil { return []byte{}, err } return v.Value().([]byte), nil } // GetWriteAcquired get WriteAcquired value func (a *GattCharacteristic1) GetWriteAcquired() (bool, error) { v, err := a.GetProperty("WriteAcquired") if err != nil { return false, err } return v.Value().(bool), nil } // Close the connection func (a *GattCharacteristic1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return GattCharacteristic1 object path func (a *GattCharacteristic1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return GattCharacteristic1 dbus client func (a *GattCharacteristic1) Client() *bluez.Client { return a.client } // Interface return GattCharacteristic1 interface func (a *GattCharacteristic1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *GattCharacteristic1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a GattCharacteristic1Properties to map func (a *GattCharacteristic1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an GattCharacteristic1Properties func (a *GattCharacteristic1Properties) FromMap(props map[string]interface{}) (*GattCharacteristic1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an GattCharacteristic1Properties func (a *GattCharacteristic1Properties) FromDBusMap(props map[string]dbus.Variant) (*GattCharacteristic1Properties, error) { s := new(GattCharacteristic1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *GattCharacteristic1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *GattCharacteristic1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *GattCharacteristic1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *GattCharacteristic1) GetProperties() (*GattCharacteristic1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *GattCharacteristic1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *GattCharacteristic1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *GattCharacteristic1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *GattCharacteristic1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *GattCharacteristic1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *GattCharacteristic1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* ReadValue Issues a request to read the value of the characteristic and returns the value if the operation was successful. Possible options: "offset": uint16 offset "mtu": Exchanged MTU (Server only) "device": Object Device (Server only) Possible Errors: org.bluez.Error.Failed org.bluez.Error.InProgress org.bluez.Error.NotPermitted org.bluez.Error.NotAuthorized org.bluez.Error.InvalidOffset org.bluez.Error.NotSupported */ func (a *GattCharacteristic1) ReadValue(options map[string]interface{}) ([]byte, error) { val0 := []byte{} err := a.client.Call("ReadValue", 0, options).Store(&val0) return val0, err } /* WriteValue Issues a request to write the value of the characteristic. Possible options: "offset": Start offset "type": string Possible values: "command": Write without response "request": Write with response "reliable": Reliable Write "mtu": Exchanged MTU (Server only) "device": Device path (Server only) "link": Link type (Server only) "prepare-authorize": True if prepare authorization request Possible Errors: org.bluez.Error.Failed org.bluez.Error.InProgress org.bluez.Error.NotPermitted org.bluez.Error.InvalidValueLength org.bluez.Error.NotAuthorized org.bluez.Error.NotSupported */ func (a *GattCharacteristic1) WriteValue(value []byte, options map[string]interface{}) error { return a.client.Call("WriteValue", 0, value, options).Store() } /* AcquireWrite Acquire file descriptor and MTU for writing. Only sockets are supported. Usage of WriteValue will be locked causing it to return NotPermitted error. For server the MTU returned shall be equal or smaller than the negotiated MTU. For client it only works with characteristic that has WriteAcquired property which relies on write-without-response Flag. To release the lock the client shall close the file descriptor, a HUP is generated in case the device is disconnected. Note: the MTU can only be negotiated once and is symmetric therefore this method may be delayed in order to have the exchange MTU completed, because of that the file descriptor is closed during reconnections as the MTU has to be renegotiated. Possible options: "device": Object Device (Server only) "mtu": Exchanged MTU (Server only) "link": Link type (Server only) Possible Errors: org.bluez.Error.Failed org.bluez.Error.NotSupported */ func (a *GattCharacteristic1) AcquireWrite(options map[string]interface{}) (dbus.UnixFD, uint16, error) { var val0 dbus.UnixFD var val1 uint16 err := a.client.Call("AcquireWrite", 0, options).Store(&val0, &val1) return val0, val1, err } /* AcquireNotify Acquire file descriptor and MTU for notify. Only sockets are support. Usage of StartNotify will be locked causing it to return NotPermitted error. For server the MTU returned shall be equal or smaller than the negotiated MTU. Only works with characteristic that has NotifyAcquired which relies on notify Flag and no other client have called StartNotify. Notification are enabled during this procedure so StartNotify shall not be called, any notification will be dispatched via file descriptor therefore the Value property is not affected during the time where notify has been acquired. To release the lock the client shall close the file descriptor, a HUP is generated in case the device is disconnected. Note: the MTU can only be negotiated once and is symmetric therefore this method may be delayed in order to have the exchange MTU completed, because of that the file descriptor is closed during reconnections as the MTU has to be renegotiated. Possible options: "device": Object Device (Server only) "mtu": Exchanged MTU (Server only) "link": Link type (Server only) Possible Errors: org.bluez.Error.Failed org.bluez.Error.NotSupported */ func (a *GattCharacteristic1) AcquireNotify(options map[string]interface{}) (dbus.UnixFD, uint16, error) { var val0 dbus.UnixFD var val1 uint16 err := a.client.Call("AcquireNotify", 0, options).Store(&val0, &val1) return val0, val1, err } /* StartNotify Starts a notification session from this characteristic if it supports value notifications or indications. Possible Errors: org.bluez.Error.Failed org.bluez.Error.NotPermitted org.bluez.Error.InProgress org.bluez.Error.NotConnected org.bluez.Error.NotSupported */ func (a *GattCharacteristic1) StartNotify() error { return a.client.Call("StartNotify", 0).Store() } /* StopNotify This method will cancel any previous StartNotify transaction. Note that notifications from a characteristic are shared between sessions thus calling StopNotify will release a single session. Possible Errors: org.bluez.Error.Failed */ func (a *GattCharacteristic1) StopNotify() error { return a.client.Call("StopNotify", 0).Store() } /* Confirm This method doesn't expect a reply so it is just a confirmation that value was received. Possible Errors: org.bluez.Error.Failed */ func (a *GattCharacteristic1) Confirm() error { return a.client.Call("Confirm", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/gatt/gen_GattDescriptor1.go000066400000000000000000000213711420407601400251140ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package gatt import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var GattDescriptor1Interface = "org.bluez.GattDescriptor1" // NewGattDescriptor1 create a new instance of GattDescriptor1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ func NewGattDescriptor1(objectPath dbus.ObjectPath) (*GattDescriptor1, error) { a := new(GattDescriptor1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: GattDescriptor1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(GattDescriptor1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* GattDescriptor1 Characteristic Descriptors hierarchy Local or remote GATT characteristic descriptors hierarchy. */ type GattDescriptor1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *GattDescriptor1Properties watchPropertiesChannel chan *dbus.Signal } // GattDescriptor1Properties contains the exposed properties of an interface type GattDescriptor1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Characteristic Object path of the GATT characteristic the descriptor belongs to. */ Characteristic dbus.ObjectPath /* Flags Defines how the descriptor value can be used. Possible values: "read" "write" "encrypt-read" "encrypt-write" "encrypt-authenticated-read" "encrypt-authenticated-write" "secure-read" (Server Only) "secure-write" (Server Only) "authorize" */ Flags []string /* Handle Characteristic handle. When available in the server it would attempt to use to allocate into the database which may fail, to auto allocate the value 0x0000 shall be used which will cause the allocated handle to be set once registered. */ Handle uint16 /* UUID 128-bit descriptor UUID. */ UUID string /* Value The cached value of the descriptor. This property gets updated only after a successful read request, upon which a PropertiesChanged signal will be emitted. */ Value []byte `dbus:"emit"` } //Lock access to properties func (p *GattDescriptor1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *GattDescriptor1Properties) Unlock() { p.lock.Unlock() } // GetCharacteristic get Characteristic value func (a *GattDescriptor1) GetCharacteristic() (dbus.ObjectPath, error) { v, err := a.GetProperty("Characteristic") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // GetFlags get Flags value func (a *GattDescriptor1) GetFlags() ([]string, error) { v, err := a.GetProperty("Flags") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetHandle set Handle value func (a *GattDescriptor1) SetHandle(v uint16) error { return a.SetProperty("Handle", v) } // GetHandle get Handle value func (a *GattDescriptor1) GetHandle() (uint16, error) { v, err := a.GetProperty("Handle") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetUUID get UUID value func (a *GattDescriptor1) GetUUID() (string, error) { v, err := a.GetProperty("UUID") if err != nil { return "", err } return v.Value().(string), nil } // GetValue get Value value func (a *GattDescriptor1) GetValue() ([]byte, error) { v, err := a.GetProperty("Value") if err != nil { return []byte{}, err } return v.Value().([]byte), nil } // Close the connection func (a *GattDescriptor1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return GattDescriptor1 object path func (a *GattDescriptor1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return GattDescriptor1 dbus client func (a *GattDescriptor1) Client() *bluez.Client { return a.client } // Interface return GattDescriptor1 interface func (a *GattDescriptor1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *GattDescriptor1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a GattDescriptor1Properties to map func (a *GattDescriptor1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an GattDescriptor1Properties func (a *GattDescriptor1Properties) FromMap(props map[string]interface{}) (*GattDescriptor1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an GattDescriptor1Properties func (a *GattDescriptor1Properties) FromDBusMap(props map[string]dbus.Variant) (*GattDescriptor1Properties, error) { s := new(GattDescriptor1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *GattDescriptor1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *GattDescriptor1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *GattDescriptor1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *GattDescriptor1) GetProperties() (*GattDescriptor1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *GattDescriptor1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *GattDescriptor1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *GattDescriptor1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *GattDescriptor1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *GattDescriptor1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *GattDescriptor1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* ReadValue Issues a request to read the value of the characteristic and returns the value if the operation was successful. Possible options: "offset": Start offset "device": Device path (Server only) "link": Link type (Server only) Possible Errors: org.bluez.Error.Failed org.bluez.Error.InProgress org.bluez.Error.NotPermitted org.bluez.Error.NotAuthorized org.bluez.Error.NotSupported */ func (a *GattDescriptor1) ReadValue(flags map[string]interface{}) ([]byte, error) { val0 := []byte{} err := a.client.Call("ReadValue", 0, flags).Store(&val0) return val0, err } /* WriteValue Issues a request to write the value of the characteristic. Possible options: "offset": Start offset "device": Device path (Server only) "link": Link type (Server only) "prepare-authorize": boolean Is prepare authorization request Possible Errors: org.bluez.Error.Failed org.bluez.Error.InProgress org.bluez.Error.NotPermitted org.bluez.Error.InvalidValueLength org.bluez.Error.NotAuthorized org.bluez.Error.NotSupported */ func (a *GattDescriptor1) WriteValue(value []byte, flags map[string]interface{}) error { return a.client.Call("WriteValue", 0, value, flags).Store() } go-bluetooth-bluez-5.60/bluez/profile/gatt/gen_GattManager1.go000066400000000000000000000223701420407601400243500ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package gatt import ( "fmt" "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var GattManager1Interface = "org.bluez.GattManager1" // NewGattManager1 create a new instance of GattManager1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...} func NewGattManager1(objectPath dbus.ObjectPath) (*GattManager1, error) { a := new(GattManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: GattManager1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(GattManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } // NewGattManager1FromAdapterID create a new instance of GattManager1 // adapterID: ID of an adapter eg. hci0 func NewGattManager1FromAdapterID(adapterID string) (*GattManager1, error) { a := new(GattManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: GattManager1Interface, Path: dbus.ObjectPath(fmt.Sprintf("/org/bluez/%s", adapterID)), Bus: bluez.SystemBus, }, ) a.Properties = new(GattManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* GattManager1 GATT Manager hierarchy GATT Manager allows external applications to register GATT services and profiles. Registering a profile allows applications to subscribe to *remote* services. These must implement the GattProfile1 interface defined above. Registering a service allows applications to publish a *local* GATT service, which then becomes available to remote devices. A GATT service is represented by a D-Bus object hierarchy where the root node corresponds to a service and the child nodes represent characteristics and descriptors that belong to that service. Each node must implement one of GattService1, GattCharacteristic1, or GattDescriptor1 interfaces described above, based on the attribute it represents. Each node must also implement the standard D-Bus Properties interface to expose their properties. These objects collectively represent a GATT service definition. To make service registration simple, BlueZ requires that all objects that belong to a GATT service be grouped under a D-Bus Object Manager that solely manages the objects of that service. Hence, the standard DBus.ObjectManager interface must be available on the root service path. An example application hierarchy containing two separate GATT services may look like this: -> /com/example | - org.freedesktop.DBus.ObjectManager | -> /com/example/service0 | | - org.freedesktop.DBus.Properties | | - org.bluez.GattService1 | | | -> /com/example/service0/char0 | | - org.freedesktop.DBus.Properties | | - org.bluez.GattCharacteristic1 | | | -> /com/example/service0/char1 | | - org.freedesktop.DBus.Properties | | - org.bluez.GattCharacteristic1 | | | -> /com/example/service0/char1/desc0 | - org.freedesktop.DBus.Properties | - org.bluez.GattDescriptor1 | -> /com/example/service1 | - org.freedesktop.DBus.Properties | - org.bluez.GattService1 | -> /com/example/service1/char0 - org.freedesktop.DBus.Properties - org.bluez.GattCharacteristic1 When a service is registered, BlueZ will automatically obtain information about all objects using the service's Object Manager. Once a service has been registered, the objects of a service should not be removed. If BlueZ receives an InterfacesRemoved signal from a service's Object Manager, it will immediately unregister the service. Similarly, if the application disconnects from the bus, all of its registered services will be automatically unregistered. InterfacesAdded signals will be ignored. Examples: - Client test/example-gatt-client client/bluetoothctl - Server test/example-gatt-server tools/gatt-service */ type GattManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *GattManager1Properties watchPropertiesChannel chan *dbus.Signal } // GattManager1Properties contains the exposed properties of an interface type GattManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *GattManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *GattManager1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *GattManager1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return GattManager1 object path func (a *GattManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return GattManager1 dbus client func (a *GattManager1) Client() *bluez.Client { return a.client } // Interface return GattManager1 interface func (a *GattManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *GattManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a GattManager1Properties to map func (a *GattManager1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an GattManager1Properties func (a *GattManager1Properties) FromMap(props map[string]interface{}) (*GattManager1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an GattManager1Properties func (a *GattManager1Properties) FromDBusMap(props map[string]dbus.Variant) (*GattManager1Properties, error) { s := new(GattManager1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *GattManager1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *GattManager1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *GattManager1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *GattManager1) GetProperties() (*GattManager1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *GattManager1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *GattManager1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *GattManager1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *GattManager1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *GattManager1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *GattManager1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* RegisterApplication Registers a local GATT services hierarchy as described above (GATT Server) and/or GATT profiles (GATT Client). The application object path together with the D-Bus system bus connection ID define the identification of the application registering a GATT based service or profile. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists */ func (a *GattManager1) RegisterApplication(application dbus.ObjectPath, options map[string]interface{}) error { return a.client.Call("RegisterApplication", 0, application, options).Store() } /* UnregisterApplication This unregisters the services that has been previously registered. The object path parameter must match the same value that has been used on registration. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.DoesNotExist */ func (a *GattManager1) UnregisterApplication(application dbus.ObjectPath) error { return a.client.Call("UnregisterApplication", 0, application).Store() } go-bluetooth-bluez-5.60/bluez/profile/gatt/gen_GattProfile1.go000066400000000000000000000137571420407601400244070ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package gatt import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var GattProfile1Interface = "org.bluez.GattProfile1" // NewGattProfile1 create a new instance of GattProfile1 // // Args: // - servicePath: // - objectPath: func NewGattProfile1(servicePath string, objectPath dbus.ObjectPath) (*GattProfile1, error) { a := new(GattProfile1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: GattProfile1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(GattProfile1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* GattProfile1 GATT Profile hierarchy Local profile (GATT client) instance. By registering this type of object an application effectively indicates support for a specific GATT profile and requests automatic connections to be established to devices supporting it. */ type GattProfile1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *GattProfile1Properties watchPropertiesChannel chan *dbus.Signal } // GattProfile1Properties contains the exposed properties of an interface type GattProfile1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* UUIDs 128-bit GATT service UUIDs to auto connect. */ UUIDs []string } //Lock access to properties func (p *GattProfile1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *GattProfile1Properties) Unlock() { p.lock.Unlock() } // GetUUIDs get UUIDs value func (a *GattProfile1) GetUUIDs() ([]string, error) { v, err := a.GetProperty("UUIDs") if err != nil { return []string{}, err } return v.Value().([]string), nil } // Close the connection func (a *GattProfile1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return GattProfile1 object path func (a *GattProfile1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return GattProfile1 dbus client func (a *GattProfile1) Client() *bluez.Client { return a.client } // Interface return GattProfile1 interface func (a *GattProfile1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *GattProfile1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a GattProfile1Properties to map func (a *GattProfile1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an GattProfile1Properties func (a *GattProfile1Properties) FromMap(props map[string]interface{}) (*GattProfile1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an GattProfile1Properties func (a *GattProfile1Properties) FromDBusMap(props map[string]dbus.Variant) (*GattProfile1Properties, error) { s := new(GattProfile1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *GattProfile1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *GattProfile1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *GattProfile1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *GattProfile1) GetProperties() (*GattProfile1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *GattProfile1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *GattProfile1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *GattProfile1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *GattProfile1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *GattProfile1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *GattProfile1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Release This method gets called when the service daemon unregisters the profile. The profile can use it to do cleanup tasks. There is no need to unregister the profile, because when this method gets called it has already been unregistered. */ func (a *GattProfile1) Release() error { return a.client.Call("Release", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/gatt/gen_GattService1.go000066400000000000000000000203001420407601400243650ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package gatt import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var GattService1Interface = "org.bluez.GattService1" // NewGattService1 create a new instance of GattService1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX func NewGattService1(objectPath dbus.ObjectPath) (*GattService1, error) { a := new(GattService1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: GattService1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(GattService1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* GattService1 Service hierarchy GATT remote and local service representation. Object path for local services is freely definable. External applications implementing local services must register the services using GattManager1 registration method and must implement the methods and properties defined in GattService1 interface. */ type GattService1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *GattService1Properties watchPropertiesChannel chan *dbus.Signal } // GattService1Properties contains the exposed properties of an interface type GattService1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Characteristics */ Characteristics []dbus.ObjectPath `dbus:"emit"` /* Device Object path of the Bluetooth device the service belongs to. Only present on services from remote devices. */ Device dbus.ObjectPath `dbus:"ignore=IsService"` /* Handle Service handle. When available in the server it would attempt to use to allocate into the database which may fail, to auto allocate the value 0x0000 shall be used which will cause the allocated handle to be set once registered. */ Handle uint16 /* Includes Array of object paths representing the included services of this service. */ Includes []dbus.ObjectPath `dbus:"omitEmpty"` /* IsService */ IsService bool `dbus:"ignore"` /* Primary Indicates whether or not this GATT service is a primary service. If false, the service is secondary. */ Primary bool /* UUID 128-bit service UUID. */ UUID string } //Lock access to properties func (p *GattService1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *GattService1Properties) Unlock() { p.lock.Unlock() } // SetCharacteristics set Characteristics value func (a *GattService1) SetCharacteristics(v []dbus.ObjectPath) error { return a.SetProperty("Characteristics", v) } // GetCharacteristics get Characteristics value func (a *GattService1) GetCharacteristics() ([]dbus.ObjectPath, error) { v, err := a.GetProperty("Characteristics") if err != nil { return []dbus.ObjectPath{}, err } return v.Value().([]dbus.ObjectPath), nil } // GetDevice get Device value func (a *GattService1) GetDevice() (dbus.ObjectPath, error) { v, err := a.GetProperty("Device") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetHandle set Handle value func (a *GattService1) SetHandle(v uint16) error { return a.SetProperty("Handle", v) } // GetHandle get Handle value func (a *GattService1) GetHandle() (uint16, error) { v, err := a.GetProperty("Handle") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetIncludes get Includes value func (a *GattService1) GetIncludes() ([]dbus.ObjectPath, error) { v, err := a.GetProperty("Includes") if err != nil { return []dbus.ObjectPath{}, err } return v.Value().([]dbus.ObjectPath), nil } // SetIsService set IsService value func (a *GattService1) SetIsService(v bool) error { return a.SetProperty("IsService", v) } // GetIsService get IsService value func (a *GattService1) GetIsService() (bool, error) { v, err := a.GetProperty("IsService") if err != nil { return false, err } return v.Value().(bool), nil } // GetPrimary get Primary value func (a *GattService1) GetPrimary() (bool, error) { v, err := a.GetProperty("Primary") if err != nil { return false, err } return v.Value().(bool), nil } // GetUUID get UUID value func (a *GattService1) GetUUID() (string, error) { v, err := a.GetProperty("UUID") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *GattService1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return GattService1 object path func (a *GattService1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return GattService1 dbus client func (a *GattService1) Client() *bluez.Client { return a.client } // Interface return GattService1 interface func (a *GattService1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *GattService1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a GattService1Properties to map func (a *GattService1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an GattService1Properties func (a *GattService1Properties) FromMap(props map[string]interface{}) (*GattService1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an GattService1Properties func (a *GattService1Properties) FromDBusMap(props map[string]dbus.Variant) (*GattService1Properties, error) { s := new(GattService1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *GattService1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *GattService1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *GattService1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *GattService1) GetProperties() (*GattService1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *GattService1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *GattService1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *GattService1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *GattService1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *GattService1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *GattService1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } go-bluetooth-bluez-5.60/bluez/profile/gatt/gen_gatt.go000066400000000000000000000016631420407601400230360ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus GATT API description [gatt-api.txt] GATT local and remote services share the same high-level D-Bus API. Local refers to GATT based service exported by a BlueZ plugin or an external application. Remote refers to GATT services exported by the peer. BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and Properties (or the opposite). Support for D-Bus Object Manager is mandatory for external services to allow seamless GATT declarations (Service, Characteristic and Descriptors) discovery. Each GATT service tree is required to export a D-Bus Object Manager at its root that is solely responsible for the objects that belong to that service. Releasing a registered GATT service is not defined yet. Any API extension should avoid breaking the defined API, and if possible keep an unified GATT remote and local services representation. */ package gatt go-bluetooth-bluez-5.60/bluez/profile/gen_errors.go000066400000000000000000000036001420407601400224450ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package profile import ( "github.com/godbus/dbus/v5" ) var ( // NotReady map to org.bluez.Error.NotReady ErrNotReady = dbus.Error{ Name: "org.bluez.Error.NotReady", Body: []interface{}{"NotReady"}, } // InvalidArguments map to org.bluez.Error.InvalidArguments ErrInvalidArguments = dbus.Error{ Name: "org.bluez.Error.InvalidArguments", Body: []interface{}{"InvalidArguments"}, } // Failed map to org.bluez.Error.Failed ErrFailed = dbus.Error{ Name: "org.bluez.Error.Failed", Body: []interface{}{"Failed"}, } // DoesNotExist map to org.bluez.Error.DoesNotExist ErrDoesNotExist = dbus.Error{ Name: "org.bluez.Error.DoesNotExist", Body: []interface{}{"DoesNotExist"}, } // Rejected map to org.bluez.Error.Rejected ErrRejected = dbus.Error{ Name: "org.bluez.Error.Rejected", Body: []interface{}{"Rejected"}, } // NotConnected map to org.bluez.Error.NotConnected ErrNotConnected = dbus.Error{ Name: "org.bluez.Error.NotConnected", Body: []interface{}{"NotConnected"}, } // NotAcquired map to org.bluez.Error.NotAcquired ErrNotAcquired = dbus.Error{ Name: "org.bluez.Error.NotAcquired", Body: []interface{}{"NotAcquired"}, } // NotSupported map to org.bluez.Error.NotSupported ErrNotSupported = dbus.Error{ Name: "org.bluez.Error.NotSupported", Body: []interface{}{"NotSupported"}, } // NotAuthorized map to org.bluez.Error.NotAuthorized ErrNotAuthorized = dbus.Error{ Name: "org.bluez.Error.NotAuthorized", Body: []interface{}{"NotAuthorized"}, } // NotAvailable map to org.bluez.Error.NotAvailable ErrNotAvailable = dbus.Error{ Name: "org.bluez.Error.NotAvailable", Body: []interface{}{"NotAvailable"}, } // AlreadyConnected map to org.bluez.Error.AlreadyConnected ErrAlreadyConnected = dbus.Error{ Name: "org.bluez.Error.AlreadyConnected", Body: []interface{}{"AlreadyConnected"}, } ) go-bluetooth-bluez-5.60/bluez/profile/gen_version.go000066400000000000000000000001401420407601400226120ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package profile const Version = 5.60 go-bluetooth-bluez-5.60/bluez/profile/health/000077500000000000000000000000001420407601400212175ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/health/gen_HealthChannel1.go000066400000000000000000000164121420407601400251620ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package health import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var HealthChannel1Interface = "org.bluez.HealthChannel1" // NewHealthChannel1 create a new instance of HealthChannel1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/chanZZZ func NewHealthChannel1(objectPath dbus.ObjectPath) (*HealthChannel1, error) { a := new(HealthChannel1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: HealthChannel1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(HealthChannel1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* HealthChannel1 HealthChannel hierarchy */ type HealthChannel1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *HealthChannel1Properties watchPropertiesChannel chan *dbus.Signal } // HealthChannel1Properties contains the exposed properties of an interface type HealthChannel1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Application Identifies the HealthApplication to which this channel is related to (which indirectly defines its role and data type). */ Application dbus.ObjectPath /* Device Identifies the Remote Device that is connected with. Maps with a HealthDevice object. */ Device dbus.ObjectPath /* Type The quality of service of the data channel. ("reliable" or "streaming") */ Type string } //Lock access to properties func (p *HealthChannel1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *HealthChannel1Properties) Unlock() { p.lock.Unlock() } // SetApplication set Application value func (a *HealthChannel1) SetApplication(v dbus.ObjectPath) error { return a.SetProperty("Application", v) } // GetApplication get Application value func (a *HealthChannel1) GetApplication() (dbus.ObjectPath, error) { v, err := a.GetProperty("Application") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetDevice set Device value func (a *HealthChannel1) SetDevice(v dbus.ObjectPath) error { return a.SetProperty("Device", v) } // GetDevice get Device value func (a *HealthChannel1) GetDevice() (dbus.ObjectPath, error) { v, err := a.GetProperty("Device") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetType set Type value func (a *HealthChannel1) SetType(v string) error { return a.SetProperty("Type", v) } // GetType get Type value func (a *HealthChannel1) GetType() (string, error) { v, err := a.GetProperty("Type") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *HealthChannel1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return HealthChannel1 object path func (a *HealthChannel1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return HealthChannel1 dbus client func (a *HealthChannel1) Client() *bluez.Client { return a.client } // Interface return HealthChannel1 interface func (a *HealthChannel1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *HealthChannel1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a HealthChannel1Properties to map func (a *HealthChannel1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an HealthChannel1Properties func (a *HealthChannel1Properties) FromMap(props map[string]interface{}) (*HealthChannel1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an HealthChannel1Properties func (a *HealthChannel1Properties) FromDBusMap(props map[string]dbus.Variant) (*HealthChannel1Properties, error) { s := new(HealthChannel1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *HealthChannel1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *HealthChannel1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *HealthChannel1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *HealthChannel1) GetProperties() (*HealthChannel1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *HealthChannel1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *HealthChannel1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *HealthChannel1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *HealthChannel1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *HealthChannel1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *HealthChannel1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Acquire Returns the file descriptor for this data channel. If the data channel is not connected it will also reconnect. Possible Errors: org.bluez.Error.NotConnected org.bluez.Error.NotAllowed */ func (a *HealthChannel1) Acquire() (dbus.UnixFD, error) { var val0 dbus.UnixFD err := a.client.Call("Acquire", 0).Store(&val0) return val0, err } /* Release Releases the fd. Application should also need to close() it. Possible Errors: org.bluez.Error.NotAcquired org.bluez.Error.NotAllowed */ func (a *HealthChannel1) Release() error { return a.client.Call("Release", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/health/gen_HealthDevice1.go000066400000000000000000000163121420407601400250100ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package health import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var HealthDevice1Interface = "org.bluez.HealthDevice1" // NewHealthDevice1 create a new instance of HealthDevice1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX func NewHealthDevice1(objectPath dbus.ObjectPath) (*HealthDevice1, error) { a := new(HealthDevice1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: HealthDevice1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(HealthDevice1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* HealthDevice1 HealthDevice hierarchy */ type HealthDevice1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *HealthDevice1Properties watchPropertiesChannel chan *dbus.Signal } // HealthDevice1Properties contains the exposed properties of an interface type HealthDevice1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* MainChannel The first reliable channel opened. It is needed by upper applications in order to send specific protocol data units. The first reliable can change after a reconnection. */ MainChannel dbus.ObjectPath } //Lock access to properties func (p *HealthDevice1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *HealthDevice1Properties) Unlock() { p.lock.Unlock() } // SetMainChannel set MainChannel value func (a *HealthDevice1) SetMainChannel(v dbus.ObjectPath) error { return a.SetProperty("MainChannel", v) } // GetMainChannel get MainChannel value func (a *HealthDevice1) GetMainChannel() (dbus.ObjectPath, error) { v, err := a.GetProperty("MainChannel") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // Close the connection func (a *HealthDevice1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return HealthDevice1 object path func (a *HealthDevice1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return HealthDevice1 dbus client func (a *HealthDevice1) Client() *bluez.Client { return a.client } // Interface return HealthDevice1 interface func (a *HealthDevice1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *HealthDevice1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a HealthDevice1Properties to map func (a *HealthDevice1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an HealthDevice1Properties func (a *HealthDevice1Properties) FromMap(props map[string]interface{}) (*HealthDevice1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an HealthDevice1Properties func (a *HealthDevice1Properties) FromDBusMap(props map[string]dbus.Variant) (*HealthDevice1Properties, error) { s := new(HealthDevice1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *HealthDevice1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *HealthDevice1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *HealthDevice1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *HealthDevice1) GetProperties() (*HealthDevice1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *HealthDevice1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *HealthDevice1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *HealthDevice1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *HealthDevice1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *HealthDevice1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *HealthDevice1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Echo Sends an echo petition to the remote service. Returns True if response matches with the buffer sent. If some error is detected False value is returned. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.OutOfRange */ func (a *HealthDevice1) Echo() (bool, error) { var val0 bool err := a.client.Call("Echo", 0).Store(&val0) return val0, err } /* CreateChannel Creates a new data channel. The configuration should indicate the channel quality of service using one of this values "reliable", "streaming", "any". Returns the object path that identifies the data channel that is already connected. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.HealthError */ func (a *HealthDevice1) CreateChannel(application dbus.ObjectPath, configuration string) (dbus.ObjectPath, error) { var val0 dbus.ObjectPath err := a.client.Call("CreateChannel", 0, application, configuration).Store(&val0) return val0, err } /* DestroyChannel Destroys the data channel object. Only the creator of the channel or the creator of the HealthApplication that received the data channel will be able to destroy it. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotFound org.bluez.Error.NotAllowed */ func (a *HealthDevice1) DestroyChannel(channel dbus.ObjectPath) error { return a.client.Call("DestroyChannel", 0, channel).Store() } go-bluetooth-bluez-5.60/bluez/profile/health/gen_HealthManager1.go000066400000000000000000000144601420407601400251650ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package health import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var HealthManager1Interface = "org.bluez.HealthManager1" // NewHealthManager1 create a new instance of HealthManager1 // // Args: func NewHealthManager1() (*HealthManager1, error) { a := new(HealthManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: HealthManager1Interface, Path: dbus.ObjectPath("/org/bluez/"), Bus: bluez.SystemBus, }, ) a.Properties = new(HealthManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* HealthManager1 HealthManager hierarchy */ type HealthManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *HealthManager1Properties watchPropertiesChannel chan *dbus.Signal } // HealthManager1Properties contains the exposed properties of an interface type HealthManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *HealthManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *HealthManager1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *HealthManager1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return HealthManager1 object path func (a *HealthManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return HealthManager1 dbus client func (a *HealthManager1) Client() *bluez.Client { return a.client } // Interface return HealthManager1 interface func (a *HealthManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *HealthManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a HealthManager1Properties to map func (a *HealthManager1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an HealthManager1Properties func (a *HealthManager1Properties) FromMap(props map[string]interface{}) (*HealthManager1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an HealthManager1Properties func (a *HealthManager1Properties) FromDBusMap(props map[string]dbus.Variant) (*HealthManager1Properties, error) { s := new(HealthManager1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *HealthManager1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *HealthManager1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *HealthManager1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *HealthManager1) GetProperties() (*HealthManager1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *HealthManager1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *HealthManager1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *HealthManager1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *HealthManager1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *HealthManager1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *HealthManager1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* CreateApplication Returns the path of the new registered application. Application will be closed by the call or implicitly when the programs leaves the bus. config: uint16 DataType: Mandatory string Role: Mandatory. Possible values: "source", "sink" string Description: Optional ChannelType: Optional, just for sources. Possible values: "reliable", "streaming" Possible Errors: org.bluez.Error.InvalidArguments */ func (a *HealthManager1) CreateApplication(config map[string]interface{}) (dbus.ObjectPath, error) { var val0 dbus.ObjectPath err := a.client.Call("CreateApplication", 0, config).Store(&val0) return val0, err } /* DestroyApplication Closes the HDP application identified by the object path. Also application will be closed if the process that started it leaves the bus. Only the creator of the application will be able to destroy it. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotFound org.bluez.Error.NotAllowed */ func (a *HealthManager1) DestroyApplication(application dbus.ObjectPath) error { return a.client.Call("DestroyApplication", 0, application).Store() } go-bluetooth-bluez-5.60/bluez/profile/health/gen_health.go000066400000000000000000000002051420407601400236410ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Health API description [health-api.txt] */ package health go-bluetooth-bluez-5.60/bluez/profile/input/000077500000000000000000000000001420407601400211115ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/input/gen_Input1.go000066400000000000000000000136461420407601400234630ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package input import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Input1Interface = "org.bluez.Input1" // NewInput1 create a new instance of Input1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX func NewInput1(objectPath dbus.ObjectPath) (*Input1, error) { a := new(Input1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Input1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Input1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Input1 Input hierarchy */ type Input1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Input1Properties watchPropertiesChannel chan *dbus.Signal } // Input1Properties contains the exposed properties of an interface type Input1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* ReconnectMode Determines the Connectability mode of the HID device as defined by the HID Profile specification, Section 5.4.2. This mode is based in the two properties HIDReconnectInitiate (see Section 5.3.4.6) and HIDNormallyConnectable (see Section 5.3.4.14) which define the following four possible values: "none" Device and host are not required to automatically restore the connection. "host" Bluetooth HID host restores connection. "device" Bluetooth HID device restores connection. "any" Bluetooth HID device shall attempt to restore the lost connection, but Bluetooth HID Host may also restore the connection. */ ReconnectMode string } //Lock access to properties func (p *Input1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Input1Properties) Unlock() { p.lock.Unlock() } // SetReconnectMode set ReconnectMode value func (a *Input1) SetReconnectMode(v string) error { return a.SetProperty("ReconnectMode", v) } // GetReconnectMode get ReconnectMode value func (a *Input1) GetReconnectMode() (string, error) { v, err := a.GetProperty("ReconnectMode") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *Input1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Input1 object path func (a *Input1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Input1 dbus client func (a *Input1) Client() *bluez.Client { return a.client } // Interface return Input1 interface func (a *Input1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Input1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Input1Properties to map func (a *Input1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Input1Properties func (a *Input1Properties) FromMap(props map[string]interface{}) (*Input1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Input1Properties func (a *Input1Properties) FromDBusMap(props map[string]dbus.Variant) (*Input1Properties, error) { s := new(Input1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Input1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Input1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Input1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Input1) GetProperties() (*Input1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Input1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Input1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Input1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Input1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Input1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Input1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } go-bluetooth-bluez-5.60/bluez/profile/input/gen_input.go000066400000000000000000000002011420407601400234210ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Input API description [input-api.txt] */ package input go-bluetooth-bluez-5.60/bluez/profile/media/000077500000000000000000000000001420407601400210315ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/media/gen_Media1.go000066400000000000000000000172551420407601400233230ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package media import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Media1Interface = "org.bluez.Media1" // NewMedia1 create a new instance of Media1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...} func NewMedia1(objectPath dbus.ObjectPath) (*Media1, error) { a := new(Media1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Media1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Media1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Media1 Media hierarchy */ type Media1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Media1Properties watchPropertiesChannel chan *dbus.Signal } // Media1Properties contains the exposed properties of an interface type Media1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Media1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Media1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Media1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Media1 object path func (a *Media1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Media1 dbus client func (a *Media1) Client() *bluez.Client { return a.client } // Interface return Media1 interface func (a *Media1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Media1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Media1Properties to map func (a *Media1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Media1Properties func (a *Media1Properties) FromMap(props map[string]interface{}) (*Media1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Media1Properties func (a *Media1Properties) FromDBusMap(props map[string]dbus.Variant) (*Media1Properties, error) { s := new(Media1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Media1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Media1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Media1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Media1) GetProperties() (*Media1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Media1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Media1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Media1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Media1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Media1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Media1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* RegisterEndpoint Register a local end point to sender, the sender can register as many end points as it likes. Note: If the sender disconnects the end points are automatically unregistered. possible properties: string UUID: UUID of the profile which the endpoint is for. byte Codec: Assigned number of codec that the endpoint implements. The values should match the profile specification which is indicated by the UUID. array{byte} Capabilities: Capabilities blob, it is used as it is so the size and byte order must match. Possible Errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotSupported - emitted when interface for the end-point is disabled. */ func (a *Media1) RegisterEndpoint(endpoint dbus.ObjectPath, properties map[string]interface{}) error { return a.client.Call("RegisterEndpoint", 0, endpoint, properties).Store() } /* UnregisterEndpoint Unregister sender end point. */ func (a *Media1) UnregisterEndpoint(endpoint dbus.ObjectPath) error { return a.client.Call("UnregisterEndpoint", 0, endpoint).Store() } /* RegisterPlayer Register a media player object to sender, the sender can register as many objects as it likes. Object must implement at least org.mpris.MediaPlayer2.Player as defined in MPRIS 2.2 spec: http://specifications.freedesktop.org/mpris-spec/latest/ Note: If the sender disconnects its objects are automatically unregistered. Possible Errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotSupported */ func (a *Media1) RegisterPlayer(player dbus.ObjectPath, properties map[string]interface{}) error { return a.client.Call("RegisterPlayer", 0, player, properties).Store() } /* UnregisterPlayer Unregister sender media player. */ func (a *Media1) UnregisterPlayer(player dbus.ObjectPath) error { return a.client.Call("UnregisterPlayer", 0, player).Store() } /* RegisterApplication Register endpoints an player objects within root object which must implement ObjectManager. The application object path together with the D-Bus system bus connection ID define the identification of the application. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists */ func (a *Media1) RegisterApplication(root dbus.ObjectPath, options map[string]interface{}) error { return a.client.Call("RegisterApplication", 0, root, options).Store() } /* UnregisterApplication This unregisters the services that has been previously registered. The object path parameter must match the same value that has been used on registration. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.DoesNotExist */ func (a *Media1) UnregisterApplication(application dbus.ObjectPath) error { return a.client.Call("UnregisterApplication", 0, application).Store() } go-bluetooth-bluez-5.60/bluez/profile/media/gen_MediaControl1.go000066400000000000000000000174101420407601400246550ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package media import ( "fmt" "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var MediaControl1Interface = "org.bluez.MediaControl1" // NewMediaControl1 create a new instance of MediaControl1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX func NewMediaControl1(objectPath dbus.ObjectPath) (*MediaControl1, error) { a := new(MediaControl1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: MediaControl1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaControl1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } // NewMediaControl1FromAdapterID create a new instance of MediaControl1 // adapterID: ID of an adapter eg. hci0 func NewMediaControl1FromAdapterID(adapterID string) (*MediaControl1, error) { a := new(MediaControl1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: MediaControl1Interface, Path: dbus.ObjectPath(fmt.Sprintf("/org/bluez/%s", adapterID)), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaControl1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* MediaControl1 Media Control hierarchy */ type MediaControl1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *MediaControl1Properties watchPropertiesChannel chan *dbus.Signal } // MediaControl1Properties contains the exposed properties of an interface type MediaControl1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Connected */ Connected bool /* Player Addressed Player object path. */ Player dbus.ObjectPath } //Lock access to properties func (p *MediaControl1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *MediaControl1Properties) Unlock() { p.lock.Unlock() } // SetConnected set Connected value func (a *MediaControl1) SetConnected(v bool) error { return a.SetProperty("Connected", v) } // GetConnected get Connected value func (a *MediaControl1) GetConnected() (bool, error) { v, err := a.GetProperty("Connected") if err != nil { return false, err } return v.Value().(bool), nil } // SetPlayer set Player value func (a *MediaControl1) SetPlayer(v dbus.ObjectPath) error { return a.SetProperty("Player", v) } // GetPlayer get Player value func (a *MediaControl1) GetPlayer() (dbus.ObjectPath, error) { v, err := a.GetProperty("Player") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // Close the connection func (a *MediaControl1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return MediaControl1 object path func (a *MediaControl1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return MediaControl1 dbus client func (a *MediaControl1) Client() *bluez.Client { return a.client } // Interface return MediaControl1 interface func (a *MediaControl1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *MediaControl1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a MediaControl1Properties to map func (a *MediaControl1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an MediaControl1Properties func (a *MediaControl1Properties) FromMap(props map[string]interface{}) (*MediaControl1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an MediaControl1Properties func (a *MediaControl1Properties) FromDBusMap(props map[string]dbus.Variant) (*MediaControl1Properties, error) { s := new(MediaControl1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *MediaControl1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *MediaControl1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *MediaControl1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *MediaControl1) GetProperties() (*MediaControl1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *MediaControl1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *MediaControl1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *MediaControl1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *MediaControl1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *MediaControl1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *MediaControl1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Play Resume playback. */ func (a *MediaControl1) Play() error { return a.client.Call("Play", 0).Store() } /* Pause Pause playback. */ func (a *MediaControl1) Pause() error { return a.client.Call("Pause", 0).Store() } /* Stop Stop playback. */ func (a *MediaControl1) Stop() error { return a.client.Call("Stop", 0).Store() } /* Next Next item. */ func (a *MediaControl1) Next() error { return a.client.Call("Next", 0).Store() } /* Previous Previous item. */ func (a *MediaControl1) Previous() error { return a.client.Call("Previous", 0).Store() } /* VolumeUp Adjust remote volume one step up */ func (a *MediaControl1) VolumeUp() error { return a.client.Call("VolumeUp", 0).Store() } /* VolumeDown Adjust remote volume one step down */ func (a *MediaControl1) VolumeDown() error { return a.client.Call("VolumeDown", 0).Store() } /* FastForward Fast forward playback, this action is only stopped when another method in this interface is called. */ func (a *MediaControl1) FastForward() error { return a.client.Call("FastForward", 0).Store() } /* Rewind Rewind playback, this action is only stopped when another method in this interface is called. */ func (a *MediaControl1) Rewind() error { return a.client.Call("Rewind", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/media/gen_MediaEndpoint1.go000066400000000000000000000226101420407601400250130ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package media import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var MediaEndpoint1Interface = "org.bluez.MediaEndpoint1" // NewMediaEndpoint1Server create a new instance of MediaEndpoint1 // // Args: // - servicePath: unique name func NewMediaEndpoint1Server(servicePath string, objectPath dbus.ObjectPath) (*MediaEndpoint1, error) { a := new(MediaEndpoint1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: MediaEndpoint1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaEndpoint1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } // NewMediaEndpoint1Client create a new instance of MediaEndpoint1 // // Args: func NewMediaEndpoint1Client(objectPath dbus.ObjectPath) (*MediaEndpoint1, error) { a := new(MediaEndpoint1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: MediaEndpoint1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaEndpoint1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* MediaEndpoint1 MediaEndpoint1 hierarchy */ type MediaEndpoint1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *MediaEndpoint1Properties watchPropertiesChannel chan *dbus.Signal } // MediaEndpoint1Properties contains the exposed properties of an interface type MediaEndpoint1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Capabilities Capabilities blob, it is used as it is so the size and byte order must match. */ Capabilities []byte /* Codec Assigned number of codec that the endpoint implements. The values should match the profile specification which is indicated by the UUID. */ Codec byte /* DelayReporting Indicates if endpoint supports Delay Reporting. */ DelayReporting bool /* Device Device object which the endpoint is belongs to. */ Device dbus.ObjectPath /* UUID UUID of the profile which the endpoint is for. */ UUID string } //Lock access to properties func (p *MediaEndpoint1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *MediaEndpoint1Properties) Unlock() { p.lock.Unlock() } // SetCapabilities set Capabilities value func (a *MediaEndpoint1) SetCapabilities(v []byte) error { return a.SetProperty("Capabilities", v) } // GetCapabilities get Capabilities value func (a *MediaEndpoint1) GetCapabilities() ([]byte, error) { v, err := a.GetProperty("Capabilities") if err != nil { return []byte{}, err } return v.Value().([]byte), nil } // SetCodec set Codec value func (a *MediaEndpoint1) SetCodec(v byte) error { return a.SetProperty("Codec", v) } // GetCodec get Codec value func (a *MediaEndpoint1) GetCodec() (byte, error) { v, err := a.GetProperty("Codec") if err != nil { return byte(0), err } return v.Value().(byte), nil } // SetDelayReporting set DelayReporting value func (a *MediaEndpoint1) SetDelayReporting(v bool) error { return a.SetProperty("DelayReporting", v) } // GetDelayReporting get DelayReporting value func (a *MediaEndpoint1) GetDelayReporting() (bool, error) { v, err := a.GetProperty("DelayReporting") if err != nil { return false, err } return v.Value().(bool), nil } // SetDevice set Device value func (a *MediaEndpoint1) SetDevice(v dbus.ObjectPath) error { return a.SetProperty("Device", v) } // GetDevice get Device value func (a *MediaEndpoint1) GetDevice() (dbus.ObjectPath, error) { v, err := a.GetProperty("Device") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetUUID set UUID value func (a *MediaEndpoint1) SetUUID(v string) error { return a.SetProperty("UUID", v) } // GetUUID get UUID value func (a *MediaEndpoint1) GetUUID() (string, error) { v, err := a.GetProperty("UUID") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *MediaEndpoint1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return MediaEndpoint1 object path func (a *MediaEndpoint1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return MediaEndpoint1 dbus client func (a *MediaEndpoint1) Client() *bluez.Client { return a.client } // Interface return MediaEndpoint1 interface func (a *MediaEndpoint1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *MediaEndpoint1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a MediaEndpoint1Properties to map func (a *MediaEndpoint1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an MediaEndpoint1Properties func (a *MediaEndpoint1Properties) FromMap(props map[string]interface{}) (*MediaEndpoint1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an MediaEndpoint1Properties func (a *MediaEndpoint1Properties) FromDBusMap(props map[string]dbus.Variant) (*MediaEndpoint1Properties, error) { s := new(MediaEndpoint1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *MediaEndpoint1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *MediaEndpoint1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *MediaEndpoint1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *MediaEndpoint1) GetProperties() (*MediaEndpoint1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *MediaEndpoint1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *MediaEndpoint1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *MediaEndpoint1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *MediaEndpoint1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *MediaEndpoint1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *MediaEndpoint1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* SetConfiguration Set configuration for the transport. For client role transport must be set with a server endpoint oject which will be configured and the properties must contain the following properties: array{byte} Capabilities */ func (a *MediaEndpoint1) SetConfiguration(transport dbus.ObjectPath, properties map[string]interface{}) error { return a.client.Call("SetConfiguration", 0, transport, properties).Store() } /* SelectConfiguration Select preferable configuration from the supported capabilities. Returns a configuration which can be used to setup a transport. Note: There is no need to cache the selected configuration since on success the configuration is send back as parameter of SetConfiguration. */ func (a *MediaEndpoint1) SelectConfiguration(capabilities []byte) ([]byte, error) { val0 := []byte{} err := a.client.Call("SelectConfiguration", 0, capabilities).Store(&val0) return val0, err } /* ClearConfiguration Clear transport configuration. */ func (a *MediaEndpoint1) ClearConfiguration(transport dbus.ObjectPath) error { return a.client.Call("ClearConfiguration", 0, transport).Store() } /* Release This method gets called when the service daemon unregisters the endpoint. An endpoint can use it to do cleanup tasks. There is no need to unregister the endpoint, because when this method gets called it has already been unregistered. */ func (a *MediaEndpoint1) Release() error { return a.client.Call("Release", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/media/gen_MediaFolder1.go000066400000000000000000000226121420407601400244500ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package media import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var MediaFolder1Interface = "org.bluez.MediaFolder1" // NewMediaFolder1 create a new instance of MediaFolder1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewMediaFolder1(servicePath string, objectPath dbus.ObjectPath) (*MediaFolder1, error) { a := new(MediaFolder1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: MediaFolder1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaFolder1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } // NewMediaFolder1Controller create a new instance of MediaFolder1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX func NewMediaFolder1Controller(objectPath dbus.ObjectPath) (*MediaFolder1, error) { a := new(MediaFolder1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: MediaFolder1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaFolder1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* MediaFolder1 MediaFolder1 hierarchy */ type MediaFolder1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *MediaFolder1Properties watchPropertiesChannel chan *dbus.Signal } // MediaFolder1Properties contains the exposed properties of an interface type MediaFolder1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Attributes Item properties that should be included in the list. Possible Values: "title", "artist", "album", "genre", "number-of-tracks", "number", "duration" Default Value: All */ Attributes []string /* End Offset of the last item. Default value: NumbeOfItems */ End uint32 /* Name Folder name: Possible values: "/Filesystem/...": Filesystem scope "/NowPlaying/...": NowPlaying scope Note: /NowPlaying folder might not be listed if player is stopped, folders created by Search are virtual so once another Search is perform or the folder is changed using ChangeFolder it will no longer be listed. Filters */ Name string /* NumberOfItems Number of items in the folder */ NumberOfItems uint32 /* Start Offset of the first item. Default value: 0 */ Start uint32 } //Lock access to properties func (p *MediaFolder1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *MediaFolder1Properties) Unlock() { p.lock.Unlock() } // SetAttributes set Attributes value func (a *MediaFolder1) SetAttributes(v []string) error { return a.SetProperty("Attributes", v) } // GetAttributes get Attributes value func (a *MediaFolder1) GetAttributes() ([]string, error) { v, err := a.GetProperty("Attributes") if err != nil { return []string{}, err } return v.Value().([]string), nil } // SetEnd set End value func (a *MediaFolder1) SetEnd(v uint32) error { return a.SetProperty("End", v) } // GetEnd get End value func (a *MediaFolder1) GetEnd() (uint32, error) { v, err := a.GetProperty("End") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetName set Name value func (a *MediaFolder1) SetName(v string) error { return a.SetProperty("Name", v) } // GetName get Name value func (a *MediaFolder1) GetName() (string, error) { v, err := a.GetProperty("Name") if err != nil { return "", err } return v.Value().(string), nil } // SetNumberOfItems set NumberOfItems value func (a *MediaFolder1) SetNumberOfItems(v uint32) error { return a.SetProperty("NumberOfItems", v) } // GetNumberOfItems get NumberOfItems value func (a *MediaFolder1) GetNumberOfItems() (uint32, error) { v, err := a.GetProperty("NumberOfItems") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetStart set Start value func (a *MediaFolder1) SetStart(v uint32) error { return a.SetProperty("Start", v) } // GetStart get Start value func (a *MediaFolder1) GetStart() (uint32, error) { v, err := a.GetProperty("Start") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // Close the connection func (a *MediaFolder1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return MediaFolder1 object path func (a *MediaFolder1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return MediaFolder1 dbus client func (a *MediaFolder1) Client() *bluez.Client { return a.client } // Interface return MediaFolder1 interface func (a *MediaFolder1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *MediaFolder1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a MediaFolder1Properties to map func (a *MediaFolder1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an MediaFolder1Properties func (a *MediaFolder1Properties) FromMap(props map[string]interface{}) (*MediaFolder1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an MediaFolder1Properties func (a *MediaFolder1Properties) FromDBusMap(props map[string]dbus.Variant) (*MediaFolder1Properties, error) { s := new(MediaFolder1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *MediaFolder1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *MediaFolder1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *MediaFolder1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *MediaFolder1) GetProperties() (*MediaFolder1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *MediaFolder1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *MediaFolder1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *MediaFolder1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *MediaFolder1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *MediaFolder1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *MediaFolder1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Search Return a folder object containing the search result. To list the items found use the folder object returned and pass to ChangeFolder. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaFolder1) Search(value string, filter map[string]interface{}) (dbus.ObjectPath, error) { var val0 dbus.ObjectPath err := a.client.Call("Search", 0, value, filter).Store(&val0) return val0, err } /* ListItems Return a list of items found Possible Errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaFolder1) ListItems(filter map[string]interface{}) ([]Item, error) { val0 := []Item{} err := a.client.Call("ListItems", 0, filter).Store(&val0) return val0, err } /* ChangeFolder Change current folder. Note: By changing folder the items of previous folder might be destroyed and have to be listed again, the exception is NowPlaying folder which should be always present while the player is active. Possible Errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaFolder1) ChangeFolder(folder dbus.ObjectPath) error { return a.client.Call("ChangeFolder", 0, folder).Store() } go-bluetooth-bluez-5.60/bluez/profile/media/gen_MediaItem1.go000066400000000000000000000267461420407601400241470ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package media import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var MediaItem1Interface = "org.bluez.MediaItem1" // NewMediaItem1 create a new instance of MediaItem1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewMediaItem1(servicePath string, objectPath dbus.ObjectPath) (*MediaItem1, error) { a := new(MediaItem1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: MediaItem1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaItem1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } // NewMediaItem1Controller create a new instance of MediaItem1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX func NewMediaItem1Controller(objectPath dbus.ObjectPath) (*MediaItem1, error) { a := new(MediaItem1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: MediaItem1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaItem1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* MediaItem1 MediaItem1 hierarchy */ type MediaItem1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *MediaItem1Properties watchPropertiesChannel chan *dbus.Signal } // MediaItem1Properties contains the exposed properties of an interface type MediaItem1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Album Item album name Available if property Type is "audio" or "video" */ Album string /* Artist Item artist name Available if property Type is "audio" or "video" */ Artist string /* Duration Item duration in milliseconds Available if property Type is "audio" or "video" */ Duration uint32 /* FolderType Folder type. Possible values: "mixed", "titles", "albums", "artists" Available if property Type is "Folder" */ FolderType string /* Genre Item genre name Available if property Type is "audio" or "video" */ Genre string /* Metadata Item metadata. Possible values: */ Metadata map[string]interface{} /* Name Item displayable name */ Name string /* Number Item album number Available if property Type is "audio" or "video" */ Number uint32 /* NumberOfTracks Item album number of tracks in total Available if property Type is "audio" or "video" */ NumberOfTracks uint32 /* Playable Indicates if the item can be played Available if property Type is "folder" */ Playable bool /* Player Player object path the item belongs to */ Player dbus.ObjectPath /* Title Item title name Available if property Type is "audio" or "video" */ Title string /* Type Item type Possible values: "video", "audio", "folder" */ Type string } //Lock access to properties func (p *MediaItem1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *MediaItem1Properties) Unlock() { p.lock.Unlock() } // SetAlbum set Album value func (a *MediaItem1) SetAlbum(v string) error { return a.SetProperty("Album", v) } // GetAlbum get Album value func (a *MediaItem1) GetAlbum() (string, error) { v, err := a.GetProperty("Album") if err != nil { return "", err } return v.Value().(string), nil } // SetArtist set Artist value func (a *MediaItem1) SetArtist(v string) error { return a.SetProperty("Artist", v) } // GetArtist get Artist value func (a *MediaItem1) GetArtist() (string, error) { v, err := a.GetProperty("Artist") if err != nil { return "", err } return v.Value().(string), nil } // SetDuration set Duration value func (a *MediaItem1) SetDuration(v uint32) error { return a.SetProperty("Duration", v) } // GetDuration get Duration value func (a *MediaItem1) GetDuration() (uint32, error) { v, err := a.GetProperty("Duration") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetFolderType set FolderType value func (a *MediaItem1) SetFolderType(v string) error { return a.SetProperty("FolderType", v) } // GetFolderType get FolderType value func (a *MediaItem1) GetFolderType() (string, error) { v, err := a.GetProperty("FolderType") if err != nil { return "", err } return v.Value().(string), nil } // SetGenre set Genre value func (a *MediaItem1) SetGenre(v string) error { return a.SetProperty("Genre", v) } // GetGenre get Genre value func (a *MediaItem1) GetGenre() (string, error) { v, err := a.GetProperty("Genre") if err != nil { return "", err } return v.Value().(string), nil } // SetMetadata set Metadata value func (a *MediaItem1) SetMetadata(v map[string]interface{}) error { return a.SetProperty("Metadata", v) } // GetMetadata get Metadata value func (a *MediaItem1) GetMetadata() (map[string]interface{}, error) { v, err := a.GetProperty("Metadata") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetName set Name value func (a *MediaItem1) SetName(v string) error { return a.SetProperty("Name", v) } // GetName get Name value func (a *MediaItem1) GetName() (string, error) { v, err := a.GetProperty("Name") if err != nil { return "", err } return v.Value().(string), nil } // SetNumber set Number value func (a *MediaItem1) SetNumber(v uint32) error { return a.SetProperty("Number", v) } // GetNumber get Number value func (a *MediaItem1) GetNumber() (uint32, error) { v, err := a.GetProperty("Number") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetNumberOfTracks set NumberOfTracks value func (a *MediaItem1) SetNumberOfTracks(v uint32) error { return a.SetProperty("NumberOfTracks", v) } // GetNumberOfTracks get NumberOfTracks value func (a *MediaItem1) GetNumberOfTracks() (uint32, error) { v, err := a.GetProperty("NumberOfTracks") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetPlayable set Playable value func (a *MediaItem1) SetPlayable(v bool) error { return a.SetProperty("Playable", v) } // GetPlayable get Playable value func (a *MediaItem1) GetPlayable() (bool, error) { v, err := a.GetProperty("Playable") if err != nil { return false, err } return v.Value().(bool), nil } // SetPlayer set Player value func (a *MediaItem1) SetPlayer(v dbus.ObjectPath) error { return a.SetProperty("Player", v) } // GetPlayer get Player value func (a *MediaItem1) GetPlayer() (dbus.ObjectPath, error) { v, err := a.GetProperty("Player") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetTitle set Title value func (a *MediaItem1) SetTitle(v string) error { return a.SetProperty("Title", v) } // GetTitle get Title value func (a *MediaItem1) GetTitle() (string, error) { v, err := a.GetProperty("Title") if err != nil { return "", err } return v.Value().(string), nil } // SetType set Type value func (a *MediaItem1) SetType(v string) error { return a.SetProperty("Type", v) } // GetType get Type value func (a *MediaItem1) GetType() (string, error) { v, err := a.GetProperty("Type") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *MediaItem1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return MediaItem1 object path func (a *MediaItem1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return MediaItem1 dbus client func (a *MediaItem1) Client() *bluez.Client { return a.client } // Interface return MediaItem1 interface func (a *MediaItem1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *MediaItem1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a MediaItem1Properties to map func (a *MediaItem1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an MediaItem1Properties func (a *MediaItem1Properties) FromMap(props map[string]interface{}) (*MediaItem1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an MediaItem1Properties func (a *MediaItem1Properties) FromDBusMap(props map[string]dbus.Variant) (*MediaItem1Properties, error) { s := new(MediaItem1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *MediaItem1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *MediaItem1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *MediaItem1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *MediaItem1) GetProperties() (*MediaItem1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *MediaItem1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *MediaItem1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *MediaItem1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *MediaItem1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *MediaItem1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *MediaItem1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Play Play item Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaItem1) Play() error { return a.client.Call("Play", 0).Store() } /* AddtoNowPlaying Add item to now playing list Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaItem1) AddtoNowPlaying() error { return a.client.Call("AddtoNowPlaying", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/media/gen_MediaPlayer1.go000066400000000000000000000416051420407601400244740ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package media import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var MediaPlayer1Interface = "org.bluez.MediaPlayer1" // NewMediaPlayer1 create a new instance of MediaPlayer1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX func NewMediaPlayer1(objectPath dbus.ObjectPath) (*MediaPlayer1, error) { a := new(MediaPlayer1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: MediaPlayer1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaPlayer1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* MediaPlayer1 MediaPlayer1 hierarchy */ type MediaPlayer1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *MediaPlayer1Properties watchPropertiesChannel chan *dbus.Signal } // MediaPlayer1Properties contains the exposed properties of an interface type MediaPlayer1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Album Track album name */ Album string /* Artist Track artist name */ Artist string /* Browsable If present indicates the player can be browsed using MediaFolder interface. Possible values: True: Supported and active False: Supported but inactive Note: If supported but inactive clients can enable it by using MediaFolder interface but it might interfere in the playback of other players. */ Browsable bool /* Device Device object path. */ Device dbus.ObjectPath /* Duration Track duration in milliseconds */ Duration uint32 /* Equalizer Possible values: "off" or "on" */ Equalizer string /* Genre Track genre name */ Genre string /* Name Player name */ Name string /* NumberOfTracks Number of tracks in total */ NumberOfTracks uint32 /* Playlist Playlist object path. */ Playlist dbus.ObjectPath /* Position Playback position in milliseconds. Changing the position may generate additional events that will be sent to the remote device. When position is 0 it means the track is starting and when it's greater than or equal to track's duration the track has ended. Note that even if duration is not available in metadata it's possible to signal its end by setting position to the maximum uint32 value. */ Position uint32 /* Repeat Possible values: "off", "singletrack", "alltracks" or "group" */ Repeat string /* Scan Possible values: "off", "alltracks" or "group" */ Scan string /* Searchable If present indicates the player can be searched using MediaFolder interface. Possible values: True: Supported and active False: Supported but inactive Note: If supported but inactive clients can enable it by using MediaFolder interface but it might interfere in the playback of other players. */ Searchable bool /* Shuffle Possible values: "off", "alltracks" or "group" */ Shuffle string /* Status Possible status: "playing", "stopped", "paused", "forward-seek", "reverse-seek" or "error" */ Status string /* Subtype Player subtype Possible values: "Audio Book" "Podcast" */ Subtype string /* Title Track title name */ Title string /* Track Track metadata. Possible values: */ Track Track /* TrackNumber Track number */ TrackNumber uint32 /* Type Player type Possible values: "Audio" "Video" "Audio Broadcasting" "Video Broadcasting" */ Type string } //Lock access to properties func (p *MediaPlayer1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *MediaPlayer1Properties) Unlock() { p.lock.Unlock() } // SetAlbum set Album value func (a *MediaPlayer1) SetAlbum(v string) error { return a.SetProperty("Album", v) } // GetAlbum get Album value func (a *MediaPlayer1) GetAlbum() (string, error) { v, err := a.GetProperty("Album") if err != nil { return "", err } return v.Value().(string), nil } // SetArtist set Artist value func (a *MediaPlayer1) SetArtist(v string) error { return a.SetProperty("Artist", v) } // GetArtist get Artist value func (a *MediaPlayer1) GetArtist() (string, error) { v, err := a.GetProperty("Artist") if err != nil { return "", err } return v.Value().(string), nil } // SetBrowsable set Browsable value func (a *MediaPlayer1) SetBrowsable(v bool) error { return a.SetProperty("Browsable", v) } // GetBrowsable get Browsable value func (a *MediaPlayer1) GetBrowsable() (bool, error) { v, err := a.GetProperty("Browsable") if err != nil { return false, err } return v.Value().(bool), nil } // SetDevice set Device value func (a *MediaPlayer1) SetDevice(v dbus.ObjectPath) error { return a.SetProperty("Device", v) } // GetDevice get Device value func (a *MediaPlayer1) GetDevice() (dbus.ObjectPath, error) { v, err := a.GetProperty("Device") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetDuration set Duration value func (a *MediaPlayer1) SetDuration(v uint32) error { return a.SetProperty("Duration", v) } // GetDuration get Duration value func (a *MediaPlayer1) GetDuration() (uint32, error) { v, err := a.GetProperty("Duration") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetEqualizer set Equalizer value func (a *MediaPlayer1) SetEqualizer(v string) error { return a.SetProperty("Equalizer", v) } // GetEqualizer get Equalizer value func (a *MediaPlayer1) GetEqualizer() (string, error) { v, err := a.GetProperty("Equalizer") if err != nil { return "", err } return v.Value().(string), nil } // SetGenre set Genre value func (a *MediaPlayer1) SetGenre(v string) error { return a.SetProperty("Genre", v) } // GetGenre get Genre value func (a *MediaPlayer1) GetGenre() (string, error) { v, err := a.GetProperty("Genre") if err != nil { return "", err } return v.Value().(string), nil } // SetName set Name value func (a *MediaPlayer1) SetName(v string) error { return a.SetProperty("Name", v) } // GetName get Name value func (a *MediaPlayer1) GetName() (string, error) { v, err := a.GetProperty("Name") if err != nil { return "", err } return v.Value().(string), nil } // SetNumberOfTracks set NumberOfTracks value func (a *MediaPlayer1) SetNumberOfTracks(v uint32) error { return a.SetProperty("NumberOfTracks", v) } // GetNumberOfTracks get NumberOfTracks value func (a *MediaPlayer1) GetNumberOfTracks() (uint32, error) { v, err := a.GetProperty("NumberOfTracks") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetPlaylist set Playlist value func (a *MediaPlayer1) SetPlaylist(v dbus.ObjectPath) error { return a.SetProperty("Playlist", v) } // GetPlaylist get Playlist value func (a *MediaPlayer1) GetPlaylist() (dbus.ObjectPath, error) { v, err := a.GetProperty("Playlist") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetPosition set Position value func (a *MediaPlayer1) SetPosition(v uint32) error { return a.SetProperty("Position", v) } // GetPosition get Position value func (a *MediaPlayer1) GetPosition() (uint32, error) { v, err := a.GetProperty("Position") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetRepeat set Repeat value func (a *MediaPlayer1) SetRepeat(v string) error { return a.SetProperty("Repeat", v) } // GetRepeat get Repeat value func (a *MediaPlayer1) GetRepeat() (string, error) { v, err := a.GetProperty("Repeat") if err != nil { return "", err } return v.Value().(string), nil } // SetScan set Scan value func (a *MediaPlayer1) SetScan(v string) error { return a.SetProperty("Scan", v) } // GetScan get Scan value func (a *MediaPlayer1) GetScan() (string, error) { v, err := a.GetProperty("Scan") if err != nil { return "", err } return v.Value().(string), nil } // SetSearchable set Searchable value func (a *MediaPlayer1) SetSearchable(v bool) error { return a.SetProperty("Searchable", v) } // GetSearchable get Searchable value func (a *MediaPlayer1) GetSearchable() (bool, error) { v, err := a.GetProperty("Searchable") if err != nil { return false, err } return v.Value().(bool), nil } // SetShuffle set Shuffle value func (a *MediaPlayer1) SetShuffle(v string) error { return a.SetProperty("Shuffle", v) } // GetShuffle get Shuffle value func (a *MediaPlayer1) GetShuffle() (string, error) { v, err := a.GetProperty("Shuffle") if err != nil { return "", err } return v.Value().(string), nil } // SetStatus set Status value func (a *MediaPlayer1) SetStatus(v string) error { return a.SetProperty("Status", v) } // GetStatus get Status value func (a *MediaPlayer1) GetStatus() (string, error) { v, err := a.GetProperty("Status") if err != nil { return "", err } return v.Value().(string), nil } // SetSubtype set Subtype value func (a *MediaPlayer1) SetSubtype(v string) error { return a.SetProperty("Subtype", v) } // GetSubtype get Subtype value func (a *MediaPlayer1) GetSubtype() (string, error) { v, err := a.GetProperty("Subtype") if err != nil { return "", err } return v.Value().(string), nil } // SetTitle set Title value func (a *MediaPlayer1) SetTitle(v string) error { return a.SetProperty("Title", v) } // GetTitle get Title value func (a *MediaPlayer1) GetTitle() (string, error) { v, err := a.GetProperty("Title") if err != nil { return "", err } return v.Value().(string), nil } // SetTrack set Track value func (a *MediaPlayer1) SetTrack(v map[string]interface{}) error { return a.SetProperty("Track", v) } // GetTrack get Track value func (a *MediaPlayer1) GetTrack() (map[string]interface{}, error) { v, err := a.GetProperty("Track") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetTrackNumber set TrackNumber value func (a *MediaPlayer1) SetTrackNumber(v uint32) error { return a.SetProperty("TrackNumber", v) } // GetTrackNumber get TrackNumber value func (a *MediaPlayer1) GetTrackNumber() (uint32, error) { v, err := a.GetProperty("TrackNumber") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // SetType set Type value func (a *MediaPlayer1) SetType(v string) error { return a.SetProperty("Type", v) } // GetType get Type value func (a *MediaPlayer1) GetType() (string, error) { v, err := a.GetProperty("Type") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *MediaPlayer1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return MediaPlayer1 object path func (a *MediaPlayer1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return MediaPlayer1 dbus client func (a *MediaPlayer1) Client() *bluez.Client { return a.client } // Interface return MediaPlayer1 interface func (a *MediaPlayer1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *MediaPlayer1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a MediaPlayer1Properties to map func (a *MediaPlayer1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an MediaPlayer1Properties func (a *MediaPlayer1Properties) FromMap(props map[string]interface{}) (*MediaPlayer1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an MediaPlayer1Properties func (a *MediaPlayer1Properties) FromDBusMap(props map[string]dbus.Variant) (*MediaPlayer1Properties, error) { s := new(MediaPlayer1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *MediaPlayer1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *MediaPlayer1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *MediaPlayer1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *MediaPlayer1) GetProperties() (*MediaPlayer1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *MediaPlayer1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *MediaPlayer1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *MediaPlayer1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *MediaPlayer1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *MediaPlayer1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *MediaPlayer1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Play Resume playback. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Play() error { return a.client.Call("Play", 0).Store() } /* Pause Pause playback. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Pause() error { return a.client.Call("Pause", 0).Store() } /* Stop Stop playback. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Stop() error { return a.client.Call("Stop", 0).Store() } /* Next Next item. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Next() error { return a.client.Call("Next", 0).Store() } /* Previous Previous item. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Previous() error { return a.client.Call("Previous", 0).Store() } /* FastForward Fast forward playback, this action is only stopped when another method in this interface is called. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) FastForward() error { return a.client.Call("FastForward", 0).Store() } /* Rewind Rewind playback, this action is only stopped when another method in this interface is called. Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Rewind() error { return a.client.Call("Rewind", 0).Store() } /* Press Press a specific key to send as passthrough command. The key will be released automatically. Use Hold() instead if the intention is to hold down the key. Possible Errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Press(avc_key byte) error { return a.client.Call("Press", 0, avc_key).Store() } /* Hold Press and hold a specific key to send as passthrough command. It is your responsibility to make sure that Release() is called after calling this method. The held key will also be released when any other method in this interface is called. Possible Errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Hold(avc_key byte) error { return a.client.Call("Hold", 0, avc_key).Store() } /* Release Release the previously held key invoked using Hold(). Possible Errors: org.bluez.Error.NotSupported org.bluez.Error.Failed */ func (a *MediaPlayer1) Release() error { return a.client.Call("Release", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/media/gen_MediaTransport1.go000066400000000000000000000241671420407601400252400ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package media import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var MediaTransport1Interface = "org.bluez.MediaTransport1" // NewMediaTransport1 create a new instance of MediaTransport1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX func NewMediaTransport1(objectPath dbus.ObjectPath) (*MediaTransport1, error) { a := new(MediaTransport1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: MediaTransport1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MediaTransport1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* MediaTransport1 MediaTransport1 hierarchy */ type MediaTransport1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *MediaTransport1Properties watchPropertiesChannel chan *dbus.Signal } // MediaTransport1Properties contains the exposed properties of an interface type MediaTransport1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Codec Assigned number of codec that the transport support. The values should match the profile specification which is indicated by the UUID. */ Codec byte /* Configuration Configuration blob, it is used as it is so the size and byte order must match. */ Configuration []byte /* Delay Optional. Transport delay in 1/10 of millisecond, this property is only writeable when the transport was acquired by the sender. */ Delay uint16 /* Device Device object which the transport is connected to. */ Device dbus.ObjectPath /* Endpoint Endpoint object which the transport is associated with. */ Endpoint dbus.ObjectPath /* State Indicates the state of the transport. Possible values are: "idle": not streaming "pending": streaming but not acquired "active": streaming and acquired */ State string /* UUID UUID of the profile which the transport is for. */ UUID string /* Volume Optional. Indicates volume level of the transport, this property is only writeable when the transport was acquired by the sender. Possible Values: 0-127 */ Volume uint16 } //Lock access to properties func (p *MediaTransport1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *MediaTransport1Properties) Unlock() { p.lock.Unlock() } // SetCodec set Codec value func (a *MediaTransport1) SetCodec(v byte) error { return a.SetProperty("Codec", v) } // GetCodec get Codec value func (a *MediaTransport1) GetCodec() (byte, error) { v, err := a.GetProperty("Codec") if err != nil { return byte(0), err } return v.Value().(byte), nil } // SetConfiguration set Configuration value func (a *MediaTransport1) SetConfiguration(v []byte) error { return a.SetProperty("Configuration", v) } // GetConfiguration get Configuration value func (a *MediaTransport1) GetConfiguration() ([]byte, error) { v, err := a.GetProperty("Configuration") if err != nil { return []byte{}, err } return v.Value().([]byte), nil } // SetDelay set Delay value func (a *MediaTransport1) SetDelay(v uint16) error { return a.SetProperty("Delay", v) } // GetDelay get Delay value func (a *MediaTransport1) GetDelay() (uint16, error) { v, err := a.GetProperty("Delay") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetDevice set Device value func (a *MediaTransport1) SetDevice(v dbus.ObjectPath) error { return a.SetProperty("Device", v) } // GetDevice get Device value func (a *MediaTransport1) GetDevice() (dbus.ObjectPath, error) { v, err := a.GetProperty("Device") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetEndpoint set Endpoint value func (a *MediaTransport1) SetEndpoint(v dbus.ObjectPath) error { return a.SetProperty("Endpoint", v) } // GetEndpoint get Endpoint value func (a *MediaTransport1) GetEndpoint() (dbus.ObjectPath, error) { v, err := a.GetProperty("Endpoint") if err != nil { return dbus.ObjectPath(""), err } return v.Value().(dbus.ObjectPath), nil } // SetState set State value func (a *MediaTransport1) SetState(v string) error { return a.SetProperty("State", v) } // GetState get State value func (a *MediaTransport1) GetState() (string, error) { v, err := a.GetProperty("State") if err != nil { return "", err } return v.Value().(string), nil } // SetUUID set UUID value func (a *MediaTransport1) SetUUID(v string) error { return a.SetProperty("UUID", v) } // GetUUID get UUID value func (a *MediaTransport1) GetUUID() (string, error) { v, err := a.GetProperty("UUID") if err != nil { return "", err } return v.Value().(string), nil } // SetVolume set Volume value func (a *MediaTransport1) SetVolume(v uint16) error { return a.SetProperty("Volume", v) } // GetVolume get Volume value func (a *MediaTransport1) GetVolume() (uint16, error) { v, err := a.GetProperty("Volume") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // Close the connection func (a *MediaTransport1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return MediaTransport1 object path func (a *MediaTransport1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return MediaTransport1 dbus client func (a *MediaTransport1) Client() *bluez.Client { return a.client } // Interface return MediaTransport1 interface func (a *MediaTransport1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *MediaTransport1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a MediaTransport1Properties to map func (a *MediaTransport1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an MediaTransport1Properties func (a *MediaTransport1Properties) FromMap(props map[string]interface{}) (*MediaTransport1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an MediaTransport1Properties func (a *MediaTransport1Properties) FromDBusMap(props map[string]dbus.Variant) (*MediaTransport1Properties, error) { s := new(MediaTransport1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *MediaTransport1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *MediaTransport1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *MediaTransport1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *MediaTransport1) GetProperties() (*MediaTransport1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *MediaTransport1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *MediaTransport1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *MediaTransport1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *MediaTransport1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *MediaTransport1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *MediaTransport1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Acquire Acquire transport file descriptor and the MTU for read and write respectively. Possible Errors: org.bluez.Error.NotAuthorized org.bluez.Error.Failed */ func (a *MediaTransport1) Acquire() (dbus.UnixFD, uint16, uint16, error) { var val0 dbus.UnixFD var val1 uint16 var val2 uint16 err := a.client.Call("Acquire", 0).Store(&val0, &val1, &val2) return val0, val1, val2, err } /* TryAcquire Acquire transport file descriptor only if the transport is in "pending" state at the time the message is received by BlueZ. Otherwise no request will be sent to the remote device and the function will just fail with org.bluez.Error.NotAvailable. Possible Errors: org.bluez.Error.NotAuthorized org.bluez.Error.Failed org.bluez.Error.NotAvailable */ func (a *MediaTransport1) TryAcquire() (dbus.UnixFD, uint16, uint16, error) { var val0 dbus.UnixFD var val1 uint16 var val2 uint16 err := a.client.Call("TryAcquire", 0).Store(&val0, &val1, &val2) return val0, val1, val2, err } /* Release Releases file descriptor. */ func (a *MediaTransport1) Release() error { return a.client.Call("Release", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/media/gen_media.go000066400000000000000000000002021420407601400232620ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Media API description [media-api.txt] */ package media go-bluetooth-bluez-5.60/bluez/profile/media/types.go000066400000000000000000000007761420407601400225360ustar00rootroot00000000000000package media import "github.com/godbus/dbus/v5" // Item map to array{objects, properties} type Item struct { Object dbus.ObjectPath Property map[string]interface{} } // Track map to a media track type Track struct { // Track title name Title string // Track artist name Artist string // Track album name Album string // Track genre name Genre string // Number of tracks in total NumberOfTracks uint32 // Track number TrackNumber uint32 // Track duration in milliseconds Duration uint32 } go-bluetooth-bluez-5.60/bluez/profile/mesh/000077500000000000000000000000001420407601400207065ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_Application1.go000066400000000000000000000167451420407601400244270ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Application1Interface = "org.bluez.mesh.Application1" // NewApplication1 create a new instance of Application1 // // Args: // - servicePath: unique name // - objectPath: func NewApplication1(servicePath string, objectPath dbus.ObjectPath) (*Application1, error) { a := new(Application1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: Application1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Application1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Application1 Mesh Application Hierarchy */ type Application1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Application1Properties watchPropertiesChannel chan *dbus.Signal } // Application1Properties contains the exposed properties of an interface type Application1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* CRPL A 16-bit minimum number of replay protection list entries */ CRPL uint16 /* CompanyID A 16-bit Bluetooth-assigned Company Identifier of the vendor as defined by Bluetooth SIG */ CompanyID uint16 /* ProductID A 16-bit vendor-assigned product identifier */ ProductID uint16 /* VersionID A 16-bit vendor-assigned product version identifier */ VersionID uint16 } //Lock access to properties func (p *Application1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Application1Properties) Unlock() { p.lock.Unlock() } // GetCRPL get CRPL value func (a *Application1) GetCRPL() (uint16, error) { v, err := a.GetProperty("CRPL") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetCompanyID get CompanyID value func (a *Application1) GetCompanyID() (uint16, error) { v, err := a.GetProperty("CompanyID") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetProductID get ProductID value func (a *Application1) GetProductID() (uint16, error) { v, err := a.GetProperty("ProductID") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetVersionID get VersionID value func (a *Application1) GetVersionID() (uint16, error) { v, err := a.GetProperty("VersionID") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // Close the connection func (a *Application1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Application1 object path func (a *Application1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Application1 dbus client func (a *Application1) Client() *bluez.Client { return a.client } // Interface return Application1 interface func (a *Application1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Application1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Application1Properties to map func (a *Application1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Application1Properties func (a *Application1Properties) FromMap(props map[string]interface{}) (*Application1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Application1Properties func (a *Application1Properties) FromDBusMap(props map[string]dbus.Variant) (*Application1Properties, error) { s := new(Application1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Application1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Application1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Application1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Application1) GetProperties() (*Application1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Application1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Application1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Application1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Application1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Application1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Application1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* JoinComplete This method is called when the node provisioning initiated by a Join() method call successfully completed. The token parameter serves as a unique identifier of the particular node. The token must be preserved by the application in order to authenticate itself to the mesh daemon and attach to the network as a mesh node by calling Attach() method or permanently remove the identity of the mesh node by calling Leave() method. If this method returns an error, the daemon will assume that the application failed to preserve the token, and will remove the freshly created node. */ func (a *Application1) JoinComplete(token uint64) error { return a.client.Call("JoinComplete", 0, token).Store() } /* JoinFailed This method is called when the node provisioning initiated by Join() has failed. The reason parameter identifies the reason for provisioning failure. The defined values are: "timeout", "bad-pdu", "confirmation-failed", "out-of-resources", "decryption-error", "unexpected-error", "cannot-assign-addresses". */ func (a *Application1) JoinFailed(reason string) error { return a.client.Call("JoinFailed", 0, reason).Store() } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_Attention1.go000066400000000000000000000135711420407601400241230ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Attention1Interface = "org.bluez.mesh.Attention1" // NewAttention1 create a new instance of Attention1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewAttention1(servicePath string, objectPath dbus.ObjectPath) (*Attention1, error) { a := new(Attention1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: Attention1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Attention1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Attention1 Mesh Attention Hierarchy */ type Attention1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Attention1Properties watchPropertiesChannel chan *dbus.Signal } // Attention1Properties contains the exposed properties of an interface type Attention1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Attention1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Attention1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Attention1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Attention1 object path func (a *Attention1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Attention1 dbus client func (a *Attention1) Client() *bluez.Client { return a.client } // Interface return Attention1 interface func (a *Attention1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Attention1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Attention1Properties to map func (a *Attention1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Attention1Properties func (a *Attention1Properties) FromMap(props map[string]interface{}) (*Attention1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Attention1Properties func (a *Attention1Properties) FromDBusMap(props map[string]dbus.Variant) (*Attention1Properties, error) { s := new(Attention1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Attention1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Attention1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Attention1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Attention1) GetProperties() (*Attention1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Attention1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Attention1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Attention1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Attention1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Attention1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Attention1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* SetTimer The element_index parameter is the element's index within the node where the health server model is hosted. The time parameter indicates how many seconds the attention state shall be on. PossibleErrors: org.bluez.mesh.Error.NotSupported */ func (a *Attention1) SetTimer(element_index uint8, time uint16) error { return a.client.Call("SetTimer", 0, element_index, time).Store() } /* GetTimer The element parameter is the unicast address within the node where the health server model is hosted. Returns the number of seconds for how long the attention action remains staying on. PossibleErrors: org.bluez.mesh.Error.NotSupported */ func (a *Attention1) GetTimer(element uint16) (uint16, error) { var val0 uint16 err := a.client.Call("GetTimer", 0, element).Store(&val0) return val0, err } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_Element1.go000066400000000000000000000236001420407601400235410ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Element1Interface = "org.bluez.mesh.Element1" // NewElement1 create a new instance of Element1 // // Args: // - servicePath: unique name // - objectPath: func NewElement1(servicePath string, objectPath dbus.ObjectPath) (*Element1, error) { a := new(Element1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: Element1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Element1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Element1 Mesh Element Hierarchy */ type Element1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Element1Properties watchPropertiesChannel chan *dbus.Signal } // Element1Properties contains the exposed properties of an interface type Element1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Location Location descriptor as defined in the GATT Bluetooth Namespace Descriptors section of the Bluetooth SIG Assigned Numbers */ Location uint16 /* Models An array of SIG Models: id - SIG Model Identifier options - a dictionary that may contain additional model info. The following keys are defined: */ Models []ConfigurationItem /* Publish supports publication mechanism */ Publish bool /* Subscribe supports subscription mechanism The array may be empty. */ Subscribe bool /* VendorModels An array of Vendor Models: vendor - a 16-bit Bluetooth-assigned Company ID as defined by Bluetooth SIG. id - a 16-bit vendor-assigned Model Identifier options - a dictionary that may contain additional model info. The following keys are defined: */ VendorModels []VendorOptionsItem } //Lock access to properties func (p *Element1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Element1Properties) Unlock() { p.lock.Unlock() } // GetLocation get Location value func (a *Element1) GetLocation() (uint16, error) { v, err := a.GetProperty("Location") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // GetModels get Models value func (a *Element1) GetModels() ([]ConfigurationItem, error) { v, err := a.GetProperty("Models") if err != nil { return []ConfigurationItem{}, err } return v.Value().([]ConfigurationItem), nil } // SetPublish set Publish value func (a *Element1) SetPublish(v bool) error { return a.SetProperty("Publish", v) } // GetPublish get Publish value func (a *Element1) GetPublish() (bool, error) { v, err := a.GetProperty("Publish") if err != nil { return false, err } return v.Value().(bool), nil } // SetSubscribe set Subscribe value func (a *Element1) SetSubscribe(v bool) error { return a.SetProperty("Subscribe", v) } // GetSubscribe get Subscribe value func (a *Element1) GetSubscribe() (bool, error) { v, err := a.GetProperty("Subscribe") if err != nil { return false, err } return v.Value().(bool), nil } // GetVendorModels get VendorModels value func (a *Element1) GetVendorModels() ([]VendorOptionsItem, error) { v, err := a.GetProperty("VendorModels") if err != nil { return []VendorOptionsItem{}, err } return v.Value().([]VendorOptionsItem), nil } // Close the connection func (a *Element1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Element1 object path func (a *Element1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Element1 dbus client func (a *Element1) Client() *bluez.Client { return a.client } // Interface return Element1 interface func (a *Element1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Element1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Element1Properties to map func (a *Element1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Element1Properties func (a *Element1Properties) FromMap(props map[string]interface{}) (*Element1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Element1Properties func (a *Element1Properties) FromDBusMap(props map[string]dbus.Variant) (*Element1Properties, error) { s := new(Element1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Element1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Element1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Element1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Element1) GetProperties() (*Element1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Element1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Element1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Element1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Element1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Element1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Element1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* MessageReceived This method is called by bluetooth-meshd daemon when a message arrives addressed to the application. The source parameter is unicast address of the remote node-element that sent the message. The key_index parameter indicates which application key has been used to decode the incoming message. The same key_index should be used by the application when sending a response to this message (in case a response is expected). The destination parameter contains the destination address of received message. Underlying variant types are: uint16 Destination is an unicast address, or a well known group address array{byte} Destination is a virtual address label The data parameter is the incoming message. */ func (a *Element1) MessageReceived(source uint16, key_index uint16, destination dbus.Variant, data []byte) error { return a.client.Call("MessageReceived", 0, source, key_index, destination, data).Store() } /* DevKeyMessageReceived This method is called by meshd daemon when a message arrives addressed to the application, which was sent with the remote node's device key. The source parameter is unicast address of the remote node-element that sent the message. The remote parameter if true indicates that the device key used to decrypt the message was from the sender. False indicates that the local nodes device key was used, and the message has permissions to modify local states. The net_index parameter indicates what subnet the message was received on, and if a response is required, the same subnet must be used to send the response. The data parameter is the incoming message. */ func (a *Element1) DevKeyMessageReceived(source uint16, remote bool, net_index uint16, data []byte) error { return a.client.Call("DevKeyMessageReceived", 0, source, remote, net_index, data).Store() } /* UpdateModelConfiguration This method is called by bluetooth-meshd daemon when a model's configuration is updated. The model_id parameter contains BT SIG Model Identifier or, if Vendor key is present in config dictionary, a 16-bit vendor-assigned Model Identifier. The config parameter is a dictionary with the following keys defined: array{uint16} Bindings Indices of application keys bound to the model uint32 PublicationPeriod Model publication period in milliseconds uint16 Vendor A 16-bit Bluetooth-assigned Company Identifier of the vendor as defined by Bluetooth SIG array{variant} Subscriptions Addresses the model is subscribed to. Each address is provided either as uint16 for group addresses, or as array{byte} for virtual labels. */ func (a *Element1) UpdateModelConfiguration(model_id uint16, config map[string]interface{}) error { return a.client.Call("UpdateModelConfiguration", 0, model_id, config).Store() } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_Management1.go000066400000000000000000000344201420407601400242260ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Management1Interface = "org.bluez.mesh.Management1" // NewManagement1 create a new instance of Management1 // // Args: func NewManagement1(objectPath dbus.ObjectPath) (*Management1, error) { a := new(Management1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.mesh", Iface: Management1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Management1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Management1 Mesh Provisioning Hierarchy */ type Management1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Management1Properties watchPropertiesChannel chan *dbus.Signal } // Management1Properties contains the exposed properties of an interface type Management1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Management1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Management1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Management1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Management1 object path func (a *Management1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Management1 dbus client func (a *Management1) Client() *bluez.Client { return a.client } // Interface return Management1 interface func (a *Management1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Management1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Management1Properties to map func (a *Management1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Management1Properties func (a *Management1Properties) FromMap(props map[string]interface{}) (*Management1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Management1Properties func (a *Management1Properties) FromDBusMap(props map[string]dbus.Variant) (*Management1Properties, error) { s := new(Management1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Management1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Management1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Management1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Management1) GetProperties() (*Management1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Management1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Management1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Management1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Management1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Management1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Management1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* UnprovisionedScan This method is used by the application that supports org.bluez.mesh.Provisioner1 interface to start listening (scanning) for unprovisioned devices in the area. The options parameter is a dictionary with the following keys defined: uint16 Seconds Specifies number of seconds for scanning to be active. If set to 0 or if this key is not present, then the scanning will continue until UnprovisionedScanCancel() or AddNode() methods are called. Each time a unique unprovisioned beacon is heard, the ScanResult() method on the app will be called with the result. PossibleErrors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotAuthorized org.bluez.mesh.Error.Busy */ func (a *Management1) UnprovisionedScan(options map[string]interface{}) error { return a.client.Call("UnprovisionedScan", 0, options).Store() } /* UnprovisionedScanCancel */ func (a *Management1) UnprovisionedScanCancel() error { return a.client.Call("UnprovisionedScanCancel", 0).Store() } /* AddNode This method is used by the application that supports org.bluez.mesh.Provisioner1 interface to add the unprovisioned device specified by uuid, to the Network. The uuid parameter is a 16-byte array that contains Device UUID of the unprovisioned device to be added to the network. The options parameter is a dictionary that may contain additional configuration info (currently an empty placeholder for forward compatibility). PossibleErrors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotAuthorized */ func (a *Management1) AddNode(uuid []byte, options map[string]interface{}) error { return a.client.Call("AddNode", 0, uuid, options).Store() } /* CreateSubnet This method is used by the application to generate and add a new network subnet key. The net_index parameter is a 12-bit value (0x001-0xFFF) specifying which net key to add. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.AlreadyExists */ func (a *Management1) CreateSubnet(net_index uint16) error { return a.client.Call("CreateSubnet", 0, net_index).Store() } /* ImportSubnet This method is used by the application to add a network subnet key, that was originally generated by a remote Config Client. The net_index parameter is a 12-bit value (0x000-0xFFF) specifying which net key to add. The net_key parameter is the 16-byte value of the net key being imported. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.AlreadyExists */ func (a *Management1) ImportSubnet(net_index uint16, net_key []byte) error { return a.client.Call("ImportSubnet", 0, net_index, net_key).Store() } /* UpdateSubnet This method is used by the application to generate a new network subnet key, and set it's key refresh state to Phase 1. The net_index parameter is a 12-bit value (0x000-0xFFF) specifying which net key to update. Note that the subnet must exist prior to updating. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.DoesNotExist org.bluez.mesh.Error.Busy */ func (a *Management1) UpdateSubnet(net_index uint16) error { return a.client.Call("UpdateSubnet", 0, net_index).Store() } /* DeleteSubnet This method is used by the application that to delete a subnet. The net_index parameter is a 12-bit value (0x001-0xFFF) specifying which net key to delete. The primary net key (0x000) may not be deleted. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.InvalidArguments */ func (a *Management1) DeleteSubnet(net_index uint16) error { return a.client.Call("DeleteSubnet", 0, net_index).Store() } /* SetKeyPhase This method is used to set the master key update phase of the given subnet. When finalizing the procedure, it is important to CompleteAppKeyUpdate() on all app keys that have been updated during the procedure prior to setting phase 3. The net_index parameter is a 12-bit value (0x000-0xFFF) specifying which subnet phase to set. The phase parameter is used to cycle the local key database through the phases as defined by the Mesh Profile Specification. Allowed values: 0 - Cancel Key Refresh (May only be called from Phase 1, and should never be called once the new key has started propagating) 1 - Invalid Argument (see NetKeyUpdate method) 2 - Go to Phase 2 (May only be called from Phase 1) 3 - Complete Key Refresh procedure (May only be called from Phase 2) This call affects the local bluetooth-meshd key database only. It is the responsibility of the application to maintain the key refresh phases per the Mesh Profile Specification. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.DoesNotExist */ func (a *Management1) SetKeyPhase(net_index uint16, phase uint8) error { return a.client.Call("SetKeyPhase", 0, net_index, phase).Store() } /* CreateAppKey This method is used by the application to generate and add a new application key. The net_index parameter is a 12-bit value (0x000-0xFFF) specifying which net key to bind the application key to. The app_index parameter is a 12-bit value (0x000-0xFFF) specifying which app key to add. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.AlreadyExists org.bluez.mesh.Error.DoesNotExist */ func (a *Management1) CreateAppKey(net_index uint16, app_index uint16) error { return a.client.Call("CreateAppKey", 0, net_index, app_index).Store() } /* ImportAppKey This method is used by the application to add an application key, that was originally generated by a remote Config Client. The net_index parameter is a 12-bit value (0x000-0xFFF) specifying which net key to bind the application key to. The app_index parameter is a 12-bit value (0x000-0xFFF) specifying which app key to import. The app_key parameter is the 16-byte value of the key being imported. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.AlreadyExists org.bluez.mesh.Error.DoesNotExist */ func (a *Management1) ImportAppKey(net_index uint16, app_index uint16, app_key []byte) error { return a.client.Call("ImportAppKey", 0, net_index, app_index, app_key).Store() } /* UpdateAppKey This method is used by the application to generate a new application key. The app_index parameter is a 12-bit value (0x000-0xFFF) specifying which app key to update. Note that the subnet that the key is bound to must exist and be in Phase 1. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.DoesNotExist org.bluez.mesh.Error.InProgress */ func (a *Management1) UpdateAppKey(app_index uint16) error { return a.client.Call("UpdateAppKey", 0, app_index).Store() } /* DeleteAppKey This method is used by the application to delete an application key. The app_index parameter is a 12-bit value (0x000-0xFFF) specifying which app key to delete. This call affects the local bluetooth-meshd key database only. PossibleErrors: org.bluez.mesh.Error.InvalidArguments */ func (a *Management1) DeleteAppKey(app_index uint16) error { return a.client.Call("DeleteAppKey", 0, app_index).Store() } /* ImportRemoteNode This method is used by the application to import a remote node that has been provisioned by an external process. The primary parameter specifies the unicast address of the the node being imported. The count parameter specifies the number of elements that are assigned to this remote node. The device_key parameter is the access layer key that will be will used to decrypt privledged messages from this remote node. This call affects the local bluetooth-meshd key database only. It is an error to call this with address range overlapping with local element addresses. PossibleErrors: org.bluez.mesh.Error.Failed org.bluez.mesh.Error.InvalidArguments */ func (a *Management1) ImportRemoteNode(primary uint16, count uint8, device_key []byte) error { return a.client.Call("ImportRemoteNode", 0, primary, count, device_key).Store() } /* DeleteRemoteNode This method is used by the application to delete a remote node from the local device key database. The primary parameter specifies the unicast address of the the node being deleted. The count parameter specifies the number of elements that were assigned to the remote node. This call affects the local bluetooth-meshd key database only. It is an error to call this with address range overlapping with local element addresses. PossibleErrors: org.bluez.mesh.Error.InvalidArguments */ func (a *Management1) DeleteRemoteNode(primary uint16, count uint8) error { return a.client.Call("DeleteRemoteNode", 0, primary, count).Store() } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_Network1.go000066400000000000000000000312071420407601400236030ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Network1Interface = "org.bluez.mesh.Network1" // NewNetwork1 create a new instance of Network1 // // Args: func NewNetwork1() (*Network1, error) { a := new(Network1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.mesh", Iface: Network1Interface, Path: dbus.ObjectPath("/org/bluez/mesh"), Bus: bluez.SystemBus, }, ) a.Properties = new(Network1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Network1 Mesh Network Hierarchy */ type Network1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Network1Properties watchPropertiesChannel chan *dbus.Signal } // Network1Properties contains the exposed properties of an interface type Network1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Network1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Network1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Network1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Network1 object path func (a *Network1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Network1 dbus client func (a *Network1) Client() *bluez.Client { return a.client } // Interface return Network1 interface func (a *Network1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Network1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Network1Properties to map func (a *Network1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Network1Properties func (a *Network1Properties) FromMap(props map[string]interface{}) (*Network1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Network1Properties func (a *Network1Properties) FromDBusMap(props map[string]dbus.Variant) (*Network1Properties, error) { s := new(Network1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Network1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Network1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Network1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Network1) GetProperties() (*Network1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Network1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Network1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Network1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Network1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Network1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Network1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Join This is the first method that an application has to call to become a provisioned node on a mesh network. The call will initiate broadcasting of Unprovisioned Device Beacon. The app_root parameter is a D-Bus object root path of the application that implements org.bluez.mesh.Application1 interface. The application represents a node where child mesh elements have their own objects that implement org.bluez.mesh.Element1 interface. The application hierarchy also contains a provision agent object that implements org.bluez.mesh.ProvisionAgent1 interface. The standard DBus.ObjectManager interface must be available on the app_root path. The uuid parameter is a 16-byte array that contains Device UUID. This UUID must be unique (at least from the daemon perspective), therefore attempting to call this function using already registered UUID results in an error. The composition of the UUID octets must be in compliance with RFC 4122. When provisioning finishes, the daemon will call either JoinComplete or JoinFailed method on object implementing org.bluez.mesh.Application1 interface. PossibleErrors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.AlreadyExists, */ func (a *Network1) Join(app_root dbus.ObjectPath, uuid []byte) error { return a.client.Call("Join", 0, app_root, uuid).Store() } /* Cancel */ func (a *Network1) Cancel() error { return a.client.Call("Cancel", 0).Store() } /* Attach This is the first method that an application must call to get access to mesh node functionalities. The app_root parameter is a D-Bus object root path of the application that implements org.bluez.mesh.Application1 interface. The application represents a node where child mesh elements have their own objects that implement org.bluez.mesh.Element1 interface. The standard DBus.ObjectManager interface must be available on the app_root path. The token parameter is a 64-bit number that has been assigned to the application when it first got provisioned/joined mesh network, i.e. upon receiving JoinComplete() method. The daemon uses the token to verify whether the application is authorized to assume the mesh node identity. In case of success, the method call returns mesh node object (see Mesh Node Hierarchy section) and current configuration settings. The return value of configuration parameter is an array, where each entry is a structure that contains element configuration. The element configuration structure is organized as follows: byte Element index, identifies the element to which this configuration entry pertains. array{struct} Models array where each entry is a structure with the following members: uint16 Either a SIG Model Identifier or, if Vendor key is present in model configuration dictionary, a 16-bit vendor-assigned Model Identifier dict A dictionary that contains model configuration with the following keys defined: array{uint16} Bindings Indices of application keys bound to the model uint32 PublicationPeriod Model publication period in milliseconds uint16 Vendor A 16-bit Company ID as defined by the Bluetooth SIG array{variant} Subscriptions Addresses the model is subscribed to. Each address is provided either as uint16 for group addresses, or as array{byte} for virtual labels. PossibleErrors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotFound, org.bluez.mesh.Error.AlreadyExists, org.bluez.mesh.Error.Busy, org.bluez.mesh.Error.Failed */ func (a *Network1) Attach(app_root dbus.ObjectPath, token uint64) (dbus.ObjectPath, []ConfigurationItem, error) { var val0 dbus.ObjectPath val1 := []ConfigurationItem{} err := a.client.Call("Attach", 0, app_root, token).Store(&val0, &val1) return val0, val1, err } /* Leave This removes the configuration information about the mesh node identified by the 64-bit token parameter. The token parameter has been obtained as a result of successful Join() method call. PossibleErrors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotFound org.bluez.mesh.Error.Busy */ func (a *Network1) Leave(token uint64) error { return a.client.Call("Leave", 0, token).Store() } /* CreateNetwork This is the first method that an application calls to become a Provisioner node, and a Configuration Client on a newly created Mesh Network. The app_root parameter is a D-Bus object root path of the application that implements org.bluez.mesh.Application1 interface, and a org.bluez.mesh.Provisioner1 interface. The application represents a node where child mesh elements have their own objects that implement org.bluez.mesh.Element1 interface. The application hierarchy also contains a provision agent object that implements org.bluez.mesh.ProvisionAgent1 interface. The standard DBus.ObjectManager interface must be available on the app_root path. The uuid parameter is a 16-byte array that contains Device UUID. This UUID must be unique (at least from the daemon perspective), therefore attempting to call this function using already registered UUID results in an error. The composition of the UUID octets must be in compliance with RFC 4122. The other information the bluetooth-meshd daemon will preserve about the initial node, is to give it the initial primary unicast address (0x0001), and create and assign a net_key as the primary network net_index (0x000). Upon successful processing of Create() method, the daemon will call JoinComplete method on object implementing org.bluez.mesh.Application1. PossibleErrors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.AlreadyExists, */ func (a *Network1) CreateNetwork(app_root dbus.ObjectPath, uuid []byte) error { return a.client.Call("CreateNetwork", 0, app_root, uuid).Store() } /* Import This method creates a local mesh node based on node configuration that has been generated outside bluetooth-meshd. The app_root parameter is a D-Bus object root path of the application that implements org.bluez.mesh.Application1 interface. The uuid parameter is a 16-byte array that contains Device UUID. This UUID must be unique (at least from the daemon perspective), therefore attempting to call this function using already registered UUID results in an error. The composition of the UUID octets must be in compliance with RFC 4122. The dev_key parameter is the 16-byte value of the dev key of the imported mesh node. Remaining parameters correspond to provisioning data: The net_key and net_index parameters describe the network (or a subnet, if net_index is not 0) the imported mesh node belongs to. The flags parameter is a dictionary containing provisioning flags. Supported values are: boolean IvUpdate When true, indicates that the network is in the middle of IV Index Update procedure. boolean KeyRefresh When true, indicates that the specified net key is in the middle of a key refresh procedure. The iv_index parameter is the current IV Index value used by the network. This value is known by the provisioner. The unicast parameter is the primary unicast address of the imported node. Upon successful processing of Import() method, the daemon will call JoinComplete method on object implementing org.bluez.mesh.Application1 interface. PossibleErrors: org.bluez.mesh.Error.InvalidArguments, org.bluez.mesh.Error.AlreadyExists, org.bluez.mesh.Error.NotSupported, org.bluez.mesh.Error.Failed */ func (a *Network1) Import(app_root dbus.ObjectPath, uuid []byte, dev_key []byte, net_key []byte, net_index uint16, flags map[string]interface{}, iv_index uint32, unicast uint16) error { return a.client.Call("Import", 0, app_root, uuid, dev_key, net_key, net_index, flags, iv_index, unicast).Store() } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_Node1.go000066400000000000000000000367701420407601400230510ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Node1Interface = "org.bluez.mesh.Node1" // NewNode1 create a new instance of Node1 // // Args: func NewNode1(objectPath dbus.ObjectPath) (*Node1, error) { a := new(Node1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.mesh", Iface: Node1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Node1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Node1 Mesh Node Hierarchy */ type Node1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Node1Properties watchPropertiesChannel chan *dbus.Signal } // Node1Properties contains the exposed properties of an interface type Node1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Addresses This property contains unicast addresses of node's elements. */ Addresses []uint16 /* Beacon This property indicates whether the periodic beaconing is enabled (true) or disabled (false). */ Beacon bool /* Features The dictionary that contains information about feature support. The following keys are defined: */ Features map[string]interface{} /* Friend Indicates the ability to establish a friendship with a Low Power node */ Friend bool /* IvIndex This property may be read at any time to determine the IV_Index that the current network is on. This information is only useful for provisioning. */ IvIndex uint32 /* IvUpdate When true, indicates that the network is in the middle of IV Index Update procedure. This information is only useful for provisioning. */ IvUpdate bool /* LowPower Indicates support for operating in Low Power node mode */ LowPower bool /* Proxy Indicates support for GATT proxy */ Proxy bool /* Relay Indicates support for relaying messages If a key is absent from the dictionary, the feature is not supported. Otherwise, true means that the feature is enabled and false means that the feature is disabled. */ Relay bool /* SecondsSinceLastHeard This property may be read at any time to determine the number of seconds since mesh network layer traffic was last detected on this node's network. */ SecondsSinceLastHeard uint32 /* SequenceNumber This property may be read at any time to determine the sequence number. */ SequenceNumber uint32 } //Lock access to properties func (p *Node1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Node1Properties) Unlock() { p.lock.Unlock() } // GetAddresses get Addresses value func (a *Node1) GetAddresses() ([]uint16, error) { v, err := a.GetProperty("Addresses") if err != nil { return []uint16{}, err } return v.Value().([]uint16), nil } // GetBeacon get Beacon value func (a *Node1) GetBeacon() (bool, error) { v, err := a.GetProperty("Beacon") if err != nil { return false, err } return v.Value().(bool), nil } // GetFeatures get Features value func (a *Node1) GetFeatures() (map[string]interface{}, error) { v, err := a.GetProperty("Features") if err != nil { return map[string]interface{}{}, err } return v.Value().(map[string]interface{}), nil } // SetFriend set Friend value func (a *Node1) SetFriend(v bool) error { return a.SetProperty("Friend", v) } // GetFriend get Friend value func (a *Node1) GetFriend() (bool, error) { v, err := a.GetProperty("Friend") if err != nil { return false, err } return v.Value().(bool), nil } // GetIvIndex get IvIndex value func (a *Node1) GetIvIndex() (uint32, error) { v, err := a.GetProperty("IvIndex") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // GetIvUpdate get IvUpdate value func (a *Node1) GetIvUpdate() (bool, error) { v, err := a.GetProperty("IvUpdate") if err != nil { return false, err } return v.Value().(bool), nil } // SetLowPower set LowPower value func (a *Node1) SetLowPower(v bool) error { return a.SetProperty("LowPower", v) } // GetLowPower get LowPower value func (a *Node1) GetLowPower() (bool, error) { v, err := a.GetProperty("LowPower") if err != nil { return false, err } return v.Value().(bool), nil } // SetProxy set Proxy value func (a *Node1) SetProxy(v bool) error { return a.SetProperty("Proxy", v) } // GetProxy get Proxy value func (a *Node1) GetProxy() (bool, error) { v, err := a.GetProperty("Proxy") if err != nil { return false, err } return v.Value().(bool), nil } // SetRelay set Relay value func (a *Node1) SetRelay(v bool) error { return a.SetProperty("Relay", v) } // GetRelay get Relay value func (a *Node1) GetRelay() (bool, error) { v, err := a.GetProperty("Relay") if err != nil { return false, err } return v.Value().(bool), nil } // GetSecondsSinceLastHeard get SecondsSinceLastHeard value func (a *Node1) GetSecondsSinceLastHeard() (uint32, error) { v, err := a.GetProperty("SecondsSinceLastHeard") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // GetSequenceNumber get SequenceNumber value func (a *Node1) GetSequenceNumber() (uint32, error) { v, err := a.GetProperty("SequenceNumber") if err != nil { return uint32(0), err } return v.Value().(uint32), nil } // Close the connection func (a *Node1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Node1 object path func (a *Node1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Node1 dbus client func (a *Node1) Client() *bluez.Client { return a.client } // Interface return Node1 interface func (a *Node1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Node1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Node1Properties to map func (a *Node1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Node1Properties func (a *Node1Properties) FromMap(props map[string]interface{}) (*Node1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Node1Properties func (a *Node1Properties) FromDBusMap(props map[string]dbus.Variant) (*Node1Properties, error) { s := new(Node1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Node1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Node1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Node1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Node1) GetProperties() (*Node1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Node1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Node1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Node1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Node1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Node1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Node1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Send This method is used to send a message originated by a local model. The element_path parameter is the object path of an element from a collection of the application elements (see Mesh Application Hierarchy section). The destination parameter contains the destination address. This destination must be a uint16 to a unicast address, or a well known group address. The key_index parameter determines which application key to use for encrypting the message. The key_index must be valid for that element, i.e., the application key must be bound to a model on this element. Otherwise, org.bluez.mesh.Error.NotAuthorized will be returned. The options parameter is a dictionary with the following keys defined: bool ForceSegmented Specifies whether to force sending of a short message as one-segment payload. If not present, the default setting is "false". The data parameter is an outgoing message to be encypted by the bluetooth-meshd daemon and sent on. Possible errors: org.bluez.mesh.Error.NotAuthorized org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotFound */ func (a *Node1) Send(element_path dbus.ObjectPath, destination uint16, key_index uint16, options map[string]interface{}, data []byte) error { return a.client.Call("Send", 0, element_path, destination, key_index, options, data).Store() } /* DevKeySend This method is used to send a message originated by a local model encoded with the device key of the remote node. The element_path parameter is the object path of an element from a collection of the application elements (see Mesh Application Hierarchy section). The destination parameter contains the destination address. This destination must be a uint16 to a unicast address, or a well known group address. The remote parameter, if true, looks up the device key by the destination address in the key database to encrypt the message. If remote is true, but requested key does not exist, a NotFound error will be returned. If set to false, the local node's device key is used. The net_index parameter is the subnet index of the network on which the message is to be sent. The options parameter is a dictionary with the following keys defined: bool ForceSegmented Specifies whether to force sending of a short message as one-segment payload. If not present, the default setting is "false". The data parameter is an outgoing message to be encypted by the meshd daemon and sent on. Possible errors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotFound */ func (a *Node1) DevKeySend(element_path dbus.ObjectPath, destination uint16, remote bool, net_index uint16, options map[string]interface{}, data []byte) error { return a.client.Call("DevKeySend", 0, element_path, destination, remote, net_index, options, data).Store() } /* AddNetKey This method is used to send add or update network key originated by the local configuration client to a remote configuration server. The element_path parameter is the object path of an element from a collection of the application elements (see Mesh Application Hierarchy section). The destination parameter contains the destination address. This destination must be a uint16 to a nodes primary unicast address. The subnet_index parameter refers to the subnet index of the network that is being added or updated. This key must exist in the local key database. The net_index parameter is the subnet index of the network on which the message is to be sent. The update parameter indicates if this is an addition or an update. If true, the subnet key must be in the phase 1 state of the key update procedure. Possible errors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotFound */ func (a *Node1) AddNetKey(element_path dbus.ObjectPath, destination uint16, subnet_index uint16, net_index uint16, update bool) error { return a.client.Call("AddNetKey", 0, element_path, destination, subnet_index, net_index, update).Store() } /* AddAppKey This method is used to send add or update network key originated by the local configuration client to a remote configuration server. The element_path parameter is the object path of an element from a collection of the application elements (see Mesh Application Hierarchy section). The destination parameter contains the destination address. This destination must be a uint16 to a nodes primary unicast address. The app_index parameter refers to the application key which is being added or updated. This key must exist in the local key database. The net_index parameter is the subnet index of the network on which the message is to be sent. The update parameter indicates if this is an addition or an update. If true, the subnet key must be in the phase 1 state of the key update procedure. Possible errors: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.NotFound */ func (a *Node1) AddAppKey(element_path dbus.ObjectPath, destination uint16, app_index uint16, net_index uint16, update bool) error { return a.client.Call("AddAppKey", 0, element_path, destination, app_index, net_index, update).Store() } /* Publish This method is used to send a publication originated by a local model. If the model does not exist, or it has no publication record, the method returns org.bluez.mesh.Error.DoesNotExist error. The element_path parameter is the object path of an element from a collection of the application elements (see Mesh Application Hierarchy section). The model parameter contains a model ID, as defined by the Bluetooth SIG. If the options dictionary contains a "Vendor" key, then this ID is defined by the specified vendor. The options parameter is a dictionary with the following keys defined: bool ForceSegmented Specifies whether to force sending of a short message as one-segment payload. If not present, the default setting is "false". uint16 Vendor A 16-bit Company ID as defined by the Bluetooth SIG. This key should only exist when publishing on a Vendor defined model. The data parameter is an outgoing message to be encypted by the meshd daemon and sent on. Since only one Publish record may exist per element-model, the destination and key_index are obtained from the Publication record cached by the daemon. Possible errors: org.bluez.mesh.Error.DoesNotExist org.bluez.mesh.Error.InvalidArguments */ func (a *Node1) Publish(element_path dbus.ObjectPath, model uint16, options map[string]interface{}, data []byte) error { return a.client.Call("Publish", 0, element_path, model, options, data).Store() } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_ProvisionAgent1.go000066400000000000000000000253531420407601400251260ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var ProvisionAgent1Interface = "org.bluez.mesh.ProvisionAgent1" // NewProvisionAgent1 create a new instance of ProvisionAgent1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewProvisionAgent1(servicePath string, objectPath dbus.ObjectPath) (*ProvisionAgent1, error) { a := new(ProvisionAgent1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: ProvisionAgent1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(ProvisionAgent1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* ProvisionAgent1 Provisioning Agent Hierarchy */ type ProvisionAgent1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *ProvisionAgent1Properties watchPropertiesChannel chan *dbus.Signal } // ProvisionAgent1Properties contains the exposed properties of an interface type ProvisionAgent1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Capabilities An array of strings with the following allowed values: "blink" "beep" "vibrate" "out-numeric" "out-alpha" "push" "twist" "in-numeric" "in-alpha" "static-oob" "public-oob" */ Capabilities []string /* OutOfBandInfo Indicates availability of OOB data. An array of strings with the following allowed values: "other" "uri" "machine-code-2d" "bar-code" "nfc" "number" "string" "on-box" "in-box" "on-paper", "in-manual" "on-device" */ OutOfBandInfo []string /* URI Uniform Resource Identifier points to out-of-band (OOB) information (e.g., a public key) */ URI string } //Lock access to properties func (p *ProvisionAgent1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *ProvisionAgent1Properties) Unlock() { p.lock.Unlock() } // GetCapabilities get Capabilities value func (a *ProvisionAgent1) GetCapabilities() ([]string, error) { v, err := a.GetProperty("Capabilities") if err != nil { return []string{}, err } return v.Value().([]string), nil } // GetOutOfBandInfo get OutOfBandInfo value func (a *ProvisionAgent1) GetOutOfBandInfo() ([]string, error) { v, err := a.GetProperty("OutOfBandInfo") if err != nil { return []string{}, err } return v.Value().([]string), nil } // GetURI get URI value func (a *ProvisionAgent1) GetURI() (string, error) { v, err := a.GetProperty("URI") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *ProvisionAgent1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return ProvisionAgent1 object path func (a *ProvisionAgent1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return ProvisionAgent1 dbus client func (a *ProvisionAgent1) Client() *bluez.Client { return a.client } // Interface return ProvisionAgent1 interface func (a *ProvisionAgent1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *ProvisionAgent1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a ProvisionAgent1Properties to map func (a *ProvisionAgent1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an ProvisionAgent1Properties func (a *ProvisionAgent1Properties) FromMap(props map[string]interface{}) (*ProvisionAgent1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an ProvisionAgent1Properties func (a *ProvisionAgent1Properties) FromDBusMap(props map[string]dbus.Variant) (*ProvisionAgent1Properties, error) { s := new(ProvisionAgent1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *ProvisionAgent1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *ProvisionAgent1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *ProvisionAgent1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *ProvisionAgent1) GetProperties() (*ProvisionAgent1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *ProvisionAgent1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *ProvisionAgent1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *ProvisionAgent1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *ProvisionAgent1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *ProvisionAgent1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *ProvisionAgent1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* PrivateKey This method is called during provisioning if the Provisioner has requested Out-Of-Band ECC key exchange. The Private key is returned to the Daemon, and the Public Key is delivered to the remote Provisioner using a method that does not involve the Bluetooth Mesh system. The Private Key returned must be 32 octets in size, or the Provisioning procedure will fail and be canceled. This function will only be called if the Provisioner has requested pre-determined keys to be exchanged Out-of-Band, and the local role is Unprovisioned device. */ func (a *ProvisionAgent1) PrivateKey() ([]byte, error) { val0 := []byte{} err := a.client.Call("PrivateKey", 0).Store(&val0) return val0, err } /* PublicKey This method is called during provisioning if the local device is the Provisioner, and is requestng Out-Of-Band ECC key exchange. The Public key is returned to the Daemon that is the matched pair of the Private key of the remote device. The Public Key returned must be 64 octets in size, or the Provisioning procedure will fail and be canceled. This function will only be called if the Provisioner has requested pre-determined keys to be exchanged Out-of-Band, and the local role is Provisioner. */ func (a *ProvisionAgent1) PublicKey() ([]byte, error) { val0 := []byte{} err := a.client.Call("PublicKey", 0).Store(&val0) return val0, err } /* DisplayString This method is called when the Daemon has something important for the Agent to Display, but does not require any additional input locally. For instance: "Enter "ABCDE" on remote device". */ func (a *ProvisionAgent1) DisplayString(value string) error { return a.client.Call("DisplayString", 0, value).Store() } /* DisplayNumeric This method is called when the Daemon has something important for the Agent to Display, but does not require any additional input locally. For instance: "Enter 14939264 on remote device". The type parameter indicates the display method. Allowed values are: "blink" - Locally blink LED "beep" - Locally make a noise "vibrate" - Locally vibrate "out-numeric" - Display value to enter remotely "push" - Request pushes on remote button "twist" - Request twists on remote knob The number parameter is the specific value represented by the Prompt. */ func (a *ProvisionAgent1) DisplayNumeric(type1 string, number uint32) error { return a.client.Call("DisplayNumeric", 0, type1, number).Store() } /* PromptNumeric This method is called when the Daemon requests the user to enter a decimal value between 1-99999999. The type parameter indicates the input method. Allowed values are: "blink" - Enter times remote LED blinked "beep" - Enter times remote device beeped "vibrate" - Enter times remote device vibrated "in-numeric" - Enter remotely displayed value "push" - Push local button remotely requested times "twist" - Twist local knob remotely requested times This agent should prompt the user for specific input. For instance: "Enter value being displayed by remote device". */ func (a *ProvisionAgent1) PromptNumeric(type1 string) (uint32, error) { var val0 uint32 err := a.client.Call("PromptNumeric", 0, type1).Store(&val0) return val0, err } /* PromptStatic This method is called when the Daemon requires a 16 octet byte array, as an Out-of-Band authentication. The type parameter indicates the input method. Allowed values are: "static-oob" - return 16 octet array "in-alpha" - return 16 octet alpha array The Static data returned must be 16 octets in size, or the Provisioning procedure will fail and be canceled. If input type is "in-alpha", the printable characters should be left-justified, with trailing 0x00 octets filling the remaining bytes. */ func (a *ProvisionAgent1) PromptStatic(type1 string) ([]byte, error) { val0 := []byte{} err := a.client.Call("PromptStatic", 0, type1).Store(&val0) return val0, err } /* Cancel This method gets called by the daemon to cancel any existing Agent Requests. When called, any pending user input should be canceled, and any display requests removed. */ func (a *ProvisionAgent1) Cancel() error { return a.client.Call("Cancel", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_Provisioner1.go000066400000000000000000000200771420407601400244740ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package mesh import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Provisioner1Interface = "org.bluez.mesh.Provisioner1" // NewProvisioner1 create a new instance of Provisioner1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewProvisioner1(servicePath string, objectPath dbus.ObjectPath) (*Provisioner1, error) { a := new(Provisioner1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: Provisioner1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Provisioner1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Provisioner1 Mesh Provisioner Hierarchy */ type Provisioner1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Provisioner1Properties watchPropertiesChannel chan *dbus.Signal } // Provisioner1Properties contains the exposed properties of an interface type Provisioner1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Provisioner1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Provisioner1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Provisioner1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Provisioner1 object path func (a *Provisioner1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Provisioner1 dbus client func (a *Provisioner1) Client() *bluez.Client { return a.client } // Interface return Provisioner1 interface func (a *Provisioner1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Provisioner1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Provisioner1Properties to map func (a *Provisioner1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Provisioner1Properties func (a *Provisioner1Properties) FromMap(props map[string]interface{}) (*Provisioner1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Provisioner1Properties func (a *Provisioner1Properties) FromDBusMap(props map[string]dbus.Variant) (*Provisioner1Properties, error) { s := new(Provisioner1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Provisioner1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Provisioner1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Provisioner1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Provisioner1) GetProperties() (*Provisioner1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Provisioner1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Provisioner1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Provisioner1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Provisioner1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Provisioner1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Provisioner1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* ScanResult The method is called from the bluetooth-meshd daemon when a unique UUID has been seen during UnprovisionedScan() for unprovsioned devices. The rssi parameter is a signed, normalized measurement of the signal strength of the recieved unprovisioned beacon. The data parameter is a variable length byte array, that may have 1, 2 or 3 distinct fields contained in it including the 16 byte remote device UUID (always), a 16 bit mask of OOB authentication flags (optional), and a 32 bit URI hash (if URI bit set in OOB mask). Whether these fields exist or not is a decision of the remote device. The options parameter is a dictionary that may contain additional scan result info (currently an empty placeholder for forward compatibility). If a beacon with a UUID that has already been reported is recieved by the daemon, it will be silently discarded unless it was recieved at a higher rssi power level. */ func (a *Provisioner1) ScanResult(rssi int16, data []byte, options map[string]interface{}) error { return a.client.Call("ScanResult", 0, rssi, data, options).Store() } /* RequestProvData This method is implemented by a Provisioner capable application and is called when the remote device has been fully authenticated and confirmed. The count parameter is the number of consecutive unicast addresses the remote device is requesting. Return Parameters are from the Mesh Profile Spec: net_index - Subnet index of the net_key unicast - Primary Unicast address of the new node PossibleErrors: org.bluez.mesh.Error.Abort */ func (a *Provisioner1) RequestProvData(count uint8) (uint16, error) { var val0 uint16 err := a.client.Call("RequestProvData", 0, count).Store(&val0) return val0, err } /* AddNodeComplete This method is called when the node provisioning initiated by an AddNode() method call successfully completed. The unicast parameter is the primary address that has been assigned to the new node, and the address of it's config server. The count parameter is the number of unicast addresses assigned to the new node. The new node may now be sent messages using the credentials supplied by the RequestProvData method. */ func (a *Provisioner1) AddNodeComplete(uuid []byte, unicast uint16, count uint8) error { return a.client.Call("AddNodeComplete", 0, uuid, unicast, count).Store() } /* AddNodeFailed This method is called when the node provisioning initiated by AddNode() has failed. Depending on how far Provisioning proceeded before failing, some cleanup of cached data may be required. The reason parameter identifies the reason for provisioning failure. The defined values are: "aborted", "timeout", "bad-pdu", "confirmation-failed", "out-of-resources", "decryption-error", "unexpected-error", "cannot-assign-addresses". */ func (a *Provisioner1) AddNodeFailed(uuid []byte, reason string) error { return a.client.Call("AddNodeFailed", 0, uuid, reason).Store() } go-bluetooth-bluez-5.60/bluez/profile/mesh/gen_mesh.go000066400000000000000000000001761420407601400230260ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Mesh API description [mesh-api.txt] */ package mesh go-bluetooth-bluez-5.60/bluez/profile/mesh/types.go000066400000000000000000000011551420407601400224030ustar00rootroot00000000000000package mesh import "github.com/godbus/dbus/v5" //VendorItem array{(uint16, uint16)} type VendorItem struct { Vendor uint16 ModelID uint16 } //VendorItem array{(uint16, uint16, dict)} type VendorOptionsItem struct { VendorItem Options map[string]interface{} } // ModelConfig type ModelConfig struct { Bindings []uint16 PublicationPeriod uint32 Vendor uint16 Subscriptions []dbus.Variant } // Model type Model struct { Identifier uint16 Config ModelConfig } // ConfigurationItem array{byte, array{(uint16, dict)}} type ConfigurationItem struct { Index byte Models []Model } go-bluetooth-bluez-5.60/bluez/profile/network/000077500000000000000000000000001420407601400214435ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/network/gen_Network1.go000066400000000000000000000161101420407601400243340ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package network import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Network1Interface = "org.bluez.Network1" // NewNetwork1 create a new instance of Network1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX func NewNetwork1(objectPath dbus.ObjectPath) (*Network1, error) { a := new(Network1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Network1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Network1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Network1 Network hierarchy */ type Network1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Network1Properties watchPropertiesChannel chan *dbus.Signal } // Network1Properties contains the exposed properties of an interface type Network1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Connected Indicates if the device is connected. */ Connected bool /* Interface Indicates the network interface name when available. */ Interface string /* UUID Indicates the connection role when available. */ UUID string } //Lock access to properties func (p *Network1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Network1Properties) Unlock() { p.lock.Unlock() } // SetConnected set Connected value func (a *Network1) SetConnected(v bool) error { return a.SetProperty("Connected", v) } // GetConnected get Connected value func (a *Network1) GetConnected() (bool, error) { v, err := a.GetProperty("Connected") if err != nil { return false, err } return v.Value().(bool), nil } // SetInterface set Interface value func (a *Network1) SetInterface(v string) error { return a.SetProperty("Interface", v) } // GetInterface get Interface value func (a *Network1) GetInterface() (string, error) { v, err := a.GetProperty("Interface") if err != nil { return "", err } return v.Value().(string), nil } // SetUUID set UUID value func (a *Network1) SetUUID(v string) error { return a.SetProperty("UUID", v) } // GetUUID get UUID value func (a *Network1) GetUUID() (string, error) { v, err := a.GetProperty("UUID") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *Network1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Network1 object path func (a *Network1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Network1 dbus client func (a *Network1) Client() *bluez.Client { return a.client } // Interface return Network1 interface func (a *Network1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Network1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Network1Properties to map func (a *Network1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Network1Properties func (a *Network1Properties) FromMap(props map[string]interface{}) (*Network1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Network1Properties func (a *Network1Properties) FromDBusMap(props map[string]dbus.Variant) (*Network1Properties, error) { s := new(Network1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Network1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Network1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Network1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Network1) GetProperties() (*Network1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Network1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Network1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Network1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Network1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Network1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Network1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Connect Connect to the network device and return the network interface name. Examples of the interface name are bnep0, bnep1 etc. uuid can be either one of "gn", "panu" or "nap" (case insensitive) or a traditional string representation of UUID or a hexadecimal number. The connection will be closed and network device released either upon calling Disconnect() or when the client disappears from the message bus. Possible errors: org.bluez.Error.AlreadyConnected org.bluez.Error.ConnectionAttemptFailed */ func (a *Network1) Connect(uuid string) (string, error) { var val0 string err := a.client.Call("Connect", 0, uuid).Store(&val0) return val0, err } /* Disconnect Disconnect from the network device. To abort a connection attempt in case of errors or timeouts in the client it is fine to call this method. Possible errors: org.bluez.Error.Failed */ func (a *Network1) Disconnect() error { return a.client.Call("Disconnect", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/network/gen_NetworkServer1.go000066400000000000000000000136541420407601400255350ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package network import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var NetworkServer1Interface = "org.bluez.NetworkServer1" // NewNetworkServer1 create a new instance of NetworkServer1 // // Args: // - objectPath: /org/bluez/{hci0,hci1,...} func NewNetworkServer1(objectPath dbus.ObjectPath) (*NetworkServer1, error) { a := new(NetworkServer1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: NetworkServer1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(NetworkServer1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* NetworkServer1 Network server hierarchy */ type NetworkServer1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *NetworkServer1Properties watchPropertiesChannel chan *dbus.Signal } // NetworkServer1Properties contains the exposed properties of an interface type NetworkServer1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *NetworkServer1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *NetworkServer1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *NetworkServer1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return NetworkServer1 object path func (a *NetworkServer1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return NetworkServer1 dbus client func (a *NetworkServer1) Client() *bluez.Client { return a.client } // Interface return NetworkServer1 interface func (a *NetworkServer1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *NetworkServer1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a NetworkServer1Properties to map func (a *NetworkServer1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an NetworkServer1Properties func (a *NetworkServer1Properties) FromMap(props map[string]interface{}) (*NetworkServer1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an NetworkServer1Properties func (a *NetworkServer1Properties) FromDBusMap(props map[string]dbus.Variant) (*NetworkServer1Properties, error) { s := new(NetworkServer1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *NetworkServer1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *NetworkServer1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *NetworkServer1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *NetworkServer1) GetProperties() (*NetworkServer1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *NetworkServer1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *NetworkServer1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *NetworkServer1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *NetworkServer1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *NetworkServer1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *NetworkServer1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Register Register server for the provided UUID. Every new connection to this server will be added the bridge interface. Valid UUIDs are "gn", "panu" or "nap". Initially no network server SDP is provided. Only after this method a SDP record will be available and the BNEP server will be ready for incoming connections. */ func (a *NetworkServer1) Register(uuid string, bridge string) error { return a.client.Call("Register", 0, uuid, bridge).Store() } /* Unregister Unregister the server for provided UUID. All servers will be automatically unregistered when the calling application terminates. */ func (a *NetworkServer1) Unregister(uuid string) error { return a.client.Call("Unregister", 0, uuid).Store() } go-bluetooth-bluez-5.60/bluez/profile/network/gen_network.go000066400000000000000000000002101420407601400243050ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Network API description [network-api.txt] */ package network go-bluetooth-bluez-5.60/bluez/profile/obex/000077500000000000000000000000001420407601400207075ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/obex/Client1.go000066400000000000000000000035471420407601400225460ustar00rootroot00000000000000package obex import ( "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" log "github.com/sirupsen/logrus" ) // TODO: https://github.com/blueman-project/blueman/issues/218#issuecomment-89315974 // NewObexClient1 create a new ObexClient1 client func NewObexClient1() *ObexClient1 { a := new(ObexClient1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: "org.bluez.obex.Client1", Path: "/org/bluez/obex", Bus: bluez.SessionBus, }, ) return a } // ObexClient1 client type ObexClient1 struct { client *bluez.Client } // Close the connection func (a *ObexClient1) Close() { a.client.Disconnect() } // Create a new OBEX session for the given remote address. // // The last parameter is a dictionary to hold optional or // type-specific parameters. Typical parameters that can // be set in this dictionary include the following: // // string "Target" : type of session to be created // string "Source" : local address to be used // byte "Channel" // // The currently supported targets are the following: // // - "ftp" // - "map" // - "opp" // - "pbap" // - "sync" // // Possible errors: // - org.bluez.obex.Error.InvalidArguments // - org.bluez.obex.Error.Failed // // TODO: Use ObexSession1 struct instead of generic map for options func (a *ObexClient1) CreateSession(destination string, options map[string]interface{}) (string, error) { log.Debugf("CreateSession to %s", destination) var sessionPath string err := a.client.Call("CreateSession", 0, destination, options).Store(&sessionPath) return sessionPath, err } // Unregister session and abort pending transfers. // // Possible errors: // - org.bluez.obex.Error.InvalidArguments // - org.bluez.obex.Error.NotAuthorized // func (a *ObexClient1) RemoveSession(session string) error { return a.client.Call("RemoveSession", 0, dbus.ObjectPath(session)).Store() } go-bluetooth-bluez-5.60/bluez/profile/obex/Client1_test.go000066400000000000000000000006001420407601400235700ustar00rootroot00000000000000package obex import ( "testing" ) func TestNewObexClient1(t *testing.T) { t.Log("Create ObexClient1") a := NewObexClient1() t.Log("Start CreateSession") temp := map[string]interface{}{} //temp := map[string]dbus.Variant{} temp["Target"] = "opp" _, err := a.CreateSession("98:4E:97:00:3F:3C", temp) if err != nil { t.Logf("Error on CreateSession") t.Fatal(err) } } go-bluetooth-bluez-5.60/bluez/profile/obex/ObjectPush1.go000066400000000000000000000027201420407601400233660ustar00rootroot00000000000000package obex import ( "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/util" ) // NewObjectPush1 create a new ObjectPush1 client func NewObjectPush1(sessionPath string) *ObjectPush1 { a := new(ObjectPush1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: "org.bluez.obex.ObjectPush1", Path: dbus.ObjectPath(sessionPath), Bus: bluez.SessionBus, }, ) return a } // ObjectPush1 client type ObjectPush1 struct { client *bluez.Client } // Close the connection func (d *ObjectPush1) Close() { d.client.Disconnect() } // // Send one local file to the remote device. // // The returned path represents the newly created transfer, // which should be used to find out if the content has been // successfully transferred or if the operation fails. // // The properties of this transfer are also returned along // with the object path, to avoid a call to GetProperties. // // Possible errors: // - org.bluez.obex.Error.InvalidArguments // - org.bluez.obex.Error.Failed // func (a *ObjectPush1) SendFile(sourcefile string) (string, *ObexTransfer1Properties, error) { result := make(map[string]dbus.Variant) var sessionPath string err := a.client.Call("SendFile", 0, sourcefile).Store(&sessionPath, &result) if err != nil { return "", nil, err } transportProps := new(ObexTransfer1Properties) err = util.MapToStruct(transportProps, result) return sessionPath, transportProps, err } go-bluetooth-bluez-5.60/bluez/profile/obex/Session1.go000066400000000000000000000026501420407601400227450ustar00rootroot00000000000000package obex import ( "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" log "github.com/sirupsen/logrus" ) // NewObexSession1 create a new ObexSession1 client func NewObexSession1(path string) *ObexSession1 { a := new(ObexSession1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: "org.bluez.obex.Session1", Path: dbus.ObjectPath(path), Bus: bluez.SessionBus, }, ) a.Properties = new(ObexSession1Properties) _, err := a.GetProperties() if err != nil { log.Warn(err) } return a } // ObexSession1 client type ObexSession1 struct { client *bluez.Client Properties *ObexSession1Properties } // ObexSession1Properties exposed properties for ObexSession1 type ObexSession1Properties struct { Source string // [readonly] Bluetooth adapter address Destination string // [readonly] Bluetooth device address Channel byte // [readonly] Bluetooth channel Target string // [readonly] Target UUID Root string // [readonly] Root path } // Close the connection func (d *ObexSession1) Close() { d.client.Disconnect() } //GetProperties load all available properties func (d *ObexSession1) GetProperties() (*ObexSession1Properties, error) { err := d.client.GetProperties(d.Properties) return d.Properties, err } //GetProperty get a property func (d *ObexSession1) GetProperty(name string) (dbus.Variant, error) { return d.client.GetProperty(name) } go-bluetooth-bluez-5.60/bluez/profile/obex/Transfer1.go000066400000000000000000000044311420407601400231050ustar00rootroot00000000000000package obex import ( "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" log "github.com/sirupsen/logrus" ) // NewObexTransfer1 create a new ObexTransfer1 client func NewObexTransfer1(path string) *ObexTransfer1 { a := new(ObexTransfer1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: "org.bluez.obex.Transfer1", Path: dbus.ObjectPath(path), Bus: bluez.SessionBus, }, ) a.Properties = new(ObexTransfer1Properties) _, err := a.GetProperties() if err != nil { log.Warn(err) } return a } // ObexTransfer1 client type ObexTransfer1 struct { client *bluez.Client Properties *ObexTransfer1Properties } // ObexTransfer1Properties exposed properties for ObexTransfer1 type ObexTransfer1Properties struct { Status string Session dbus.ObjectPath Name string Type string Time uint64 Size uint64 Transferred uint64 Filename string } // Close the connection func (d *ObexTransfer1) Close() { d.client.Disconnect() } //GetProperties load all available properties func (d *ObexTransfer1) GetProperties() (*ObexTransfer1Properties, error) { err := d.client.GetProperties(d.Properties) return d.Properties, err } //GetProperty get a property func (d *ObexTransfer1) GetProperty(name string) (dbus.Variant, error) { return d.client.GetProperty(name) } // // Stops the current transference. // // Possible errors: org.bluez.obex.Error.NotAuthorized // - org.bluez.obex.Error.InProgress // - org.bluez.obex.Error.Failed // func (a *ObexTransfer1) Cancel() error { return a.client.Call("Cancel", 0).Store() } // // Suspend transference. // // Possible errors: org.bluez.obex.Error.NotAuthorized // org.bluez.obex.Error.NotInProgress // // Note that it is not possible to suspend transfers // which are queued which is why NotInProgress is listed // as possible error. // func (a *ObexTransfer1) Suspend() error { return a.client.Call("Suspend", 0).Store() } // // Resume transference. // // Possible errors: org.bluez.obex.Error.NotAuthorized // org.bluez.obex.Error.NotInProgress // // Note that it is not possible to resume transfers // which are queued which is why NotInProgress is listed // as possible error. // func (a *ObexTransfer1) Resume() error { return a.client.Call("Resume", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/obex/gen_FileTransfer.go000066400000000000000000000215251420407601400244600ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package obex import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var FileTransferInterface = "org.bluez.obex.FileTransfer" // NewFileTransfer create a new instance of FileTransfer // // Args: // - objectPath: [Session object path] func NewFileTransfer(objectPath dbus.ObjectPath) (*FileTransfer, error) { a := new(FileTransfer) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: FileTransferInterface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(FileTransferProperties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* FileTransfer File Transfer hierarchy */ type FileTransfer struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *FileTransferProperties watchPropertiesChannel chan *dbus.Signal } // FileTransferProperties contains the exposed properties of an interface type FileTransferProperties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *FileTransferProperties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *FileTransferProperties) Unlock() { p.lock.Unlock() } // Close the connection func (a *FileTransfer) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return FileTransfer object path func (a *FileTransfer) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return FileTransfer dbus client func (a *FileTransfer) Client() *bluez.Client { return a.client } // Interface return FileTransfer interface func (a *FileTransfer) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *FileTransfer) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a FileTransferProperties to map func (a *FileTransferProperties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an FileTransferProperties func (a *FileTransferProperties) FromMap(props map[string]interface{}) (*FileTransferProperties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an FileTransferProperties func (a *FileTransferProperties) FromDBusMap(props map[string]dbus.Variant) (*FileTransferProperties, error) { s := new(FileTransferProperties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *FileTransfer) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *FileTransfer) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *FileTransfer) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *FileTransfer) GetProperties() (*FileTransferProperties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *FileTransfer) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *FileTransfer) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *FileTransfer) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *FileTransfer) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *FileTransfer) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *FileTransfer) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* ChangeFolder Change the current folder of the remote device. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *FileTransfer) ChangeFolder(folder string) error { return a.client.Call("ChangeFolder", 0, folder).Store() } /* CreateFolder Create a new folder in the remote device. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *FileTransfer) CreateFolder(folder string) error { return a.client.Call("CreateFolder", 0, folder).Store() } /* ListFolder Returns a dictionary containing information about the current folder content. The following keys are defined: string Name : Object name in UTF-8 format string Type : Either "folder" or "file" uint64 Size : Object size or number of items in folder string Permission : Group, owner and other permission uint64 Modified : Last change uint64 Accessed : Last access uint64 Created : Creation date Possible errors: org.bluez.obex.Error.Failed */ func (a *FileTransfer) ListFolder() ([]map[string]interface{}, error) { val0 := []map[string]interface{}{} err := a.client.Call("ListFolder", 0).Store(&val0) return val0, err } /* GetFile Copy the source file (from remote device) to the target file (on local filesystem). If an empty target file is given, a name will be automatically calculated for the temporary file. The returned path represents the newly created transfer, which should be used to find out if the content has been successfully transferred or if the operation fails. The properties of this transfer are also returned along with the object path, to avoid a call to GetProperties. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *FileTransfer) GetFile(targetfile string, sourcefile string) (dbus.ObjectPath, map[string]interface{}, error) { var val0 dbus.ObjectPath var val1 map[string]interface{} err := a.client.Call("GetFile", 0, targetfile, sourcefile).Store(&val0, &val1) return val0, val1, err } /* PutFile Copy the source file (from local filesystem) to the target file (on remote device). The returned path represents the newly created transfer, which should be used to find out if the content has been successfully transferred or if the operation fails. The properties of this transfer are also returned along with the object path, to avoid a call to GetProperties. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *FileTransfer) PutFile(sourcefile string, targetfile string) (dbus.ObjectPath, map[string]interface{}, error) { var val0 dbus.ObjectPath var val1 map[string]interface{} err := a.client.Call("PutFile", 0, sourcefile, targetfile).Store(&val0, &val1) return val0, val1, err } /* CopyFile Copy a file within the remote device from source file to target file. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *FileTransfer) CopyFile(sourcefile string, targetfile string) error { return a.client.Call("CopyFile", 0, sourcefile, targetfile).Store() } /* MoveFile Move a file within the remote device from source file to the target file. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *FileTransfer) MoveFile(sourcefile string, targetfile string) error { return a.client.Call("MoveFile", 0, sourcefile, targetfile).Store() } /* Delete Deletes the specified file/folder. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *FileTransfer) Delete(file string) error { return a.client.Call("Delete", 0, file).Store() } go-bluetooth-bluez-5.60/bluez/profile/obex/gen_Message1.go000066400000000000000000000265441420407601400235470ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package obex import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Message1Interface = "org.bluez.obex.Message1" // NewMessage1 create a new instance of Message1 // // Args: // - objectPath: [Session object path]/{message0,...} func NewMessage1(objectPath dbus.ObjectPath) (*Message1, error) { a := new(Message1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: Message1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Message1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Message1 Message hierarchy */ type Message1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Message1Properties watchPropertiesChannel chan *dbus.Signal } // Message1Properties contains the exposed properties of an interface type Message1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Deleted Message deleted flag */ Deleted bool /* Folder Folder which the message belongs to */ Folder string /* Priority Message priority flag */ Priority bool /* Protected Message protected flag */ Protected bool /* Read Message read flag */ Read bool /* Recipient Message recipient name */ Recipient string /* RecipientAddress Message recipient address */ RecipientAddress string /* ReplyTo Message Reply-To address */ ReplyTo string /* Sender Message sender name */ Sender string /* SenderAddress Message sender address */ SenderAddress string /* Sent Message sent flag */ Sent bool /* Status Message reception status Possible values: "complete", "fractioned" and "notification" */ Status string /* Subject Message subject */ Subject string /* Timestamp Message timestamp */ Timestamp string /* Type Message type Possible values: "email", "sms-gsm", "sms-cdma" and "mms" uint64 Size [readonly] Message size in bytes */ Type string } //Lock access to properties func (p *Message1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Message1Properties) Unlock() { p.lock.Unlock() } // SetDeleted set Deleted value func (a *Message1) SetDeleted(v bool) error { return a.SetProperty("Deleted", v) } // GetDeleted get Deleted value func (a *Message1) GetDeleted() (bool, error) { v, err := a.GetProperty("Deleted") if err != nil { return false, err } return v.Value().(bool), nil } // SetFolder set Folder value func (a *Message1) SetFolder(v string) error { return a.SetProperty("Folder", v) } // GetFolder get Folder value func (a *Message1) GetFolder() (string, error) { v, err := a.GetProperty("Folder") if err != nil { return "", err } return v.Value().(string), nil } // SetPriority set Priority value func (a *Message1) SetPriority(v bool) error { return a.SetProperty("Priority", v) } // GetPriority get Priority value func (a *Message1) GetPriority() (bool, error) { v, err := a.GetProperty("Priority") if err != nil { return false, err } return v.Value().(bool), nil } // SetProtected set Protected value func (a *Message1) SetProtected(v bool) error { return a.SetProperty("Protected", v) } // GetProtected get Protected value func (a *Message1) GetProtected() (bool, error) { v, err := a.GetProperty("Protected") if err != nil { return false, err } return v.Value().(bool), nil } // SetRead set Read value func (a *Message1) SetRead(v bool) error { return a.SetProperty("Read", v) } // GetRead get Read value func (a *Message1) GetRead() (bool, error) { v, err := a.GetProperty("Read") if err != nil { return false, err } return v.Value().(bool), nil } // SetRecipient set Recipient value func (a *Message1) SetRecipient(v string) error { return a.SetProperty("Recipient", v) } // GetRecipient get Recipient value func (a *Message1) GetRecipient() (string, error) { v, err := a.GetProperty("Recipient") if err != nil { return "", err } return v.Value().(string), nil } // SetRecipientAddress set RecipientAddress value func (a *Message1) SetRecipientAddress(v string) error { return a.SetProperty("RecipientAddress", v) } // GetRecipientAddress get RecipientAddress value func (a *Message1) GetRecipientAddress() (string, error) { v, err := a.GetProperty("RecipientAddress") if err != nil { return "", err } return v.Value().(string), nil } // SetReplyTo set ReplyTo value func (a *Message1) SetReplyTo(v string) error { return a.SetProperty("ReplyTo", v) } // GetReplyTo get ReplyTo value func (a *Message1) GetReplyTo() (string, error) { v, err := a.GetProperty("ReplyTo") if err != nil { return "", err } return v.Value().(string), nil } // SetSender set Sender value func (a *Message1) SetSender(v string) error { return a.SetProperty("Sender", v) } // GetSender get Sender value func (a *Message1) GetSender() (string, error) { v, err := a.GetProperty("Sender") if err != nil { return "", err } return v.Value().(string), nil } // SetSenderAddress set SenderAddress value func (a *Message1) SetSenderAddress(v string) error { return a.SetProperty("SenderAddress", v) } // GetSenderAddress get SenderAddress value func (a *Message1) GetSenderAddress() (string, error) { v, err := a.GetProperty("SenderAddress") if err != nil { return "", err } return v.Value().(string), nil } // SetSent set Sent value func (a *Message1) SetSent(v bool) error { return a.SetProperty("Sent", v) } // GetSent get Sent value func (a *Message1) GetSent() (bool, error) { v, err := a.GetProperty("Sent") if err != nil { return false, err } return v.Value().(bool), nil } // SetStatus set Status value func (a *Message1) SetStatus(v string) error { return a.SetProperty("Status", v) } // GetStatus get Status value func (a *Message1) GetStatus() (string, error) { v, err := a.GetProperty("Status") if err != nil { return "", err } return v.Value().(string), nil } // SetSubject set Subject value func (a *Message1) SetSubject(v string) error { return a.SetProperty("Subject", v) } // GetSubject get Subject value func (a *Message1) GetSubject() (string, error) { v, err := a.GetProperty("Subject") if err != nil { return "", err } return v.Value().(string), nil } // SetTimestamp set Timestamp value func (a *Message1) SetTimestamp(v string) error { return a.SetProperty("Timestamp", v) } // GetTimestamp get Timestamp value func (a *Message1) GetTimestamp() (string, error) { v, err := a.GetProperty("Timestamp") if err != nil { return "", err } return v.Value().(string), nil } // SetType set Type value func (a *Message1) SetType(v string) error { return a.SetProperty("Type", v) } // GetType get Type value func (a *Message1) GetType() (string, error) { v, err := a.GetProperty("Type") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *Message1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Message1 object path func (a *Message1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Message1 dbus client func (a *Message1) Client() *bluez.Client { return a.client } // Interface return Message1 interface func (a *Message1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Message1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Message1Properties to map func (a *Message1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Message1Properties func (a *Message1Properties) FromMap(props map[string]interface{}) (*Message1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Message1Properties func (a *Message1Properties) FromDBusMap(props map[string]dbus.Variant) (*Message1Properties, error) { s := new(Message1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Message1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Message1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Message1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Message1) GetProperties() (*Message1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Message1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Message1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Message1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Message1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Message1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Message1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Get Download message and store it in the target file. If an empty target file is given, a temporary file will be automatically generated. The returned path represents the newly created transfer, which should be used to find out if the content has been successfully transferred or if the operation fails. The properties of this transfer are also returned along with the object path, to avoid a call to GetProperties. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *Message1) Get(targetfile string, attachment bool) (dbus.ObjectPath, map[string]interface{}, error) { var val0 dbus.ObjectPath var val1 map[string]interface{} err := a.client.Call("Get", 0, targetfile, attachment).Store(&val0, &val1) return val0, val1, err } go-bluetooth-bluez-5.60/bluez/profile/obex/gen_MessageAccess1.go000066400000000000000000000203031420407601400246540ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package obex import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var MessageAccess1Interface = "org.bluez.obex.MessageAccess1" // NewMessageAccess1 create a new instance of MessageAccess1 // // Args: // - objectPath: [Session object path] func NewMessageAccess1(objectPath dbus.ObjectPath) (*MessageAccess1, error) { a := new(MessageAccess1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: MessageAccess1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(MessageAccess1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* MessageAccess1 Message Access hierarchy */ type MessageAccess1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *MessageAccess1Properties watchPropertiesChannel chan *dbus.Signal } // MessageAccess1Properties contains the exposed properties of an interface type MessageAccess1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *MessageAccess1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *MessageAccess1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *MessageAccess1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return MessageAccess1 object path func (a *MessageAccess1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return MessageAccess1 dbus client func (a *MessageAccess1) Client() *bluez.Client { return a.client } // Interface return MessageAccess1 interface func (a *MessageAccess1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *MessageAccess1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a MessageAccess1Properties to map func (a *MessageAccess1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an MessageAccess1Properties func (a *MessageAccess1Properties) FromMap(props map[string]interface{}) (*MessageAccess1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an MessageAccess1Properties func (a *MessageAccess1Properties) FromDBusMap(props map[string]dbus.Variant) (*MessageAccess1Properties, error) { s := new(MessageAccess1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *MessageAccess1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *MessageAccess1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *MessageAccess1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *MessageAccess1) GetProperties() (*MessageAccess1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *MessageAccess1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *MessageAccess1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *MessageAccess1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *MessageAccess1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *MessageAccess1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *MessageAccess1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* SetFolder Set working directory for current session, *name* may be the directory name or '..[/dir]'. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *MessageAccess1) SetFolder(name string) error { return a.client.Call("SetFolder", 0, name).Store() } /* ListFolders Returns a dictionary containing information about the current folder content. The following keys are defined: string Name : Folder name Possible filters: Offset and MaxCount Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *MessageAccess1) ListFolders(filter map[string]interface{}) ([]map[string]interface{}, error) { val0 := []map[string]interface{}{} err := a.client.Call("ListFolders", 0, filter).Store(&val0) return val0, err } /* ListFilterFields Return all available fields that can be used in Fields filter. Possible errors: None */ func (a *MessageAccess1) ListFilterFields() ([]string, error) { val0 := []string{} err := a.client.Call("ListFilterFields", 0).Store(&val0) return val0, err } /* ListMessages Returns an array containing the messages found in the given subfolder of the current folder, or in the current folder if folder is empty. Possible Filters: Offset, MaxCount, SubjectLength, Fields, Type, PeriodStart, PeriodEnd, Status, Recipient, Sender, Priority Each message is represented by an object path followed by a dictionary of the properties. Properties: string Subject: Message subject string Timestamp: Message timestamp string Sender: Message sender name string SenderAddress: Message sender address string ReplyTo: Message Reply-To address string Recipient: Message recipient name string RecipientAddress: Message recipient address string Type: Message type Possible values: "email", "sms-gsm", "sms-cdma" and "mms" uint64 Size: Message size in bytes boolean Text: Message text flag Specifies whether message has textual content or is binary only string Status: Message status Possible values for received messages: "complete", "fractioned", "notification" Possible values for sent messages: "delivery-success", "sending-success", "delivery-failure", "sending-failure" uint64 AttachmentSize: Message overall attachment size in bytes boolean Priority: Message priority flag boolean Read: Message read flag boolean Sent: Message sent flag boolean Protected: Message protected flag Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *MessageAccess1) ListMessages(folder string, filter map[string]interface{}) ([]Message, error) { val0 := []Message{} err := a.client.Call("ListMessages", 0, folder, filter).Store(&val0) return val0, err } /* UpdateInbox */ func (a *MessageAccess1) UpdateInbox() error { return a.client.Call("UpdateInbox", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/obex/gen_PhonebookAccess1.go000066400000000000000000000315701420407601400252240ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package obex import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var PhonebookAccess1Interface = "org.bluez.obex.PhonebookAccess1" // NewPhonebookAccess1 create a new instance of PhonebookAccess1 // // Args: // - objectPath: [Session object path] func NewPhonebookAccess1(objectPath dbus.ObjectPath) (*PhonebookAccess1, error) { a := new(PhonebookAccess1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: PhonebookAccess1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(PhonebookAccess1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* PhonebookAccess1 Phonebook Access hierarchy */ type PhonebookAccess1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *PhonebookAccess1Properties watchPropertiesChannel chan *dbus.Signal } // PhonebookAccess1Properties contains the exposed properties of an interface type PhonebookAccess1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* DatabaseIdentifier 128 bits persistent database identifier. Possible values: 32-character hexadecimal such as A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 */ DatabaseIdentifier string /* FixedImageSize Indicate support for fixed image size. Possible values: True if image is JPEG 300x300 pixels otherwise False. */ FixedImageSize bool /* Folder Current folder. */ Folder string /* PrimaryCounter 128 bits primary version counter. Possible values: 32-character hexadecimal such as A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 */ PrimaryCounter string /* SecondaryCounter 128 bits secondary version counter. Possible values: 32-character hexadecimal such as A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 */ SecondaryCounter string } //Lock access to properties func (p *PhonebookAccess1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *PhonebookAccess1Properties) Unlock() { p.lock.Unlock() } // SetDatabaseIdentifier set DatabaseIdentifier value func (a *PhonebookAccess1) SetDatabaseIdentifier(v string) error { return a.SetProperty("DatabaseIdentifier", v) } // GetDatabaseIdentifier get DatabaseIdentifier value func (a *PhonebookAccess1) GetDatabaseIdentifier() (string, error) { v, err := a.GetProperty("DatabaseIdentifier") if err != nil { return "", err } return v.Value().(string), nil } // SetFixedImageSize set FixedImageSize value func (a *PhonebookAccess1) SetFixedImageSize(v bool) error { return a.SetProperty("FixedImageSize", v) } // GetFixedImageSize get FixedImageSize value func (a *PhonebookAccess1) GetFixedImageSize() (bool, error) { v, err := a.GetProperty("FixedImageSize") if err != nil { return false, err } return v.Value().(bool), nil } // SetFolder set Folder value func (a *PhonebookAccess1) SetFolder(v string) error { return a.SetProperty("Folder", v) } // GetFolder get Folder value func (a *PhonebookAccess1) GetFolder() (string, error) { v, err := a.GetProperty("Folder") if err != nil { return "", err } return v.Value().(string), nil } // SetPrimaryCounter set PrimaryCounter value func (a *PhonebookAccess1) SetPrimaryCounter(v string) error { return a.SetProperty("PrimaryCounter", v) } // GetPrimaryCounter get PrimaryCounter value func (a *PhonebookAccess1) GetPrimaryCounter() (string, error) { v, err := a.GetProperty("PrimaryCounter") if err != nil { return "", err } return v.Value().(string), nil } // SetSecondaryCounter set SecondaryCounter value func (a *PhonebookAccess1) SetSecondaryCounter(v string) error { return a.SetProperty("SecondaryCounter", v) } // GetSecondaryCounter get SecondaryCounter value func (a *PhonebookAccess1) GetSecondaryCounter() (string, error) { v, err := a.GetProperty("SecondaryCounter") if err != nil { return "", err } return v.Value().(string), nil } // Close the connection func (a *PhonebookAccess1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return PhonebookAccess1 object path func (a *PhonebookAccess1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return PhonebookAccess1 dbus client func (a *PhonebookAccess1) Client() *bluez.Client { return a.client } // Interface return PhonebookAccess1 interface func (a *PhonebookAccess1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *PhonebookAccess1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a PhonebookAccess1Properties to map func (a *PhonebookAccess1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an PhonebookAccess1Properties func (a *PhonebookAccess1Properties) FromMap(props map[string]interface{}) (*PhonebookAccess1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an PhonebookAccess1Properties func (a *PhonebookAccess1Properties) FromDBusMap(props map[string]dbus.Variant) (*PhonebookAccess1Properties, error) { s := new(PhonebookAccess1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *PhonebookAccess1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *PhonebookAccess1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *PhonebookAccess1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *PhonebookAccess1) GetProperties() (*PhonebookAccess1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *PhonebookAccess1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *PhonebookAccess1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *PhonebookAccess1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *PhonebookAccess1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *PhonebookAccess1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *PhonebookAccess1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Select Select the phonebook object for other operations. Should be call before all the other operations. location : Where the phonebook is stored, possible inputs : "int" ( "internal" which is default ) "sim" ( "sim1" ) "sim2" ... phonebook : Possible inputs : "pb" : phonebook for the saved contacts "ich": incoming call history "och": outgoing call history "mch": missing call history "cch": combination of ich och mch "spd": speed dials entry ( only for "internal" ) "fav": favorites entry ( only for "internal" ) Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *PhonebookAccess1) Select(location string, phonebook string) error { return a.client.Call("Select", 0, location, phonebook).Store() } /* PullAll Return the entire phonebook object from the PSE server in plain string with vcard format, and store it in a local file. If an empty target file is given, a name will be automatically calculated for the temporary file. The returned path represents the newly created transfer, which should be used to find out if the content has been successfully transferred or if the operation fails. The properties of this transfer are also returned along with the object path, to avoid a call to GetProperties. Possible filters: Format, Order, Offset, MaxCount and Fields Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Forbidden */ func (a *PhonebookAccess1) PullAll(targetfile string, filters map[string]interface{}) (dbus.ObjectPath, map[string]interface{}, error) { var val0 dbus.ObjectPath var val1 map[string]interface{} err := a.client.Call("PullAll", 0, targetfile, filters).Store(&val0, &val1) return val0, val1, err } /* List Return an array of vcard-listing data where every entry consists of a pair of strings containing the vcard handle and the contact name. For example: "1.vcf" : "John" Possible filters: Order, Offset and MaxCount Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Forbidden */ func (a *PhonebookAccess1) List(filters map[string]interface{}) ([]VCardItem, error) { val0 := []VCardItem{} err := a.client.Call("List", 0, filters).Store(&val0) return val0, err } /* Pull Given a vcard handle, retrieve the vcard in the current phonebook object and store it in a local file. If an empty target file is given, a name will be automatically calculated for the temporary file. The returned path represents the newly created transfer, which should be used to find out if the content has been successfully transferred or if the operation fails. The properties of this transfer are also returned along with the object path, to avoid a call to GetProperties. Possbile filters: Format and Fields Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Forbidden org.bluez.obex.Error.Failed */ func (a *PhonebookAccess1) Pull(vcard string, targetfile string, filters map[string]interface{}) (dbus.ObjectPath, map[string]interface{}, error) { var val0 dbus.ObjectPath var val1 map[string]interface{} err := a.client.Call("Pull", 0, vcard, targetfile, filters).Store(&val0, &val1) return val0, val1, err } /* Search Search for entries matching the given condition and return an array of vcard-listing data where every entry consists of a pair of strings containing the vcard handle and the contact name. vcard : name paired string match the search condition. field : the field in the vcard to search with { "name" (default) | "number" | "sound" } value : the string value to search for Possible filters: Order, Offset and MaxCount Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Forbidden org.bluez.obex.Error.Failed */ func (a *PhonebookAccess1) Search(field string, value string, filters map[string]interface{}) ([]VCardItem, error) { val0 := []VCardItem{} err := a.client.Call("Search", 0, field, value, filters).Store(&val0) return val0, err } /* GetSize Return the number of entries in the selected phonebook object that are actually used (i.e. indexes that correspond to non-NULL entries). Possible errors: org.bluez.obex.Error.Forbidden org.bluez.obex.Error.Failed */ func (a *PhonebookAccess1) GetSize() (uint16, error) { var val0 uint16 err := a.client.Call("GetSize", 0).Store(&val0) return val0, err } /* UpdateVersion Attempt to update PrimaryCounter and SecondaryCounter. Possible errors: org.bluez.obex.Error.NotSupported org.bluez.obex.Error.Forbidden org.bluez.obex.Error.Failed */ func (a *PhonebookAccess1) UpdateVersion() error { return a.client.Call("UpdateVersion", 0).Store() } /* ListFilterFields Return All Available fields that can be used in Fields filter. Possible errors: None */ func (a *PhonebookAccess1) ListFilterFields() ([]string, error) { val0 := []string{} err := a.client.Call("ListFilterFields", 0).Store(&val0) return val0, err } go-bluetooth-bluez-5.60/bluez/profile/obex/gen_Synchronization1.go000066400000000000000000000164611420407601400253610ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package obex import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Synchronization1Interface = "org.bluez.obex.Synchronization1" // NewSynchronization1 create a new instance of Synchronization1 // // Args: // - objectPath: [Session object path] func NewSynchronization1(objectPath dbus.ObjectPath) (*Synchronization1, error) { a := new(Synchronization1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: Synchronization1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Synchronization1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Synchronization1 Synchronization hierarchy */ type Synchronization1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Synchronization1Properties watchPropertiesChannel chan *dbus.Signal } // Synchronization1Properties contains the exposed properties of an interface type Synchronization1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Synchronization1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Synchronization1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Synchronization1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Synchronization1 object path func (a *Synchronization1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Synchronization1 dbus client func (a *Synchronization1) Client() *bluez.Client { return a.client } // Interface return Synchronization1 interface func (a *Synchronization1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Synchronization1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Synchronization1Properties to map func (a *Synchronization1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Synchronization1Properties func (a *Synchronization1Properties) FromMap(props map[string]interface{}) (*Synchronization1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Synchronization1Properties func (a *Synchronization1Properties) FromDBusMap(props map[string]dbus.Variant) (*Synchronization1Properties, error) { s := new(Synchronization1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Synchronization1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Synchronization1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Synchronization1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Synchronization1) GetProperties() (*Synchronization1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Synchronization1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Synchronization1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Synchronization1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Synchronization1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Synchronization1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Synchronization1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* SetLocation Set the phonebook object store location for other operations. Should be called before all the other operations. location: Where the phonebook is stored, possible values: "int" ( "internal" which is default ) "sim1" "sim2" ...... Possible errors: org.bluez.obex.Error.InvalidArguments */ func (a *Synchronization1) SetLocation(location string) error { return a.client.Call("SetLocation", 0, location).Store() } /* GetPhonebook Retrieve an entire Phonebook Object store from remote device, and stores it in a local file. If an empty target file is given, a name will be automatically calculated for the temporary file. The returned path represents the newly created transfer, which should be used to find out if the content has been successfully transferred or if the operation fails. The properties of this transfer are also returned along with the object path, to avoid a call to GetProperties. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *Synchronization1) GetPhonebook(targetfile string) (dbus.ObjectPath, map[string]interface{}, error) { var val0 dbus.ObjectPath var val1 map[string]interface{} err := a.client.Call("GetPhonebook", 0, targetfile).Store(&val0, &val1) return val0, val1, err } /* PutPhonebook Send an entire Phonebook Object store to remote device. The returned path represents the newly created transfer, which should be used to find out if the content has been successfully transferred or if the operation fails. The properties of this transfer are also returned along with the object path, to avoid a call to GetProperties. Possible errors: org.bluez.obex.Error.InvalidArguments org.bluez.obex.Error.Failed */ func (a *Synchronization1) PutPhonebook(sourcefile string) (dbus.ObjectPath, map[string]interface{}, error) { var val0 dbus.ObjectPath var val1 map[string]interface{} err := a.client.Call("PutPhonebook", 0, sourcefile).Store(&val0, &val1) return val0, val1, err } go-bluetooth-bluez-5.60/bluez/profile/obex/gen_obex.go000066400000000000000000000001711420407601400230230ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* OBEX D-Bus API description [obex-api.txt] */ package obex go-bluetooth-bluez-5.60/bluez/profile/obex/types.go000066400000000000000000000005671420407601400224120ustar00rootroot00000000000000package obex import "github.com/godbus/dbus/v5" //VCardItem vcard-listing data where every entry consists of a pair of strings containing the vcard handle and the contact name. For example:"1.vcf" : "John" type VCardItem struct { Vcard string Name string } //Message map to array{object, dict} type Message struct { Path dbus.ObjectPath Dict map[string]interface{} } go-bluetooth-bluez-5.60/bluez/profile/obex_agent/000077500000000000000000000000001420407601400220655ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/obex_agent/gen_Agent1.go000066400000000000000000000140511420407601400243650ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package obex_agent import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Agent1Interface = "org.bluez.obex.Agent1" // NewAgent1 create a new instance of Agent1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewAgent1(servicePath string, objectPath dbus.ObjectPath) (*Agent1, error) { a := new(Agent1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: Agent1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Agent1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Agent1 Agent hierarchy */ type Agent1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Agent1Properties watchPropertiesChannel chan *dbus.Signal } // Agent1Properties contains the exposed properties of an interface type Agent1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Agent1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Agent1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Agent1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Agent1 object path func (a *Agent1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Agent1 dbus client func (a *Agent1) Client() *bluez.Client { return a.client } // Interface return Agent1 interface func (a *Agent1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Agent1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Agent1Properties to map func (a *Agent1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Agent1Properties func (a *Agent1Properties) FromMap(props map[string]interface{}) (*Agent1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Agent1Properties func (a *Agent1Properties) FromDBusMap(props map[string]dbus.Variant) (*Agent1Properties, error) { s := new(Agent1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Agent1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Agent1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Agent1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Agent1) GetProperties() (*Agent1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Agent1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Agent1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Agent1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Agent1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Agent1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Agent1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Release This method gets called when the service daemon unregisters the agent. An agent can use it to do cleanup tasks. There is no need to unregister the agent, because when this method gets called it has already been unregistered. */ func (a *Agent1) Release() error { return a.client.Call("Release", 0).Store() } /* AuthorizePush This method gets called when the service daemon needs to accept/reject a Bluetooth object push request. Returns the full path (including the filename) where the object shall be stored. The tranfer object will contain a Filename property that contains the default location and name that can be returned. Possible errors: org.bluez.obex.Error.Rejected org.bluez.obex.Error.Canceled */ func (a *Agent1) AuthorizePush(transfer dbus.ObjectPath) (string, error) { var val0 string err := a.client.Call("AuthorizePush", 0, transfer).Store(&val0) return val0, err } /* Cancel This method gets called to indicate that the agent request failed before a reply was returned. It cancels the previous request. */ func (a *Agent1) Cancel() error { return a.client.Call("Cancel", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/obex_agent/gen_AgentManager1.go000066400000000000000000000134671420407601400256720ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package obex_agent import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var AgentManager1Interface = "org.bluez.obex.AgentManager1" // NewAgentManager1 create a new instance of AgentManager1 // // Args: func NewAgentManager1() (*AgentManager1, error) { a := new(AgentManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez.obex", Iface: AgentManager1Interface, Path: dbus.ObjectPath("/org/bluez/obex"), Bus: bluez.SystemBus, }, ) a.Properties = new(AgentManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* AgentManager1 Agent Manager hierarchy */ type AgentManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *AgentManager1Properties watchPropertiesChannel chan *dbus.Signal } // AgentManager1Properties contains the exposed properties of an interface type AgentManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *AgentManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *AgentManager1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *AgentManager1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return AgentManager1 object path func (a *AgentManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return AgentManager1 dbus client func (a *AgentManager1) Client() *bluez.Client { return a.client } // Interface return AgentManager1 interface func (a *AgentManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *AgentManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a AgentManager1Properties to map func (a *AgentManager1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an AgentManager1Properties func (a *AgentManager1Properties) FromMap(props map[string]interface{}) (*AgentManager1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an AgentManager1Properties func (a *AgentManager1Properties) FromDBusMap(props map[string]dbus.Variant) (*AgentManager1Properties, error) { s := new(AgentManager1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *AgentManager1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *AgentManager1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *AgentManager1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *AgentManager1) GetProperties() (*AgentManager1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *AgentManager1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *AgentManager1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *AgentManager1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *AgentManager1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *AgentManager1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *AgentManager1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* RegisterAgent Register an agent to request authorization of the user to accept/reject objects. Object push service needs to authorize each received object. Possible errors: org.bluez.obex.Error.AlreadyExists */ func (a *AgentManager1) RegisterAgent(agent dbus.ObjectPath) error { return a.client.Call("RegisterAgent", 0, agent).Store() } /* UnregisterAgent This unregisters the agent that has been previously registered. The object path parameter must match the same value that has been used on registration. Possible errors: org.bluez.obex.Error.DoesNotExist */ func (a *AgentManager1) UnregisterAgent(agent dbus.ObjectPath) error { return a.client.Call("UnregisterAgent", 0, agent).Store() } go-bluetooth-bluez-5.60/bluez/profile/obex_agent/gen_obex_agent.go000066400000000000000000000002131420407601400253540ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* OBEX D-Bus Agent API description [obex-agent-api.txt] */ package obex_agent go-bluetooth-bluez-5.60/bluez/profile/profile.go000066400000000000000000000003121420407601400217350ustar00rootroot00000000000000package profile import "github.com/godbus/dbus/v5" // BluezApi is the shared interface for the Bluez API implmentation type BluezApi interface { Path() dbus.ObjectPath Interface() string Close() } go-bluetooth-bluez-5.60/bluez/profile/profile/000077500000000000000000000000001420407601400214125ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/profile/gen_Profile1.go000066400000000000000000000074301420407601400242570ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package profile import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" ) var Profile1Interface = "org.bluez.Profile1" // NewProfile1 create a new instance of Profile1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewProfile1(servicePath string, objectPath dbus.ObjectPath) (*Profile1, error) { a := new(Profile1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: Profile1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) return a, nil } /* Profile1 Profile hierarchy */ type Profile1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Profile1Properties watchPropertiesChannel chan *dbus.Signal } // Profile1Properties contains the exposed properties of an interface type Profile1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *Profile1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Profile1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *Profile1) Close() { a.client.Disconnect() } // Path return Profile1 object path func (a *Profile1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Profile1 dbus client func (a *Profile1) Client() *bluez.Client { return a.client } // Interface return Profile1 interface func (a *Profile1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Profile1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } /* Release This method gets called when the service daemon unregisters the profile. A profile can use it to do cleanup tasks. There is no need to unregister the profile, because when this method gets called it has already been unregistered. */ func (a *Profile1) Release() error { return a.client.Call("Release", 0).Store() } /* NewConnection This method gets called when a new service level connection has been made and authorized. Common fd_properties: uint16 Version Profile version (optional) uint16 Features Profile features (optional) Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Profile1) NewConnection(device dbus.ObjectPath, fd int32, fd_properties map[string]interface{}) error { return a.client.Call("NewConnection", 0, device, fd, fd_properties).Store() } /* RequestDisconnection This method gets called when a profile gets disconnected. The file descriptor is no longer owned by the service daemon and the profile implementation needs to take care of cleaning up all connections. If multiple file descriptors are indicated via NewConnection, it is expected that all of them are disconnected before returning from this method call. Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled */ func (a *Profile1) RequestDisconnection(device dbus.ObjectPath) error { return a.client.Call("RequestDisconnection", 0, device).Store() } go-bluetooth-bluez-5.60/bluez/profile/profile/gen_ProfileManager1.go000066400000000000000000000125251420407601400255530ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package profile import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" ) var ProfileManager1Interface = "org.bluez.ProfileManager1" // NewProfileManager1 create a new instance of ProfileManager1 // // Args: func NewProfileManager1() (*ProfileManager1, error) { a := new(ProfileManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: ProfileManager1Interface, Path: dbus.ObjectPath("/org/bluez"), Bus: bluez.SystemBus, }, ) return a, nil } /* ProfileManager1 Profile Manager hierarchy */ type ProfileManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *ProfileManager1Properties watchPropertiesChannel chan *dbus.Signal } // ProfileManager1Properties contains the exposed properties of an interface type ProfileManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *ProfileManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *ProfileManager1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *ProfileManager1) Close() { a.client.Disconnect() } // Path return ProfileManager1 object path func (a *ProfileManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return ProfileManager1 dbus client func (a *ProfileManager1) Client() *bluez.Client { return a.client } // Interface return ProfileManager1 interface func (a *ProfileManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *ProfileManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } /* RegisterProfile This registers a profile implementation. If an application disconnects from the bus all its registered profiles will be removed. Some predefined services: HFP AG UUID: 0000111f-0000-1000-8000-00805f9b34fb Default profile Version is 1.7, profile Features is 0b001001 and RFCOMM channel is 13. Authentication is required. HFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb Default profile Version is 1.7, profile Features is 0b000000 and RFCOMM channel is 7. Authentication is required. HSP AG UUID: 00001112-0000-1000-8000-00805f9b34fb Default profile Version is 1.2, RFCOMM channel is 12 and Authentication is required. Does not support any Features, option is ignored. HSP HS UUID: 00001108-0000-1000-8000-00805f9b34fb Default profile Version is 1.2, profile Features is 0b0 and RFCOMM channel is 6. Authentication is required. Features is one bit value, specify capability of Remote Audio Volume Control (by default turned off). Available options: string Name Human readable name for the profile string Service The primary service class UUID (if different from the actual profile UUID) string Role For asymmetric profiles that do not have UUIDs available to uniquely identify each side this parameter allows specifying the precise local role. Possible values: "client", "server" uint16 Channel RFCOMM channel number that is used for client and server UUIDs. If applicable it will be used in the SDP record as well. uint16 PSM PSM number that is used for client and server UUIDs. If applicable it will be used in the SDP record as well. boolean RequireAuthentication Pairing is required before connections will be established. No devices will be connected if not paired. boolean RequireAuthorization Request authorization before any connection will be established. boolean AutoConnect In case of a client UUID this will force connection of the RFCOMM or L2CAP channels when a remote device is connected. string ServiceRecord Provide a manual SDP record. uint16 Version Profile version (for SDP record) uint16 Features Profile features (for SDP record) Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists */ func (a *ProfileManager1) RegisterProfile(profile dbus.ObjectPath, uuid string, options map[string]interface{}) error { return a.client.Call("RegisterProfile", 0, profile, uuid, options).Store() } /* UnregisterProfile This unregisters the profile that has been previously registered. The object path parameter must match the same value that has been used on registration. Possible errors: org.bluez.Error.DoesNotExist */ func (a *ProfileManager1) UnregisterProfile(profile dbus.ObjectPath) error { return a.client.Call("UnregisterProfile", 0, profile).Store() } go-bluetooth-bluez-5.60/bluez/profile/profile/gen_profile.go000066400000000000000000000002101420407601400242230ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Profile API description [profile-api.txt] */ package profile go-bluetooth-bluez-5.60/bluez/profile/sap/000077500000000000000000000000001420407601400205355ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/sap/gen_SimAccess1.go000066400000000000000000000131701420407601400236520ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package sap import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var SimAccess1Interface = "org.bluez.SimAccess1" // NewSimAccess1 create a new instance of SimAccess1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...} func NewSimAccess1(objectPath dbus.ObjectPath) (*SimAccess1, error) { a := new(SimAccess1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: SimAccess1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(SimAccess1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* SimAccess1 Sim Access Profile hierarchy */ type SimAccess1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *SimAccess1Properties watchPropertiesChannel chan *dbus.Signal } // SimAccess1Properties contains the exposed properties of an interface type SimAccess1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Connected Indicates if SAP client is connected to the server. */ Connected bool } //Lock access to properties func (p *SimAccess1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *SimAccess1Properties) Unlock() { p.lock.Unlock() } // SetConnected set Connected value func (a *SimAccess1) SetConnected(v bool) error { return a.SetProperty("Connected", v) } // GetConnected get Connected value func (a *SimAccess1) GetConnected() (bool, error) { v, err := a.GetProperty("Connected") if err != nil { return false, err } return v.Value().(bool), nil } // Close the connection func (a *SimAccess1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return SimAccess1 object path func (a *SimAccess1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return SimAccess1 dbus client func (a *SimAccess1) Client() *bluez.Client { return a.client } // Interface return SimAccess1 interface func (a *SimAccess1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *SimAccess1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a SimAccess1Properties to map func (a *SimAccess1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an SimAccess1Properties func (a *SimAccess1Properties) FromMap(props map[string]interface{}) (*SimAccess1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an SimAccess1Properties func (a *SimAccess1Properties) FromDBusMap(props map[string]dbus.Variant) (*SimAccess1Properties, error) { s := new(SimAccess1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *SimAccess1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *SimAccess1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *SimAccess1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *SimAccess1) GetProperties() (*SimAccess1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *SimAccess1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *SimAccess1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *SimAccess1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *SimAccess1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *SimAccess1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *SimAccess1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* Disconnect Disconnects SAP client from the server. Possible errors: org.bluez.Error.Failed */ func (a *SimAccess1) Disconnect() error { return a.client.Call("Disconnect", 0).Store() } go-bluetooth-bluez-5.60/bluez/profile/sap/gen_sap.go000066400000000000000000000002031420407601400224730ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Sim Access API description [sap-api.txt] */ package sap go-bluetooth-bluez-5.60/bluez/profile/thermometer/000077500000000000000000000000001420407601400223055ustar00rootroot00000000000000go-bluetooth-bluez-5.60/bluez/profile/thermometer/gen_Thermometer1.go000066400000000000000000000162061420407601400260460ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package thermometer import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var Thermometer1Interface = "org.bluez.Thermometer1" // NewThermometer1 create a new instance of Thermometer1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX func NewThermometer1(objectPath dbus.ObjectPath) (*Thermometer1, error) { a := new(Thermometer1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: Thermometer1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(Thermometer1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* Thermometer1 Health Thermometer Profile hierarchy */ type Thermometer1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *Thermometer1Properties watchPropertiesChannel chan *dbus.Signal } // Thermometer1Properties contains the exposed properties of an interface type Thermometer1Properties struct { lock sync.RWMutex `dbus:"ignore"` /* Intermediate True if the thermometer supports intermediate measurement notifications. */ Intermediate bool /* Interval (optional) The Measurement Interval defines the time (in seconds) between measurements. This interval is not related to the intermediate measurements and must be defined into a valid range. Setting it to zero means that no periodic measurements will be taken. */ Interval uint16 /* Maximum (optional) Defines the maximum value allowed for the interval between periodic measurements. */ Maximum uint16 /* Minimum (optional) Defines the minimum value allowed for the interval between periodic measurements. */ Minimum uint16 } //Lock access to properties func (p *Thermometer1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *Thermometer1Properties) Unlock() { p.lock.Unlock() } // SetIntermediate set Intermediate value func (a *Thermometer1) SetIntermediate(v bool) error { return a.SetProperty("Intermediate", v) } // GetIntermediate get Intermediate value func (a *Thermometer1) GetIntermediate() (bool, error) { v, err := a.GetProperty("Intermediate") if err != nil { return false, err } return v.Value().(bool), nil } // SetInterval set Interval value func (a *Thermometer1) SetInterval(v uint16) error { return a.SetProperty("Interval", v) } // GetInterval get Interval value func (a *Thermometer1) GetInterval() (uint16, error) { v, err := a.GetProperty("Interval") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetMaximum set Maximum value func (a *Thermometer1) SetMaximum(v uint16) error { return a.SetProperty("Maximum", v) } // GetMaximum get Maximum value func (a *Thermometer1) GetMaximum() (uint16, error) { v, err := a.GetProperty("Maximum") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // SetMinimum set Minimum value func (a *Thermometer1) SetMinimum(v uint16) error { return a.SetProperty("Minimum", v) } // GetMinimum get Minimum value func (a *Thermometer1) GetMinimum() (uint16, error) { v, err := a.GetProperty("Minimum") if err != nil { return uint16(0), err } return v.Value().(uint16), nil } // Close the connection func (a *Thermometer1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return Thermometer1 object path func (a *Thermometer1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return Thermometer1 dbus client func (a *Thermometer1) Client() *bluez.Client { return a.client } // Interface return Thermometer1 interface func (a *Thermometer1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *Thermometer1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a Thermometer1Properties to map func (a *Thermometer1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an Thermometer1Properties func (a *Thermometer1Properties) FromMap(props map[string]interface{}) (*Thermometer1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an Thermometer1Properties func (a *Thermometer1Properties) FromDBusMap(props map[string]dbus.Variant) (*Thermometer1Properties, error) { s := new(Thermometer1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *Thermometer1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *Thermometer1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *Thermometer1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *Thermometer1) GetProperties() (*Thermometer1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *Thermometer1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *Thermometer1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *Thermometer1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *Thermometer1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *Thermometer1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *Thermometer1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } go-bluetooth-bluez-5.60/bluez/profile/thermometer/gen_ThermometerManager1.go000066400000000000000000000155101420407601400273360ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package thermometer import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var ThermometerManager1Interface = "org.bluez.ThermometerManager1" // NewThermometerManager1 create a new instance of ThermometerManager1 // // Args: // - objectPath: [variable prefix]/{hci0,hci1,...} func NewThermometerManager1(objectPath dbus.ObjectPath) (*ThermometerManager1, error) { a := new(ThermometerManager1) a.client = bluez.NewClient( &bluez.Config{ Name: "org.bluez", Iface: ThermometerManager1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(ThermometerManager1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* ThermometerManager1 Health Thermometer Manager hierarchy */ type ThermometerManager1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *ThermometerManager1Properties watchPropertiesChannel chan *dbus.Signal } // ThermometerManager1Properties contains the exposed properties of an interface type ThermometerManager1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *ThermometerManager1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *ThermometerManager1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *ThermometerManager1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return ThermometerManager1 object path func (a *ThermometerManager1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return ThermometerManager1 dbus client func (a *ThermometerManager1) Client() *bluez.Client { return a.client } // Interface return ThermometerManager1 interface func (a *ThermometerManager1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *ThermometerManager1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a ThermometerManager1Properties to map func (a *ThermometerManager1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an ThermometerManager1Properties func (a *ThermometerManager1Properties) FromMap(props map[string]interface{}) (*ThermometerManager1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an ThermometerManager1Properties func (a *ThermometerManager1Properties) FromDBusMap(props map[string]dbus.Variant) (*ThermometerManager1Properties, error) { s := new(ThermometerManager1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *ThermometerManager1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *ThermometerManager1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *ThermometerManager1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *ThermometerManager1) GetProperties() (*ThermometerManager1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *ThermometerManager1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *ThermometerManager1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *ThermometerManager1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *ThermometerManager1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *ThermometerManager1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *ThermometerManager1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* RegisterWatcher Registers a watcher to monitor scanned measurements. This agent will be notified about final temperature measurements. Possible Errors: org.bluez.Error.InvalidArguments */ func (a *ThermometerManager1) RegisterWatcher(agent dbus.ObjectPath) error { return a.client.Call("RegisterWatcher", 0, agent).Store() } /* UnregisterWatcher Unregisters a watcher. */ func (a *ThermometerManager1) UnregisterWatcher(agent dbus.ObjectPath) error { return a.client.Call("UnregisterWatcher", 0, agent).Store() } /* EnableIntermediateMeasurement Enables intermediate measurement notifications for this agent. Intermediate measurements will be enabled only for thermometers which support it. Possible Errors: org.bluez.Error.InvalidArguments */ func (a *ThermometerManager1) EnableIntermediateMeasurement(agent dbus.ObjectPath) error { return a.client.Call("EnableIntermediateMeasurement", 0, agent).Store() } /* DisableIntermediateMeasurement Disables intermediate measurement notifications for this agent. It will disable notifications in thermometers when the last agent removes the watcher for intermediate measurements. Possible Errors: org.bluez.Error.InvalidArguments org.bluez.Error.NotFound */ func (a *ThermometerManager1) DisableIntermediateMeasurement(agent dbus.ObjectPath) error { return a.client.Call("DisableIntermediateMeasurement", 0, agent).Store() } go-bluetooth-bluez-5.60/bluez/profile/thermometer/gen_ThermometerWatcher1.go000066400000000000000000000152271420407601400273660ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package thermometer import ( "sync" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez" "github.com/muka/go-bluetooth/props" "github.com/muka/go-bluetooth/util" ) var ThermometerWatcher1Interface = "org.bluez.ThermometerWatcher1" // NewThermometerWatcher1 create a new instance of ThermometerWatcher1 // // Args: // - servicePath: unique name // - objectPath: freely definable func NewThermometerWatcher1(servicePath string, objectPath dbus.ObjectPath) (*ThermometerWatcher1, error) { a := new(ThermometerWatcher1) a.client = bluez.NewClient( &bluez.Config{ Name: servicePath, Iface: ThermometerWatcher1Interface, Path: dbus.ObjectPath(objectPath), Bus: bluez.SystemBus, }, ) a.Properties = new(ThermometerWatcher1Properties) _, err := a.GetProperties() if err != nil { return nil, err } return a, nil } /* ThermometerWatcher1 Health Thermometer Watcher hierarchy */ type ThermometerWatcher1 struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *ThermometerWatcher1Properties watchPropertiesChannel chan *dbus.Signal } // ThermometerWatcher1Properties contains the exposed properties of an interface type ThermometerWatcher1Properties struct { lock sync.RWMutex `dbus:"ignore"` } //Lock access to properties func (p *ThermometerWatcher1Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *ThermometerWatcher1Properties) Unlock() { p.lock.Unlock() } // Close the connection func (a *ThermometerWatcher1) Close() { a.unregisterPropertiesSignal() a.client.Disconnect() } // Path return ThermometerWatcher1 object path func (a *ThermometerWatcher1) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return ThermometerWatcher1 dbus client func (a *ThermometerWatcher1) Client() *bluez.Client { return a.client } // Interface return ThermometerWatcher1 interface func (a *ThermometerWatcher1) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *ThermometerWatcher1) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } // ToMap convert a ThermometerWatcher1Properties to map func (a *ThermometerWatcher1Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an ThermometerWatcher1Properties func (a *ThermometerWatcher1Properties) FromMap(props map[string]interface{}) (*ThermometerWatcher1Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an ThermometerWatcher1Properties func (a *ThermometerWatcher1Properties) FromDBusMap(props map[string]dbus.Variant) (*ThermometerWatcher1Properties, error) { s := new(ThermometerWatcher1Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *ThermometerWatcher1) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *ThermometerWatcher1) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *ThermometerWatcher1) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *ThermometerWatcher1) GetProperties() (*ThermometerWatcher1Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *ThermometerWatcher1) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *ThermometerWatcher1) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *ThermometerWatcher1) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *ThermometerWatcher1) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *ThermometerWatcher1) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *ThermometerWatcher1) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } /* MeasurementReceived This callback gets called when a measurement has been scanned in the thermometer. Measurement: int16 Exponent: int32 Mantissa: Exponent and Mantissa values as extracted from float value defined by IEEE-11073-20601. Measurement value is calculated as (Mantissa) * (10^Exponent) For special cases Exponent is set to 0 and Mantissa is set to one of following values: +(2^23 - 1) NaN (invalid or missing data) -(2^23) NRes +(2^23 - 2) +Infinity -(2^23 - 2) -Infinity string Unit: Possible values: "celsius" or "fahrenheit" uint64 Time (optional): Time of measurement, if supported by device. Expressed in seconds since epoch. string Type (optional): Only present if measurement type is known. Possible values: "armpit", "body", "ear", "finger", "intestines", "mouth", "rectum", "toe", "tympanum" string Measurement: Possible values: "final" or "intermediate" */ func (a *ThermometerWatcher1) MeasurementReceived(measurement map[string]interface{}) error { return a.client.Call("MeasurementReceived", 0, measurement).Store() } go-bluetooth-bluez-5.60/bluez/profile/thermometer/gen_thermometer.go000066400000000000000000000003001420407601400260110ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* BlueZ D-Bus Thermometer API description [thermometer-api.txt] Santiago Carot-Nemesio */ package thermometer go-bluetooth-bluez-5.60/bluez/props.go000066400000000000000000000047301420407601400200100ustar00rootroot00000000000000package bluez import ( "reflect" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/util" log "github.com/sirupsen/logrus" ) type WatchableClient interface { Client() *Client Path() dbus.ObjectPath ToProps() Properties GetWatchPropertiesChannel() chan *dbus.Signal SetWatchPropertiesChannel(chan *dbus.Signal) } // WatchProperties updates on property changes func WatchProperties(wprop WatchableClient) (chan *PropertyChanged, error) { channel, err := wprop.Client().Register(wprop.Path(), PropertiesInterface) if err != nil { return nil, err } wprop.SetWatchPropertiesChannel(channel) ch := make(chan *PropertyChanged) go (func() { defer func() { if err := recover(); err != nil { log.Warnf("Recovering from panic in SetWatchPropertiesChannel: %s", err) } }() for { if channel == nil { break } sig := <-channel if sig == nil { return } if sig.Name != PropertiesChanged { continue } if sig.Path != wprop.Path() { continue } iface := sig.Body[0].(string) changes := sig.Body[1].(map[string]dbus.Variant) for field, val := range changes { // updates [*]Properties struct when a property change s := reflect.ValueOf(wprop.ToProps()).Elem() // exported field f := s.FieldByName(field) if f.IsValid() { // A Value can be changed only if it is // addressable and was not obtained by // the use of unexported struct fields. if f.CanSet() { x := reflect.ValueOf(val.Value()) wprop.ToProps().Lock() // map[*]variant -> map[*]interface{} ok, err := util.AssignMapVariantToInterface(f, x) if err != nil { log.Errorf("Failed to set %s: %s", f.String(), err) continue } // direct assignment if !ok { f.Set(x) } wprop.ToProps().Unlock() } } propChanged := &PropertyChanged{ Interface: iface, Name: field, Value: val.Value(), } ch <- propChanged } } })() return ch, nil } func UnwatchProperties(wprop WatchableClient, ch chan *PropertyChanged) error { defer func() { if err := recover(); err != nil { log.Warnf("Recovering from panic in UnwatchProperties: %s", err) } }() if wprop.GetWatchPropertiesChannel() != nil { wprop.GetWatchPropertiesChannel() <- nil err := wprop.Client().Unregister(wprop.Path(), PropertiesInterface, wprop.GetWatchPropertiesChannel()) if err != nil { return err } } ch <- nil close(ch) return nil } go-bluetooth-bluez-5.60/devices/000077500000000000000000000000001420407601400166135ustar00rootroot00000000000000go-bluetooth-bluez-5.60/devices/sensortag/000077500000000000000000000000001420407601400206205ustar00rootroot00000000000000go-bluetooth-bluez-5.60/devices/sensortag/barometric.go000066400000000000000000000107751420407601400233100ustar00rootroot00000000000000package sensortag import ( "bytes" "encoding/binary" "errors" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) //getting config,data,period characteristics for BAROMETRIC sensor func newBarometricSensor(tag *SensorTag) (*BarometricSensor, error) { dev := tag.Device1 BarometerConfigUUID, err := getUUID("BarometerConfig") if err != nil { return nil, err } BarometerDataUUID, err := getUUID("BarometerData") if err != nil { return nil, err } BarometerPeriodUUID, err := getUUID("BarometerPeriod") if err != nil { return nil, err } i, err := retryCall(DefaultRetry, DefaultRetryWait, func() (interface{}, error) { cfg, err := dev.GetCharByUUID(BarometerConfigUUID) if err != nil { return nil, err } data, err := dev.GetCharByUUID(BarometerDataUUID) if err != nil { return nil, err } if data == nil { return nil, errors.New("Cannot find BarometerData characteristic " + BarometerDataUUID) } period, err := dev.GetCharByUUID(BarometerPeriodUUID) if err != nil { return nil, err } if period == nil { return nil, errors.New("Cannot find BarometerPeriod characteristic " + BarometerPeriodUUID) } return &BarometricSensor{tag, cfg, data, period}, err }) return i.(*BarometricSensor), err } //BarometricSensor structure type BarometricSensor struct { tag *SensorTag cfg *gatt.GattCharacteristic1 data *gatt.GattCharacteristic1 period *gatt.GattCharacteristic1 } //GetName return the sensor name func (s BarometricSensor) GetName() string { return "pressure" } //Enable barometric measurements func (s *BarometricSensor) Enable() error { enabled, err := s.IsEnabled() if err != nil { return err } if enabled { return nil } options := getOptions() err = s.cfg.WriteValue([]byte{1}, options) if err != nil { return err } return nil } //Disable barometric measurements func (s *BarometricSensor) Disable() error { enabled, err := s.IsEnabled() if err != nil { return err } if !enabled { return nil } options := getOptions() err = s.cfg.WriteValue([]byte{0}, options) if err != nil { return err } return nil } //IsEnabled check if BarometricSensor measurements are enabled func (s *BarometricSensor) IsEnabled() (bool, error) { options := getOptions() val, err := s.cfg.ReadValue(options) if err != nil { return false, err } buf := bytes.NewBuffer(val) enabled, err := binary.ReadVarint(buf) if err != nil { return false, err } return (enabled == 1), nil } //IsNotifying check if BarometricSensor sensors are Notifying func (s *BarometricSensor) IsNotifying() (bool, error) { n, err := s.data.GetProperty("Notifying") if err != nil { return false, err } return n.Value().(bool), nil } //Read value from the BarometricSensor sensors func (s *BarometricSensor) Read() (float64, error) { err := s.Enable() if err != nil { return 0, err } options := getOptions() b, err := s.data.ReadValue(options) if err != nil { return 0, err } amb := binary.LittleEndian.Uint16(b[2:]) ambientValue := calcTmpLocal(uint16(amb)) return ambientValue, err } //StartNotify enable BarometricSensorDataChannel func (s *BarometricSensor) StartNotify(macAddress string) error { err := s.Enable() if err != nil { return err } propsChanged, err := s.data.WatchProperties() if err != nil { return err } go func() { for prop := range propsChanged { if prop == nil { return } if prop.Name != "Value" { return } b1 := prop.Value.([]byte) barometer := binary.LittleEndian.Uint32(b1[2:]) barometericPressureValue := calcBarometricPressure(uint32(barometer)) barometerTemperature := binary.LittleEndian.Uint32(b1[0:4]) barometerTempValue := calcBarometricTemperature(uint32(barometerTemperature)) dataEvent := SensorTagDataEvent{ Device: s.tag.Device1, SensorType: "pressure", BarometericPressureValue: barometericPressureValue, BarometericPressureUnit: "hPa", BarometericTempValue: barometerTempValue, BarometericTempUnit: "C", SensorID: macAddress, } s.tag.Data() <- &dataEvent } }() n, err := s.IsNotifying() if err != nil { return err } if !n { return s.data.StartNotify() } return nil } //StopNotify disable Barometric Sensor DataChannel func (s *BarometricSensor) StopNotify() error { err := s.Disable() if err != nil { return err } if dataChannel != nil { close(dataChannel) } n, err := s.IsNotifying() if err != nil { return err } if n { return s.data.StopNotify() } return nil } go-bluetooth-bluez-5.60/devices/sensortag/calc.go000066400000000000000000000044241420407601400220550ustar00rootroot00000000000000package sensortag import "math" // Port from http://processors.wiki.ti.com/index.php/SensorTag_User_Guide#IR_Temperature_Sensor var calcBarometricPressure = func(raw uint32) float64 { //barometric pressure...... pressureMask := (int(raw) >> 8) & 0x00ffffff return float64(pressureMask) / 100.0 } var calcBarometricTemperature = func(raw uint32) float64 { //TEMPERATURE calibiration data coming from barometric sensor tempMask := int(raw) & 0x00ffffff return float64(tempMask) / 100.0 } // Port from http://processors.wiki.ti.com/index.php/SensorTag_User_Guide#IR_Temperature_Sensor var calcHumidLocal = func(raw uint16) float64 { //humidity calibiration......... return float64(raw) * 100 / 65536.0 } var calcTmpFromHumidSensor = func(raw uint16) float64 { //TEMPERATURE calibiration for data coming from humidity sensor return -40 + ((165 * float64(raw)) / 65536.0) } // Port from http://processors.wiki.ti.com/index.php/SensorTag_User_Guide#IR_Temperature_Sensor var calcTmpLocal = func(raw uint16) float64 { //ambient temperature calberation return float64(raw) / 128.0 } /* Conversion algorithm for target temperature */ var calcTmpTarget = func(raw uint16) float64 { //..object temperature caliberation........... return float64(raw) / 128.0 } // Port from http://processors.wiki.ti.com/index.php/SensorTag_User_Guide#IR_Temperature_Sensor var calcMpuGyroscope = func(rawX, rawY, rawZ uint16) (float64, float64, float64) { Xg := float64(rawX) / 128.0 Yg := float64(rawY) / 128.0 Zg := float64(rawZ) / 128.0 return Xg, Yg, Zg } var calcMpuAccelerometer = func(rawX, rawY, rawZ uint16) (float64, float64, float64) { Xg := float64(rawX) / 4096.0 Yg := float64(rawY) / 4096.0 Zg := float64(rawZ) / 4096.0 return Xg, Yg, Zg } var calcMpuMagnetometer = func(rawX, rawY, rawZ uint16) (float64, float64, float64) { Xg := float64(rawX) * 4912.0 / 32768.0 Yg := float64(rawY) * 4912.0 / 32768.0 Zg := float64(rawZ) * 4912.0 / 32768.0 return Xg, Yg, Zg } // Port from http://processors.wiki.ti.com/index.php/SensorTag_User_Guide#IR_Temperature_Sensor var calcLuxometer = func(raw uint16) float64 { exponent := (int(raw) & 0xF000) >> 12 mantissa := (int(raw) & 0x0FFF) exp := float64(exponent) man := float64(mantissa) flLux := man * math.Pow(2, exp) / 100 return float64(flLux) } go-bluetooth-bluez-5.60/devices/sensortag/humidity.go000066400000000000000000000105311420407601400230030ustar00rootroot00000000000000package sensortag import ( "bytes" "encoding/binary" "errors" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) //getting config,data,period characteristics for Humidity sensor func newHumiditySensor(tag *SensorTag) (*HumiditySensor, error) { dev := tag.Device1 HumidityConfigUUID, err := getUUID("HumidityConfig") if err != nil { return nil, err } HumidityDataUUID, err := getUUID("HumidityData") if err != nil { return nil, err } HumidityPeriodUUID, err := getUUID("HumidityPeriod") if err != nil { return nil, err } i, err := retryCall(DefaultRetry, DefaultRetryWait, func() (interface{}, error) { cfg, err := dev.GetCharByUUID(HumidityConfigUUID) if err != nil { return nil, err } data, err := dev.GetCharByUUID(HumidityDataUUID) if err != nil { return nil, err } if data == nil { return nil, errors.New("Cannot find HumidityData characteristic " + HumidityDataUUID) } period, err := dev.GetCharByUUID(HumidityPeriodUUID) if err != nil { return nil, err } if period == nil { return nil, errors.New("Cannot find HumidityPeriod characteristic " + HumidityPeriodUUID) } return &HumiditySensor{tag, cfg, data, period}, err }) return i.(*HumiditySensor), err } //HumiditySensor struct type HumiditySensor struct { tag *SensorTag cfg *gatt.GattCharacteristic1 data *gatt.GattCharacteristic1 period *gatt.GattCharacteristic1 } //GetName return the sensor name func (s HumiditySensor) GetName() string { return "humidity" } //Enable humidity measurements func (s *HumiditySensor) Enable() error { enabled, err := s.IsEnabled() if err != nil { return err } if enabled { return nil } options := getOptions() err = s.cfg.WriteValue([]byte{1}, options) if err != nil { return err } return nil } //Disable humidity measurements func (s *HumiditySensor) Disable() error { enabled, err := s.IsEnabled() if err != nil { return err } if !enabled { return nil } options := make(map[string]interface{}) err = s.cfg.WriteValue([]byte{0}, options) if err != nil { return err } return nil } // IsEnabled check if humidity measurements are enabled func (s *HumiditySensor) IsEnabled() (bool, error) { options := make(map[string]interface{}) val, err := s.cfg.ReadValue(options) if err != nil { return false, err } buf := bytes.NewBuffer(val) enabled, err := binary.ReadVarint(buf) if err != nil { return false, err } return (enabled == 1), nil } //IsNotifying check if humidity sensor is notyfing func (s *HumiditySensor) IsNotifying() (bool, error) { n, err := s.data.GetProperty("Notifying") if err != nil { return false, err } return n.Value().(bool), nil } //Read value from the humidity sensor func (s *HumiditySensor) Read() (float64, error) { err := s.Enable() if err != nil { return 0, err } options := make(map[string]interface{}) b, err := s.data.ReadValue(options) if err != nil { return 0, err } humid := binary.LittleEndian.Uint16(b[2:]) humidValue := calcHumidLocal(uint16(humid)) return humidValue, err } //StartNotify enable DataChannel for humidity func (s *HumiditySensor) StartNotify() error { err := s.Enable() if err != nil { return err } dataChannel, err := s.data.WatchProperties() if err != nil { return err } go func() { for prop := range dataChannel { if prop == nil { return } if prop.Name != "Value" { return } b1 := prop.Value.([]byte) humid := binary.LittleEndian.Uint16(b1[2:]) humidityValue := calcHumidLocal(uint16(humid)) temperature := binary.LittleEndian.Uint16(b1[0:2]) tempValue := calcTmpFromHumidSensor(uint16(temperature)) dataEvent := SensorTagDataEvent{ Device: s.tag.Device1, SensorType: "humidity", HumidityValue: humidityValue, HumidityUnit: "%RH", HumidityTempValue: tempValue, HumidityTempUnit: "C", SensorID: s.tag.Properties.Address, } s.tag.Data() <- &dataEvent } }() n, err := s.IsNotifying() if err != nil { return err } if !n { return s.data.StartNotify() } return nil } //StopNotify disable DataChannel for humidity sensor func (s *HumiditySensor) StopNotify() error { err := s.Disable() if err != nil { return err } if dataChannel != nil { close(dataChannel) } n, err := s.IsNotifying() if err != nil { return err } if n { return s.data.StopNotify() } return nil } go-bluetooth-bluez-5.60/devices/sensortag/luxometer.go000066400000000000000000000104121420407601400231710ustar00rootroot00000000000000package sensortag import ( "bytes" "encoding/binary" "errors" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) //Luxometer Sensor.. //getting config,data,period characteristics for luxometer sensor func newLuxometerSensor(tag *SensorTag) (*LuxometerSensor, error) { dev := tag.Device1 LuxometerConfigUUID, err := getUUID("LUXOMETER_CONFIG_UUID") if err != nil { return nil, err } LuxometerDataUUID, err := getUUID("LUXOMETER_DATA_UUID") if err != nil { return nil, err } LuxometerPeriodUUID, err := getUUID("LUXOMETER_PERIOD_UUID") if err != nil { return nil, err } i, err := retryCall(DefaultRetry, DefaultRetryWait, func() (interface{}, error) { cfg, err := dev.GetCharByUUID(LuxometerConfigUUID) if err != nil { return nil, err } data, err := dev.GetCharByUUID(LuxometerDataUUID) if err != nil { return nil, err } if data == nil { return nil, errors.New("Cannot find LuxometerDataUUID characteristic " + LuxometerDataUUID) } period, err := dev.GetCharByUUID(LuxometerPeriodUUID) if err != nil { return nil, err } if period == nil { return nil, errors.New("Cannot find LuxometerPeriodUUID characteristic " + LuxometerPeriodUUID) } return &LuxometerSensor{tag, cfg, data, period}, err }) return i.(*LuxometerSensor), err } //LuxometerSensor sensor structure type LuxometerSensor struct { tag *SensorTag cfg *gatt.GattCharacteristic1 data *gatt.GattCharacteristic1 period *gatt.GattCharacteristic1 } //GetName return the sensor name func (s LuxometerSensor) GetName() string { return "luxometer" } //Enable LuxometerSensor measurements func (s *LuxometerSensor) Enable() error { enabled, err := s.IsEnabled() if err != nil { return err } if enabled { return nil } options := getOptions() err = s.cfg.WriteValue([]byte{1}, options) if err != nil { return err } return nil } //Disable LuxometerSensor measurements func (s *LuxometerSensor) Disable() error { enabled, err := s.IsEnabled() if err != nil { return err } if !enabled { return nil } options := make(map[string]interface{}) err = s.cfg.WriteValue([]byte{0}, options) if err != nil { return err } return nil } //IsEnabled check if LuxometerSensor measurements are enabled func (s *LuxometerSensor) IsEnabled() (bool, error) { options := getOptions() val, err := s.cfg.ReadValue(options) if err != nil { return false, err } buf := bytes.NewBuffer(val) enabled, err := binary.ReadVarint(buf) if err != nil { return false, err } return (enabled == 1), nil } //IsNotifying check if LuxometerSensor sensors are Notifying func (s *LuxometerSensor) IsNotifying() (bool, error) { n, err := s.data.GetProperty("Notifying") if err != nil { return false, err } return n.Value().(bool), nil } //Read value from the LuxometerSensor sensors func (s *LuxometerSensor) Read() (float64, error) { err := s.Enable() if err != nil { return 0, err } options := getOptions() b, err := s.data.ReadValue(options) if err != nil { return 0, err } amb := binary.LittleEndian.Uint16(b[2:]) ambientValue := calcTmpLocal(uint16(amb)) return ambientValue, err } //StartNotify enable LuxometerSensorDataChannel func (s *LuxometerSensor) StartNotify(macAddress string) error { err := s.Enable() if err != nil { return err } dataChannel, err := s.data.WatchProperties() if err != nil { return err } go func() { for prop := range dataChannel { if prop == nil { return } if prop.Name != "Value" { return } b1 := prop.Value.([]byte) luxometer := binary.LittleEndian.Uint16(b1[0:]) luxometerValue := calcLuxometer(uint16(luxometer)) dataEvent := SensorTagDataEvent{ Device: s.tag.Device1, SensorType: "luxometer", LuxometerValue: luxometerValue, LuxometerUnit: "candela", SensorID: macAddress, } s.tag.Data() <- &dataEvent } }() n, err := s.IsNotifying() if err != nil { return err } if !n { return s.data.StartNotify() } return nil } //StopNotify disable Luxometer Sensor DataChannel func (s *LuxometerSensor) StopNotify() error { err := s.Disable() if err != nil { return err } if dataChannel != nil { close(dataChannel) } n, err := s.IsNotifying() if err != nil { return err } if n { return s.data.StopNotify() } return nil } go-bluetooth-bluez-5.60/devices/sensortag/mpu.go000066400000000000000000000125031420407601400217510ustar00rootroot00000000000000package sensortag import ( "bytes" "encoding/binary" "errors" "fmt" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) //getting config,data,period characteristics for Humidity sensor func newMpuSensor(tag *SensorTag) (*MpuSensor, error) { dev := tag.Device1 //accelerometer,magnetometer,gyroscope MpuConfigUUID, err := getUUID("MPU9250_CONFIG_UUID") if err != nil { return nil, err } MpuDataUUID, err := getUUID("MPU9250_DATA_UUID") if err != nil { return nil, err } MpuPeriodUUID, err := getUUID("MPU9250_PERIOD_UUID") if err != nil { return nil, err } i, err := retryCall(DefaultRetry, DefaultRetryWait, func() (interface{}, error) { cfg, err := dev.GetCharByUUID(MpuConfigUUID) if err != nil { return nil, err } data, err := dev.GetCharByUUID(MpuDataUUID) if err != nil { return nil, err } if data == nil { return nil, errors.New("Cannot find MpuData characteristic " + MpuDataUUID) } period, err := dev.GetCharByUUID(MpuPeriodUUID) if err != nil { return nil, err } if period == nil { return nil, errors.New("Cannot find MpuPeriod characteristic " + MpuPeriodUUID) } return &MpuSensor{tag, cfg, data, period}, err }) return i.(*MpuSensor), err } //MpuSensor structure type MpuSensor struct { tag *SensorTag cfg *gatt.GattCharacteristic1 data *gatt.GattCharacteristic1 period *gatt.GattCharacteristic1 } //GetName return's the sensor name func (s MpuSensor) GetName() string { return "Ac-Mg-Gy" } //Enable mpuSensors measurements func (s *MpuSensor) Enable() error { enabled, err := s.IsEnabled() if err != nil { return err } if enabled { return nil } options := make(map[string]interface{}) err = s.cfg.WriteValue([]byte{0x0007f, 0x0007f}, options) if err != nil { return err } return nil } //Disable mpuSensors measurements func (s *MpuSensor) Disable() error { enabled, err := s.IsEnabled() if err != nil { return err } if !enabled { return nil } options := make(map[string]interface{}) err = s.cfg.WriteValue([]byte{0}, options) if err != nil { return err } return nil } //IsEnabled check if mpu measurements are enabled func (s *MpuSensor) IsEnabled() (bool, error) { options := make(map[string]interface{}) val, err := s.cfg.ReadValue(options) if err != nil { return false, err } buf := bytes.NewBuffer(val) enabled, err := binary.ReadVarint(buf) if err != nil { return false, err } return (enabled == 1), nil } //IsNotifying check if mpu sensors are notifying func (s *MpuSensor) IsNotifying() (bool, error) { n, err := s.data.GetProperty("Notifying") if err != nil { return false, err } return n.Value().(bool), nil } //Read value from the mpu sensors func (s *MpuSensor) Read() (float64, error) { err := s.Enable() if err != nil { return 0, err } options := make(map[string]interface{}) b, err := s.data.ReadValue(options) if err != nil { return 0, err } amb := binary.LittleEndian.Uint16(b[2:]) ambientValue := calcTmpLocal(uint16(amb)) return ambientValue, err } //StartNotify enable mpuDataChannel func (s *MpuSensor) StartNotify(macAddress string) error { err := s.Enable() if err != nil { return err } propsChanged, err := s.data.WatchProperties() if err != nil { return err } go func() { for prop := range propsChanged { if prop == nil { return } if prop.Name != "Value" { return } b1 := prop.Value.([]byte) var mpuAccelerometer string var mpuGyroscope string var mpuMagnetometer string //... calculate Gyroscope........... mpuXg := binary.LittleEndian.Uint16(b1[0:2]) mpuYg := binary.LittleEndian.Uint16(b1[2:4]) mpuZg := binary.LittleEndian.Uint16(b1[4:6]) mpuGyX, mpuGyY, mpuGyZ := calcMpuGyroscope(uint16(mpuXg), uint16(mpuYg), uint16(mpuZg)) mpuGyroscope = fmt.Sprint(mpuGyX, " , ", mpuGyY, " , ", mpuGyZ) //... calculate Accelerometer....... mpuXa := binary.LittleEndian.Uint16(b1[6:8]) mpuYa := binary.LittleEndian.Uint16(b1[8:10]) mpuZa := binary.LittleEndian.Uint16(b1[10:12]) mpuAcX, mpuAcY, mpuAcZ := calcMpuAccelerometer(uint16(mpuXa), uint16(mpuYa), uint16(mpuZa)) mpuAccelerometer = fmt.Sprint(mpuAcX, " , ", mpuAcY, " , ", mpuAcZ) //... calculate Magnetometer....... mpuXm := binary.LittleEndian.Uint16(b1[12:14]) mpuYm := binary.LittleEndian.Uint16(b1[14:16]) mpuZm := binary.LittleEndian.Uint16(b1[16:18]) mpuMgX, mpuMgY, mpuMgZ := calcMpuMagnetometer(uint16(mpuXm), uint16(mpuYm), uint16(mpuZm)) mpuMagnetometer = fmt.Sprint(mpuMgX, " , ", mpuMgY, " , ", mpuMgZ) dataEvent := SensorTagDataEvent{ Device: s.tag.Device1, SensorType: "mpu", MpuGyroscopeValue: mpuGyroscope, MpuGyroscopeUnit: "deg/s", MpuAccelerometerValue: mpuAccelerometer, MpuAccelerometerUnit: "G", MpuMagnetometerValue: mpuMagnetometer, MpuMagnetometerUnit: "uT", SensorID: macAddress, } s.tag.Data() <- &dataEvent } }() n, err := s.IsNotifying() if err != nil { return err } if !n { return s.data.StartNotify() } return nil } //StopNotify disable DataChannel for mpu sensors func (s *MpuSensor) StopNotify() error { err := s.Disable() if err != nil { return err } if dataChannel != nil { close(dataChannel) } n, err := s.IsNotifying() if err != nil { return err } if n { return s.data.StopNotify() } return nil } go-bluetooth-bluez-5.60/devices/sensortag/sensortag.go000066400000000000000000000175061420407601400231650ustar00rootroot00000000000000package sensortag import ( "errors" "fmt" "time" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/bluez/profile/device" "github.com/muka/go-bluetooth/bluez/profile/gatt" log "github.com/sirupsen/logrus" ) // DefaultRetry times const DefaultRetry = 3 // DefaultRetryWait in millis const DefaultRetryWait = 500 var dataChannel chan dbus.Signal var sensorTagUUIDs = map[string]string{ "TemperatureData": "AA01", "TemperatureConfig": "AA02", "TemperaturePeriod": "AA03", "AccelerometerData": "AA11", "AccelerometerConfig": "AA12", "AccelerometerPeriod": "AA13", "HumidityData": "AA21", "HumidityConfig": "AA22", "HumidityPeriod": "AA23", "MagnetometerData": "AA31", "MagnetometerConfig": "AA32", "MagnetometerPeriod": "AA33", "BarometerData": "AA41", "BarometerConfig": "AA42", "BarometerPeriod": "AA44", "BarometerCalibration": "AA43", "GyroscopeData": "AA51", "GyroscopeConfig": "AA52", "GyroscopePeriod": "AA53", "TestData": "AA61", "TestConfig": "AA62", "ConnectionParams": "CCC1", "ConnectionReqConnParams": "CCC2", "ConnectionDisconnReq": "CCC3", "OADImageIdentify": "FFC1", "OADImageBlock": "FFC2", "MPU9250_DATA_UUID": "AA81", "MPU9250_CONFIG_UUID": "AA82", "MPU9250_PERIOD_UUID": "AA83", "LUXOMETER_CONFIG_UUID": "aa72", "LUXOMETER_DATA_UUID": "aa71", "LUXOMETER_PERIOD_UUID": "aa73", "DEVICE_INFORMATION_UUID": "180A", "SYSTEM_ID_UUID": "2A23", "MODEL_NUMBER_UUID": "2A24", "SERIAL_NUMBER_UUID": "2A25", "FIRMWARE_REVISION_UUID": "2A26", "HARDWARE_REVISION_UUID": "2A27", "SOFTWARE_REVISION_UUID": "2A28", "MANUFACTURER_NAME_UUID": "2A29", } //SensorTagDataEvent contains SensorTagSpecific data structure type SensorTagDataEvent struct { Device *device.Device1 SensorType string AmbientTempValue interface{} AmbientTempUnit string ObjectTempValue interface{} ObjectTempUnit string SensorID string BarometericPressureValue interface{} BarometericPressureUnit string BarometericTempValue interface{} BarometericTempUnit string HumidityValue interface{} HumidityUnit string HumidityTempValue interface{} HumidityTempUnit string MpuGyroscopeValue interface{} MpuGyroscopeUnit string MpuAccelerometerValue interface{} MpuAccelerometerUnit string MpuMagnetometerValue interface{} MpuMagnetometerUnit string LuxometerValue interface{} LuxometerUnit string FirmwareVersion string HardwareVersion string Manufacturer string Model string } //Period =[Input*10]ms,(lowerlimit 300 ms, max 2500ms),default 1000 ms const ( TemperaturePeriodHigh = 0x32 // 500 ms, TemperaturePeriodMedium = 0x64 // 1000 ms, TemperaturePeriodLow = 0x128 // 2000 ms, ) func getUUID(name string) (string, error) { if sensorTagUUIDs[name] == "" { return "", fmt.Errorf("Not found %s", name) } return fmt.Sprintf("F000%s-0451-4000-B000-000000000000", sensorTagUUIDs[name]), nil } func getDeviceInfoUUID(name string) string { if sensorTagUUIDs[name] == "" { panic("Not found " + name) } return "0000" + sensorTagUUIDs[name] + "-0000-1000-8000-00805F9B34FB" } //retryCall n. times, sleep millis, callback func retryCall(times int, sleep int64, fn func() (interface{}, error)) (intf interface{}, err error) { for i := 0; i < times; i++ { intf, err = fn() if err == nil { return intf, nil } time.Sleep(time.Millisecond * time.Duration(sleep)) } return nil, err } //NewSensorTag creates a new sensortag instance func NewSensorTag(d *device.Device1) (*SensorTag, error) { if !d.Properties.Connected { log.Debug("Connecting") err := d.Connect() if err != nil { return nil, err } log.Debug("Connected") } s := new(SensorTag) s.dataChannel = make(chan *SensorTagDataEvent) // ch , err := d.WatchProperties() // if err != nil { // return nil, err // } // go func() { // for prop := range propsChannel { // if prop.Name == "Connected" { // val := prop.Value.(bool) // if val == true { // if dataChannel != nil { // close(dataChannel) // break // } // } // } // } // }() // if err != nil { // return nil, err // } s.Device1 = d temp, err := newTemperatureSensor(s) if err != nil { return nil, err } s.Temperature = *temp humid, err := newHumiditySensor(s) if err != nil { return nil, err } s.Humidity = *humid mpu, err := newMpuSensor(s) if err != nil { return nil, err } s.Mpu = *mpu barometric, err := newBarometricSensor(s) if err != nil { return nil, err } s.Barometric = *barometric luxometer, err := newLuxometerSensor(s) if err != nil { return nil, err } s.Luxometer = *luxometer devInformation, err := newDeviceInfo(s) if err != nil { return nil, err } s.DeviceInfo = devInformation return s, nil } //SensorTag a SensorTag object representation type SensorTag struct { *device.Device1 dataChannel chan *SensorTagDataEvent Temperature TemperatureSensor Humidity HumiditySensor Mpu MpuSensor Barometric BarometricSensor Luxometer LuxometerSensor DeviceInfo SensorTagDeviceInfo } func (s *SensorTag) Data() chan *SensorTagDataEvent { return s.dataChannel } //Sensor generic sensor interface type Sensor interface { GetName() string IsEnabled() (bool, error) Enable() error Disable() error } func newDeviceInfo(tag *SensorTag) (SensorTagDeviceInfo, error) { dev := tag.Device1 DeviceFirmwareUUID := getDeviceInfoUUID("FIRMWARE_REVISION_UUID") DeviceHardwareUUID := getDeviceInfoUUID("HARDWARE_REVISION_UUID") DeviceManufacturerUUID := getDeviceInfoUUID("MANUFACTURER_NAME_UUID") DeviceModelUUID := getDeviceInfoUUID("MODEL_NUMBER_UUID") loadChars := func() (SensorTagDeviceInfo, error) { firmwareInfo, err := dev.GetCharByUUID(DeviceFirmwareUUID) if err != nil { return SensorTagDeviceInfo{}, err } if firmwareInfo == nil { return SensorTagDeviceInfo{}, errors.New("Cannot find DeviceFirmwareUUID characteristic " + DeviceFirmwareUUID) } hardwareInfo, err := dev.GetCharByUUID(DeviceHardwareUUID) if err != nil { return SensorTagDeviceInfo{}, err } if hardwareInfo == nil { return SensorTagDeviceInfo{}, errors.New("Cannot find DeviceHardwareUUID characteristic " + DeviceHardwareUUID) } manufacturerInfo, err := dev.GetCharByUUID(DeviceManufacturerUUID) if err != nil { return SensorTagDeviceInfo{}, err } if manufacturerInfo == nil { return SensorTagDeviceInfo{}, errors.New("Cannot find DeviceManufacturerUUID characteristic " + DeviceManufacturerUUID) } modelInfo, err := dev.GetCharByUUID(DeviceModelUUID) if err != nil { return SensorTagDeviceInfo{}, err } if modelInfo == nil { return SensorTagDeviceInfo{}, errors.New("Cannot find DeviceModelUUID characteristic " + DeviceModelUUID) } return SensorTagDeviceInfo{tag, modelInfo, manufacturerInfo, hardwareInfo, firmwareInfo}, err } return loadChars() } //SensorTagDeviceInfo sensorTag structure type SensorTagDeviceInfo struct { tag *SensorTag firmwareInfo *gatt.GattCharacteristic1 hardwareInfo *gatt.GattCharacteristic1 manufacturerInfo *gatt.GattCharacteristic1 modelInfo *gatt.GattCharacteristic1 } //Read device info from sensorTag func (s *SensorTagDeviceInfo) Read() (*SensorTagDataEvent, error) { options1 := getOptions() fw, err := s.firmwareInfo.ReadValue(options1) if err != nil { return nil, err } options2 := getOptions() hw, err := s.hardwareInfo.ReadValue(options2) if err != nil { return nil, err } options3 := getOptions() manufacturer, err := s.manufacturerInfo.ReadValue(options3) if err != nil { return nil, err } options4 := getOptions() model, err := s.modelInfo.ReadValue(options4) if err != nil { return nil, err } dataEvent := SensorTagDataEvent{ FirmwareVersion: string(fw), HardwareVersion: string(hw), Manufacturer: string(manufacturer), Model: string(model), } return &dataEvent, err } go-bluetooth-bluez-5.60/devices/sensortag/st.go000066400000000000000000000001711420407601400215740ustar00rootroot00000000000000package sensortag func getOptions() map[string]interface{} { options := make(map[string]interface{}) return options } go-bluetooth-bluez-5.60/devices/sensortag/temperature.go000066400000000000000000000105601420407601400235060ustar00rootroot00000000000000package sensortag import ( "bytes" "encoding/binary" "fmt" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) //.....getting config,data,period characteristics for TEMPERATURE sensor............ func newTemperatureSensor(tag *SensorTag) (*TemperatureSensor, error) { dev := tag.Device1 TemperatureConfigUUID, err := getUUID("TemperatureConfig") if err != nil { return nil, err } TemperatureDataUUID, err := getUUID("TemperatureData") if err != nil { return nil, err } TemperaturePeriodUUID, err := getUUID("TemperaturePeriod") if err != nil { return nil, err } i, err := retryCall(DefaultRetry, DefaultRetryWait, func() (interface{}, error) { cfg, err := dev.GetCharByUUID(TemperatureConfigUUID) if err != nil { return nil, err } data, err := dev.GetCharByUUID(TemperatureDataUUID) if err != nil { return nil, err } if data == nil { return nil, fmt.Errorf("Cannot find TemperatureData characteristic %s", TemperatureDataUUID) } period, err := dev.GetCharByUUID(TemperaturePeriodUUID) if err != nil { return nil, err } if period == nil { return nil, fmt.Errorf("Cannot find TemperaturePeriod characteristic %s", TemperaturePeriodUUID) } return &TemperatureSensor{tag, cfg, data, period}, err }) if err != nil { return nil, err } return i.(*TemperatureSensor), nil } //TemperatureSensor the temperature sensor structure type TemperatureSensor struct { tag *SensorTag cfg *gatt.GattCharacteristic1 data *gatt.GattCharacteristic1 period *gatt.GattCharacteristic1 } // GetName return the sensor name func (s TemperatureSensor) GetName() string { return "temperature" } //Enable measurements func (s *TemperatureSensor) Enable() error { enabled, err := s.IsEnabled() if err != nil { return err } if enabled { return nil } options := getOptions() err = s.cfg.WriteValue([]byte{1}, options) return err } //Disable measurements func (s *TemperatureSensor) Disable() error { enabled, err := s.IsEnabled() if err != nil { return err } if !enabled { return nil } options := getOptions() err = s.cfg.WriteValue([]byte{0}, options) if err != nil { return err } return nil } //IsEnabled check if measurements are enabled func (s *TemperatureSensor) IsEnabled() (bool, error) { options := make(map[string]interface{}) val, err := s.cfg.ReadValue(options) if err != nil { return false, err } buf := bytes.NewBuffer(val) enabled, err := binary.ReadVarint(buf) if err != nil { // TODO investigate why it report EOF only on that return false, nil } return (enabled == 1), nil } //IsNotifying check if notyfing func (s *TemperatureSensor) IsNotifying() (bool, error) { n, err := s.data.GetNotifying() if err != nil { return false, err } return n, nil } //Read value from the sensor func (s *TemperatureSensor) Read() (float64, error) { err := s.Enable() if err != nil { return 0, err } options := getOptions() b, err := s.data.ReadValue(options) if err != nil { return 0, err } amb := binary.LittleEndian.Uint16(b[2:]) ambientValue := calcTmpLocal(uint16(amb)) return ambientValue, err } //StartNotify enable temperature DataChannel func (s *TemperatureSensor) StartNotify() error { err := s.Enable() if err != nil { return err } dataChannel, err := s.data.WatchProperties() if err != nil { return err } go func() { for prop := range dataChannel { if prop == nil { return } if prop.Name != "Value" { return } b := prop.Value.([]byte) amb := binary.LittleEndian.Uint16(b[2:]) ambientValue := calcTmpLocal(uint16(amb)) die := binary.LittleEndian.Uint16(b[0:2]) dieValue := calcTmpTarget(uint16(die)) dataEvent := SensorTagDataEvent{ Device: s.tag.Device1, SensorType: "temperature", AmbientTempValue: ambientValue, AmbientTempUnit: "C", ObjectTempValue: dieValue, ObjectTempUnit: "C", SensorID: s.tag.Properties.Address, } s.tag.Data() <- &dataEvent } }() n, err := s.IsNotifying() if err != nil { return err } if !n { return s.data.StartNotify() } return nil } //StopNotify disable temperature DataChannel func (s *TemperatureSensor) StopNotify() error { err := s.Disable() if err != nil { return err } if dataChannel != nil { close(dataChannel) } n, err := s.IsNotifying() if err != nil { return err } if n { return s.data.StopNotify() } return nil } go-bluetooth-bluez-5.60/docs/000077500000000000000000000000001420407601400161215ustar00rootroot00000000000000go-bluetooth-bluez-5.60/docs/index.md000066400000000000000000000011641420407601400175540ustar00rootroot00000000000000 # Examples ## Running the service example Requires two adapters. In two shell run in order - `go run main.go service server` - `go run main.go service client 00:1A:7D:DA:71:15 --adapterID hci1 ` ## Development Edit `/etc/systemd/system/bluetooth.target.wants/bluetooth.service` and update the `ExecStart` command adding those optios `ExecStart=/usr/lib/bluetooth/bluetoothd -E -d -P hostname` - `-E` experimental mode - `-d` debug mode - `-P` no plugin Afterwards run `systemctl daemon-reload` to reload the config and `service bluetooth restart` to restart the service. To view logs `journalctl -u bluetooth -f` go-bluetooth-bluez-5.60/env/000077500000000000000000000000001420407601400157615ustar00rootroot00000000000000go-bluetooth-bluez-5.60/env/bluez/000077500000000000000000000000001420407601400171025ustar00rootroot00000000000000go-bluetooth-bluez-5.60/env/bluez/Dockerfile000066400000000000000000000011631420407601400210750ustar00rootroot00000000000000FROM ubuntu:19.10 ARG BLUEZ_VERSION=5.54 WORKDIR /bluez RUN apt update -qq && apt remove --purge -y bluetooth && apt install -y && \ DEBIAN_FRONTEND=noninteractive apt install -y \ git libdbus-1-dev libudev-dev libical-dev libreadline-dev \ autotools-dev automake libtool libglib2.0-dev udev ENV BLUEZ_VERSION=$BLUEZ_VERSION RUN cd / && git clone https://git.kernel.org/pub/scm/bluetooth/bluez.git && cd bluez && git checkout $BLUEZ_VERSION && \ ./bootstrap && ./configure --disable-systemd && make && make install COPY ./entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh CMD ["sh", "/entrypoint.sh"] go-bluetooth-bluez-5.60/env/bluez/entrypoint.sh000066400000000000000000000000771420407601400216550ustar00rootroot00000000000000 /usr/local/libexec/bluetooth/bluetoothd -E -d -n -P hostname go-bluetooth-bluez-5.60/examples/000077500000000000000000000000001420407601400170075ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/agent/000077500000000000000000000000001420407601400201055ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/agent/agent.go000066400000000000000000000026731420407601400215420ustar00rootroot00000000000000package agent_example import ( "fmt" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/adapter" "github.com/muka/go-bluetooth/bluez/profile/agent" log "github.com/sirupsen/logrus" ) // ToDo: allow enabling "simple pairing" (sspmode set via hcitool) func Run(deviceAddress, adapterID string) error { defer api.Exit() //Connect DBus System bus conn, err := dbus.SystemBus() if err != nil { return err } ag := agent.NewSimpleAgent() err = agent.ExposeAgent(conn, ag, agent.CapKeyboardDisplay, true) if err != nil { return fmt.Errorf("SimpleAgent: %s", err) } a, err := adapter.GetAdapter(adapterID) if err != nil { return err } devices, err := a.GetDevices() if err != nil { return fmt.Errorf("GetDevices: %s", err) } found := false for _, dev := range devices { if dev.Properties.Address != deviceAddress { continue } if dev.Properties.Paired { continue } found = true // log.Info(i, v.Path) log.Infof("Pairing with %s", dev.Properties.Address) err := dev.Pair() if err != nil { return fmt.Errorf("Pair failed: %s", err) } log.Info("Pair succeed, connecting...") agent.SetTrusted(adapterID, dev.Path()) err = dev.Connect() if err != nil { return fmt.Errorf("Connect failed: %s", err) } } if !found { return fmt.Errorf("No device found that need to be paired on %s", adapterID) } log.Info("Working...") select {} } go-bluetooth-bluez-5.60/examples/beacon/000077500000000000000000000000001420407601400202365ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/beacon/beacon.go000066400000000000000000000022721420407601400220170ustar00rootroot00000000000000package beacon_example import ( "os" "time" "github.com/muka/go-bluetooth/api/beacon" log "github.com/sirupsen/logrus" ) func Run(beaconType, eddystoneBeaconType, adapterID string) error { var b *beacon.Beacon if beaconType == "ibeacon" { b1, err := beacon.CreateIBeacon("AAAABBBBCCCCDDDDAAAABBBBCCCCDDDD", 111, 999, 89) if err != nil { return err } b = b1 } else { if eddystoneBeaconType == "URL" { log.Infof("Exposing eddystone URL") b1, err := beacon.CreateEddystoneURL("https://bit.ly/2OCrFK2", 99) if err != nil { return err } b = b1 } else { // UID log.Infof("Exposing eddystone UID") b1, err := beacon.CreateEddystoneUID("AAAAAAAAAABBBBBBBBBB", "123456123456", -59) if err != nil { return err } b = b1 } } // A timeout of 0 cause an immediate timeout and advertisement deregistration // see https://www.spinics.net/lists/linux-bluetooth/msg79915.html // In seconds timeout := uint16(60 * 60 * 18) cancel, err := b.Expose(adapterID, timeout) if err != nil { return err } defer cancel() log.Debugf("%s ready", beaconType) go func() { time.Sleep(time.Duration(timeout) * time.Second) os.Exit(0) }() select {} } go-bluetooth-bluez-5.60/examples/btmgmt/000077500000000000000000000000001420407601400203015ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/btmgmt/btmgmt.go000066400000000000000000000005201420407601400221170ustar00rootroot00000000000000// Example use of the btmgmt wrapper package btmgmt_example import ( "github.com/muka/go-bluetooth/hw/linux/btmgmt" log "github.com/sirupsen/logrus" ) func Run() error { list, err := btmgmt.GetAdapters() if err != nil { return err } for i, a := range list { log.Infof("%d) %s (%v)", i+1, a.Name, a.Addr) } return nil } go-bluetooth-bluez-5.60/examples/discovery/000077500000000000000000000000001420407601400210165ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/discovery/discovery.go000066400000000000000000000053451420407601400233630ustar00rootroot00000000000000//shows how to watch for new devices and list them package discovery_example import ( "context" "os" "os/signal" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/api/beacon" "github.com/muka/go-bluetooth/bluez/profile/adapter" "github.com/muka/go-bluetooth/bluez/profile/device" log "github.com/sirupsen/logrus" eddystone "github.com/suapapa/go_eddystone" ) func Run(adapterID string, onlyBeacon bool) error { //clean up connection on exit defer api.Exit() a, err := adapter.GetAdapter(adapterID) if err != nil { return err } log.Debug("Flush cached devices") err = a.FlushDevices() if err != nil { return err } log.Debug("Start discovery") discovery, cancel, err := api.Discover(a, nil) if err != nil { return err } defer cancel() go func() { for ev := range discovery { if ev.Type == adapter.DeviceRemoved { continue } dev, err := device.NewDevice1(ev.Path) if err != nil { log.Errorf("%s: %s", ev.Path, err) continue } if dev == nil { log.Errorf("%s: not found", ev.Path) continue } log.Infof("name=%s addr=%s rssi=%d", dev.Properties.Name, dev.Properties.Address, dev.Properties.RSSI) go func(ev *adapter.DeviceDiscovered) { err = handleBeacon(dev) if err != nil { log.Errorf("%s: %s", ev.Path, err) } }(ev) } }() ch := make(chan os.Signal) signal.Notify(ch, os.Interrupt, os.Kill) // get notified of all OS signals sig := <-ch log.Infof("Received signal [%v]; shutting down...\n", sig) return nil } func handleBeacon(dev *device.Device1) error { b, err := beacon.NewBeacon(dev) if err != nil { return err } beaconUpdated, err := b.WatchDeviceChanges(context.Background()) if err != nil { return err } isBeacon := <-beaconUpdated if !isBeacon { return nil } name := b.Device.Properties.Alias if name == "" { name = b.Device.Properties.Name } log.Debugf("Found beacon %s %s", b.Type, name) if b.IsEddystone() { ed := b.GetEddystone() switch ed.Frame { case eddystone.UID: log.Debugf( "Eddystone UID %s instance %s (%ddbi)", ed.UID, ed.InstanceUID, ed.CalibratedTxPower, ) break case eddystone.TLM: log.Debugf( "Eddystone TLM temp:%.0f batt:%d last reboot:%d advertising pdu:%d (%ddbi)", ed.TLMTemperature, ed.TLMBatteryVoltage, ed.TLMLastRebootedTime, ed.TLMAdvertisingPDU, ed.CalibratedTxPower, ) break case eddystone.URL: log.Debugf( "Eddystone URL %s (%ddbi)", ed.URL, ed.CalibratedTxPower, ) break } } if b.IsIBeacon() { ibeacon := b.GetIBeacon() log.Debugf( "IBeacon %s (%ddbi) (major=%d minor=%d)", ibeacon.ProximityUUID, ibeacon.MeasuredPower, ibeacon.Major, ibeacon.Minor, ) } return nil } go-bluetooth-bluez-5.60/examples/hci_updown/000077500000000000000000000000001420407601400211465ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/hci_updown/hci_updown.go000066400000000000000000000012361420407601400236360ustar00rootroot00000000000000package hci_updown_example import ( "fmt" "strconv" "strings" "github.com/muka/go-bluetooth/hw/linux/hci" log "github.com/sirupsen/logrus" ) //HciUpDownExample hciconfig up / down func Run(rawAdapterID string) error { log.Info("Turn down") adapterID, err := strconv.Atoi(strings.Replace(rawAdapterID, "hci", "", 1)) if err != nil { return err } err = hci.Down(adapterID) if err != nil { return fmt.Errorf("Failed to stop device hci%d: %s", adapterID, err.Error()) } log.Info("Turn on") err = hci.Up(adapterID) if err != nil { return fmt.Errorf("Failed to start device hci%d: %s", adapterID, err.Error()) } log.Info("Done.") return nil } go-bluetooth-bluez-5.60/examples/obex_push/000077500000000000000000000000001420407601400210035ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/obex_push/obex_push.go000066400000000000000000000057271420407601400233410ustar00rootroot00000000000000//this example starts discovery on adapter //after discovery process GetDevices method //returns list of discovered devices //then with the help of mac address //connectivity starts //once sensors are connected it will //fetch sensor name,manufacturer detail, //firmware version, hardware version, model //and sensor data... package obex_push_example import ( "sync" "time" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/obex" log "github.com/sirupsen/logrus" ) var wg sync.WaitGroup func Run(targetAddress, filePath, adapterID string) error { a, err := api.GetAdapter(adapterID) if err != nil { return err } dev, err := a.GetDeviceByAddress(targetAddress) if err != nil { return err } log.Debugf("device %s (%s)", dev.Properties.Name, dev.Properties.Address) if dev == nil { return err } props, err := dev.GetProperties() if err != nil { return err } if !props.Paired { log.Debug("not paired") err = dev.Pair() if err != nil { return err } } else { log.Debug("already paired") } sessionArgs := map[string]interface{}{} sessionArgs["Target"] = "opp" obexClient := obex.NewObexClient1() tries := 1 maxRetry := 20 var sessionPath string for tries < maxRetry { log.Debug("Create Session...") sessionPath, err = obexClient.CreateSession(targetAddress, sessionArgs) if err == nil { break } tries++ if err != nil { return err } } if tries >= maxRetry { log.Fatal("Max tries reached") } log.Debug("Session created: ", sessionPath) obexSession := obex.NewObexSession1(sessionPath) sessionProps, err := obexSession.GetProperties() if err != nil { return err } log.Debug("Source : ", sessionProps.Source) log.Debug("Destination : ", sessionProps.Destination) log.Debug("Channel : ", sessionProps.Channel) log.Debug("Target : ", sessionProps.Target) log.Debug("Root : ", sessionProps.Root) log.Debug("Init transmission on ", sessionPath) obexObjectPush := obex.NewObjectPush1(sessionPath) log.Debug("Send File: ", filePath) transPath, transProps, err := obexObjectPush.SendFile(filePath) if err != nil { return err } log.Debug("Transmission initiated: ", transPath) log.Debug("Status : ", transProps.Status) log.Debug("Session : ", transProps.Session) log.Debug("Name : ", transProps.Name) log.Debug("Type : ", transProps.Type) log.Debug("Time : ", transProps.Time) log.Debug("Size : ", transProps.Size) log.Debug("Transferred : ", transProps.Transferred) log.Debug("Filename : ", transProps.Filename) for transProps.Transferred < transProps.Size { time.Sleep(1 * time.Second) obexTransfer := obex.NewObexTransfer1(transPath) transProps, err = obexTransfer.GetProperties() if err != nil { return err } transferedPercent := (100 / float64(transProps.Size)) * float64(transProps.Transferred) log.Debug("Progress : ", transferedPercent) } obexClient.RemoveSession(sessionPath) log.Debug(sessionPath) return nil } go-bluetooth-bluez-5.60/examples/sensortag_info/000077500000000000000000000000001420407601400220275ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/sensortag_info/sensortag_info.go000066400000000000000000000046451420407601400254070ustar00rootroot00000000000000//this example starts discovery on adapter //after discovery process GetDevices method //returns list of discovered devices //then with the help of mac address //connectivity starts //once sensors are connected it will //fetch sensor name,manufacturer detail, //firmware version, hardware version, model //and sensor data... package sensortag_info_example import ( "fmt" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/battery" "github.com/muka/go-bluetooth/devices/sensortag" log "github.com/sirupsen/logrus" ) func Run(address, adapterID string) error { a, err := api.GetAdapter(adapterID) if err != nil { return err } dev, err := a.GetDeviceByAddress(address) if err != nil { return err } if dev == nil { return fmt.Errorf("device %s not found", address) } sensorTag, err := sensortag.NewSensorTag(dev) if err != nil { return err } name := sensorTag.Temperature.GetName() log.Debugf("sensor name: %s", name) name1 := sensorTag.Humidity.GetName() log.Debugf("sensor name: %s", name1) mpu := sensorTag.Mpu.GetName() log.Debugf("sensor name: %s", mpu) barometric := sensorTag.Barometric.GetName() log.Debugf("sensor name: %s", barometric) luxometer := sensorTag.Luxometer.GetName() log.Debugf("sensor name: %s", luxometer) devInfo, err := sensorTag.DeviceInfo.Read() if err != nil { return err } log.Debug("FirmwareVersion: ", devInfo.FirmwareVersion) log.Debug("HardwareVersion: ", devInfo.HardwareVersion) log.Debug("Manufacturer: ", devInfo.Manufacturer) log.Debug("Model: ", devInfo.Model) batt, err := battery.NewBattery1(sensorTag.Device1.Path()) if err != nil { log.Errorf("Cannot load battery profile: %s", err) } else { perc, err1 := batt.GetPercentage() if err1 != nil { log.Errorf("Cannot load battery percentage: %s", err) } else { log.Debugf("Battery: %d%%", perc) } } err = sensorTag.Temperature.StartNotify() if err != nil { return err } err = sensorTag.Humidity.StartNotify() if err != nil { return err } err = sensorTag.Mpu.StartNotify(address) if err != nil { return err } err = sensorTag.Barometric.StartNotify(address) if err != nil { return err } err = sensorTag.Luxometer.StartNotify(address) if err != nil { return err } go func() { // sensortag.SensorTagDataEvent for data := range sensorTag.Data() { log.Debugf("data received: %++v", data) } }() log.Debug("Waiting for data") select {} } go-bluetooth-bluez-5.60/examples/sensortag_temperature/000077500000000000000000000000001420407601400234315ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/sensortag_temperature/sensortag_temperature.go000066400000000000000000000020401420407601400303760ustar00rootroot00000000000000package sensortag_temperature_example import ( "fmt" log "github.com/sirupsen/logrus" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/devices/sensortag" ) // example of reading temperature from a TI sensortag func Run(tagAddress, adapterID string) error { a, err := api.GetAdapter(adapterID) if err != nil { return err } dev, err := a.GetDeviceByAddress(tagAddress) if err != nil { return err } if dev == nil { return fmt.Errorf("Device %s not found", tagAddress) } err = dev.Connect() if err != nil { return err } sensorTag, err := sensortag.NewSensorTag(dev) if err != nil { return err } // var readTemperature = func() { // temp, err := sensorTag.Temperature.Read() // if err != nil { // panic(err) // } // log.Printf("Temperature %v°", temp) // } var notifyTemperature = func(fn func(temperature float64)) { sensorTag.Temperature.StartNotify() select {} } // readTemperature() notifyTemperature(func(t float64) { log.Infof("Temperature update: %f", t) }) return nil } go-bluetooth-bluez-5.60/examples/service/000077500000000000000000000000001420407601400204475ustar00rootroot00000000000000go-bluetooth-bluez-5.60/examples/service/client.go000066400000000000000000000074501420407601400222620ustar00rootroot00000000000000package service_example import ( "errors" "fmt" "strings" "time" "github.com/godbus/dbus/v5" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/adapter" "github.com/muka/go-bluetooth/bluez/profile/agent" "github.com/muka/go-bluetooth/bluez/profile/device" log "github.com/sirupsen/logrus" ) func client(adapterID, hwaddr string) (err error) { log.Infof("Discovering %s on %s", hwaddr, adapterID) a, err := adapter.NewAdapter1FromAdapterID(adapterID) if err != nil { return err } //Connect DBus System bus conn, err := dbus.SystemBus() if err != nil { return err } // do not reuse agent0 from service agent.NextAgentPath() ag := agent.NewSimpleAgent() err = agent.ExposeAgent(conn, ag, agent.CapNoInputNoOutput, true) if err != nil { return fmt.Errorf("SimpleAgent: %s", err) } dev, err := findDevice(a, hwaddr) if err != nil { return fmt.Errorf("findDevice: %s", err) } watchProps, err := dev.WatchProperties() if err != nil { return err } go func() { for propUpdate := range watchProps { log.Debugf("--> updated %s=%v", propUpdate.Name, propUpdate.Value) } }() err = connect(dev, ag, adapterID) if err != nil { return err } retrieveServices(a, dev) select {} // return nil } func findDevice(a *adapter.Adapter1, hwaddr string) (*device.Device1, error) { // // devices, err := a.GetDevices() // if err != nil { // return nil, err // } // // for _, dev := range devices { // devProps, err := dev.GetProperties() // if err != nil { // log.Errorf("Failed to load dev props: %s", err) // continue // } // // log.Info(devProps.Address) // if devProps.Address != hwaddr { // continue // } // // log.Infof("Found cached device Connected=%t Trusted=%t Paired=%t", devProps.Connected, devProps.Trusted, devProps.Paired) // return dev, nil // } dev, err := discover(a, hwaddr) if err != nil { return nil, err } if dev == nil { return nil, errors.New("Device not found, is it advertising?") } return dev, nil } func discover(a *adapter.Adapter1, hwaddr string) (*device.Device1, error) { err := a.FlushDevices() if err != nil { return nil, err } discovery, cancel, err := api.Discover(a, nil) if err != nil { return nil, err } defer cancel() for ev := range discovery { dev, err := device.NewDevice1(ev.Path) if err != nil { return nil, err } if dev == nil || dev.Properties == nil { continue } p := dev.Properties n := p.Alias if p.Name != "" { n = p.Name } log.Debugf("Discovered (%s) %s", n, p.Address) if p.Address != hwaddr { continue } return dev, nil } return nil, nil } func connect(dev *device.Device1, ag *agent.SimpleAgent, adapterID string) error { props, err := dev.GetProperties() if err != nil { return fmt.Errorf("Failed to load props: %s", err) } log.Infof("Found device name=%s addr=%s rssi=%d", props.Name, props.Address, props.RSSI) if props.Connected { log.Trace("Device is connected") return nil } if !props.Paired || !props.Trusted { log.Trace("Pairing device") err := dev.Pair() if err != nil { return fmt.Errorf("Pair failed: %s", err) } log.Info("Pair succeed, connecting...") agent.SetTrusted(adapterID, dev.Path()) } if !props.Connected { log.Trace("Connecting device") err = dev.Connect() if err != nil { if !strings.Contains(err.Error(), "Connection refused") { return fmt.Errorf("Connect failed: %s", err) } } } return nil } func retrieveServices(a *adapter.Adapter1, dev *device.Device1) error { log.Debug("Listing exposed services") list, err := dev.GetAllServicesAndUUID() if err != nil { return err } if len(list) == 0 { time.Sleep(time.Second * 2) return retrieveServices(a, dev) } for _, servicePath := range list { log.Debugf("%s", servicePath) } return nil } go-bluetooth-bluez-5.60/examples/service/main.go000066400000000000000000000010261420407601400217210ustar00rootroot00000000000000package service_example import ( "os" "github.com/muka/go-bluetooth/hw" log "github.com/sirupsen/logrus" ) func Run(adapterID string, mode string, hwaddr string) error { log.SetLevel(log.TraceLevel) btmgmt := hw.NewBtMgmt(adapterID) if len(os.Getenv("DOCKER")) > 0 { btmgmt.BinPath = "./bin/docker-btmgmt" } // set LE mode btmgmt.SetPowered(false) btmgmt.SetLe(true) btmgmt.SetBredr(false) btmgmt.SetPowered(true) if mode == "client" { return client(adapterID, hwaddr) } else { return serve(adapterID) } } go-bluetooth-bluez-5.60/examples/service/server.go000066400000000000000000000046201420407601400223060ustar00rootroot00000000000000package service_example import ( "time" "github.com/muka/go-bluetooth/api/service" "github.com/muka/go-bluetooth/bluez/profile/agent" "github.com/muka/go-bluetooth/bluez/profile/gatt" log "github.com/sirupsen/logrus" ) func serve(adapterID string) error { options := service.AppOptions{ AdapterID: adapterID, AgentCaps: agent.CapNoInputNoOutput, UUIDSuffix: "-0000-1000-8000-00805F9B34FB", UUID: "1234", } a, err := service.NewApp(options) if err != nil { return err } defer a.Close() a.SetName("go_bluetooth") log.Infof("HW address %s", a.Adapter().Properties.Address) if !a.Adapter().Properties.Powered { err = a.Adapter().SetPowered(true) if err != nil { log.Fatalf("Failed to power the adapter: %s", err) } } service1, err := a.NewService("2233") if err != nil { return err } err = a.AddService(service1) if err != nil { return err } char1, err := service1.NewChar("3344") if err != nil { return err } char1.Properties.Flags = []string{ gatt.FlagCharacteristicRead, gatt.FlagCharacteristicWrite, } char1.OnRead(service.CharReadCallback(func(c *service.Char, options map[string]interface{}) ([]byte, error) { log.Warnf("GOT READ REQUEST") return []byte{42}, nil })) char1.OnWrite(service.CharWriteCallback(func(c *service.Char, value []byte) ([]byte, error) { log.Warnf("GOT WRITE REQUEST") return value, nil })) err = service1.AddChar(char1) if err != nil { return err } descr1, err := char1.NewDescr("4455") if err != nil { return err } descr1.Properties.Flags = []string{ gatt.FlagDescriptorRead, gatt.FlagDescriptorWrite, } descr1.OnRead(service.DescrReadCallback(func(c *service.Descr, options map[string]interface{}) ([]byte, error) { log.Warnf("GOT READ REQUEST") return []byte{42}, nil })) descr1.OnWrite(service.DescrWriteCallback(func(d *service.Descr, value []byte) ([]byte, error) { log.Warnf("GOT WRITE REQUEST") return value, nil })) err = char1.AddDescr(descr1) if err != nil { return err } err = a.Run() if err != nil { return err } log.Infof("Exposed service %s", service1.Properties.UUID) timeout := uint32(6 * 3600) // 6h log.Infof("Advertising for %ds...", timeout) cancel, err := a.Advertise(timeout) if err != nil { return err } defer cancel() wait := make(chan bool) go func() { time.Sleep(time.Duration(timeout) * time.Second) wait <- true }() <-wait return nil } go-bluetooth-bluez-5.60/gen/000077500000000000000000000000001420407601400157425ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/Makefile000066400000000000000000000012631420407601400174040ustar00rootroot00000000000000 .PHONY: adapter advertising adapter: BASEDIR=.. \ FILE_FILTER=adapter \ xAPI_FILTER="Provisioner" \ xMETHOD_FILTER=Attach LOG_LEVEL=trace \ go run ./srcgen/main.go full --debug advertising: BASEDIR=.. \ FILE_FILTER=advertising-api \ xAPI_FILTER="Provisioner" \ xMETHOD_FILTER=Attach LOG_LEVEL=trace \ go run ./srcgen/main.go full --debug mesh: BASEDIR=.. \ FILE_FILTER=mesh-api \ xAPI_FILTER="Provisioner" \ xMETHOD_FILTER=Attach LOG_LEVEL=trace \ go run ./srcgen/main.go full --debug advertisement-monitor: BASEDIR=.. \ FILE_FILTER=advertisement-monitor-api \ xAPI_FILTER="Provisioner" \ xMETHOD_FILTER=Attach LOG_LEVEL=trace \ go run ./srcgen/main.go full --debuggo-bluetooth-bluez-5.60/gen/README.md000066400000000000000000000013061420407601400172210ustar00rootroot00000000000000# BLueZ docs parser & generator This software parse `doc` bluez folder and output a set of struct to interact with the bluez DBus API. ## Usage: Env variables - `BASEDIR` base directory for docs and generation output, default ./ - `FILE_FILTER` filter docs files by name - `API_FILTER` filter docs API by name - `METHOD_FILTER` filter docs API method by name - `LOG_LEVEL` tune CLI log level output ## Notes - Generated files have a `gen_` prefix, followed by the API name - If a `.go` file exists, it will be skipped from the generation. This to allow custom code to live with generated one. - Generation process does not overwrite existing files, ensure to remove previously generated files. go-bluetooth-bluez-5.60/gen/bluez_api.go000066400000000000000000000012231420407601400202410ustar00rootroot00000000000000package gen import ( "encoding/json" "io/ioutil" "github.com/muka/go-bluetooth/gen/types" ) type BluezAPI struct { Version string Api []*types.ApiGroup } // Serialize store the structure as JSON func (g *BluezAPI) Serialize(destFile string) error { data, err := json.Marshal(g) if err != nil { return err } return ioutil.WriteFile(destFile, data, 0755) } // LoadJSON parse an ApiGroup from JSON definition func LoadJSON(srcFile string) (*BluezAPI, error) { b, err := ioutil.ReadFile(srcFile) if err != nil { return nil, err } a := new(BluezAPI) err = json.Unmarshal(b, a) if err != nil { return nil, err } return a, nil } go-bluetooth-bluez-5.60/gen/filters/000077500000000000000000000000001420407601400174125ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/filters/filter.go000066400000000000000000000030211420407601400212220ustar00rootroot00000000000000package filters import ( "fmt" "os" "strings" ) type FilterContext int const ( FilterFile FilterContext = 0 FilterApi FilterContext = iota FilterMethod FilterContext = iota ) const ( ParamFileFilter = "file_filter" ParamApiFilter = "api_filter" ParamMethodFilter = "method_filter" ) type Filter struct { Context FilterContext Value string } func NewFilter(value string, context FilterContext) Filter { return Filter{context, value} } func extractFilters(param string, paramType FilterContext) []Filter { list := []Filter{} // parse from env vars rawFilters := strings.Split(os.Getenv(strings.ToUpper(param)), ",") for _, filter := range rawFilters { filter = strings.Trim(filter, " ") if len(filter) == 0 { continue } list = append(list, NewFilter(filter, paramType)) } // parse from args if len(os.Args) > 1 { args := os.Args[1:] for _, arg := range args { if strings.Contains(arg, fmt.Sprintf("%s=", param)) { filters2 := strings.Split(strings.Split(arg, "=")[1], ",") for _, filter := range filters2 { filter = strings.Trim(filter, " ") if len(filter) == 0 { continue } list = append(list, NewFilter(filter, paramType)) } } } } return list } func ParseCliFilters() []Filter { filters := []Filter{} filters = append(filters, extractFilters(ParamFileFilter, FilterFile)...) filters = append(filters, extractFilters(ParamApiFilter, FilterApi)...) filters = append(filters, extractFilters(ParamMethodFilter, FilterMethod)...) return filters } go-bluetooth-bluez-5.60/gen/generator/000077500000000000000000000000001420407601400177305ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/generator/generator.go000066400000000000000000000055571420407601400222610ustar00rootroot00000000000000package generator import ( "fmt" "io/ioutil" "path" "strings" "github.com/muka/go-bluetooth/gen" "github.com/muka/go-bluetooth/gen/util" log "github.com/sirupsen/logrus" "golang.org/x/tools/imports" ) // Generate go code from the API definition func Generate(bluezApi gen.BluezAPI, outDir string, debug bool, forceOverwrite bool) error { apiGroups := bluezApi.Api err := util.Mkdir(outDir) if err != nil { log.Errorf("Failed to mkdir %s: %s", outDir, err) return err } outDir += "/profile" err = util.Mkdir(outDir) if err != nil { log.Errorf("Failed to mkdir %s: %s", outDir, err) return err } errorsFile := path.Join(outDir, "gen_errors.go") if forceOverwrite || !util.Exists(errorsFile) { err = ErrorsTemplate(errorsFile, apiGroups) if err != nil { return err } } versionFile := path.Join(outDir, "gen_version.go") if forceOverwrite || !util.Exists(versionFile) { err = VersionTemplate(versionFile, bluezApi.Version) if err != nil { return err } } // filename = filepath.Join(outDir, "interfaces.go") // err = InterfacesTemplate(filename, apiGroups) // if err != nil { // return err // } for _, apiGroup := range apiGroups { if apiGroup == nil { continue } apiName := getApiPackage(apiGroup) dirpath := path.Join(outDir, apiName) err := util.Mkdir(dirpath) if err != nil { log.Errorf("Failed to mkdir %s: %s", dirpath, err) continue } rootFile := path.Join(dirpath, fmt.Sprintf("gen_%s.go", apiName)) if forceOverwrite || !util.Exists(rootFile) { err = RootTemplate(rootFile, apiGroup) if err != nil { log.Errorf("Failed to create %s: %s", rootFile, err) continue } if debug { log.Tracef("Wrote %s", rootFile) } } for _, api := range apiGroup.Api { if api == nil { continue } pts := strings.Split(api.Interface, ".") apiBaseName := pts[len(pts)-1] apiBaseName = strings.Replace(apiBaseName, " [experimental]", "", -1) apiFilename := path.Join(dirpath, fmt.Sprintf("%s.go", apiBaseName)) apiGenFilename := path.Join(dirpath, fmt.Sprintf("gen_%s.go", apiBaseName)) if util.Exists(apiFilename) { // log.Debugf("Skipped generation, API file exists: %s", apiFilename) continue } if !forceOverwrite && util.Exists(apiGenFilename) { // log.Debugf("Skipped, file exists: %s", apiGenFilename) continue } err1 := ApiTemplate(apiGenFilename, api, apiGroup) if err1 != nil { log.Errorf("Api generation failed %s: %s", api.Title, err1) return err1 } if debug { log.Tracef("Wrote %s", apiGenFilename) } code, err := imports.Process(apiGenFilename, nil, nil) if err != nil { log.Tracef("format code: %s: %v", apiGenFilename, err) } if err := ioutil.WriteFile(apiGenFilename, code, 0644); err != nil { log.Tracef("rewrite with formatted code: %s", apiGenFilename) return err } } } return nil } go-bluetooth-bluez-5.60/gen/generator/generator_test.go000066400000000000000000000013451420407601400233070ustar00rootroot00000000000000package generator import ( "fmt" "testing" "github.com/muka/go-bluetooth/gen" "github.com/muka/go-bluetooth/gen/filters" "github.com/muka/go-bluetooth/gen/util" "github.com/stretchr/testify/assert" ) func TestGenerate(t *testing.T) { TplPath = "../../gen/generator/tpl/%s.go.tpl" outdir := "../../test/out" bluezApi, err := gen.Parse("../../src/bluez/doc", []filters.Filter{}, false) if err != nil { t.Fatal(err) } err = util.Mkdir("../../test") if err != nil { t.Fatal(err) } err = util.Mkdir(outdir) if err != nil { t.Fatal(err) } err = Generate(bluezApi, outdir, true, true) if err != nil { t.Fatal(err) } assert.DirExists(t, outdir) assert.DirExists(t, fmt.Sprintf("%s/profile/adapter", outdir)) } go-bluetooth-bluez-5.60/gen/generator/generator_tpl.go000066400000000000000000000046411420407601400231310ustar00rootroot00000000000000package generator import ( "fmt" "os" "strings" "github.com/muka/go-bluetooth/gen/types" ) func RootTemplate(filename string, api *types.ApiGroup) error { fw, err := os.Create(filename) if err != nil { return fmt.Errorf("create file: %s", err) } apidoc := types.ApiGroupDoc{ ApiGroup: api, Package: getApiPackage(api), } apidoc.ApiGroup.Description = prepareDocs(apidoc.ApiGroup.Description, false, 0) tmpl := loadtpl("root") err = tmpl.Execute(fw, apidoc) if err != nil { return fmt.Errorf("write tpl: %s", err) } // log.Debugf("Created %s", filename) return nil } func ErrorsTemplate(filename string, apis []*types.ApiGroup) error { fw, err := os.Create(filename) if err != nil { return fmt.Errorf("create file: %s", err) } errors := []string{} for _, apiGroup := range apis { if apiGroup == nil { continue } for _, api := range apiGroup.Api { if api == nil { continue } for _, method := range api.Methods { if method == nil { continue } for _, err := range method.Errors { errors = appendIfMissing(errors, err) } } } } errorsList := types.BluezErrors{ List: make([]types.BluezError, len(errors)), } for i, err := range errors { errorsList.List[i] = types.BluezError{ Name: strings.Replace(err, "org.bluez.Error.", "", 1), } } tmpl := loadtpl("errors") err = tmpl.Execute(fw, errorsList) if err != nil { return fmt.Errorf("tpl write: %s", err) } // log.Debugf("Created %s", filename) return nil } func InterfacesTemplate(filename string, apis []types.ApiGroup) error { fw, err := os.Create(filename) if err != nil { return fmt.Errorf("create file: %s", err) } interfaces := []types.InterfaceDoc{} for _, apiGroup := range apis { for _, api := range apiGroup.Api { pts := strings.Split(api.Interface, ".") ifaceName := pts[len(pts)-1] // org.bluez.obex.AgentManager1 if len(pts) > 3 { ifaceName = "" for _, pt := range pts[2:] { ifaceName += strings.ToUpper(string(pt[0])) + pt[1:] } } iface := types.InterfaceDoc{ Title: api.Title, Name: ifaceName, Interface: api.Interface, } interfaces = append(interfaces, iface) } } ifaces := types.InterfacesDoc{ Interfaces: interfaces, } tmpl := loadtpl("interfaces") err = tmpl.Execute(fw, ifaces) if err != nil { return fmt.Errorf("tpl write: %s", err) } // log.Debugf("Created %s", filename) return nil } go-bluetooth-bluez-5.60/gen/generator/generator_tpl_api.go000066400000000000000000000145611420407601400237640ustar00rootroot00000000000000package generator import ( "fmt" "os" "sort" "strings" "github.com/muka/go-bluetooth/gen/override" "github.com/muka/go-bluetooth/gen/types" log "github.com/sirupsen/logrus" ) func ApiTemplate(filename string, api *types.Api, apiGroup *types.ApiGroup) error { fw, err := os.Create(filename) if err != nil { return fmt.Errorf("create file: %s", err) } apiName := getApiPackage(apiGroup) imports := []string{ "sync", "github.com/muka/go-bluetooth/bluez", } // Expose Properties interface ? exposeProps := override.ExposeProperties(api.Interface) if exposeProps { propsImports := []string{ // "log github.com/sirupsen/logrus", // "reflect", // "github.com/fatih/structs", "github.com/muka/go-bluetooth/util", "github.com/muka/go-bluetooth/props", } imports = append(imports, propsImports...) } // flag to import dbus // NOTE: set to true to handle dbus.Signalling // importDbus := false importDbus := true pts := strings.Split(api.Interface, ".") iface := pts[len(pts)-1] propsList := map[string]*types.PropertyDoc{} for _, p := range api.Properties { prop := types.PropertyDoc{ Property: p, } prop.Name = strings.Trim(p.Name, ": \t") prop.Property.Docs = prepareDocs(p.Docs, true, 2) prop.Property.Type = castType(p.Type) prop.RawType = getRawType(prop.Property.Type) prop.RawTypeInitializer, err = getRawTypeInitializer(prop.Property.Type) if err != nil { log.Errorf("%s %s: %s", api.Interface, prop.Name, err) } propsList[prop.Name] = &prop } propertiesOverride, found := override.GetPropertiesOverride(api.Interface) if found { log.Debugf("Found overrides %s", api.Interface) for propName, propType := range propertiesOverride { var prop *types.PropertyDoc if _, ok := propsList[propName]; ok { prop = propsList[propName] log.Debugf("\tUsing overridden property %s", propName) rawTypeInitializer, err := getRawTypeInitializer(prop.Property.Type) if err != nil { log.Errorf("Override %s %s: %s", api.Interface, prop.Name, err) } prop.RawType = getRawType(prop.Property.Type) prop.RawTypeInitializer = rawTypeInitializer prop.Property.Type = propType // log.Debugf("props --> %s %s", propName, propType) } else { rawTypeInitializer, err := getRawTypeInitializer(propType) if err != nil { log.Errorf("Override %s %s: %s", api.Interface, prop.Name, err) } prop = &types.PropertyDoc{ Property: &types.Property{ Name: propName, Type: propType, }, RawType: getRawType(propType), RawTypeInitializer: rawTypeInitializer, } propsList[propName] = prop } if !importDbus { importDbus = strings.Contains(prop.Property.Type, "dbus.") } } } props := []types.PropertyDoc{} for _, prop := range propsList { // add propery flags for _, flag := range prop.Flags { if flag == types.FlagReadOnly { prop.ReadOnly = true } if flag == types.FlagWriteOnly { prop.WriteOnly = true } if flag == types.FlagReadWrite { prop.ReadWrite = true } } props = append(props, *prop) } sort.Slice(props, func(i, j int) bool { return props[i].Name < props[j].Name }) methods := []types.MethodDoc{} for _, m := range api.Methods { args := []string{} params := []string{} for _, a := range m.Args { argName := renameReserved(a.Name) arg := fmt.Sprintf("%s %s", argName, castType(a.Type)) args = append(args, arg) params = append(params, argName) } mm := types.MethodDoc{ Method: m, ArgsList: strings.Join(args, ", "), ParamsList: strings.Join(params, ", "), } if !importDbus { importDbus = strings.Contains(mm.ArgsList, "dbus.") log.Debugf("%t %s", importDbus, mm.ArgsList) } if !importDbus { importDbus = strings.Contains(mm.ParamsList, "dbus.") } mm.Method.Name = strings.Replace(mm.Method.Name, " (optional)", "", -1) mm.Method.Docs = prepareDocs(mm.Method.Docs, true, 0) mm.Method.ReturnType = castType(mm.Method.ReturnType) mm.SingleReturn = len(mm.Method.ReturnType) == 0 if mm.SingleReturn { mm.Method.ReturnType = "error" } else { // log.Debugf("With return type %s", mm.Method.ReturnType) returnTypes := strings.Split(mm.Method.ReturnType, ", ") defs := []string{} refs := []string{} list := []string{} for i, returnType := range returnTypes { varName := fmt.Sprintf("val%d", i) varDeclaration := "var" // handle array if strings.HasPrefix(returnType, "[]") { varDeclaration = "" returnType = fmt.Sprintf(":= %s{}", returnType) } // def := fmt.Sprintf("var %s %s %s%s", varName, objInitialization1, returnType, objInitialization2) def := fmt.Sprintf("%s %s %s", varDeclaration, varName, returnType) ref := "&" + varName defs = append(defs, def) refs = append(refs, ref) list = append(list, varName) } mm.ReturnVarsDefinition = strings.Join(defs, "\n ") mm.ReturnVarsRefs = strings.Join(refs, ", ") mm.ReturnVarsList = strings.Join(list, ", ") if !importDbus { importDbus = strings.Contains(mm.Method.ReturnType, "dbus.") } mm.Method.ReturnType = "(" + mm.Method.ReturnType + ", error)" } if len(mm.Method.Name) == 0 { continue } methods = append(methods, mm) } if importDbus { imports = append(imports, "github.com/godbus/dbus/v5") } api.Description = prepareDocs(api.Description, false, 0) api.Title = strings.Trim(api.Title, "\n \t") ctrs := createConstructors(api) for _, c := range ctrs { importFmt := strings.Contains(c.ObjectPath, "fmt.") if !importFmt { importFmt = strings.Contains(c.Service, "fmt.") } if importFmt { imports = append(imports, "fmt") } } importsTpl := "" if len(imports) > 0 { for i := range imports { pts := strings.Split(imports[i], " ") if len(pts) == 1 { pts = append(pts, pts[0]) pts[0] = "" } imports[i] = fmt.Sprintf(`%s "%s"`, pts[0], pts[1]) } importsTpl = fmt.Sprintf("import (\n %s\n)", strings.Join(imports, "\n ")) } apidocs := types.ApiDoc{ Imports: importsTpl, Package: apiName, Api: api, InterfaceName: iface, Properties: props, Methods: methods, Constructors: ctrs, ExposeProperties: exposeProps, } tmpl := loadtpl("api") err = tmpl.Execute(fw, apidocs) if err != nil { return fmt.Errorf("api tpl: %s", err) } // log.Debugf("Created %s", filename) return nil } go-bluetooth-bluez-5.60/gen/generator/generator_tpl_constr.go000066400000000000000000000132521420407601400245170ustar00rootroot00000000000000package generator import ( "fmt" "regexp" "strings" "github.com/muka/go-bluetooth/gen/override" "github.com/muka/go-bluetooth/gen/types" ) var defaultService = "org.bluez" func isDefaultService(s string) bool { return len(s) >= len(defaultService) && s[:len(defaultService)] == defaultService } func createConstructors(api *types.Api) []types.Constructor { // log.Debugf("-------------------------------------- %s", api.Interface) constructors := []types.Constructor{} constructors = inspectServiceName(api.Service, constructors) constructors = inspectObjectPath(api.ObjectPath, constructors) for i, c := range constructors { args := []string{} if c.Service == "" { args = append(args, "servicePath string") c.Service = "servicePath" } else { c.Service = fmt.Sprintf(`"%s"`, c.Service) } if c.ObjectPath == "" { args = append(args, "objectPath dbus.ObjectPath") c.ObjectPath = "objectPath" } else { c.ObjectPath = fmt.Sprintf(`"%s"`, c.ObjectPath) } c.Args = strings.Join(args, ", ") docs := []string{} for _, doc := range c.Docs { for _, d1 := range strings.Split(doc, "\n") { docs = append(docs, "// - "+d1) } } c.ArgsDocs = "//\n// Args:\n" + strings.Join(docs, "\n") // target as the deafult initializer if c.Role == "Target" { c.Role = "" } constructors[i] = c } if overrides, hasOverride := override.GetConstructorsOverrides(api.Interface); hasOverride { for _, coverride := range overrides { // add new constructors which take an adapter as arg if coverride.AdapterAsArgument { for _, c1 := range constructors { // log.Debugf("------ oveerride %+v", c1) c := types.Constructor{ Args: "adapterID string", ArgsDocs: "// adapterID: ID of an adapter eg. hci0", Docs: c1.Docs, ObjectPath: `fmt.Sprintf("/org/bluez/%s", adapterID)`, Service: c1.Service, Role: "FromAdapterID", } constructors = append(constructors, c) } } } } // log.Debugf("constructors %++v", constructors) return constructors } func inspectServiceName(serviceName string, constructors []types.Constructor) []types.Constructor { // log.Debugf("ObjectPath %s", api.ObjectPath) // log.Debugf("Interface %s", api.Interface) apiService := serviceName if apiService != "" { apiService = strings.Split(apiService, " ")[0] } if !isDefaultService(apiService) { // log.Debugf("Service %s", apiService) // case 1 // unique name (Target role) // org.bluez (Controller role) if strings.Contains(serviceName, "\n") { re := regexp.MustCompile(`(.+) \((.+?) .+\)`) matches1 := re.FindAllSubmatch([]byte(serviceName), -1) // log.Debugf("%s ----> %s", serviceName, matches1) for _, m1 := range matches1 { doc := "" srvc := strings.Trim(string(m1[1]), " \t") if !isDefaultService(srvc) { doc = srvc srvc = "" } docslist := []string{} if doc != "" { docslist = append(docslist, "servicePath: "+doc) } c := types.Constructor{ Service: srvc, Role: string(m1[2]), Docs: docslist, } constructors = append(constructors, c) } } else { c := types.Constructor{ Service: "", Role: "", Docs: []string{ "servicePath: " + serviceName, }, } constructors = append(constructors, c) } } else { c := types.Constructor{ Service: apiService, Role: "", ObjectPath: "", Args: "", Docs: []string{}, } constructors = append(constructors, c) } return constructors } func inspectObjectPath(objectPath string, constructors []types.Constructor) []types.Constructor { constructors2 := []types.Constructor{} // log.Debugf("%d %s", len(constructors), objectPath) // log.Debugf("%+v", constructors) for _, c := range constructors { if strings.Contains(objectPath, "\n") { // log.Debugf("ObjectPath: \n----\n%s\n\n-----", objectPath) anchor1 := " (Target role)" idx := strings.Index(objectPath, anchor1) if idx > -1 { target := objectPath[:idx] anchor2 := "(Controller role)" idx2 := strings.Index(objectPath, anchor2) controller := objectPath[idx+len(anchor1) : idx2] target = strings.Replace(strings.Trim(target, " \t\n"), "\n", "", -1) controller = strings.Replace(strings.Trim(controller, " \t\n"), "\n\t", "", -1) // if Role is set apply a objectPath if c.Role == "Target" { c.ObjectPath = "" c.Docs = append(c.Docs, "objectPath: "+target) } if c.Role == "Controller" { c.ObjectPath = "" c.Docs = append(c.Docs, "objectPath: "+controller) } // if no Role, create a contructor for each objectPath if c.Role == "" { if controller != "" { c1 := c c1.Role = "Controller" c1.ObjectPath = "" c1.Docs = append(c1.Docs, "objectPath: "+controller) constructors2 = append(constructors2, c1) } if target != "" { c1 := c c1.Role = "Target" c1.ObjectPath = "" c1.Docs = append(c1.Docs, "objectPath: "+target) constructors2 = append(constructors2, c1) } continue } } constructors2 = append(constructors2, c) continue } defaultObjectPath := "/org/bluez" isDefaultPath := len(objectPath) >= len(defaultObjectPath) && objectPath[:len(defaultObjectPath)] == defaultObjectPath pathHasVariables := strings.Contains(objectPath, "{") // log.Debugf("%s %t %t", objectPath, isDefaultPath, pathHasVariables) if !isDefaultPath || pathHasVariables { c.ObjectPath = "" c.Docs = append(c.Docs, "objectPath: "+objectPath) } else { c.ObjectPath = objectPath } // log.Debugf("----> %++v", c) constructors2 = append(constructors2, c) } return constructors2 } go-bluetooth-bluez-5.60/gen/generator/generator_tpl_test.go000066400000000000000000000006741420407601400241720ustar00rootroot00000000000000package generator import ( "fmt" "testing" log "github.com/sirupsen/logrus" ) func TestCastType(t *testing.T) { log.SetLevel(log.DebugLevel) typedef := "object" res := castType(typedef) if res != "dbus.ObjectPath" { t.Fatal(fmt.Sprintf("%s != %s", typedef, res)) } typedef = "array{objects, properties}" res = castType(typedef) if res != "[]dbus.ObjectPath, string" { t.Fatal(fmt.Sprintf("%s != %s", typedef, res)) } } go-bluetooth-bluez-5.60/gen/generator/generator_types.go000066400000000000000000000071101420407601400234700ustar00rootroot00000000000000package generator import ( "fmt" "regexp" "strings" "github.com/muka/go-bluetooth/gen/override" ) func toType(t string) string { switch strings.ToLower(strings.Trim(t, " \t\r\n")) { case "boolean": return "bool" case "int16": return "int16" case "uint16_t": return "uint16" case "uint32_t": return "uint32" case "uint8_t": return "uint8" case "dict": // return "map[string]dbus.Variant" return "map[string]interface{}" // check in media-api case "properties": return "string" case "variant": return "dbus.Variant" case "object": return "dbus.ObjectPath" case "objects": return "dbus.ObjectPath" case "fd": return "dbus.UnixFD" case "": return "" case "unknown": return "" case "void": return "" } return t } func listCastType(typedef string) string { // handle multiple items eg. byte, uint16 if strings.Contains(typedef, ", ") && typedef[:5] != "array" { parts := strings.Split(typedef, ", ") defs := make([]string, 0) for _, part := range parts { subtype := castType(part) if len(subtype) > 0 { defs = append(defs, subtype) } } typedef = strings.Join(defs, ", ") } return typedef } func castType(rawtype string) string { if rawtype == "" { return "" } if mappedType, ok := override.MapType(rawtype); ok { return mappedType } typedef := listCastType(rawtype) //eg. array{string} or array{string, foo} re := regexp.MustCompile(`array\{([a-zA-Z0-9, ()]+)\}`) matches := re.FindSubmatch([]byte(rawtype)) // log.Warnf("submatch -> %s", matches) if len(matches) > 0 { subtype := string(matches[1]) subtype = listCastType(subtype) //special case 1 (obex): `array{string vcard, string name}` pts := strings.Split(subtype, ", ") pts2 := []string{} for _, pt := range pts { pts1 := strings.Split(pt, " ") // log.Debug("pts1 ", pts1[0]) if len(pts1) == 2 { pts2 = append(pts2, pts1[0]) } } if len(pts2) > 0 { subtype = strings.Join(pts2, ", ") } // TODO this is incomplete as it is not handling the case // array{ string, string } ==> []string, string typedef = "[]" + toType(subtype) // log.Debugf("type casting %s -> %s\n", rawtype, typedef) } typedef = toType(typedef) // handle case for named type eg. "uint64 token" namedTypeRegex := regexp.MustCompile(`([^ ]+) (.*)`) namedTypeRegexMatches := namedTypeRegex.FindStringSubmatch(rawtype) if len(namedTypeRegexMatches) > 0 { typedef = namedTypeRegexMatches[1] } // log.Debugf("type casting %s -> %s\n", rawtype, typedef) return typedef } // getRawType clean tag from type func getRawType(t string) string { if strings.Contains(t, "`") { p1 := strings.Trim(strings.Split(t, "`")[0], " ") return p1 } return t } // getRawTypeInitializer return field initializer func getRawTypeInitializer(t string) (string, error) { t = getRawType(t) var checkType = func(text string, match string) bool { minlen := len(match) return len(text) >= minlen && strings.ToLower(t[:minlen]) == match } // array if checkType(t, "[]") { return t + "{}", nil } // map if checkType(t, "map") { return t + "{}", nil } // int* if checkType(t, "int") { return t + "(0)", nil } // uint* if checkType(t, "uint") { return t + "(0)", nil } // float* if checkType(t, "float") { return t + "(0.0)", nil } switch t { case "bool": return "false", nil case "string": return "\"\"", nil case "byte": return "byte(0)", nil // return "[]uint8{}" case "dbus.ObjectPath": return "dbus.ObjectPath(\"\")", nil case "dbus.objectpath": return "dbus.ObjectPath(\"\")", nil } return "", fmt.Errorf("unknown type: %s", t) } go-bluetooth-bluez-5.60/gen/generator/generator_util.go000066400000000000000000000032531420407601400233050ustar00rootroot00000000000000package generator import ( "fmt" "os" "strings" "text/template" "github.com/muka/go-bluetooth/gen/types" ) var TplPath = "gen/generator/tpl/%s.go.tpl" //rename variable name to avoid collision with Go languages func renameReserved(varname string) string { switch varname { case "type": return "type1" default: return varname } } func getBaseDir() string { baseDir := os.Getenv("BASEDIR") if baseDir == "" { baseDir = "." } return baseDir } func getTplPath() string { return fmt.Sprintf("%s/%s", getBaseDir(), TplPath) } func loadtpl(name string) *template.Template { return template.Must(template.ParseFiles(fmt.Sprintf(getTplPath(), name))) } func prepareDocs(src string, skipFirstComment bool, leftpad int) string { return src // lines := strings.Split(src, "\n") // result := []string{} // // comment := "// " // comment := "" // prefixLen := leftpad + len(comment) // fmtt := fmt.Sprintf("%%%ds%%s", prefixLen) // // for _, line := range lines { // line = strings.Trim(line, " \t\r") // if len(line) == 0 { // continue // } // // result = append(result, fmt.Sprintf(fmtt, comment, line)) // } // if skipFirstComment && len(result) > 0 && len(result[0]) > 3 { // result[0] = result[0][prefixLen:] // } // return strings.Join(result, "\n") } func getApiPackage(apiGroup *types.ApiGroup) string { apiName := strings.Replace(apiGroup.FileName, "-api.txt", "", -1) apiName = strings.Replace(apiName, "-", "_", -1) apiName = strings.Replace(apiName, " [experimental]", "", -1) return apiName } func appendIfMissing(slice []string, i string) []string { for _, ele := range slice { if ele == i { return slice } } return append(slice, i) } go-bluetooth-bluez-5.60/gen/generator/generator_version.go000066400000000000000000000006331420407601400240140ustar00rootroot00000000000000package generator import ( "fmt" "io/ioutil" ) // VersionTemplate generate the version file func VersionTemplate(filename, version string) error { tpl := `// Code generated by go-bluetooth generator DO NOT EDIT. package profile const Version = %s ` err := ioutil.WriteFile(filename, []byte(fmt.Sprintf(tpl, version)), 0644) if err != nil { return fmt.Errorf("tpl write: %s", err) } return nil } go-bluetooth-bluez-5.60/gen/generator/tpl/000077500000000000000000000000001420407601400205275ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/generator/tpl/api.go.tpl000066400000000000000000000146761420407601400224430ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package {{.Package}} {{- $InterfaceName := .InterfaceName}} {{- $ExposeProperties := .ExposeProperties}} {{.Imports}} var {{.InterfaceName}}Interface = "{{.Api.Interface}}" {{range .Constructors}} // New{{$InterfaceName}}{{.Role}} create a new instance of {{$InterfaceName}} {{.ArgsDocs}} func New{{$InterfaceName}}{{.Role}}({{.Args}}) (*{{$InterfaceName}}, error) { a := new({{$InterfaceName}}) a.client = bluez.NewClient( &bluez.Config{ Name: {{.Service}}, Iface: {{$InterfaceName}}Interface, Path: dbus.ObjectPath({{.ObjectPath}}), Bus: bluez.SystemBus, }, ) {{- if $ExposeProperties }} a.Properties = new({{$InterfaceName}}Properties) _, err := a.GetProperties() if err != nil { return nil, err } {{- end}} return a, nil } {{- end}} /* {{.InterfaceName}} {{.Api.Title}} {{.Api.Description}} */ type {{.InterfaceName}} struct { client *bluez.Client propertiesSignal chan *dbus.Signal objectManagerSignal chan *dbus.Signal objectManager *bluez.ObjectManager Properties *{{.InterfaceName}}Properties watchPropertiesChannel chan *dbus.Signal } // {{.InterfaceName}}Properties contains the exposed properties of an interface type {{.InterfaceName}}Properties struct { lock sync.RWMutex `dbus:"ignore"` {{- range .Properties }} /* {{.Property.Name}} {{.Property.Docs}} */ {{.Property.Name}} {{.Property.Type}} {{- end}} } //Lock access to properties func (p *{{.InterfaceName}}Properties) Lock() { p.lock.Lock() } //Unlock access to properties func (p *{{.InterfaceName}}Properties) Unlock() { p.lock.Unlock() } {{- range .Properties }} {{- if not .ReadOnly }} // Set{{.Property.Name}} set {{.Property.Name}} value func (a *{{$InterfaceName}}) Set{{.Property.Name}}(v {{.RawType}}) error { return a.SetProperty("{{.Property.Name}}", v) } {{- end}} {{- if not .WriteOnly }} // Get{{.Property.Name}} get {{.Property.Name}} value func (a *{{$InterfaceName}}) Get{{.Property.Name}}() ({{.RawType}}, error) { v, err := a.GetProperty("{{.Property.Name}}") if err != nil { return {{.RawTypeInitializer}}, err } return v.Value().({{.RawType}}), nil } {{- end}} {{- end}} // Close the connection func (a *{{.InterfaceName}}) Close() { {{- if $ExposeProperties }} a.unregisterPropertiesSignal() {{- end}} a.client.Disconnect() } // Path return {{.InterfaceName}} object path func (a *{{.InterfaceName}}) Path() dbus.ObjectPath { return a.client.Config.Path } // Client return {{.InterfaceName}} dbus client func (a *{{.InterfaceName}}) Client() *bluez.Client { return a.client } // Interface return {{.InterfaceName}} interface func (a *{{.InterfaceName}}) Interface() string { return a.client.Config.Iface } // GetObjectManagerSignal return a channel for receiving updates from the ObjectManager func (a *{{.InterfaceName}}) GetObjectManagerSignal() (chan *dbus.Signal, func(), error) { if a.objectManagerSignal == nil { if a.objectManager == nil { om, err := bluez.GetObjectManager() if err != nil { return nil, nil, err } a.objectManager = om } s, err := a.objectManager.Register() if err != nil { return nil, nil, err } a.objectManagerSignal = s } cancel := func() { if a.objectManagerSignal == nil { return } a.objectManagerSignal <- nil a.objectManager.Unregister(a.objectManagerSignal) a.objectManagerSignal = nil } return a.objectManagerSignal, cancel, nil } {{- if .ExposeProperties }} // ToMap convert a {{.InterfaceName}}Properties to map func (a *{{.InterfaceName}}Properties) ToMap() (map[string]interface{}, error) { return props.ToMap(a), nil } // FromMap convert a map to an {{.InterfaceName}}Properties func (a *{{.InterfaceName}}Properties) FromMap(props map[string]interface{}) (*{{.InterfaceName}}Properties, error) { props1 := map[string]dbus.Variant{} for k, val := range props { props1[k] = dbus.MakeVariant(val) } return a.FromDBusMap(props1) } // FromDBusMap convert a map to an {{.InterfaceName}}Properties func (a *{{.InterfaceName}}Properties) FromDBusMap(props map[string]dbus.Variant) (*{{.InterfaceName}}Properties, error) { s := new({{.InterfaceName}}Properties) err := util.MapToStruct(s, props) return s, err } // ToProps return the properties interface func (a *{{.InterfaceName}}) ToProps() bluez.Properties { return a.Properties } // GetWatchPropertiesChannel return the dbus channel to receive properties interface func (a *{{.InterfaceName}}) GetWatchPropertiesChannel() chan *dbus.Signal { return a.watchPropertiesChannel } // SetWatchPropertiesChannel set the dbus channel to receive properties interface func (a *{{.InterfaceName}}) SetWatchPropertiesChannel(c chan *dbus.Signal) { a.watchPropertiesChannel = c } // GetProperties load all available properties func (a *{{.InterfaceName}}) GetProperties() (*{{.InterfaceName}}Properties, error) { a.Properties.Lock() err := a.client.GetProperties(a.Properties) a.Properties.Unlock() return a.Properties, err } // SetProperty set a property func (a *{{.InterfaceName}}) SetProperty(name string, value interface{}) error { return a.client.SetProperty(name, value) } // GetProperty get a property func (a *{{.InterfaceName}}) GetProperty(name string) (dbus.Variant, error) { return a.client.GetProperty(name) } // GetPropertiesSignal return a channel for receiving udpdates on property changes func (a *{{.InterfaceName}}) GetPropertiesSignal() (chan *dbus.Signal, error) { if a.propertiesSignal == nil { s, err := a.client.Register(a.client.Config.Path, bluez.PropertiesInterface) if err != nil { return nil, err } a.propertiesSignal = s } return a.propertiesSignal, nil } // Unregister for changes signalling func (a *{{.InterfaceName}}) unregisterPropertiesSignal() { if a.propertiesSignal != nil { a.propertiesSignal <- nil a.propertiesSignal = nil } } // WatchProperties updates on property changes func (a *{{.InterfaceName}}) WatchProperties() (chan *bluez.PropertyChanged, error) { return bluez.WatchProperties(a) } func (a *{{.InterfaceName}}) UnwatchProperties(ch chan *bluez.PropertyChanged) error { return bluez.UnwatchProperties(a, ch) } {{- end}} {{- range .Methods}} /* {{.Name}} {{.Docs}} */ func (a *{{$InterfaceName}}) {{.Name}}({{.ArgsList}}) {{.Method.ReturnType}} { {{- if .SingleReturn}} return a.client.Call("{{.Name}}", 0, {{.ParamsList}}).Store() {{- else}} {{.ReturnVarsDefinition}} err := a.client.Call("{{.Name}}", 0, {{.ParamsList}}).Store({{.ReturnVarsRefs}}) return {{.ReturnVarsList}}, err{{end}} } {{- end}} go-bluetooth-bluez-5.60/gen/generator/tpl/errors.go.tpl000066400000000000000000000004611420407601400231710ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package profile import ( "github.com/godbus/dbus/v5" ) var ( {{- range .List }} // {{.Name}} map to org.bluez.Error.{{.Name}} Err{{.Name}} = dbus.Error{ Name: "org.bluez.Error.{{.Name}}", Body: []interface{}{"{{.Name}}"}, } {{- end }} ) go-bluetooth-bluez-5.60/gen/generator/tpl/interfaces.go.tpl000066400000000000000000000003421420407601400237760ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. package profile const ( OrgBluezInterface = "org.bluez" {{- range .Interfaces }} //{{.Name}}Interface {{.Title}} {{.Name}}Interface = "{{.Interface}}" {{- end }} ) go-bluetooth-bluez-5.60/gen/generator/tpl/root.go.tpl000066400000000000000000000002001420407601400226270ustar00rootroot00000000000000// Code generated by go-bluetooth generator DO NOT EDIT. /* {{.Name}} [{{.FileName}}] {{.Description}} */ package {{.Package}} go-bluetooth-bluez-5.60/gen/override/000077500000000000000000000000001420407601400175615ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/override/constructor.go000066400000000000000000000012631420407601400224770ustar00rootroot00000000000000package override type ConstructorOverride struct { AdapterAsArgument bool } var constructorOverrides = map[string][]ConstructorOverride{ "org.bluez.Adapter1": { ConstructorOverride{ AdapterAsArgument: true, }, }, "org.bluez.GattManager1": { ConstructorOverride{ AdapterAsArgument: true, }, }, "org.bluez.LEAdvertisingManager1": { ConstructorOverride{ AdapterAsArgument: true, }, }, "org.bluez.MediaControl1": { ConstructorOverride{ AdapterAsArgument: true, }, }, } func GetConstructorsOverrides(iface string) ([]ConstructorOverride, bool) { if val, ok := constructorOverrides[iface]; ok { return val, ok } return []ConstructorOverride{}, false } go-bluetooth-bluez-5.60/gen/override/expose_props.go000066400000000000000000000006301420407601400226350ustar00rootroot00000000000000package override var ExposePropertiesInterface = map[string]bool{ "org.bluez.AgentManager1": false, "org.bluez.Agent1": false, "org.bluez.ProfileManager1": false, "org.bluez.Profile1": false, } // ExposeProperties expose Properties interface to the struct func ExposeProperties(iface string) bool { if val, ok := ExposePropertiesInterface[iface]; ok { return val } return true } go-bluetooth-bluez-5.60/gen/override/properties.go000066400000000000000000000031001420407601400222760ustar00rootroot00000000000000package override func GetPropertiesOverride(iface string) (map[string]string, bool) { if props, ok := PropertyTypes[iface]; ok { return props, ok } return map[string]string{}, false } var PropertyTypes = map[string]map[string]string{ "org.bluez.Device1": { "ServiceData": "map[string]interface{}", "ManufacturerData": "map[uint16]interface{}", }, "org.bluez.GattCharacteristic1": { "Value": "[]byte `dbus:\"emit\"`", "Descriptors": "[]dbus.ObjectPath", "WriteAcquired": "bool `dbus:\"ignore\"`", "NotifyAcquired": "bool `dbus:\"ignore\"`", }, "org.bluez.GattDescriptor1": { "Value": "[]byte `dbus:\"emit\"`", "Characteristic": "dbus.ObjectPath", }, "org.bluez.GattService1": { "Characteristics": "[]dbus.ObjectPath `dbus:\"emit\"`", "Includes": "[]dbus.ObjectPath `dbus:\"omitEmpty\"`", "Device": "dbus.ObjectPath `dbus:\"ignore=IsService\"`", "IsService": "bool `dbus:\"ignore\"`", }, "org.bluez.LEAdvertisement1": { // dbus type: (yv) dict of byte variant (array of bytes) "Data": "map[byte]interface{}", // dbus type: (qv) dict of uint16 variant (array of bytes) "ManufacturerData": "map[uint16]interface{}", // dbus type: (s[v]) dict of string variant (array of bytes) "ServiceData": "map[string]interface{}", // SecondaryChannel, if set on 5.54 cause a parsing exception "SecondaryChannel": "string `dbus:\"omitEmpty\"`", }, "org.bluez.AdvertisementMonitor1": { // array{(uint8, uint8, array{byte})} "Patterns": "[]Pattern", }, "org.bluez.MediaPlayer1": { "Track": "Track", }, } go-bluetooth-bluez-5.60/gen/override/types.go000066400000000000000000000026731420407601400212640ustar00rootroot00000000000000package override var typesMap = map[string]string{ //mesh-api object node, array{byte, array{(uint16, dict)}} configuration Attach(object app_root, uint64 token) "object node, array{byte, array{(uint16, dict)}} configuration": "dbus.ObjectPath, []ConfigurationItem", "array{(uint16 id, dict caps)}": "[]ConfigurationItem", // mesh-api array{(uint16, uint16)} VendorModels [read-only] "array{(uint16, uint16)}": "[]VendorItem", "array{(uint16 vendor, uint16 id, dict options)}": "[]VendorOptionsItem", // obex-api array{string vcard, string name} List(dict filters) "array{string vcard, string name}": "[]VCardItem", // obex-api "object, dict": "dbus.ObjectPath, map[string]interface{}", // obex-api array{object, dict} ListMessages(string folder, dict filter) "array{object, dict}": "[]Message", // gatt AcquireWrite "fd, uint16": "dbus.UnixFD, uint16", // media-api array{objects, properties} ListItems(dict filter) "array{objects, properties}": "[]Item", // media-api fd, uint16, uint16 Acquire() "fd, uint16, uint16": "dbus.UnixFD, uint16, uint16", // advertisement_monitor array{(uint8, uint8, array{byte})} Patterns [read-only, optional] "array{(uint8, uint8, array{byte})}": "[]Pattern", // advertisement_monitor Uint/Int with uppercase "Uint16": "uint16", "Int16": "int16", } //MapType map a raw type literal otherwise difficult to parse func MapType(rawtype string) (string, bool) { res, ok := typesMap[rawtype] return res, ok } go-bluetooth-bluez-5.60/gen/parser.go000066400000000000000000000024151420407601400175670ustar00rootroot00000000000000package gen import ( "strings" "github.com/muka/go-bluetooth/gen/filters" "github.com/muka/go-bluetooth/gen/parser" "github.com/muka/go-bluetooth/gen/types" "github.com/muka/go-bluetooth/gen/util" log "github.com/sirupsen/logrus" ) // Parse bluez DBus API docs func Parse(docsDir string, filtersList []filters.Filter, debug bool) (BluezAPI, error) { files, err := util.ListFiles(docsDir) if err != nil { return BluezAPI{}, err } apis := make([]*types.ApiGroup, 0) for _, file := range files { keep := true if len(filtersList) > 0 { keep = false for _, filter1 := range filtersList { if filter1.Context != filters.FilterFile { continue } if strings.Contains(file, filter1.Value) { keep = true if debug { log.Debugf("[filter %s] Keep %s", filter1.Value, file) } break } } } if !keep { continue } apiGroupParser := parser.NewApiGroupParser(debug, filtersList) apiGroup, err := apiGroupParser.Parse(file) if err != nil { log.Errorf("Failed to load %s, skipped", file) continue } apis = append(apis, apiGroup) } version, err := util.GetGitVersion(docsDir) if err != nil { log.Errorf("Failed to parse version: %s", err) } return BluezAPI{ Version: version, Api: apis, }, nil } go-bluetooth-bluez-5.60/gen/parser/000077500000000000000000000000001420407601400172365ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/parser/api.go000066400000000000000000000042741420407601400203450ustar00rootroot00000000000000package parser import ( "regexp" "strings" "github.com/muka/go-bluetooth/gen/filters" "github.com/muka/go-bluetooth/gen/types" log "github.com/sirupsen/logrus" ) type ApiParser struct { model *types.Api debug bool filter []filters.Filter } // NewApiParser parser for Api func NewApiParser(debug bool, filter []filters.Filter) ApiParser { parser := ApiParser{ filter: filter, debug: debug, model: new(types.Api), } return parser } func (g *ApiParser) log(msg string) { log.Debugf("%s: %s", g.model.Title, msg) } func (g *ApiParser) Parse(raw []byte) (*types.Api, error) { var err error api := g.model // title & description re := regexp.MustCompile(`(?s)(.+)\n[=]+\n?(.*)\nService|Interface *`) matches := re.FindSubmatchIndex(raw) api.Title = string(raw[matches[2]:matches[3]]) api.Description = string(raw[matches[4]:matches[5]]) if g.debug { log.Debugf("= %s", api.Title) } if len(g.filter) > 0 { skipItem := false for _, filter := range g.filter { if filter.Context != filters.FilterApi { continue } skipItem = !strings.Contains( strings.ToLower(api.Title), strings.ToLower(filter.Value)) } if skipItem { log.Debugf("Skip filtered API %s", api.Title) return nil, nil } else { log.Debugf("Keep filtered API %s", api.Title) } } raw = raw[matches[5]:] // service interface object re = regexp.MustCompile(`Service[ \t]*((?s).+)\nInterface[ \t]*((?s).+)\nObject path[ \t]*((?s).+?)\n\n`) matches = re.FindSubmatchIndex(raw) g.model = api api.Service = string(raw[matches[2]:matches[3]]) api.Interface = strings.Replace(string(raw[matches[4]:matches[5]]), " [experimental]", "", -1) api.ObjectPath = string(raw[matches[6]:matches[7]]) if g.debug { log.Debugf("\tService %s", api.Service) log.Debugf("\tInterface %s", api.Interface) log.Debugf("\tObjectPath %s", api.ObjectPath) } raw = raw[matches[7]:] methods, err := g.ParseMethods(raw) if err != nil { return api, err } api.Methods = methods properties, err := g.ParseProperties(raw) if err != nil { return api, err } api.Properties = properties signals, err := g.ParseSignals(raw) if err != nil { return api, err } api.Signals = signals return api, nil } go-bluetooth-bluez-5.60/gen/parser/api_group.go000066400000000000000000000056301420407601400215560ustar00rootroot00000000000000package parser import ( "fmt" "path/filepath" "regexp" "github.com/muka/go-bluetooth/gen/filters" "github.com/muka/go-bluetooth/gen/types" "github.com/muka/go-bluetooth/gen/util" log "github.com/sirupsen/logrus" ) type ApiGroupParser struct { model *types.ApiGroup debug bool filter []filters.Filter } // NewApiGroupParser parser for ApiGroup func NewApiGroupParser(debug bool, filtersList []filters.Filter) ApiGroupParser { apiGroupParser := ApiGroupParser{ debug: debug, filter: filtersList, model: &types.ApiGroup{ Api: make([]*types.Api, 0), }, } return apiGroupParser } // Parse load a documentation file and parse the content func (g *ApiGroupParser) Parse(srcFile string) (*types.ApiGroup, error) { var err error apiGroup := g.model if g.debug { log.Debugf("------------------- Parsing %s -------------------", srcFile) } apiGroup.FileName = filepath.Base(srcFile) apiGroup.Api = make([]*types.Api, 0) raw, err := util.ReadFile(srcFile) if err != nil { return apiGroup, err } // Split by sections eg // group name // ****** // group description ... // api title // ====== // api contents.. // Apis re1 := regexp.MustCompile(`([A-Za-z0-1._ -]*)\n[=]+\n`) matches1 := re1.FindAllSubmatchIndex(raw, -1) if len(matches1) == 0 { return apiGroup, fmt.Errorf("%s: no service defined?", srcFile) } // split up groupText := raw[:matches1[0][0]] g.parseGroup(groupText) // log.Debugf("%d", matches1) slices := make([][]byte, 0) if len(matches1) == 1 { serviceRaw := raw[matches1[0][0]:] if len(serviceRaw) > 0 { slices = append(slices, serviceRaw) } } else { prevPos := -1 for i := 0; i < len(matches1); i++ { if prevPos == -1 { prevPos = matches1[i][0] continue } currPos := matches1[i][0] serviceRaw := raw[prevPos:currPos] prevPos = currPos // log.Debugf("%s", serviceRaw) if len(serviceRaw) > 0 { slices = append(slices, serviceRaw) } // keep the last one if i == len(matches1)-1 { serviceRaw = raw[currPos:] slices = append(slices, serviceRaw) } } } for _, slice := range slices { apiParser := NewApiParser(g.debug, g.filter) api, err := apiParser.Parse(slice) if err != nil { return apiGroup, err } apiGroup.Api = append(apiGroup.Api, api) } return apiGroup, nil } // func (g *ApiParser) parseApi(raw []byte) (*types.Api, error) { // apiParser := NewApiParser(g.debug, g.filter) // return apiParser.Parse(raw) // } func (g *ApiGroupParser) parseGroup(raw []byte) { // Group Name re := regexp.MustCompile(`(.+)\n[*]+\n(.*)`) matches := re.FindAllSubmatchIndex(raw, -1) // log.Debugf("\nRAW\n%s\n\n/RAW\n", raw) // for _, m1 := range matches { // // for _, m := range m1 { // log.Debugf("> %v", m1) // // } // } g.model.Name = string(raw[matches[0][2]:matches[0][3]]) g.model.Description = string(raw[matches[0][1]+1:]) if g.debug { log.Debugf("* %s", g.model.Name) } } go-bluetooth-bluez-5.60/gen/parser/api_methods.go000066400000000000000000000101731420407601400220630ustar00rootroot00000000000000package parser import ( "fmt" "regexp" "strings" "github.com/muka/go-bluetooth/gen/filters" "github.com/muka/go-bluetooth/gen/types" log "github.com/sirupsen/logrus" ) func (g *ApiParser) ParseMethods(raw []byte) ([]*types.Method, error) { var err error = nil methods := make([]*types.Method, 0) slices := make([][]byte, 0) hasMethods := true re := regexp.MustCompile(`(?sm)Methods:?\n?(\t+.*?)\n(?:Properties|Filter|Signals):?\n?`) matches1 := re.FindAllSubmatch(raw, -1) if len(matches1) == 0 { onlyPropsRegex := regexp.MustCompile(`(?smi)(Properties|Filter|Signals):?\n?\t+`) onlyProps := onlyPropsRegex.Match(raw) if !onlyProps { matches1 = append(matches1, [][]byte{nil, raw}) log.Tracef("[%s] No methods wrapper matched, take all text", g.model.Title) } else { hasMethods = false } // log.Debugf("matches1 %s", matches1[1:]) } for _, matches1list := range matches1 { methodsRaw := matches1list[1] // crop from [Methods:] mRe := regexp.MustCompile("Methods:?\n?") methodsPos := mRe.FindIndex(methodsRaw) if len(methodsPos) > 0 { methodsRaw = methodsRaw[methodsPos[1]:] } // remove initial \n chars that are not tabs rmLeadingRegex := regexp.MustCompile(`(?smi)^[^\t]*`) methodsRaw = rmLeadingRegex.ReplaceAll(methodsRaw, []byte{}) // methodsRaw = bytes.TrimLeft(methodsRaw, "\n") // log.Debugf("methodsRaw\n%s", methodsRaw) tabLength := 0 for { if methodsRaw[tabLength] == '\t' { tabLength++ continue } break } // at least one tab if tabLength == 0 { tabLength++ } log.Tracef("[%s] Methods tab spacing is %d", g.model.Title, tabLength) // re1 := regexp.MustCompile(`[ \t]*?(.*?)? ?([^ ]+)\(([^)]+?)?\) ?(.*)`) re1 := regexp.MustCompile(fmt.Sprintf(`(?ms)(^[\t]{%d}[^\t]+)`, tabLength)) matches2 := re1.FindAllIndex(methodsRaw, -1) // log.Debug(strings.ReplaceAll(string(methodsRaw), "\t", "->")) // os.Exit(1) // log.Debugf("%v", matches2) // os.Exit(1) // take by method line to the next method line, including anything in the middle // if there is just one method, take all if len(matches2) == 1 { if len(methodsRaw) > 0 { slices = append(slices, methodsRaw) } } else { if len(matches2) == 0 { g.log("No methods found") } lastValue := []byte{} prevPos := -1 for i := 0; i < len(matches2); i++ { if prevPos == -1 { prevPos = matches2[i][0] continue } nextPos := matches2[i][0] methodRaw := methodsRaw[prevPos:nextPos] if len(lastValue) > 0 { methodRaw = append(lastValue, methodRaw...) lastValue = []byte{} } prevPos = nextPos // obex api docs split return args from function name keeping same tabs, // aggregate if methodRaw seems short if len(methodRaw) < 40 { lastValue = methodRaw continue } // log.Tracef("raw method: %s", methodRaw) if len(methodRaw) > 0 { slices = append(slices, methodRaw) } // keep the last one lastItem := len(matches2) - 1 if i == lastItem { methodRaw = methodsRaw[matches2[lastItem][0]:] if len(methodRaw) > 0 { slices = append(slices, methodRaw) } } } } } if g.debug && hasMethods { log.Debug("\tMethods:") } for _, methodRaw := range slices { methodParser := NewMethodParser(g.debug) method, err := methodParser.Parse(methodRaw) if err != nil { log.Traceln("------") log.Warnf("[%s] method parse error: %s", g.model.Title, err) log.Tracef("[%s]: %s", g.model.Title, methodRaw) log.Traceln("------") continue } // apply filters if len(g.filter) > 0 { skipMethod := false for _, f := range g.filter { if f.Context != filters.FilterMethod { continue } skipMethod = !strings.Contains(strings.ToLower(method.Name), strings.ToLower(f.Value)) } if !skipMethod { methods = append(methods, method) // log.Debugf("Keep filtered method %s", method.Name) } else { // log.Debugf("Skip filtered method %s", method.Name) } } // keep all methods = append(methods, method) } if hasMethods && len(methods) == 0 { log.Warnf("%s: No methods found", g.model.Title) } return methods, err } go-bluetooth-bluez-5.60/gen/parser/api_properties.go000066400000000000000000000035461420407601400226220ustar00rootroot00000000000000package parser import ( "regexp" "github.com/muka/go-bluetooth/gen/types" log "github.com/sirupsen/logrus" ) func (g *ApiParser) ParseProperties(raw []byte) ([]*types.Property, error) { var err error = nil props := make([]*types.Property, 0) slices := make([][]byte, 0) re := regexp.MustCompile(`(?s)\nProperties(.+)\n\n?(Filters|)?[ \t]?`) matches1 := re.FindSubmatch(raw) if len(matches1) == 0 { return props, err } for _, propsRaw := range matches1[1:] { // string Modalias [readonly, optional] re1 := regexp.MustCompile(`(?s)[ \t]*` + propBaseRegexp + `.*?\n`) matches2 := re1.FindAllSubmatchIndex(propsRaw, -1) // log.Debugf("1*** %d", matches2) // if len(matches2) == 0 { // re1 := regexp.MustCompile(`[ \t]*(bool|byte|string|uint|dict|array.*) ([A-Za-z0-9_]+?)( ?) *\n`) // matches2 := re1.FindAllSubmatchIndex(propsRaw, -1) // } // log.Debugf("2 *** %d", matches2) if len(matches2) == 1 { if len(propsRaw) > 0 { // log.Debugf("ADD single *** %s", propsRaw) slices = append(slices, propsRaw) } } else { prevPos := -1 for i := 0; i < len(matches2); i++ { if prevPos == -1 { prevPos = matches2[i][0] continue } nextPos := matches2[i][0] propRaw := propsRaw[prevPos:nextPos] prevPos = nextPos if len(propRaw) > 0 { slices = append(slices, propRaw) } // keep the last one lastItem := len(matches2) - 1 if i == lastItem { propRaw = propsRaw[matches2[lastItem][0]:] if len(propRaw) > 0 { slices = append(slices, propRaw) } } } } } if g.debug { log.Debug("\tProperties:") } for _, propRaw := range slices { propertyParser := NewPropertyParser(g.debug) prop, err := propertyParser.Parse(propRaw) if err != nil { log.Warnf("Skipped property: %s", err) continue } props = append(props, prop) } return props, nil } go-bluetooth-bluez-5.60/gen/parser/api_signals.go000066400000000000000000000034311420407601400220570ustar00rootroot00000000000000package parser import ( "regexp" "github.com/muka/go-bluetooth/gen/types" log "github.com/sirupsen/logrus" ) func (g *ApiParser) ParseSignals(raw []byte) ([]*types.Method, error) { var err error methods := make([]*types.Method, 0) slices := make([][]byte, 0) re := regexp.MustCompile(`(?s)Signals(.+)\n\nProperties`) matches1 := re.FindSubmatch(raw) if len(matches1) == 0 { return methods, err } // if len(matches1) == 0 { // re = regexp.MustCompile(`(?s)[ \t\n]+(.+)`) // matches1 = re.FindSubmatch(raw) // if len(matches1) == 1 { // matches1 = append(matches1, matches1[0]) // } // } // log.Debugf("matches1 %s", matches1[1:]) // log.Debugf("%s", matches1) for _, methodsRaw := range matches1[1:] { re1 := regexp.MustCompile(`[ \t]*?(.*?)? ?([^ ]+)\(([^)]+?)?\) ?(.*)`) matches2 := re1.FindAllSubmatchIndex(methodsRaw, -1) if len(matches2) == 1 { if len(methodsRaw) > 0 { slices = append(slices, methodsRaw) } } else { prevPos := -1 for i := 0; i < len(matches2); i++ { if prevPos == -1 { prevPos = matches2[i][0] continue } nextPos := matches2[i][0] methodRaw := methodsRaw[prevPos:nextPos] prevPos = nextPos if len(methodRaw) > 0 { slices = append(slices, methodRaw) } // keep the last one lastItem := len(matches2) - 1 if i == lastItem { methodRaw = methodsRaw[matches2[lastItem][0]:] if len(methodRaw) > 0 { slices = append(slices, methodRaw) } } } } } if g.debug { log.Debug("\nSignals:") } for _, methodRaw := range slices { methodParser := NewMethodParser(g.debug) method, err := methodParser.Parse(methodRaw) if err != nil { log.Debugf("Skip signal: %s", err) continue } methods = append(methods, method) } return methods, nil } go-bluetooth-bluez-5.60/gen/parser/method.go000066400000000000000000000050421420407601400210460ustar00rootroot00000000000000package parser import ( "errors" "fmt" "regexp" "strings" "github.com/muka/go-bluetooth/gen/types" log "github.com/sirupsen/logrus" ) // NewMethodParser init a MethodParser func NewMethodParser(debug bool) MethodParser { return MethodParser{ model: new(types.Method), debug: debug, } } //MethodParser wrap a parsable method type MethodParser struct { model *types.Method debug bool } //Parse a method text func (g *MethodParser) Parse(raw []byte) (*types.Method, error) { var err error = nil method := g.model re := regexp.MustCompile(`[\t]{1,}(.*?)(?: |\n\t{2,})?(\w+)\(([^)]*)\) ?(.*?)\n((?s).+)`) matches1 := re.FindAllSubmatch(raw, -1) for _, matches2 := range matches1 { rtype := string(matches2[1]) if len(rtype) > 7 && rtype[:7] == "Methods" { rtype = rtype[7:] } rtype = strings.Trim(rtype, " \t") for _, srtype := range strings.Split(rtype, ",") { if len(strings.Split(strings.Trim(srtype, " "), " ")) > 2 { // log.Warnf("****** %s | %s", strings.Trim(srtype, " "), strings.Split(strings.Trim(srtype, " "), " ")) return g.model, fmt.Errorf("Method %s return type contains space: `%s`", method.Name, rtype) } } if len(rtype) > 20 { log.Warnf("Return type value is too long? `%s`", rtype) } method.ReturnType = rtype name := string(matches2[2]) method.Name = strings.Trim(name, " \t") args := []types.Arg{} if len(matches2[3]) > 0 { args1 := string(matches2[3]) if args1 == "void" { continue } argslist := strings.Split(args1, ",") for _, arg := range argslist { arg = strings.Trim(arg, " ") argsparts := strings.Split(arg, " ") if argsparts[0] == "void" { continue } if len(argsparts) < 2 { if argsparts[0] == "fd" { argsparts = []string{"int32", argsparts[0]} } else { argsparts = []string{"", argsparts[0]} } } argType := strings.Trim(argsparts[0], " \t\n") arg := types.Arg{ Type: argType, Name: argsparts[1], } args = append(args, arg) } } method.Args = args method.Docs = string(matches2[5]) } // re2 := regexp.MustCompile(`(?s)(org\.bluez\.Error\.\w+)`) matches2 := re2.FindAllSubmatch(raw, -1) if len(matches2) >= 1 { for _, merr := range matches2[0] { method.Errors = append(method.Errors, string(merr)) } } if method.Name == "" { return method, errors.New("Empty method name") } // if strings.Contains(method.ReturnType, "Handle") { // fmt.Println(method) // os.Exit(1) // } if g.debug { log.Debugf("\t - %s", method) } return method, err } go-bluetooth-bluez-5.60/gen/parser/property.go000066400000000000000000000053601420407601400214550ustar00rootroot00000000000000package parser import ( "errors" "regexp" "strings" "github.com/muka/go-bluetooth/gen/types" log "github.com/sirupsen/logrus" ) const propBaseRegexp = `(bool|boolean|byte|string|[i|I]nt16|[U|u]int16|uint16_t|uint32|dict|object|array\{.*?) ([A-Z].+?)` type PropertyParser struct { model *types.Property debug bool } // NewPropertyParser func NewPropertyParser(debug bool) PropertyParser { p := PropertyParser{ model: new(types.Property), debug: debug, } return p } func (g *PropertyParser) Parse(raw []byte) (*types.Property, error) { var err error property := g.model // log.Debugf("prop raw -> %s", raw) re1 := regexp.MustCompile(`[ \t]*?` + propBaseRegexp + `( \[[^\]]*\].*)?\n((?s).+)`) matches2 := re1.FindAllSubmatch(raw, -1) // log.Warnf("m1 %s", matches2) if len(matches2) == 0 || len(matches2[0]) == 1 { re1 = regexp.MustCompile(`[ \t]*?` + propBaseRegexp + `\n((?s).+)`) matches2 = re1.FindAllSubmatch(raw, -1) // log.Warnf("m2 %s", matches2) } if len(matches2) == 0 { log.Debugf("prop raw -> %s", raw) return property, errors.New("no property found") } flags := []types.Flag{} flagListRaw := string(matches2[0][3]) flagList := strings.Split(strings.Trim(flagListRaw, "[] "), ",") for _, f := range flagList { // track server-only flags for gatt API if strings.Contains(f, "Server Only") { flags = append(flags, types.FlagServerOnly) } // int16 Handle [read-write, optional] (Server Only) if strings.Contains(f, "]") { f = strings.Split(f, "]")[0] } f = strings.Trim(f, " []") if f != "" { var flag types.Flag = 0 switch f { case "readonly": case "read-only": flag = types.FlagReadOnly case "writeonly": case "write-only": flag = types.FlagWriteOnly case "readwrite": case "read-write": case "read/write": flag = types.FlagReadWrite case "experimental": case "Experimental": flag = types.FlagExperimental case "optional": flag = types.FlagOptional default: log.Warnf("Unknown flag %s", f) } if flag > 0 { flags = append(flags, flag) } } } docs := string(matches2[0][4]) docs = strings.Replace(docs, " \t\n", "", -1) docs = strings.Trim(docs, " \t\n") name := string(matches2[0][2]) if strings.Contains(name, "optional") { name = strings.Replace(name, " (optional)", "", -1) docs = "(optional) " + docs flags = append(flags, types.FlagOptional) } name = strings.Replace(name, " \t\n", "", -1) // theese bastards fucks up with properties names if nameParts := strings.Split(name, " "); len(nameParts) > 1 { name = nameParts[0] } property.Type = string(matches2[0][1]) property.Name = name property.Flags = flags property.Docs = docs if g.debug { log.Debugf("\t - %s", property) } return property, err } go-bluetooth-bluez-5.60/gen/parser_test.go000066400000000000000000000014651420407601400206320ustar00rootroot00000000000000package gen import ( "path" "testing" "github.com/muka/go-bluetooth/gen/filters" "github.com/muka/go-bluetooth/gen/util" "github.com/stretchr/testify/assert" ) func TestParse(t *testing.T) { api, err := Parse("../src/bluez/doc", []filters.Filter{}, false) if err != nil { t.Fatal(err) } assert.NotEmpty(t, api.Version) assert.NotEmpty(t, api.Api) } func TestSerialization(t *testing.T) { api, err := Parse("../src/bluez/doc", []filters.Filter{}, false) if err != nil { t.Fatal(err) } destDir := "../test/" jsonFile := path.Join(destDir, "test.json") err = util.Mkdir(destDir) if err != nil { t.Fatal(err) } err = api.Serialize(jsonFile) if err != nil { t.Fatal(err) } api1, err := LoadJSON(jsonFile) if err != nil { t.Fatal(err) } assert.Equal(t, api.Version, api1.Version) } go-bluetooth-bluez-5.60/gen/srcgen/000077500000000000000000000000001420407601400172235ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/srcgen/main.go000066400000000000000000000062141420407601400205010ustar00rootroot00000000000000package main import ( "encoding/json" "fmt" "io/ioutil" "os" "strings" "github.com/muka/go-bluetooth/gen" "github.com/muka/go-bluetooth/gen/filters" "github.com/muka/go-bluetooth/gen/generator" "github.com/muka/go-bluetooth/gen/util" log "github.com/sirupsen/logrus" ) const ( flagOverwrite = "overwrite" flagDebug = "debug" flagGenerateModeFull = "full" flagGenerateModeParse = "parse" flagGenerateModeGenerate = "generate" ) const docsDir = "src/bluez/doc" const outputDir = "bluez" func getBaseDir() string { baseDir := os.Getenv("BASEDIR") if baseDir == "" { baseDir = "." } return baseDir } func getDocsDir() string { return fmt.Sprintf("%s/%s", getBaseDir(), docsDir) } func getOutputDir() string { return fmt.Sprintf("%s/%s", getBaseDir(), outputDir) } func main() { parseLogLevel() bluezVersion := getBluezVersion() debug := hasFlag(flagDebug) apiFile := fmt.Sprintf("%s/bluez-%s.json", getBaseDir(), bluezVersion) if hasFlag(flagGenerateModeFull) || hasFlag(flagGenerateModeParse) { filters := parseFilters() err := Parse(filters, debug) if err != nil { os.Exit(1) } } if hasFlag(flagGenerateModeFull) || hasFlag(flagGenerateModeGenerate) { overwrite := hasFlag(flagOverwrite) err := Generate(apiFile, debug, overwrite) if err != nil { log.Fatal(err) } } } func parseFilters() []filters.Filter { return filters.ParseCliFilters() } func hasFlag(flagValue string) bool { if len(os.Args) > 1 { args := os.Args[1:] for _, arg := range args { if strings.Trim(arg, "- ") == flagValue { return true } } } return false } func getBluezVersion() string { bluezVersion, err := util.GetGitVersion(getDocsDir()) if err != nil { log.Fatal(err) } envBluezVersion := os.Getenv("BLUEZ_VERSION") if envBluezVersion != "" { bluezVersion = envBluezVersion } log.Infof("API %s", bluezVersion) return bluezVersion } func parseLogLevel() log.Level { logLevel := log.DebugLevel.String() if os.Getenv("LOG_LEVEL") != "" { logLevel = os.Getenv("LOG_LEVEL") } lvl, err := log.ParseLevel(logLevel) if err != nil { log.Fatal(err) } log.SetLevel(lvl) return lvl } func Parse(filters []filters.Filter, debug bool) error { api, err := gen.Parse(getDocsDir(), filters, debug) if err != nil { log.Fatalf("Parse failed: %s", err) return err } baseDir := os.Getenv("BASEDIR") if baseDir == "" { baseDir = "." } apiFile := fmt.Sprintf("%s/bluez-%s.json", baseDir, api.Version) log.Infof("Saving to %s\n", apiFile) err = api.Serialize(apiFile) if err != nil { log.Fatalf("Failed to serialize JSON: %s", err) return err } return nil } func Generate(filename string, debug bool, overwrite bool) error { log.Infof("Generating from %s\n", filename) file, err := ioutil.ReadFile(filename) if err != nil { log.Fatalf("Generation failed: %s", err) return err } api := gen.BluezAPI{} err = json.Unmarshal([]byte(file), &api) if err != nil { log.Fatalf("Generation failed: %s", err) return err } err = generator.Generate(api, getOutputDir(), debug, overwrite) if err != nil { log.Fatalf("Generation failed: %s", err) return err } return nil } go-bluetooth-bluez-5.60/gen/types/000077500000000000000000000000001420407601400171065ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/types/generator.go000066400000000000000000000020651420407601400214260ustar00rootroot00000000000000package types type BluezError struct { Name string Error string } type BluezErrors struct { List []BluezError } type MethodDoc struct { *Method ArgsList string ParamsList string SingleReturn bool ReturnVarsDefinition string ReturnVarsRefs string ReturnVarsList string } type InterfaceDoc struct { Title string Name string Interface string } type InterfacesDoc struct { Interfaces []InterfaceDoc } type PropertyDoc struct { *Property RawType string RawTypeInitializer string ReadOnly bool WriteOnly bool ReadWrite bool } type ApiGroupDoc struct { *ApiGroup Package string } type ApiDoc struct { Api *Api InterfaceName string Package string Properties []PropertyDoc Methods []MethodDoc Imports string Constructors []Constructor ExposeProperties bool } type Constructor struct { Service string Role string ObjectPath string Args string ArgsDocs string Docs []string } go-bluetooth-bluez-5.60/gen/types/parser.go000066400000000000000000000033741420407601400207400ustar00rootroot00000000000000package types import ( "fmt" "strings" ) type ApiGroup struct { FileName string Name string Description string Api []*Api debug bool } type Api struct { Title string Description string Service string Interface string ObjectPath string Methods []*Method // those are currently avail only in health-api Signals []*Method Properties []*Property } type Flag int const ( FlagReadOnly Flag = iota + 1 FlagWriteOnly FlagReadWrite FlagExperimental FlagOptional FlagServerOnly ) type Arg struct { Type string Name string } func (a *Arg) String() string { return fmt.Sprintf("%s %s", a.Type, a.Name) } type Method struct { Name string ReturnType string Args []Arg Errors []string Docs string } func (m *Method) String() string { args := []string{} for _, arg := range m.Args { args = append(args, arg.String()) } return fmt.Sprintf("%s %s(%s)", m.ReturnType, m.Name, strings.Join(args, ", ")) } type Property struct { Name string Type string Docs string Flags []Flag } func (p *Property) String() string { flags := []string{} for _, flag := range p.Flags { flagLabel := "" switch flag { case FlagReadOnly: flagLabel = "readonly" break case FlagWriteOnly: flagLabel = "writeonly" break case FlagReadWrite: flagLabel = "readwrite" break case FlagExperimental: flagLabel = "experimental" break case FlagOptional: flagLabel = "optional" break case FlagServerOnly: flagLabel = "server-only" break } if flagLabel != "" { flags = append(flags, flagLabel) } } flagsStr := "" if len(flags) > 0 { flagsStr = fmt.Sprintf("[%s]", strings.Join(flags, ", ")) } return fmt.Sprintf("%s %s %s", p.Type, p.Name, flagsStr) } go-bluetooth-bluez-5.60/gen/util/000077500000000000000000000000001420407601400167175ustar00rootroot00000000000000go-bluetooth-bluez-5.60/gen/util/util.go000066400000000000000000000031111420407601400202170ustar00rootroot00000000000000package util import ( "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "strings" log "github.com/sirupsen/logrus" ) // Mkdir Create a dir if not exists func Mkdir(dirpath string) error { err := os.Mkdir(dirpath, 0755) if err != nil && !os.IsExist(err) { return err } return nil } // ListFiles return a list of bluez api txt func ListFiles(dir string) ([]string, error) { list := make([]string, 0) if !Exists(dir) { return list, fmt.Errorf("Doc dir not found %s", dir) } err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if info.IsDir() { return nil } if strings.HasSuffix(path, "mgmt-api.txt") { return nil } if !strings.HasSuffix(path, "-api.txt") { return nil } list = append(list, path) return nil }) if err != nil { log.Errorf("Failed to list files: %s", err) return list, nil } return list, nil } // ReadFile read a file content func ReadFile(srcFile string) ([]byte, error) { file, err := os.Open(srcFile) if err != nil { return []byte{}, err } defer file.Close() b, err := ioutil.ReadAll(file) if err != nil { return []byte{}, err } return b, nil } // Exists reports whether the named file or directory exists. func Exists(name string) bool { if _, err := os.Stat(name); err != nil { if os.IsNotExist(err) { return false } } return true } //GetGitVersion return the docs git version func GetGitVersion(docsDir string) (string, error) { cmd := exec.Command("git", "describe") cmd.Dir = docsDir res, err := cmd.CombinedOutput() return strings.Trim(string(res), " \n\r"), err } go-bluetooth-bluez-5.60/go.mod000066400000000000000000000010031420407601400162710ustar00rootroot00000000000000module github.com/muka/go-bluetooth go 1.14 require ( github.com/fatih/structs v1.1.0 github.com/godbus/dbus/v5 v5.0.3 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.6.0 github.com/stretchr/testify v1.6.1 github.com/suapapa/go_eddystone v1.3.1 golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect ) go-bluetooth-bluez-5.60/go.sum000066400000000000000000000133651420407601400163340ustar00rootroot00000000000000github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf/go.mod h1:+AwQL2mK3Pd3S+TUwg0tYQjid0q1txyNUJuuSmz8Kdk= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/suapapa/go_eddystone v1.3.1 h1:mfW3eNoRPpaZ0iARRZtEyudFfNFtytqeCexwXg1wIKE= github.com/suapapa/go_eddystone v1.3.1/go.mod h1:bXC11TfJOS+3g3q/Uzd7FKd5g62STQEfeEIhcKe4Qy8= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346 h1:hzJjkvxUIF3bSt+v8N5tBQNx/605vszZJ+3XsIamzZo= golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= go-bluetooth-bluez-5.60/gopher.png000066400000000000000000006426631420407601400172040ustar00rootroot00000000000000PNG  IHDRp=ӤIDATxi}]KDR")갬l'vw8?H%J%yJR~(*9Ų$Q= 0{o3.ԗK,E6fzf0iL{GEb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @1A(&(Eb"PLP @K{Z{ҥr)44u] WUܾaMS-fijrSS3~q^r÷]:-5nWUt^s|+|I17)vΝn G47j05iovnw|=c׍['&=Xu"ڸ.\P *眚Ij{UUͦfRJ1|D朗hR꥔&-?.Us9ljы " glb|fǗ7醟^D>_L)W9G;)`9>w"vDDoF`n)VD49߶9?8J yivz^VjUU5n}~mmhslAx:ujz^3FsԜȹZ8zY:R^9-EQq[Hs)›s>L)vrN;XƭF3(#vNJV [Ui=tNS O{^^`ҟ'JPgK2f`0SDćSK)>b`Jɶ08@ƭ|+"6"Fr|4i}4324`v~`}}}˱^KPUSNzNp:LD^obUvbJqv`RAȓ-7Ոs6|YVU嵦I#b7缟sޫ`0ݺuk?"&9M 8p$GFFDs/Eܬuz۽˱7Ao3g"Ty'=N (#ܹsov;Ow:ٜhbI)NԍȝFGs9qHO)6r9|5"9j؟ /~6)wDFb)"F1&=Nsފ툴R^_i)_87LzGPGH#F䕈_f#wNR9)È>#RW^ݸxc頻RޟR~_i."8Ar9"vﹼsJJwoll\8!w~ҟ9;>a&N)M6snRJy?؊/~o0h~YͻpKzD|<"1`Kmx2 /4w&&=F>S%LD&=o&܏t;IwD_f/7ջt{#9$=)gsѽ3 8"&泇7AgϞ:3oD˥ꈴ#rcccwrxQO(S9zToOۍi iMM="R9Ri_߃k}yѤog"k~(HUN;n4>z}}J)Ngiol~x~7)vD|ig:>{ڵ{57 s &k3I"O&=JňYclwܹ^_}WD'RH+ o 63_[ϵi_r3zڴp4_^GSRZSMQUTڪE^ UU8E/MOqK)Bt=lNO7H}ݝ*i?NَS vvn*`Ҝc0c&ɑRN"R~^_6ZV݁H{d圿 "}2綷[\<|9TULJ%1)7Y_A?rni6ūK6MLLMOLff753sff-D;Qu1;7曙no}~vnC^;ۻh)YUU4MӾ75}<{0E٨h<o'<`5DNMirx8aGթD` {18ڨ737s mLTL̶;UW(du;6SfP˞XfۙN53׫j乪:m(.i<#ha>Su ϱn7~x?{xp^jgSnV{}og'vwcw{3vv3.bow?꺉ǟ(6t7 =˳8.fLV_|5߃9'&~?R-^Ν;9<<6MSur)t`ƍq '(rɋ9ORZx&97P>};KNLtwtrn>>R:==~7P4w/ɣ= Q>jFo 'bit,8'OG>'Nmnoj40(gU)x4u}-ˣhX^_ѕo`zD7khW37~|힋UU|D|OJ=ۣupg_rº'ҍ.wa{@He)uۥ s1sKq8qT,<'VN≓|T,.|63Sӱu p Gpg)LǙ q T{5_{KΞldwo`pngF8ۍvqly3oߊ[q{Flmތ޺;ۻQ"Ad8z4vRz98 }t:;_|I x܃VUݔwOz,/ugc񰺺z*N'ޝsDJNhva:>鷝]8khl"&RutpE-Ug yn|b,.hg.<'ϴ N( s155UwyL'52_ȟ?̹\D\yyեK g*>ɟ9}*?re7'={p]xSJMJ89Z][[[W u:ᦉO)/":pxL2FFn ttMB{"J,8K'ĩۥȋK˱|2VVbzv>nם褨hh߸FG~x|bsܝYb!p3i[:NMgf;{~u{ˠ0ZF}'nXWc˱~xujl\wn;[qA oVSU{ݦOOfd9ϥ4Lz\pŹ?Q6,ђ[9ѕ+1:>xSU4Ń3H<OiTWݳLF_Mz,+sG<,g/\3.էrl,(v=QxhPyfp/b^w~]K >GDQ0W*UzxX׮W_j\y酸v96/FD]~80ni0ݛF X*s>kjDο1,7.\8餿rD@J31=rΟ8|w> wȱwnoAn9gW O=Vz&N_Ծlԙv\LOʹhCqhOlolmo[7bc}~}J_y)no\èR≅_Xnǖ's7"._s>UUc'"C)ũ89qKms6:x?ŅX>u6Μ;ڧ/>3Zƅ Q$lfaRdx~tvmNi;fܼ~-^Z\yqcؼ{Nh~8.ތH97*+/_e|KVvD{H7Sqp0VG mt¯T[1:N{퍍ɓK̳w}LJp<ř czfti=DG{fkhOLmxO*U՞:|ׯW_~!׾W7^ bB,.8 9ʕI?H."},"/&=)~ATX9}];3</-N= +?2g>2O{NьŻajN{ukl݉׮W|˱yf餘_\zu`͔bi6M󵵵wr⹿RH|"x_/W^YIMtiFV-?<؏[7^mg<w};XX>u{QG3"lћӸӫRԝn7nI}?ߍ/|˯)WN 9:"'oܸq}`?t\J/FG#\D}3"6rp[qpЏN哧܅۟ϼ+ŧ'Ϝ a4u|v|;l OsEjg-}?q֫q X{xu}-vwSU1;73 q؍W_j~IZ)IQs9WlDOz<$hބ"}yzG/w~vcwk+@l?;Gjc_XjCƕ[n^ivyP&FLG?@>(߮ٳgOTUDDEDqy|~{鵡pmogO=qڥ˝N]|Ãd'a3!FN>5=lَq_R׾kc060їsiY]_Z[[X͹sOӈ87&m]D`׮]1RJ{Nmۼ9w~/?k!*.Wfv~)VN{<~'~W~1~Eټ+'ܿ8J]ǿ{_7[3.;wDWh鯥?ӝs?N SxO<xjOcNN{:kC(&INSS3137v7_kGˤ_z_hg1n޺<53վ}ӽ"!_fdw|6}G8wVU{!r}kujmmIDOoxp.BD[m ߹^F|ig <{>|:/}f=yU997+~y^x/}>vopiON-_xszD255u{mmmoo+++??ky{UiϹw.iF#\p M!I&ِgl:HJB`Mq]LsoF!ҕ%Yeg9RQ/9s&GZ 8B6_͘](%s gReο\#AO^JO, ]$KhlSZ+<ȃVrPJ ijy1|gۥkIE.uM5u 5CR.L9,9JSs ܞ5I)(P-g@ snSNt;:PY %o (_b]TN)(3x_➟~n_nhugю'L!v{\q"cydM7r3o 04p.Qmi` ΘT $K<4uo6E; P@ |c)H\nxA22 2>tۍ;^W^έىR1 q0IA`!KoT4 [I2*}d2;3--- %Ik,?QihUB xA(6B>tۉ=۶Z$Clp'7{'9{xR7(AM>ꈞ1HT: R-Wk&"N6}Zcfm:"pykB6?]nP4[?;HԱSZ  cq[㵗{HBU `FfZ9F@ꎎlrTO$( x>Ƥ8d0H {1wb|{w)ڊ}io2P XR"o}[^~@8w19H->@ vJNd[;s:\{SW+eE2%C96m ]-CYhhjoC1h@ %|pc1j)\۹_y_}v#R$.vcT34Or͙L&5s#$I*ND@ @QTV"I}^ܺyxm3}](T7N8n*Bz4!9_΍u{zz5Z[2&16HOkR#9pC&pKVŢ'`ꌹ4D5"|<Uj՗#0d\sjSKEwc'ăM#It Qh<2 _!VBZ~G:ySM'P+.:]')a 7d>{v ѦF^2sWZ>QF,s2?Nd lXp;Z]XET#`ʌd%j;f6޻\:\*ԚT*g(cKK Ez\#9Їڋ`йg'~T*dI&SRdԔb☋Doooa4Yim}1yƘŘ&1 i0#'֟!jj|.C)Fl~v}޼0#e|_D:B [Hk.!VFA>d%YF\@.f\yۿP@XEmqQAxE૟c<@pn}D|󫺻_tࣄYZXttH0YUUieCc 3/cWcւM.ϑh &E@ K7b7wq=\B$gڷ6?^x{vlEBZMx|x~ȊL%e5nOUxwXihm}1/l-%sydR)؝NgϾ)ӡ8P%隉#u`~Fu]'ClRW{x? ( E^U}ҁ1~mqHkk/$]1Q̛;Cv,_{"n T nGSs\?W'XĢ0/bs ёt Lkktcu#qc6sz'M?&IT(NX@`)1gѱ8̜*Nu.t BJ" Q &&9m9]n^J R] xg۾ l6;9{ 3 ɱLSSP1vhfR"cXyiX̘͆\.b>KX ] ]hKo LJb>G;];6RDZ9"R&9G #Z[#16m$6n美cfR,"ߡhnt⏿AP@,B7C@(Y:֌ +czND`-R)!JT®(bXl5^@&Lj"juXA ^4mvuMC*чm+/>^B7N&Μ7R,nL|ߪqHh4QW~hF&֌A W W`hn Sfj]M41t/0/w?݃`Pc~fs1/Z6@ J p>̨0ordx;ν=HPWZAa(E@!'|DW{ZZHlOH$UrƤ̲hC<:AT Ų 9pq|5fQJ-Ur.LD@ 8lazl6vDzy|6=^>_ڈ][c!<@9 jUE__߮D'Fv?vhGQ*7F۔8uXwŐeN| M=J 'p CTG~KP'"-1KMEwiq &=G÷@`9htH?cL:a$b/ǭU=~>t{n i5GCpy`˦߂xĕ׍sq?Ԗ -r3aa'Xip(a4̋^\W]NtFR?@YMk 5D(Ҍ#t T fiYu\յݢIXu oy&1`cb4NBQx_ND0jf" wVW@e 2|Wc3O#km✿ѵ @ŲAǀp8w0\,"ʀIZˎ•k`*4M׹BU+T8L9@ &0r5p6/s݆ovww'Z\.-3Qdhj=h6i< *M% N1Ϻ>9tώp)C_-1nXsnpd$G^Ge ~\g 62U5FxC XkN%/?8"1 %fX"H70n6ӚMTdVN%Vcq'a2zX!*f\@pB"G+PNJKF̣cطsr#rsnj_1wkrK'(M65_5Ca,2y<}Tg]hn]&FMd_7>shln)%jX%8\JSn{/c:XX@Ӿ ]jRLJ `X$̘.xt,@ Xa npTMExcat;p,65sc[loL&3 h4٤Hdy$htb|?c)Ptk[uj{Ix v 7F\뎛K% 3rw=l$D6_,I9MqX)?]y3νz5MҦ8pt;VUOν/7]=hj~u]+,"L+r,[8g71|c=S CjQTɎiXq:,[{f/XF3IW@ * ̎` ^T;lKO=?=;v+p8)6Œ8;tyk9x#/[=0$h2RL}SXvzЃJ i8sƫFODbZ푏厎O K&,LBW:@0@ ca$ }ux%J):5xD$s0gr<ȤtM_ cqY"3cc:ƘcrRrP#V;x.tEMGC|ɤ)( Zt}C:Y+w3u|,[O<,Td/jƩx2f0.e$ߧ{όIbߴz\ILz Oޅ3վ%8%<EQ,1&2QRJHy<^<ȌuV{"X3c`! EN<0aww憎j 37P$Z)gjG0Xwq;/fI̚fG\cdfsY50p6-d,>YfaclxQV2XbjVJ%(7,:]y.#8k0grjH4I&~gC u$hl&\:E %.^kOűǯCiTJH OCTu}4ر1;_pbX,q1\%Iq׾үSν7| ݾLD$?mV*̦νxP1\.e&n%1>_`cMp7oxjꞬ90o*d Io_[T[,Kѝl si,Zn?Ha~Ox-aڴ$ 1ks:sx+PfRCs.r!pYpkn5nD&1D_0J"Q 7*S,RԢihr \'K N#LXRI`)"ka|^ BXjbe$gz32Ϲ=}微BH d*||`^r!@S" cALvb1olɅ0:^$I2e8SGJNbqj21p0ŅQ'wJHٺJǯCӏ.aɵeRBPd@kkd￁1XId}PIQ)pjl\vGq9ayT7ttrFde\u LLjMǞp V]鳠k:Rr~ebQvjc1v$Ik~*\wu8D"cEclJr-sFU+?D]4 .@ ތyʥ"ΜZOawGd2VIr,@0I@P'$vp7ejؔdȲLYN< `6Eq"CfZkףsl~%}dYg?[1PM3I$ 0{'k+l0t TpށKVHs$u.T"Q p`bX@69CǼa)g`I!JBVp:(zm<cgݹ\0p8w:?eo帒,#LPKo&I @QB FvK2l6HW1ell~gHg2cؓ0ﻄ1fx3MbXf<8ׇlnpNY1 rj,^} wD0<lf[b@w3c򝌱zoFbRAtn  Wr;N?nSз$]l嘲,22 W~NuHkjS9I48\.C 0kA9Ua2ǷvcR>X1s{vcr +L (hnnnenذvͪüs0k23w13o}p,DZ`x/ J"5{0{ʂxFYfbLz?clUSR[y_OyҙAX_ D T0(4MJ e#͘p9; ;vN'r ɦ3bt<:1c&8w݅B!=z x$}1L$Q*q>Ͽ25!z^F5D&'J֭|jZYƧ۹vseuxx(mp@`׌Q;N:4ME.B-1պawZ6NPrpJ5>{>|x^x-i,7uHFjkȘA͵`rFdZ̘ >p9W\s'quLTjVo"j# @`~_ժ22n5rYT8q=-OJ:G"Z& ;T|cVaِeP.pw Drbt`lv;E'v]D 7FӁoB瞝iũtM1#sj;=^,2b=H6JԲ\.H{a( <4I4p4`#Nb;JX],14[5y,5;p%RJ@ ͪ Z #T|/{~zOhߵmge1bڸ5u]?܈x6K >3T 8@@YlX[hӴ*Sps(2QVpq<^ &o )o _ M:^HtT)+;00ڹ7=o yl߶ ߚk]|סBH$}1v*cc׹D0$z00B()gmշ}^̜d#1M= F@ 1j)5Vd,ӃserR=Ύ.s{\PeEc `')@Wfs9BөclUcʲLD\{3νsiTJE#} (y_?G(0iKcì?f6Fơ擘DTt/n8t#m`53f}8^ CQ ^IbWx0;f"{ԜE״w " 1;P*t?7\"NRĢD݁.`q&`B.\Tn|"BXu-+~l6bK$1%@wr4f/XKo_z93^gF)qBE לy/ s.;k܀ 0hߵEE,d ne]fʋ\)k9b싌uf@w{7p"𧩡]!@hmfR  T^|S+6#Xrɐe ZМZ9N?J WR)gd1 ?%dv$J. Cd.N$88|t܆~Shbo}?p4Eޝ5P,U-l#Å܊-/=};ٚ܌(h4xK?zgtP1"bbE @ xg88vQ+/^\ríp=Mcf,ʌ&'e϶nBBEjh.DZZ(#ԂL:53#۔zƌU3G^|%\̹$!BV*O41Z*> H2CcZȲ \DSS ` k튽lZ.MQMJv |^}t7o6xuTDL5]1ERZE-c*ڱt8KQQ)n7_sQ#j$;itbd ]oJ={@  DoaڬxpnG Ԁ~ 91f}kl$Iz]hii95zs[8G.z#qD,ae@ Y;pDr4 !q$zh\$ѡV+8«`j~fy/4 2r".?w~g\p*:=aW@ ,ʐAޝMǍ"~? DZ HPQ2=QC"y)堶a,$IoDz!쇮#6k+AG5SӅ7NTo:h`ƜE5mG(2j/ihc}$m~@r{\h2bS}lA-Qe D@5J IP)4A ,Sg]A5H,u1FXkJk^2I [R\ W9^U NJse~ @  n.&{AS|Xw~ݻȠyvmU"]wPmmmZ98cy*"2u5XKMH7h94FFE(*v; ^,lvA9tL1 H t]Ǐ64򆋜p8H&&)ňp*y36F&1l j: !EYBȱ)!jrJw+Z=l*AȲόՊK y:)8LQ<ۉ9VKK:cbt| s/u|[j_Gt+R@ ]HRm1߃ 7_oq>sI \,`NI>(\Do}D40+cXji3ZCr`NZ ~/ezYKKҚcg9?ž7`kզ^J8g =y-9u{ZKp1t(@ xFI2oExAWU #t7o]Waw8ءZ!Dl! Zx/,I6:f2nPib>WQV$]a“.{U87KE pcƼ8 h4#ߋ^ա@ x̘:"5Їp$Fk8O>tWع5 :\n?\)x`#v_<Ξ.ТM`y򢷻"C6ĤZ#QvmH )<w_ W{J'¦4# Ӽɨ6RcZ@pCQ 5Qxmq$€1H |v>_zS &x c)h2:>We8_N?*zMexӉ"d@TK lji3b^.zmسc+r~J5@ kd 8qʹ9> t{vl*H@0 ˣ voat<нxLy>?\Z10\:SbO$/jO1 ^eLtw<gdzX0(v;7L_UU2ufR9ZћUsKTG'?<A-2PLzv9ˏuri1 ovҊGIjuzH-h4Ϳ2 Hcn_v{TN#PM9)j)n$p Cjjj76:0u\w~;ه9?CӐѶ8Kpچ+>RQ /`3h,&zX Equã?ؽu3 nnV1lX9s31KcS׽zl璤M`:1lEl<~Aèl0Jx!*#MDu{SӰFc! X &=ZhT$؇yǮĵ|s5>M磩Ut@W5,>n .f: 8=^RIr@ u}]`wi7}'Q<-=js8UU؝j\jʐ[n/@n{vMn|\,R)S!34O@?nrD ;n&v l5Xȡs.@ cAM)ˍh+s.SOw}_'~7 MatTb%7|3/Ew.ҥSg nm֞"J /< "ո SV%8=,Yu"' zT&ciFc_L] CQ  &88c6LiVZ=APj7Easء@UU^1=;ƫ/ ^g/yKGO'|-IT n@Z&CNÞa$J‘(55ogțBߙM1><UNu*U[ H|1d>N 6tzW oQ#f#s߇ f\*PESKT )@022}p<Ƨ=,N:"1?PkwD+#ˮIg]@4I?Ԩf*SG~my7F[йw6>0\nA5=uj3/ԒaG / Ƒ Cx@ #(!&e$댱a$jN P}@~]:$Af Ct"gYR/?=?6BOw$0Db)8«hk_w;&h)ޑHf4#1=ZzAbet:D/ZD!9b'\ۉ4N0yikn^~ok< x)x1َjUǚS7ݎO>n궷Y@ 8e2i\l3*֟w1#D"Bsk3R}Ss]"dz4fLHFPKƧ@t{_C5E7M(3k^10qMźw] @&9@;bcT `ĩ9؝d%,^>{~}P "yW4"Q\Qlor>׳F6q2|JM W+*&{zT_~FH EΑer&7@0 0c@up5Ł)5+t^O" R'{1s5LQ+<_ቇʵ'̋ƱǯC=V+C l=-AFS;_D5 2ՏG8Hc0 R4ֆ}o6> OaDV2"o߆iH%Qj)&tG^@ 2hUʥZ O=KO8no "j=RGk?i͘=;G5Z@JAG4 `/pSPW5蚊yKcڬ~ڦ78&;#T,m-Lo ZT8=f(JfRȦTxTf%f,r}BL ,rQ:Yx{\v9|^a4M@.<ZfGm! I`S)2tnčO<}Vlsu{kXȣ ~7x@Tzna$ @ ԨJev t"l2 ׾$(H6#]e)y$:N|T(mH3ջ;3Iq@ ʼn֌eYQP*ȨIcI4ۓ ㄉU$A %l6s8kÒoޘu](c/´ PF$2E/tUus{| oly>l})i3!Bd)eRH8\^/^})2mw Cݡ,\R׋O5PW~}[_AXDաwnf.v;p맾)3`+D@ G%ڦF6ubPl2N2dX$1҃vg3f/"V> :QU+ nA0눶awIX@cF>nD:yecqIR\)k$!XL&Isn-vĀdlH8X듃!+ cx'𕏽"-]_0L;[O j0YQ4goLjDԐϐs G7p8*r0' NKŵ 8 4ˢ43ϲ1ׅCw>tMNr̈́,SJˈUPT w[_154ϣ+^l*:I%dWMolAo'1c=KQT9 #ZӀK~5VoBImTOT=} =' 3O<#vPMyK΃"TshǓӚTTU(ˤi3N 8uh3H;oOn,#Ls]4%^wcUo^ޕ_};&{;{{0f'+xW埨`_S[1c=(%#d5Ah=B< SrQmǒnPmx?D+ @Cg'LĢ[l& =sPRp?w _(=wd?ͤt:\S#g2D.{}~(\4᯿9ڏ/3+H;.cEl6.B\4}PBt n ϺȜNRm_+V~# :`SxfB(41yaOAWӂ"V9WoMiZ{z(=y5TG2MZQ][GqۍC}C]t2:UA.`o:?w^& t!1cfI Ã}X/SUIDAT[r\pU4N`x<6j(WWӪ]?4]c|.?KC;gԉ:rhіJrp>~$G(^eZex߉`L%Px9l(Ce!"ev%nL&,c(N(2,+ ,ByTw`B=r)wNӺ+Lz š͗zQfU dIˢd:'8z?ζ4[L@0 J"ڋy::t125MӄGv<}8[)imFAaF+׼tE!3c1&ΎUUC.E|h زXf=#18rtniZJ%|Ax}I*LI$Jϥ%!~?}1 jp*|IXo j꛰reR㾧ikh*~wwiU5^Rġ>$)kވװaǩSc1*fIjW߲[KF_O'Z.`f5NlEЏǝunsНeI QJ?IuQ9]!όM';  !(ڒkѼp)A3 tP AHu]͜\{ňDJ&ӎTHu-۩ƌEc1f3Eq˦#PوW\Eۉx=^ߤqO*@(P]~l?ť [$"|^/`# ZWObǩDuMx?H ܄g\;IBRm&$eO-: e\.7"Z"UL &zv~]QÔOi}=H/{p!Pd9HUB <חlL]+]WF:@0Rk6aPBFwG+-piI-?} Թء$mH3VBiR]U.@%,tCK lTE ^FK3zlj|KKtuuhƣrc ųB3,TUC3ߴ8?%˂ şHeuG1og>/Lө tg;PGzp/7h,CW1|KW`$10~݄nJ:exV"c1LtbKW_h<>}N9陭()^H'xf#êuo (ĕ|O?Hy_u޻ Vcxl5^: :}2~Ms!Z׈PUI0F~TEI{s;|١RʧMӺ=NTdPd9|6 B\682$-]A\;X4My ^ Jc 9 `er]TM>)Q<\RJrrYji";vx/jb&Qk.tg~ǿ!M+Q1c4c xtcݰ഼i pxٷ -Rɣl6B!?XLeǨ*<_qoA07H o'x%sr}`:8e*>UHGp׏xՔ(,t:Wt옱Հx?=Hh.7]tyE\YByvYE 3|Flغw^to^'LCG21o2ćiH˂T_8z[Q][OAU%QG:]C_|ӻN'_nc1vvX)%/2hݫP[W;G_O?(-(nq}:gꊯ\PC,?z Z[_\V|zQVdR2[':M mh㦟IiGoCxۧo>YA26GpBI!M`P5 t:ڴѺZ{6%KJE)-g9t6KѪ[mioCO7<O2;@.D&dc_VEiك\}X bl1cSWd3I +7_z.%mǁPRDSaKfy&]k)wO5 >`2 *TLuM]xEQ U߁M!fY[Trdln"cL&phbk9db,Yx8Tθ$$W"߇u[.YRh?zAp2il%L`۰t:<| ɑaD["A;H%T/eͨmX_7,iM[ c1*ˉt]fMk^HU5=bt\ӳ~{Kqn,[ RF4'}(py4 RGU5wwc˶7f6ꜫJ4Sc}|x|aI[ x>ah(֢y!5QzYlq2)ؖe!\E&~ wX!iZ?M'C(J!ĔR.0]%\2!䳙8|SzһhljG(ĠDgs&Š ߃o|Qz'Xv0C.(/R2(9oc18;W /]mq!hB !4*qv= 5=\z ݠ90t?u8j]( 5XxC}|JpCaXR(rH !6G{; }]8qُ#h=LۉcqHć]aRj(4pV(dω}46ОHs_UY |kTw⊩>g :` \q5/8[TSpՏ)Dtuܤ_)5"]J&)-QA]\`hL81cv|u| [0 "Ӷ(׼=xF#CTLonUZ?ꛛ?Rb86W=Uo0Ӊ~zdbVe)jBhte9 u}<;>iIo$:-\B/TJC1hZE\k˥Lfh7g7_,eyuv506 EƐL&P|)N)nnñA޿+r}Y&+%,. k6]TrmAsp4cNx /,E!-b 麁^_ Wuw1cUK_*,[m.NW\)hv\ K%-#>̓l3- PxO]vhfb.ôLJFߏ}C3-m.n@V^),av(nLޓmg41wӖN%q=w2t'6~^!_P*'D"_88"`W !"S݇}>,Y ?[ٟR8juq RzꤦiefיXntT3FQf;MlxV]'9u-9c1vNR.X\|+qpn3I jŻpطk'߉ED˂%T\7 ʼn'0r n0ӋFW {[` \`8Iq;VJB!'#iz^}Uu.t)nnznBO< ‘06\2N軄Dm}#v= ŏh^g',\pBq$pj!yS݇}x뇪)XwNRn5T&D:|1Vm#8~ ]At{=mRX!H$12կ~>zwP8]'R N&2cJ"U5F}c#މNr*RZpT|KO;=s'Dp~Cq<'IQ1csTGaWP~x׽^/%*R-rEA*zPTnG>=چf생@O/]$\u]4 }R,Q d`jV6s<(H%XRڸtrߛ}.q 5bܞrg]/wfl8t8^ ] ucͨkj]095UT*e|FZ>kۡ4"PIEQl ?}x{?xl.O2c+ł-kx ?zmǎR3?[, P*gNt?EVaʵ/~mhRYE"Na5Ţkb,U][G+~zhC$-BJN$OMy'1N(26~MQSn%&- ^+imvQF!OE-º!=;!aN*RHwuM@O!h.7΍o1ch$JRU`W!N`f^mY<>>/ZDۡgвpxiWF RwnfDk㑿?9U9!KJD&608DRp8 rQF:]Ǐa5hZfKP#TƋvn럶ڑ=]h{eEw{-Ц6c1JKa5E/5ؿ)"%ЖEM`~ -sVTKX]t1\t9G:]Fg(6@v.u>iSTb$6D27%cLH]w#{v9c<)ξ c LCmS݃}0]'޻nyk7v;`{A|?ZFG:tucȗM_#4N&2cS|=mTuo7,]q>OaS p!W*gKQUTE%TPs9CJ D@8uv,n5,I/;Er'B<<)'~,!תDeÂDqƛg`iiN졔rOyQI7!Kه Fbx~9g=?}yWބ;MلP:;:lJM?IJ՛st@ Xc1; 0Q4=ݿ|>j(W,U# B tv{hxp{p=ԀPnd8L8>IE{uz!l&$eD!م}2`@W^UU*+>d0Dп?uM 4If2bĔw#|$XB?}b;@Q8a |Br#VV2wZхk?=,YǏ4 N&2c P5e=mk?u,;=n:thGJɊvھJKMDr$L* ե"ib46 ͈#?/e܊&"G1tV"Lkj]%%,ˤD}k?RIiR"UIUHU`trdb \*%A~N&2V|$twwa}R~,@M]=Z~^!NssM@C0Rn4oAͲO>@g{mVԷ,@W{+x4,f1c>;nU pA475PJU ;VlCAqM}VW%+QԂP$ SJHHK¹$_LfI<%n݊bR@SU-l|/Fs)eISi &/s'z:Q[PLfi; c E&ǔR~υ(h5۟a˱pJ JAKAT[0c2Nr1>v-onΰdET3c 9F>߉QwoQSe A͠o`^ok/ +mFCh i8㒒f[RG|6($G5>/$Gk.|GZvNJN,zH;a9xcHr^9#  1<͗]M lh&n/㏿!o2o;0T2޺;nV|k!ZSLd1cPlY&҉],⥯|oT UiR\f==_K^׽pކl_SSaNSX|Ͳ,x<^3g5csى~~Пچ:8n3)JMy'SpBɳB!ʛe@mP5\TbdV'Ϥ*[7 ZNmΎ.a>qӏQElN2{;c1vv*eRkвh~>  19E2aX|+n7C&F.dey46n̤iLC{j?I'Xvw|$cPdl H$t) /giDۡXa+[N%g]J ؿqvgͤTU檭P@WG[66`xW c1c')<5T\"r޳'Z[-ct-,_HQV}-iQWh2+cߌG#NdJ!) dJ1 EƦ<(=Ry> #߃ .C/̾vRRG }]4{C&;l?EӂEXc1΄f+Z#Tҫ_V .. RV6wVH `.[؍z:hɳGK;HC!tm_4 ,* 1V EƦ(J áyB>h;t/y=>;h]#VI܋FKGjpOg'-^C_=]ca1cR#T]m׼O<W-].7r v<r~?rٴ3/qbbiY\i]+NLȟ+xB˼o DɊ 1F8I׷]UTȾXl5/_T|'/˔Gk)7ݏFhkB3LOlzvw1c( 2쥯F$Fbx`iX}RJx>\ x #C}8E#2N v|j|PE\Tq|nMPr%Wad='+C:΅á؟F:Gx8Y\OѲ,a*wKDk|e_Q,uBuX{j:3cf\l[]+Wcϓ`VlpО];1uk/䲙prL_r)r{xpWþgvi[/N|bce"c呉Drw8z;xi?d< ;ZқeʤeY}G7[P$@8,?h恾|o%/yzۏ0`1cs(@O'X"ldڍcvqW콤r{{qht?6 'z&-vSGQTaƏߨ Cu+1@WW?rggƦ6`7M{+YQF_ƼUoy/ =o"_8^B<ž>RP؏)sy^ ?ۏO:)QTfյƒko ̇H*X2^z;NkliS?O j jh: <@WKI1g6ƯoD(R ]ܭw^A*=~Ӎ/Iؤ/غjoeg̼UϚ&?_GFüy̹+R |^ijdy{qkތXb !(gi3I=]ZIRoTJ&%BIg龒LCMgƓ/S zi {0\MU) WBUUZ#Œ1;;d#f摰tĭ% ԋ $œd[R~y,Xݰde#Z@2gXH|- >CMC}٫$wwvR2N1~L(4o+o **e-k Iٓ;~^%cB^0i0'8KBI '$(ѨoQ]U7ϧ$yETT`USϪ%1L3 i&ᐙG4Yy=6H b6GYI.MOh%+ Dl>x^(tK}̋', ˅yT/*^:l|?hFR@cӆ3Uмy-7 UbTD1߇K{bAN bt AzLXx f9$b#Pc#4yXhi.zcrĀC?m -I.ㅳ\t[}%Q .->.P\/4g9Qe2x䯸y4k\k({GqqB knn^(B`Xϱ.X~ {cq檪vQ3%T16_*РKk[ !qp]FcEV IÔťعEPI.-샂@w|?кc`;;/ΌM?N(26U7AZ QHW5TCڛY:qw;<,'Eo@B+O 4j>*c̈́4kdcfcdgK16 4 ZOX6Q\*mGf06pB_AE5p[5JBQ9 :bc@@hΦРz)ؤRcY.% tJ9J<ː B!gG!1 @9!@1)  µwv挕Oj86PbP(5$,,a3ƦGPqaGGG<͏:@c$@K; PpҐs(&bt+1!%i Q"0!ħ?^";n⪇4k*uªD- 2c ͚%[=K0ع*/-tYJvb0 Cr:؄ t6AHeB AXz?$OsvN"{}=.AQZh6CBC@d[jU/jwvA1!1f F'4:tv,cMR}ݐ臂niY]H{S٬gGr~I/$V@bhr 73aըhbWKIƠfzX16R@1=EI6#^#;bs6h8Cpc3=8v覛 _pfzPlpBq[/esPXqa+ng2W0&'MJ8THਞ@gzX1Ʀ@Rރ7fz(lfpYO_es}2t~6X*wT)&cl _@!: 7Ma&5a / 2Ӄ`1°Oۍ4mtcMI."XBa2ACV#ا;I#3Cb163=6s88 Pd9>~nP}Xwma5CdB Km32c! NJ4cI{릟XFOf2cϧâxC牌19@K0ONU]Ӻ,vc+ cBFQa[<5X@!2Ʀ 8aG~/cf16E9P2ӢL h UU'WҤŴ`ND%$`y5 54ULU(H = 9H䄂*:%4*62bao/Z=­4s3=NkI-z(C`THQڑ:KBA Pq۔q .ӄHYSbg*gϖ Cs~g 9ͻ4B )U&U>M`H>Ȩg188 !06찭6`:,ASG([0+pѤZV>wx XxS~R)DzNԺF(0X;SK L0YMhHBȤ" IE ) B`H1 XR"xA3/FO> wYfz(lXA͓Oǝ aל! ] ׍ύσׅa>Nq2081qBq2f:YVUb[bEFE#l !HC'M&X&z+?'LP )'m|h͐yxޖ?zH'Fsuv{\HhnhU}BAPpBJ hߓ ;1|`I\\H5q LH Қᰳ@aa`%hIԛ@e¦a탯`p:ܺ n@5}Ns<~?\-ͧyNS!'_ qZ (xc}/mo jۇ0|^> } paxmu,&\ D| bgLOcS~kVZThހ*Eawg{¸'w4 i%O :qx{ "-D(Axu޾s#s! q#!rcPscHsGSqDh8"^UCZ=نs ,sfzH͈czJB顰i` U 4cΒMT!݀ߴ3,, .CBcNzJ&aOlI֩O.&ᦐh{k&T|+ccxOy`c󥄖AyҐ 1RCOUn<g'z,gr ŹO1fg kø47Mf +yBTjN%ɪs_y{I=Mta9K'~'ӏIN3%'=Lt~/aec|cͪ<N[ygJ@f^$>x1A!b |XM4>6hnlK ?Ot$_2uLMjCb -t݄0fjZ[I4''xbrɯ %3T W#4>d:l KC2;2(`CJChgX\LMh'p\՝/~nZT-uRk_ !7 ` axƖJe8^),aOf3CB8@-@1KƤKX"G OQJ*R|-,%.Eؑ&׃R-#;oDV]@X `+]ZW-܉qY(ں~c%- ܄MB@ r<_m3Vc$AZ+(;KKp-S.S&(xp1ȃ3p &ָ҉ՙ IˣO>atɫg5|I]?†uf-B6x USdl_?G&扇U3[ ac۴L ^fi78t)SM\܂kN-spQǃs< 2Y%9eS ]v0F;1yYf F(n3'fܢ)̩?g#yP>XKxo/Z6 glUiF.mf˶DoXSOgq?&0NgIj̨ϐ؋? ީx0!b; 4 7YxXBcĜ+^ ]e Y\e]mxEfΡ6 dm"NzDE^9~2gVOUD@-uSS/*>q5. \\ƙbQ"&{6XAq峽+Ia?r? ?~b'u VٲR)D8ɩE'^5wxǎYͲR*KjmNL=pʏ'vsBN! 7žf6 p[ n:<{5m<%"ف(L)ae'֝gcWd:M^g )*G^Lcƥۆ*vOmc/Z,Zûoږt- $]e<( o{ zr']Y:xa \1d~݉bQ2u< ՔiU4 $5ɶE)&xiq%F/$r r7Z13$ 7φ|.PAԶ7PO,µ.\Jd #[L$M¢iB}};*dn Qg{%!*]ssbuᾢ_tۡiE =.LKrEY&KFVL,˂W{ n8#xkk DAʆb^-ꌍ7Rqdۢ{x  u h^'HJ%gVۡa, _\>?U^Z<ʊ< _XGvڽmmksHlaGaZ "v $gD|ZrKKgNgʯUJriX|IH[/{ɽcqxxo<؜)$]e9KaӻcK#pɑP)I/zIt-* u[ sDEg̕@;N2Glb]:ݝ0_ Y+(N9d"}˴pim>zւ?o"NucpFC3΋hcPLۊ漉C9q1b"m4v:jTTuD=Qc2&?w̹/6-_Z  w6ߚẙmsh11Pnḱ[cGOuܓ'0Ө㐔JYMע[z^BFXR_|}DE kD1)"*ybj& 7xWv.KσکGCL;VP I`-;;qFwbeM&whq:*_:=8SdEX"ap~Hl8^H8p| >=?<7m}pl g­ˇ| 3g;*&K8{-~q u\Ix98R1r'cD',͊V<)K BT_ 0NvTD;(EA<kudzٹԒ1XAq2V) ᓇ7WW  cNJE1CX!bFNiu_PEgHrE EնU-诸⊀S($@^sV.ٲ\1ƥl)lXI,uvv|GI:^܆w^|AuMVs*jjq+JrN۟zd$&RTꃦӬRKt#Ѵ簢`C9gᓯ>We:ĔcI9,dsg>7৛?*bȇT:d C*~j M:~˳tBL8|EX 0<.bb*DC""Bn\p};l>}s/]q\T:^>s::-}:ݍuwjARq>8)/R(^%k1JaQŭ/yXбoRl}Qx3@/ bHhԭM)xKcpN tdD5,&Wx pN& q NtJU #0H1'XN2܂ZDJTyX]+”(; \""3i~X nν,WKG~ȟ /)nh$DФ.|y hcmno=s^Yz"ӝH8G^r+DEdΫ/嶕TV89#*JS#53St9>cR\%O9/߸̤KRklr8 xdꉓۂUu*p܉HIUwX N7܋Gk+Oxb?ʸ|Eg"1q8EH4,"ӏ]E 7 |*+,XW_T|i x~twXi5bbƟ]]%C̟;$<8+DBƄŨ܊[WrҥEnMV hSM \*&Rd8a-ρyn"bJ$c h!o<0{`9a#D)$C=Q' qZH6 bA1wE\7!11WbHDDy<8;x! «hɶҢ".3$ WN7 L%ӸQ]xum['AEne{Dž?s^u!a|y.sʕCmC/%!,w+sS6 C֠B[`b(%_[lSo  ]½8ڕNXcu)^OXOm{ZKBMD22_D!@q,5h/(+r'2WT7לן޴(1q1q\DXypߟ3*_ Zu Ҡ]y!@\/osU+0:®l/Bӝ%Kw=亚͠Ȩ_E 0~\ŘZR[ُ(֠h`gwBpڝ ;t 9TBd~2Y'w= mWu+-ôc'.?mCu3wbo݉&c)c="1V[U nJ. ⬌n2 a11$DMe_>Ҁ}.]$C®΢ʶl vdpN [2EؘCb\+d';?6xuۆnw밯[K+< #F}\עhҭiFC;xXQsX6nQƣz82m}ۦإ+[9? zpy.ǢgPv8 )/z=]IgJ@2YI !܉ZbI^x D; dgJh\Dv%M kc5o,r;/E{Ʈ-c|&]łvꑧ#GI8(0>\YC 1v#*ǖ;0;tut"0Fslϥʦlx3ӯ.X҈ؕͦ$бVqD; O gFD)1+2wXxCO v% )`~{K,AqDvvꈉ4XGB~^Uw>p:%Zzs(y#_Z_"j\ Nצ{Rx#u>[%n/"(8~KNr+;FIF?4P-ed#б fVz8 =AvtN._[ZM?aw"8pJt݉تi`?L,N2݉Vgdm5qƲ8"I@-rNT@*E@yؓ<kDAzd`j5''ӥQSu)5>xsIb`u K1?wgiF݉YN|q!"s'"v4bu%r\yWDb-D؇g7#(vB\[QzeQQm9ޥP 7y=&p3@.Űd2?< wOy, _9qY#k Uwaxw"))1TƬ4NH)ХqŸI_ֶ* eW[>y90SHԣ,"uO(\ض-Kڹ݅g/5wWjE"mY"LR *z ZxkA3/)u)@_݂߼ɤK 4Ǿq<;9^C`s',ޝ#1zHQXpx`Do6NfCoqaxU]HDu!b92vCօVb5X,1X\;~u8cv-!QETQ)Ĵ8[>OK1 \Olc' I, ǿsGBs)G>F۝$/ w"0V>V9#VVgH[-gDn(8q(!QPZDr !/OE[bQC/fڃk=яER,B6,,brJP)wunA Q@.:cNNm|Z͌ӥhJO})ڣf`AN"ԡC癉B;;*Gu;Qۭ*)'aXwbYkD1CCRLdk-a\Jq#F(" DBQ;wً{%ޟz?|an#֜5]"6Xl̑Zi:ukSl@>P> x tN( >)j)⭵ I VXAqh$]ϟ=;tp'd_8C1yG,-?QWHW X ǭLra \ДG'ȅ0,Kzo<$]Ύ`@dt b|bnE8Iբ{ǶR R6"6\*y :X]/3W"BbHb!KٮSFRu=? O[Zh8LEF-qEF65Q .uLGyYVP"qp"sZb|(߳'`@yS{ρ?u߅;*/BJƌ5NĺXNLNu_7]61[J-5)Q b! ,]<hD ߿8 hQKd~AryDQעKҭ.*zXq8b]&FDŐcW꠵z'`AKq&CI1XbZ"z_uKӿC?AW,d5%N&q(jKC5(KeYX_kh[O݉1lwbD30FWbTB"…&>QXQb3\AغRQQ`tfZaH݊X2[;m4s rr1DE^JI*Uѝ2Sl ]PucȝXNA BH EUL>޿*b U1y?(ˏUr%2reQc-;?2!|w!O|ې3 -'ԭK ?Dj]JdyUcbc?8gD@D-gCbN=̚$u%"bh0fZ]+?[, $]/Ea^a@}" pqܮ2Qȯi``h):rj.|,VP :Dw ?Ee ]FqVEX‰j¢0[Q D=;Q&o1LGp5sn]!=I14ZVXAqbc9"3Ё\nwTwl0PǖU(&B EX0Bw%u#F@䙕 ̴\ŗy nrHFHy "'#p+@sD=È D_1^U3l~JuLK1yw)v(b-+(NI0iۿ$ߦ[q'@2ZWakk܉+<Zvf2LRT Uoq",+:cys yG!bA;Ųʯ NK 6 #~1H݊<[@y q6TC7=}֮TOSgQ4ip)&@ǜy<$hXҥL =rW,\b܅N%X͝Nd @Mה;_+BLTvF &21] !EECpm}Xv>#I'0X0K¢0Z !EEomY=mHRx; p5m6qQ ("'.j],d`'Xh9p`Oԛ 5wNuVY(ʴJ[]ȗmu.&2bmFԺ }qB'}'5ez铋pő,fFf#_'juw+bUՖni=:H"ЀwB0P;Yqp) R0l?>/2ƕ'u 7$28_@&7K'z/]C'5Db0*($n?H.pѱgngO5aIk{ǎ{;$?/ƸbXD׃gQ &b#s0r ;j:ѤTlWyv]bPIYtEJ=,:)Em6΋=+(N[Nr<Ӊ =R%7D -։ÙR 7;+lm銉#qqecyBUKQǟbۅ}$2,}! ш(2:C !݊|<~-AJ3+a1/*z5;Q&*Zb8&K苋ILu VPFѝ@/.%|wݙ)WhKϘh5ú+_Tdׇ#5āiA }M*&-&"V]DѕCoD o~ն.E䳽Ӆ7}ʀXh (G݉Kk-[KP6C: ĽVrBfp;ƺ]=ǿogp;.2^XAqZ'7.%M6\^"ǠiwVGH;1 V #|MerȀ+B0SvvD Z-*E!1l8X=fEr] {>-479B`8Ky 1<8!uȴ# ^*Fhjp)F LK1.ƹQ^[#&]F M_vBk2VPf>x2xokk^=ƍ(^˃S%TcTɝ%ï-)!{_p[o51;J۝J4!$FB$Ԉ`K2$]&sJ-,bBkB ej5h fߝlX FO!wĄw)?Y .y'wOeozof}YY,R8\sNܕt)i]E,۩2&HG L1BB(Pi#c;QPs`F!&kƋ*~>!1" )סǒbsOYHT¢[GPl 0q+\Ttf%+g rܑWkc]Q_RA'Ւ.!-߬Sdzh;ۀ.%I.sƈzƤRN~=r4Nbu'2.Dj"1r]oЈFKà+1 !1M!7?u ^zn<,S<5QaE +k#C)x5o|Q@ `+XVEh @KWuN>)5|q}:-!y:0X#!mw)d+m`j1-݉|S[bDߝ&F$荛H8/1 c( )7]cJec'AD"hh*)ni?SVwBoS#1G܂3.EQN,}EZ;Ջ%$VPsÇ=Σh1Ѐ yZc Ph@=~Lwb\Ý(}BGl@LnC]G,&*/bȕ8"z6,w;1agXUhJXĄ2<زsn[jm6.sF9ByR!}bY\}@&]F\4lRHUOsWd TeTvgn՝3Yp6N4ӎLx:n7Vg' %hol?фW.u.b1ƫ ضt29P+NF1(ֵ ,9DEV' _gdynv%I#ҥ#mM29w{&]F{!hŤˈy0$;4ӊ+-NcݹxN/t#e܉* ݉~ RάX1`[uۛ ."Ӈ.b1HpѹU0(,v+%q8A^Z[MKPRF.ʼnYŶ=r㏦:w߻ϷX bE f& 72wIsHp9\j8ڝE?!w"Bd N>_}8xd.Ѯ r]PVg7b"ř/!15^, O)\;O dg j9e($Njd3@J3ܲm[iCn]h.E,q7 e+ Qqpp# 5p܋A[Xt+EEqM\QX |N:H]xZy k)DOlN=]wt Q@ HcE nzt&Ɂt[*ZcR;e;1vg!:'ӻz>D~W+0zPs̝+q:DA65(Bb܉u~6F'6Eq#\jϛ1y_c\ 1񶹓S%Ju(BwKU$(!߿[Qb ?@ DER()MA_:Ғ>c$~xcO,)=,xӞcIawb+(Z\ᧁ.:TD{ Ts@ -aY}0DJpJeLVc0D5^-k-((p#ÌGON[`$5N 6biFE1nEA}ZJjoA0]mᝇI`zb+(Z:;g!^:j.rG*ݹ2΢<y.ŚB`8C˼7s$I+Ԡ4*&ԣJʍp KO1&XR Qacn}^KKZDԌFVԆ́oqsM8V hɮI6$mi4I&Ov܉2"n7$cZ1BLTqekV ?yY&Sn9fm#U.59EJ=#Oc[%&wb`(EkDL冖HXL¤H5~ {7W-\Db5@Vi ;ԒZ[CT~ejNQ{l#i} E&lMKq<>)+{o?> yޟ$]eE|v heᥧVBñr.B8o&zcY/*D눸2P.H"%{ ǘy?hJH4 "F%ym{/^nȁds@ffBEtNQ 4/>2=?Ephw_ګ/KQuqlXbt$=ȷf-r8F{KXAѢ IW B|s+ݹX/F`¡f }׀f,)zlN\dq'#',( BLĎզ,&C: %NŒB/&?:!a pfDEjûb9v1]X.E쀴 #lڶXx|-B2 =Z_?{a7%+yi;H`ElLa&Q!w -;D`id)DKL1!r&zSm 8o:DX'ɋ(@[owc!xL;2g8w9I.EL,l=1֝s%Vhx !2tY^ďF(Le'Q; Q_EݹlJU/\fhl踇#"&*`UcZ$4o}lYgX)e i0d<a\V/TdnEȇ7Y!WḑHfJ\ryK8ǐp c#u]++KXAѢ&tHC ,#1i,ԕ ab,5UcZN\.b)'MaձUDMV]Zbb BhQ |X+X°%q(egAËiƕ%Pyx_1ꢢWx.wLT .ZTF,ID]u1Y5!"/MaQ\ZD]W)!qRDD64I`Hu߭,*7[Q58 !r>q/Ƣ*4uRh\nO#R s:~29XAyv $ ͳm6S `Ym"120Piiiws'ZwlRoݙ,\F1:YE_R&zX!qEA[+=[%-Z_pf&)}Ǿ"Z '>_-1?k]&2T1lu1u)&fU5ˋ5]h+Œ KY, >ۓ.NM(sL)ȑRaLnt>XJeQoو; OJIsh1>"]B?al/Ƥ+JN. l?2( E&uE=hQ-w3;-mEDc-\_LdFR eqVmqM r!d_w* /CS,}ĺ#$_XtK7@h7.v%X+(ZsM{I"㒮Qu]Hed=OQ3myW܉S;18 |Dӭα-‚aWb0G"Վ]0H;K۠L;;[W/ ^?k[̶GZ0w}م%+.*nE2X_]町# [R*h> cLK73)RL#[f}}Œ VPqǛ&FTDJIc+zNLt :V'HVGcŤ;^O;Ci[b"611W/EuhqKཕ9W&Yxgx6RxNgV'uF\Ȍ* (O[T\q5ǶTZ٭?"^^wBDv) usgpN,w$]2&CVYDxOл]ꊑBgd 0 G0zLJWV$doy}"X;ʡOulb" q:&ͺVqVs'"&߫WY[ǙrG4 ߭ šWEp,N2OcuiZf |nF2;؍Đ!]DL2w95aO_&0~ʌ!Rv9pzg`;b .Aƥ Q,Ȣ$9Ǐ5#b\sz!l9۬qsjj.Q̛:1S$$N(Q^tkœJҫWWig3(d }FZ8H$* }]^'* P|]-L1Dנ5,:b) ߓZ<:=I`+s<y׏ 4hҹ87QwGcz۝à@I kNm)4*Tlu0(&2w\D@՝˖ !pӆK}7`8׫WR ZYRH6'%ja[!ڒ<g[ 菊I0;Q#KߍI!3NUyɿX&W=?2DhH kе0v2 0rcfJ#"vgp.2b `L݉ cN (&jQwg^lL`2I3$ x%\75RP;"1i՜KS 4ۙuЉ@XĐ՗Ky$iff}y(:KQ'@T.Eqh[[:ap)(W-D Dl@ɥ?ɖeF1Όp1Zq1DܨV0׼I\<i@H\ef K'fKg6]"Fz?M>s-D%˛u)4¢{M4NCTB|"ELrY?g{;!]\~:𹥱PGIڞ':SJHR}mh1y$ D6 \cl=8 a*gڝ)U @ `X@fœ8܉1TL3DXHD 9OvdIE^$* >9 EEA>iwBh.8?g_>&x a1+c"x=?HCߑS/(I`-FcI bgU62t!+))jk4vڝC?8#b,HL5nufր3 W Tt'd $kȡt=p*zx5vgd)bFˢb,NĴ: C#Q,$ ʐY餴)3xoe,~OV["b2N"Tnt݊ n#r}Nƥ-.s^7h{6$!=)u(vmy+(ZuS)(FV<򊨀M+( +bs $:E0 ˝R)xM D#Db1fQtl"!&@0ΌA S 1^ǭ8 * U{}ĝ(*YƱ5R4 u:@ u~C> =K;9VA1ۖ E ``BlLN+w&NA @mcJ'Ւ)W_"L^$N怸ZS &F$VӤ<_/ys&͛ qH $P2A nEW)XFJVMR][NQK.KZ/äfBRnRP\-`Ey(ٗt ANN@?(tʳQ)IqFx@BڱMq(b,s'PShubҶK)1iş^t I`;xdk0OgvV#jPXD'ZQ?C ;*:C: ú),Xg6H5]}bH1Rlzsz1bEK C ~EJ  (27TP%%-ΛFD~&]@l&3tb_1-$&- ʐGRy}ˊgl)2RA8LKѡ2Q.^1%WG\ TiT1.ڢz!] ]z]=96>mLܧO' ii:-Ӎ-^6Mq %HRɋݥY#]d" 0qV h+JNrDݻa^Dd5fH.~s.!ULCD\u~xg Ip8EEFQ#/R,31%Œe([L5ZN(ڞf {!2-D褬~BS hnh1/j3XP\8Z2]QE]E'ܦNRGשJSz5[e`bq"hVp\/Ul%2REx\1+>ϸ 㧿') Xڱ|瞿B7K\c ï/Ƃ'Kc=U/B͜)SJxV{Łqf9@"PB'rXaQ>2QQ=w"ۥ(lw>Mt)z@'Os@jI{-9D8|NoIP$b bi-@IJ՘C#;h_MG+B~R]^^ߍ\ݥjup/giT"WumIj8{O#""Fg|^Zeaqu?vm&DE{=NsMKѫ|QQAy9OY4&jw;PIn% $ F(Le= #‘-NƭCQX"rE$*{%!b_sfgu ď$&]Z8: ǖm/h%‰34"Z%uXA ; !z͑߅ljha}pjឨ W\r^GEZLt10H0G>JgZB -""I}c,,^[D&x_G0ؒCNp>Rb1! 3BT$'Вdy}/oUUWUWwOG3̟c8l8cd #[@|hX!aal0>NKuuuwu{^{D|2#c77}N婗Fdčo36DbZسu.&2(Bʪ5MShLhb%cD2/mAAQCy@ )"e"Sh"@u < ӗMۦ:N %"ՀTOۑ쭭9#mc`TDR=$%fcDm罵yP(?^1ވLQL.a>x-2 qc!CT }#*Ah#"D$DM?KtJ1G"gubX@MQ =_#a' )^n6<w\qq3y>O#yzjYLp[ a W`;sSi0ls }ƍ:QqԴ#)[!m2'Qؕotcǘtb2 Bȣv3PTUaײ4jڎB\796rmOH{}~~2(wbbm>bbWbl;f)6ʮM($o+r5c2Nj@*kmVL }bߨw'J`#*c[$<;KNEBm[ˆ.cD6ԇe1)L"ϐ_>^X67XYM~StG8@׻C1ђU@T&SĶhX\m;w yPHZq rx&ȃ.S/}{V !"gsu֏f3MqHR%cb%_sFFYy"`Ӷ tApA0((" m.#z5Ja(=JAGtxGȚX=:ʟ $QމC"&FBT "q26^T$DJ\bIl-pU"*N.3+"ܮelʹɍ /z@[b[LuسpL#t7e?bGȩM@(PPD10CPWUdT{'F$M\D"-xJDĭ*Uj5Bb6 {b-"btm%iР &d/ lEBDQ猏,-HxIlK"9NʮH7VYx! AYPPDB Ɬ@|!RIzķIp;gmٌ[JI3?qޕG^q)#BNjKёY^}㘦#'`KoC{xp0L(pF!qScxYs2",Flptlj4xG 3x'FIAa<} tiԯR;˜OvMmSQ '6#oD.V+cțP9}Nw("̄;MXl凔EhZ3c9r|)&ʆb`Fb{-7J dcQXvAh`kYC㾛+O[[-RT6}-n0(Ȓa2/0y5|s܅& nG")_^)rn6*՜!RZ%m]pU\ cc qQ" N7; ܸb,މ\ aTL xC"FyaѦ՝Pq"}IHb_[\)ރ1ފ[]Tp]:k)mc5|c/E%Yf6S$*ÞE}.-A-z 奥%#loJ#^OLRpgJ'LTX$b!z(84+Ɖ$1pn'5 TX{$y)x~*RdNSgg֑C} vq<:Q};_^Y{0X$ED=rR$eA1 ķJb[^)v!0b,쳳pwDYS-TJw.wb1ƾ_ aBFA]v#dn[\+-$ƈX˚!f "Wg6/E\)%\K1-D$gvzVt\H4ڝӾ,(-[upR z(}9e΢,2=,+H%BC־#TŲ+.&vgY:y#6 #..Q/}]~3r7j7Aǃ\=nBHD4+wlN$,`9I֏HXv%9i9N uNEmڦ^T*^ˤ(2~.$"@ZX.(,&(*~_\W,Z[p%!Rюᢪ.N!3JrE8R6b"(("_ʳR39ue~^UryM(Ұ5S%mXt: ZtL|K(Nڤ/:I}╘M SE(y.KلA5FaqGbXQ13:]8Ek2Eُ"!2>UB%<Vvu\(PPDe p+;Z kVKjžt8<.Ay֢B<sY6 y;'w,4 %&)!\/TE(yfUH*O~y2K9DFBpxMEBd){d NF!i"qyJjWbkR-ǃP5k4<{u+=aJ@b~Q (W<w x'n5Y;Q^Fמpg}{L2y'ꜩݘ;TyiVW )56c[Ꮷeù1צQɑ8CT@j5A?Rc>SxR6 Y&ĄHٰ"O69H;r#G;LQ @\R|moBHT*ED/qZ3wr>ZorJoszxb,;&І4B(W1#'W-32'BL,߭jK DB2flo d*p6lg!KT9yMo;[0;v20x)feb,Zž X W&1q#]D$(=G<ZH?kkGL $dJGd0YI܉\l!~ڇpg]މR< e2ۻcR"⏫?sҌ>#DNn(J~M[E|&*f,!A4{ı < e,pUvUMKWu_Fm4ɖn3Bb $"5sg65N4Ws oDk.;рe$_|tFE`ry~3ږȟxoAJZ5"r7^N i}DOnL1F/Ee.?']ζ[UyEYh4 ayN3N)> 3JPv> "H((" <hɲ4ntжBΖV Y  0,w쾊NCLdD(+uE٩NJ%7l,ފE,*F>CL#ڣCnm6"DiB.[[.n=#(剗@Q̝;N9[;$xPԪkp H$û0*tv "dS夛RdLKvz%bT".*l2T^"xGS^TTm?FQ[[vr#mvgL{@ô+ߡ N3S/,5f>#ضmT Q=#C8GݪZRHcf)pFbR}Dd1@L8ϊ"sXX#(&;O_m JM(o߉돳NUƱ唷پ !ޢv$x.nT -ӼK$x<]-+f doG.Hމ)&cV=b"  zjlɉ!HeN'C KXT&kMybåIy܈"MHHVE>~Qln*,g Z ^id/n"^PrDB1H&MԺ ]]RRV|$A8PPDB<7$g7,xQ/B܂kVmh NJZ~HS"tOjS6KNFg)q)2gZxbv2##Hk.&/b+Ta!<:MT,~3L.ݠ GBdY;,E!vi}j+ .ԎzN~Gb(("zq\[%u9r+b58`䝘#kNJvR7JÕMFQDb qPxd1׮n.\Li!X#  0 F}$*rS. Em'@BlFBB7 +/ƶSh5\ʹ[/(]MATPPD?tMU7Cq'0Lm230p]}t<(ZހY&?DbdBIm_)Jp{)^ƉT,^ldMSexEŸv] ^| z'c5eGDK|p)tP'@ۙQ_lt+#RQϣxPZxN@s   Ȋ,+ ;ү*۸Mۜ-Bx_̮vtAt#&a76 I:#, yC'g"$EBzI*Û29 u{+H"\+ 8UӖ6cGŐC14irA=jA4xFP4 qG*HqDcFI0nDɡΙN!1{'.*F7prWb )4 ML֙;}wa 75T((v4DBF(i9>w⛐mr( (A'A'?5ɭ YsJCO#@"5еpm*SUBL4t;^]2WPl[e8X Ʉ?N$Iay ɖC.ĩ6#M#l.]'4 #Lּˇ 6"74r0Ԕ|P"J} ?v\P)!f|m%ccFbbAaw|$Ȟ\/=aCf.Zqq#lY,a um͚+Ufdǁ"(.K($ˌwb IC69Rt>y&s'5 -zIފ,l=Sgnl2R{VR@zCvSh@V栠eIb#Dn:ܮfK*/6 [!S1׶փLQ "bl"cL ^ Yf6>[Ic%tJM 91B^h8>Dvכ=˩Y̽!;|w_Zݼ.$X6l `r(ȒB'w8C6!̟/&*lbb V5f2ODEDiv-lj-&e5kS(A;XCR(_Ʋ$XAE$G@.-6H`eH+Ze=~TC3?Qacknj-)6y'auN8gNsY&U՟å&18N?MkdBd)lB(XHgL %.+_׻@'6F2LgȤ4[.DDhBқt}Az!pD}!O$bV\,6D2gwm׀gFyŤVz')I(L^ex`~Y'MLwhiMFBqĴ識RX%3YBÅx }QʂAhM<kL fʅZCY>&zsWJd#*f }f/{P$l`bB=k 7*(("3}yʻ )ƒ=!u.21ULNȟh4Sa%+/0ƃ(4C<,(.r Z"X&RTN|s Ce cTO{x^C˗zyXSzMsgBU}"$p&?'tvy톃@l^h[R:ٟc eVIrf8T;)?^<=mEŘf15sb,w&p8LȔ/FfEȁJk(.؉h`{-W3dAAAɛbRs'x'btF% A4L[SY&0û6qTnozE{pfl_@6Рq6Hй@7ٗGDW&og/B)7Y Z7*ղ4XfsV, @!>54a:(h($f!AXd cj9Tj~܎;.56#nH"4 k$a&'-t4T-I= ^w-vIcYE"=syǛ(PPDťO O% o C bia/=y/os("S+VLA6Qd{{6݆z)*O=bYStQ B!CDa18a1lx;&UHp4P*q|_ ҜސgErK)3udpg {y`N uslDŶB7"Pչ=Ns|2 lGN遭bҢ滋)\tL//dhM6ɌYpYT̷ pj|s)Y`5l҄ԀT @!Hy%q%UCZ1 ȼT}W:~>}^ŶӶ𦲡v8cOkGDD9#:O;ET⥘ 6cxx~E4IB~C>//5 W.P[A t[-v/ER!bI.P'{k|bVwFDd^`\\boHèS۝p8q.)aLsr2~NHyX$՝=wTAl68rB$#C=m9TB4&( U>Ƕݖf ` qR`u cYJhP190GpTy Cj&!!3r':r%[0E䥘~w ҈p$B6j HEo.4vFlʙ) Fx!ĭKkmq:;dKOm V?4A0;u]ֳ?Q- !3
    d?$㇔+`U"iK1uWN5RCߓrZ=RBe(u:5"ȶaPFEFԛ@ͧS8k`o2.z HLwLnb6k'z:w:uy[ HZH)]=@A1 }YN4yCW^x'ck^B}~f ȎgX&^s7q=>GSxd =EYT^G VR6+]Bb*="8 Q_Փ;V ŸCs[Ϟ[0Abf#!Up X}`B$￿oPq>TTX y}8@cyl ϯ˸&}dsDTPxe7;T# R0~O_qA “*MyHƵ(;[8rD"b&TP|-Wb(("fC5]uXW@jf0 *0'2cKOU <|ƠpR-aߏ4O7-O<٣΋T?JeBb.NɆWzjɞ\kD+kIsj$w"a#|a^m&.S~W,KX~';8OD!$m=މ>Y'\ƛ4PPD'(:c L;Cy[ν sy} f ڟq P ao%s27)T ZV[ۓ_x]')xwT3M110i^ SH!+;;A ưdó =U7.d^R꺮"b(("fbY_;NC'tz!jƜn[DQ *|Xei^̣|$"ß2I}h]Y^zƘi6J)Pb"s_!B][_&ǹ) \|10/ve_yDs I޳W+HwSgk {9a|Lڿ4/\*E,K`5"!I)Әz )3$h:T^h;_*8PPDG~i ]} *Cj5f3 );Zw pd-gGŨX0ItgڌjtQ7^OK9`7QidNdϟH9w`x8PPDq_Ňx'1XELohAx0x1K¹}U]6C9M@4`~m *`G\R0Y~oIЎf|1o}=o3Mz|FA .ɫ[},PgJ #( t׾uzK_Df) J N, -3x,)mͱPSC2 0z)A3Am?TeB6_Z9$@ea`8sh{ gf1"!Bs <2~?o(!=@uAE 3b._>ѷoGG1Y <.vdI>u6hާG,d Oo3$ V5 kc~ XHeZуp'iDplҌ0䰥 C-uDd,/ ˮRJޞ{):(("&X+#a'3kIV8 x5 :ddT 2!ě+pSAc1_6ABbA\J ZkwZru'ۦ+oʹ+Ib֓Sb8$rDBM5RYZ<jjz[ȋ''pq B P|N8UXeUt^oD=E$H'4t3@' d3eۅ;o{Om3*5],+c13(^,ӣGw-*胟ok.x!RJ2*(ECbY@=iG(3su] ZjRm": }pp! ;/.|y1}}.c }c$γ i[lCڎF/$%jBm59 |PPDf}?zM7k5 ]"`N8 )"YTILSGU/'EU\TހNgwU%E یDFdm; 7 R)&:Cp֡umt` ]XﮁCo} n^f 64=y[P7W9Ry,N:0waz HSEF+P?7_L'?sK.11>$Fe6TGBB *"!$=Kg}y?o-оq jvoHJT~SK]EhvwūU>Hy/&EPBFHɖjl;q"vv5 AA=3o/m% z F 9VkAqݵz<,_ׯ+ՋpX a މ#F ^1hR)RʕMߵ`q~{޿{`VwC.G)lt`} xxM"07<ѫOcDE-EALL";%ycpfc NV;AÇ5z$*4!/_(("F"b47o6/^~V`;B'fL BTPs~r>wDڙEXqtdwb!96 P7Zׅ2\>w]:Og_KgOz;) 5#0>y[d$YV%~BP.x+nJní87jQ8p:z:%8-"zk0mۼ)0慿{o~߫Ч)!\筤1fcGiΜ& $9ܙg,]k` A!My}9x88jB^@A1VOl;zqXj }Mye (qO'mf3 <Nwރ$C(0kNcw}0osґpGf{.Jv Vo3ӯ/ξo`}e/ l¡eYVz q Hj^ ._}"hTaCG#>{v;繰r&t;@]wvՍZ ݇׮V̜'wbܺ'"މ`XjcڬBs)VÔ#dSmP) MUϝh yCn`gdPPDLmrꋫחٻKyg5@D'%=g΢I![v*kC׏-gr*B=XAe]{!c_W_zN>$q%q P*")eCV˶5D+:mј+`٥)nSh<<x~yp\ z-#}y @ܾ ՕS #=-(z@^ KX*\*G!] 4>bN~Y#XmߖqnOSK?ֵP^[?J^Wd"b<>^ylٻKy܇ F:~27PkT C+*aQebc v BQ]J}$|Yԟ~(ow|9r<鿂| Ex[Pz ۚc&&ƅ:G~ @D1VH˟&`t$Lmm1 З?Uk7y͛Iլ$WPPD^'^m "ndS 힦<9un^(b$_&~pٯUh4+A(ӄ:;s<ڥ9h4Cų>gx776`Mem< ]. pHd(1|ؐ,lmEM4s_7+јbA{qs>~SpS6E:TĦJ/64Zs>!x7}+|? `۷VwW_^V~a.ˡ+&Fy&{';1X"FHs.pn)lPZѼyb[?OϽK%rC)u(FLEPu_< +l {A8CJ>4!@T t]_ϼl7Zd!=dzѓ5g\9q~_k;hZ%Hm3DžQF{j:7axs׮A݀K"bY6,U2|x7@o k+A`%qKWBsίpW-ʣEo9Qa!S9|ΩߘF<3?cs+^u{v}؜~'V)zqjMj8+oLt&NPqQ`ELw<~B]Ea9jÌYAJz(xap+?#S;{p]^=Zݡިbt=>g¯ͫaDž|G'{2&yJn7=`Bei#8.*DOC76қaÄd%m/ɟ<sB|B`ΈѠpQ9{kjGy_:+CzNxHV&^&޸Yu&݊L3C;CRIF#\m7~π8Ăoo)$B՚=­W~w_}wIw;͹ k'BEm;aĿ'? (W{A(ˣ7AO( Yɛ)@:C ;VC L`*;OTͽg{W8jWfY9JEϣ.// H!XYY OOGOS0;1f^Ƅ;#"OSU. Cw$- $*>s4L@[if[VaρC`l6_߇cǎ@{n>f9.pU1O>DdCy]'(0XOu8b, (;!e'lcq[]z_ꯌD@B2xQ HQR2Ouf$AV11&" +N$*j5b!2BCxUMErI+$;oJFbRӌ=hF]PP\}G)PPD 㐫So:lTl-HM c! no:\7(wfJ<6\^[,'vGx\iΞa3y /~৾W?iطo70PJu+豓p*Zx{y~'~$xԁ=8_JO.kU'ĐWl11XBӖމq imLZ~'4h2 EðdgE#ұ`aaaNHP<]!PPD eYkF7+?ʿx hgM艺2(9 Jri6Չxd_Imw'+Þ֕e`[ }3>:y]yP*|2qX[] z 1n|BHBuO_7a#vdfE%_҄D{fNlE,W!:Nff۠>^OY8z*ƹ-H3[#n`T*UQ'QPD Ha|<^{YOſ.mz۞sض(6g"۳>/rS/`8 !& b;uvfh/;b'ܙN[P:7BORT(z* 񠠈>DSZ:~R/{~{܉EƐͳxvF2aڼU}|XzQՃ:O|ӏ>h[EWp8 DA5a0meױ.\*CRzj5j8a׃ 讯.xH}h/~~r{S1[R0(JF5Bc}i"gIۊHugd3;QF3 )J!1Y,DE2oB q/|By)CJ (m^*_qʾyME=-Sδ >'ivr yEjnE4f3$ǿ~nf2,m~| TLe۰1xK ? n^w9edMnTfqjY@, lۆJeU.mFy.˕+eP*.٣w{q8Dqc ~~Nu5p`>?#?М[nMq?p>0x5s{x= aW&`YYU2r0 ^!BZDs0iv$E0tLq}W+v ]X~,;rX0~?{{ H-tM ||滛g zNju eɌ  B ]YTm[mkaT#Ln(a+,T'Z97֢@ &~,_C Fg`8] r4U*%(+P֠\bb9 푷E,l JR /¨cCf[}{C{-nKC Z7-˚hZu@Tܷw|:&g?0m^Uh]EEs2MHZ&9yKL3މs0}wMQ̌kk0 Bd |n=iW^?k#PReYBqҥCv$D)(("EV^?됍^kJ;{-,Jȉa)bqB- H}}@-@ah@U)?k7K,2x'zW.]wmU8T.CՂF zzXIDATp$~@= i^oB⦇6mIMN@_{vձ'eZ?Ya׮=pY_Y-oZug?k2iҘqKR=ښNEB%Ѩzc !dSI;S7id-+Jm]8& qOv ^y ؿwh5#?) (("uɕ'/wUy_/~TM ,k ſFp-c饜!XeK gNn bF#Ĕknc w;џ<5!bPK(Mxn|mXwsC] >?IwpJLk58?fcTbSl bڵ+ uF,RBqqp`w{nx`B&!T^pPmdg'܁+N I"㬘FRu`bjClAġ@Cu&( uИQV$/ﷵ%v\OS[D n ׯwGj/^eO +p6zk7v%Tj~NiU[4s[;3 }!q}KVEEML>x5 s|` μz>ۿZy3P6B0?7w;s/>t87LVq#j,aj>U]Ƕ#Í7Pjoqot 6x; KKK:ٷNzُAkn!`s^ ?"Dh(Йprvaj2KT 'N#N4Wռ)zTY".~o`n-/yؐj (EJ+WhzNO41 >u'i E0v&*$o3f+eAbZQ<*OOxRj|~\%a›U{=ǏÞ{"d,2:^B^ jUHT9O< ?<3ēO=.\^o4oaP%X-\;u]{ #O,.9b+ ssp=cw|`0VᴹѬBf8=ض'N'OBqKsO>])B1qz{nx~;oˍ )aО®{ӏbv?b.G@eHA2lyHReaYމ Ac7s3+yC wffdȶ(vSzZ0/_,* H!rM'xS ~|y@Y`5ZgdNL@1r= L/E!SDTO8({N̒T*mʧ:k(x0j|18~ q@H"\x-,,O$*+Z n,/Fc[dШqyyzcCш1巷,sa{=z4dO4/UR>c`ٯkyR'z~dK "!cV@w" <;CaY= O,>;C*6zv^}3>j5>7ӯ\t$D (("Eţ>gu;j ã?Px &l13ӖZ֤<@$# )J)|{f%XGJMup~Zmpƹs/ݽ< DJeXX:F@N'xx{F4 ٳg7nb]x 6?[]] <[;`,XVk6sr&إrv?F 9bX /B}ov|iA1ڋqމ~OEق,'z'ex%69+]\ "(G€"Rd.7;/vR'̓HV]ލu3Nȼn7caWFTd:7aߍQq)|Va9t4\p׷:oy y";0$PZ"h;<ڔ*dz'0?8BU  [9ǧʐ'7ITy<,\zN.w8}h 0feT@koReoׂ-/+Ҽ!nEBB\#JK5reMֲ#9i=%x"l )^ƒzLd;eڡn[nॺŏ} ͺpeBȗ/^\&0 HRJW;7kb (b۴-V;$j8^ z&>З 8l/E#8.1P݆wb މA?Ύ)E+iՋ\$[.a 6-tOHp `B&!$Ԁ'`cd[y?s^iiz~s洙;{wex ^VTuJfǒBaI,"̢/CZ !Bv؁`R[`'xxa$bJrB[lA4aҲ8R -8zuh=ZيLɩXF@;k%xD`jֶkup4 Kuowmvs(u7+ԄwnҾѤȦ?r]]v 78WZ#(Z*ˇ)ks׮EJ!׺;X/eIN) nuZg:vrn",1'Ì5KG~5}[R<R[_ c'2ΒP,  k}H)(Bb)ϣͲWG \&\ P1 Ngeu=*ٟRW!m?6,= k)#qvݵJ)N7$+^*&f@"NեhK*'貲Qi〫BRҪ'D׊vvڭjny9vYlhGYE⃏yv'9tĉ9rl@Պ'7e9s&e0]V17&řvwn )wg;.LLqݞX).~VCE8aȌ(5qUL@XdIf}D(dpv!$x=X;:%|)D",yw3EDz6+k'ՊX$I *uY(Dz#_-ulEw :i 6aPE &NZiݹ\e3Ȍ;h^SnZٚԉ\'~FN 5!3#ʕV ?z6{j$1횬Eq@891iFw҄(ǎd-ʶnv+8g\\Rp֎EXDD]j*SԒ+`bBÎ։Vbٸ,Vkq}%Y8?ÏEc谛ݙ+WM ]x}$辦| E}oƴ\x!.2gS{dMwg3Lj7XI6QPj5+er*6,'z=ʚi@ʀJD|၀TY49iDEe@AU;9sAOORηC*(k}$n r*ߠp?ǁ 8|M9k@H,J֡r"D0Qi77NTNi҉_c'6]ZqoZuV<I<Xk29E?<+dur2؄'"}5_͞Lö\'!0''"\YQ(:lRlZ`sQқÛ[M:^T*ϱ$V dYf>Yn&GdUb6˲8:LB!reP I!ZE" Bk8!x}+ߛ›˪"8d0@DhĪT€U"c<'\NW5>d.^귳h-2wgnͲ(s؍T#yzb] &xL(#ޏL)C';69W,(Z *QJR@sYSSbͮaLwΟ94W}bsrbnfh*Z?m t*?m gf ]N !k_7|Z'\r9C![RʬA\ә YڹSJɤ=D A&eKrZuがu ",+ yfa".%Zι?SƵܝP@Jm$w><_+9ٝSyf2;RYvݝ]l@ժq>TSƻx)zgQ7).n. s˶d๪:NJd[+׶_P J"]pˁ-6X?̀ ye}% b%hq(V6R[(0ׇ^2?/ޯrVIR' ek7ap]':*;PYr-|$O@v;f:sj_KR9ej}'4׃N:Nd:휶N4O`dN]6ְMOmy9$#{F58>9e&;d\j\j(=D)Yٞ2bMˈQY3ԍ2K*rjūV>7*֊۳&=kBgܚ"}Ckx~BYf"^"X*,5E"܋s'J"tm-:Fe߱YQ *Vpюf''2>W y=z?z׬Cv?5k}\q v[PpxoU*h1q 2i$ #$v&ڑ&a^hގuM+CZ`J[@@`jq?./FN|cʕVʿ?H9/{>b-|ΣD̚UɰF΍kF&ܨk@N|!SMF4@ ^_́[+޿)[$nrVk Ͳ#Be;]}-("f春 \ xzŐTy`}= T?6>77=ÈvvRԸ\ҏzLAT~ԥ @$lm=g, YhrԎ79uꁬ%։MZ\M?nwzCk{܋>sZsx)E1h~D)slljVXz:3M޲#ax^X~0t8bcz7dgJ״5ey7JѺjEU !d]olFA6DWmڎrh@FGGQ*UXs( U8\ ƶ@؅}ʹT>CG0j'v1Dk!<~~w^07= ?<*קrRoډ|_fX5݇z.K۳εLČδb'ρwz5HUQj/F}M9&"O=3sXUVFF&#|@սAfRvK;יwXeV X7hg{ eZЖ۳qm"Y_>w&R=npO,vtb .,-ObFRfIL1:6,u}XL•dXPFsn!VbY]$!cltY ײ,ch8_*n~K^Y0(שrJ/>+tzB|sq^\"x@~0ђ1U]Y S։vܝu2T^3LZ-6A",a,&_6mďoGWW։rA&U EWM%JqxxRoʀ_,Đٵ#eZ(AeOlǥj^FIZ be1՗J <6/k]xpxsY/@uG0u‘0$v\$|^L̰Q<ϣT*!ɬ8+r,wl b"edY۶!8~t8i(-ZE|n_ػn3=>Cy{TWnC/S#U9) kZhX$BJ %։U-qw% ; bo'ϭv7G5'dS(CgY7Ԕ#sZYQW Hs[y74>8: 3*7Imt 4S ܌wvx:;WۤLTۈzx~[C[P9nmtwYOLSa9]0EW^B6n c׹I,3kXgnwҩy.8D"QIF -KFbGR8) INb(9"sv6 ǟ|3:e |8 T dIddxAN`nOM~UE4.zTSU4A6{AihU&BYivZNeyhZsffNf¤巰3wVN=f뙭kz;v~o 3 JN869WZ((Zurh4N_y O '-[۪4P zTZփhp4\,֩ V Jy 40)gpmiֆTT{yC,4(pwV?Bw 'F/|K±Ǭxg1L  2Ub,!yk;[9'P}} s&~?p9`l+]ϋytvu"{~<;vȒRս|[=ܗFJ.b,.K)H`Zui"0HTN`5`MÑs2GK MsNa)~b3Ψ:fꙭk#AXӯ|]~GB?@˳(*IN~>qܑ 8-s!h}hjW3.>輝Kbh#Zט8tu;IRz˄FA:F[߬׏h#_PK>>fx/oGj[p4 ҏAY*#H$ls*}J%fIJPr9y%#ɰ{Q8(?lϪ\* 7 Gf֨jr*o+dF|tRK@&bYj'`$bA"Zi [ ;Xw_Ǝ3li.וq<O:>yJ{8U+W h'6ZmŅU,TU/1KV,y;A:Kc{ =(fimg~Ø~In\ۍ4T4yCUKs74tz߇=$I̍H2KħpD(e1Sy}2=x"Bxr<k@EX+2+@cV333xr>V&b[Y^K%7C">ObCϕW[#WO…Huyp`M=`QKeh. Z.;M؎i0AmO4+i)#P].J>tv_~yb1Lڢ+IˑIr&r*J? HؔQ㫁48mr @^>X1h8O-8J[㶫b#L r0Nx[Lp@"I*bp&;4ny[|[,^2?{=#aL$H8sCa01HC6kJVg+Ē D(w>ǘ9 PX[%*{!I+Ri+0 Z%υj4&j&coS͸;[{aBu:դ|/G͹~kbbcs EWVyR,!ГMzr 5nآtU#~h]Annpg砢qhg{!G4ׅ6 Y~,%p}k_=oz{OjRuǎb|bY)zDـgL1(zXj#8v8dيݨ9lssDQhk(WPd=(XB'X6RR ^kܾpߎ{n!֬ 0r$Qr=+u+uiKRu%RA:=ƀ]h" SXU։Z㵋šEwg. =ݞ";=M.G^QߏȤ\j#@ժ!=z&91ִqkEoj_4h6mÌ6Vz:ܾ[lvR Tt,<;/؄ߺl)s/?׾W-F!,[!J) (gqadX|FDaX(20P;$5r0fC9GTU,`frȟU ۀp)_VnU9 ʗ+@bU,KDCuw6։Fښ aCZzdYخm-6wR:/ S;ȕqʤ'$YFmMYɃ׋sK %7]mJfkopz@ڷ{IݦJDdۍW{>kcQY[{9iaFgmG4i|xZ|zYp-^h#$KgpwWžR\OsH$ |afAX*J|Sb1zbd>82 ssv*rfA*i`8J@0t2?ՐJed)B%~bAJ_P͎NiJ5{Ȳoiv(-ġ6 \ǍPV|<7^kLS։['j5crn1[Ҧo򵤅:Vlf~YK}''\\.Wplr\\jUy@% 05{9AS^\2  @=ifҖ"^ l˙4(P41-׏94:ɳ]eH84"V\_C jCpS_MjMxdg_-.ޥrŏDWW"s/nUX.o!gVzAOY,=TP,P,Ab5Z.\}8TfLJOMK Dq(fg "~o"9_ x)dl:}en'[c%H'^8=,Dʐ*s]R.Rs&mss{[։:g-ٯnilȾMӨ}v,F\u]Eh 5Y}6xl;SJߧήV\jU* nBX4p"ːa׭iOH3XYs*e\׀"ۚJ43 J6u΃&׿8UȾ3rN%^|\tv*Z 7[c3hE$/}ݸAIjU! BY%RIp  A=([NJʏr|;XN$ 9z68Js 省m7LMM,fSX{4g3xa!&2Q0֍7M"(C-9U=!aXu,{PjG))5OՁ`ŵ0R% B9ׁv]];S:,O:7c` usP[ko?yX;2T>d̡]ZrUh4 $)d۴9">S}`u--C4QB*PeiZ.C61G3gL|hMXr/ z ^]PE(rmvI E* ‡߅_}2c5.a3-VL$Ȥ="A?xt UT*3(Iդ-`u1 #X,?򽘘aq):}^|88;8}.*fX,K8TJ9>QBoU,kN<="KpUT4u{N4;tw-7ؿagsO';YL=u9/Y}X'* ʶ)e|o||N͕v ]JáK !BN? 6B5 ^333xqȔ2dWW3sxǟH3H$S|% 7՗Ů[f3d JQ*~.{e2(*n;=1ܕGN7pc5",J@!' Ө@). ?_+au"4;ezoݺVRns+w'Zo)MʼntWb'玠?>'IStzܙr~rUh4r-!x!@%vh<{)3be(*L 4,K7k23P6"4kUNFY8L>V;AMTQk*ܾ ԼEۉuyCe @|}}= IDRK3,uT/D|~f'[H,S< " |yA`bYN2;XߏT:Ηpc#(%LNL.g>v%#2r<۷lK>t>Ȁs@\.GC8 ˦E1yqoa1H gNOcx;箇젵]+kMBz7o| ,b#X<?~[M;v!I2 Ny5b=xE%"pLA P_NxB荭،Dz‘d,zZXU?h684_8's"c}2Jqln\\jU*rZm9TPزisyH͹QpiKmq8abCNje ͂Ƭs,fq= jk!+ŦCE,ͩNϼZ(]uE9>q&],n_x :;",0Q2wK^2lX?}abj)7JK-ӈHg2(K, K\I%iX,/RT~ȢjlN,EA`urrsavvY#z^ˏF4;ǚ^|™mǯeT PY+ض yG`V"t: 'î=ht]7O 2!5҅7OгFb(:s)Џ45Q ayX'-o`|ؖ Y^{0&<[xOP#r媍EWQ$  v 3H]rޢ$Ǜ|v5;-'4VJkq(imX*I'm\ ]ZWR9``&e]f8Y}Vm/E`Q)xnl\K1dMŵX3 'W@ r &VTPD&e=p;0O#-q OBฆ"jFhYd'I3|(0$;img.RY%Rg7J\WEA`\;G73;Ǐ㹃q R Q08:"a_݃F˲q>r"2,v: /l/f0Wp?@8C?~]rBN/xɕm]E9x?n8q,F\*rBkDICN& a42Zhd,>'YEԅ/l[jkIzu)3OR͕6 ]:uttDEDŽ@uU˕ʐ:( 4mNwrD*PɸY|Geۤe!$M%AcL# (;`y#6Q\4؟xEyuhfy%q{gzvN2?3L)ee6о I,;ҙ {Kk)Bf_._@_7ر#8v| 3h;Ţ|r9$S)SdBdLCXhp"VAbG9*TsXfI\<7Nc|rAGĉQ$l4@|Y~c^CGOϥji?8 vv/x1S ^عk7oَ|. lvex 30Ǐcj-&*Hd{|~Κzzr&jft^$9X atma|swnuD[ YL@G;.c }.š#'XK0qS*1Ob ,NOg@뵟G9ϑHc8q\pŵc,&e(WBJ8JjOn N^UNѵ a仼 0QO#0%Xڛ VMf"~b|a<lny[}PJʷRG+Wm.(Zu r0=CpǺbP *h. TũmDkIM-z3Mi%bנeNITf,ׅ^恥 gt?&PdW"ػgtV4(MX~3x_9rNG,ycL^y)^k8} KZ<ؾk16>)p̢PQMO*iA`vrr>_C輳L,JĪ8@*q׭c#x\:y*C>h9 .1rY yd 9vLV$݌G_ǂ @]1E9y}؁5dX%XDFSMC?^zf vG*A*u/~r.\|gP)x|^xDϔB=P'ymgò>9DeZͿqYZA8{ ekeX`X@D։jerc3jwg3m;hh]pHvKWy4O&G+W+@paE'gs&yOp0 |rbNs^[E\odw84P.59~h'yd-x0 ,2A:V"8X,xnl6k,Iˆv[Y~7՟ ,G2/_{DoW'.8:2G2L,# "Hӏ«^hGu;Jz<7܍WM$/D57`"W?Y;kq> D5Tzh fׅmfC}v6jL#:j}s|yd8zn'Șky'(Zu ï8b(3Q$?ED*2zV궜][$P$XH\9]- ϪŔ4mέF&u83;zLmh}B"?SK.̵ûL9e֬܁~N*8L3+ʗ\ɬ S,YlZxq2~k"܉,mF|#nRӳrkbǪwK2z;kVtv053)2e`QJDY02:\W_w5 =ŲL$skER$zpឳ#OᣈFöxr<¶F:9B6Ӹ0'iZ <TVٹ%#·8du=Ph8BL%5!ab8ٹ։&cYqnDG(ڈqOsc=t=ɩdMcj ]6y;h"ϡeCcgVY%WH/LKn4ͤkg䟥Ko|G۶v涕6:'+F(4Q2ПnvrC336Z T\ǿgyl%| ~s fX׾%M HX8}f64gf۵c_G A033Yl4On-e.S3s ZqAwR *x p,ώR ߇G_Q2(9/&k^`. |bO# $ iyfXD~4-+fy3b3>ܝA|m0`q >x4+I郎M̕$(ZUE Yc8>E{dӯn S>|+MZW'=(woڶN3PsYɸt='2V|Z߿RA Z*ht̚ꎁEg)l^˃kM:гQd)ttuVU|3s8曮c/Hh&u[TB\F$۷b˦,K==+*E9\##c7z? d9ffK4gO}lܰy7^-Bm Ӄ=^c>C cbGAΖr ' Q bK?; 봭)SN=:btˀ&)3 D O:f;޿>CX똁V8 TgK![}8!!NoMU$"1?oww٩ y^w=:cQn5ړV_e-S%8Xv_M2+Yl8X'gd½{ُox L" g=U\e$4~쎻{Y;x8ziJt T.cc$tz8~;;5*byf12ɀ45dtPzjêFf[9z>ݹ$5;9Vc;?Q9 (v>mϨRJe~6J?\ZarUp8Մ~qT36Nq(\Q?󠅜)@%ca7`(I%i!>Tob\VlbZ*(ׅOд/'X)kt9MB :D5אRp k|_A@(lՙ4B?W`}͂Vq$IB\fwkXd9e^M19CX<% mی ?y ׭aǝdY|vM%dy\|޹}>H$lcJ1z|@pկD&`V!B&@Omĵ L*uh.9quh+:ђŠU`h1͸;ܿ'~QwǑ|߸D9|'L=\ZyrUh4|@#F@dA@q$ f&Z}lЀ`Dmx};:͵ݯmr(IS lF4=DWyJ]Ta':sj%VEk !&b## 49㳢[nQC0fmjjm ^u`^ ()LdT32 `tʜzi&p̉ k Pd&ݎPQB X<nEI+b^6R a@?WFx-[1S.#+^|9rOex,1;}3:c(J#ɰcano ]sx՗u7\^ptb'+NIo6GOWvlހq7r>-RQ`nj\ |l(c=@8=Q+ h*`"ʐj^>y h&lNZ's`Թ6yitwg'αZx߃KXג\6ƋERT*}rEWJH*BcfnL$-=x> &`WܝO>tYvb yb#P<4Hu4V j(wi&ф:-Fh1n/ܻI}nB8<eT_ҧ0~z%Yo|9~Kیw1KBBXm߂]mŦk Q1O0WSJ*Oq\e \%Uyضi.p"qΙ;c\@bq ;mf'WP1y<:Ͼv4J"8XZViJF9ٗF=ժ-NRohikp<ŕ |\~6̵Le>nb:Q"}?CWovss}/-0536j(’9 `qش~-::" ^2YsT.n\ ;W^\qp.lBog2JlDBew0{itvlY)r<<W|PYqJmO1NC*j?u`aĥI@ĆM\(׃`3t!>Ql>0m~t]S։UK&S?qCWVOL\j`\.AIN̰ӷgm8 o9oܔRhA6«Jg|3RօCh:\Kk?cgik1cpzm{=SPQh"0079t8&*zGd ֿ8=^3m|pkErB_t;;`g@,ݓ,y2gχs~4F'1:6IMLz|A>yg0%vG59 Yz/X*-[)eT,p<`5c?Aow'B<^@Ł( -=J9BH7ǞB<@,l]E_/ؼc2$7@N5F`xL1 k1r f2 -U xe*K^R^\w;Zݤxr{^۟|=ݐm:S R^u);|-]jQ_!0KYd:fqLM1xD K@St{%x{ utDс类#B!x="Dg~Y(Q,,[{.%ffgN |p,ݢNj٩smؾkB(Jʹ, qyf1nfE m#1yp$ԫdvnL4k٧ %su֒P$ciW m gw7 {]xԺ_r ]ٝR@Pohȍ<0p9*/̧ Q흺eC9eG8Z. FCPl%Y).yF>6pZqۋnk;8,f)$ȦS|%kVY-J Ԋز2_( W('/6aYKEds0˱"9e;_,2-)ʒ #+D$ ' ! x# xD6J,yP;e^_xva[;Y!|ΟůzQ,Q.lx7n's,|*AeLMYV}F`>0.[5։j4RV,% h{W^a? H/:99>&\5Q.PtjJQ2 |>?ބo<5s_L.$!-wgC؄Ty/dj_\UV&΋!$Cϡ>`;RB{'iXJRsBDwO*Rdy}v.ͫYX"Lτ0笔gPRΩ ,qґ,/X+2=aEA+V x<%%ĵW]i떱,7/P#1;P$@0ܡYHtAh_۝vb_쬋s 99XT>;DkhhޢF;[׈U nzF헍 &kjը\:"RP} ˦߉ޟqsjg_5h˲d#ˋl˖ml&,LHBr@rܐo! `l x-Ydgzzni4fq[RW9N='bXxmƝ{Z؁y7Ta5Ͻc*olΚTa(:6ǥh=Ϧܦr*}A\euz]!Ȋ{ ?!܉:v]t>122@!!Eɻ fGrAg!n܅.Qd]^; y !WܩC._Yc4s1f2Yc)uxh֔d*7ᩧtt^lʥ<${}:ò P7K So cOB11[V·<σ:SR/)G}aφb.Sfr)飬e6>ՠɌBl㴰MxKZ͸NN.ӍG ӳXte\T2p KvlC:fnFYfl&%W> E#KL<~M`a>Y`FXͪT=U"\.̥y6lۺ ?8}LRx ݯ "dAD2G"O7q fmT+mB"82w-b"II܎Pg#0-փ;⹩Bǩq>wPJ@{Q8sEeҊrX M˂xvf6QUr-\-xH*Ȑ3w"+m.҆^M0lmK< oks~?o56#t>[;,¶"mPBv: pte }O=|tE\wl< یNLLN5q9䩼>æuظv+نp~„Fq ͪr"D2:JHgAiTWMwCÒJ nYYSawó\ݯ0>2 _ MSYU͞zqւv*򙬠i`_NssmszUPgCbXu~Uu'] fmxU6N8|>$l>|?aQfQGPtX8ÒOfT9:8^M臿 ZWcu&+:)PPU*.h8=M#HeR\ŖoK{}ֺv0!*.rQy]k.c,ωzBeȳ5؏`8|VXQݗLX7lֲI Bb,`bFOg+90{Fa:aaddK/ gjwĥlú5by+ËG*|nF,*Uvλx͵Ek-t'EU܉pW'Sۚ.r1že+mj$h6e1wmL[VžͺBEERyK]>\pZqD|!>va?(ƆG(޳8֯ĊNwĶ)b8puhetL&/Ry`PJJeӉ-1AlH? L<+>?{D@8 Z=uBgW^l]/SeJ3Gԣх7[Tbu]B,Tk2ib, viZ;4+]'!tU[MU_eg NUB$x|nlljó  jG6L wb]=#W޶gR4LC-7aJTV\z۷l.L<ⳳxG Qo (cYUC(*ʎ*3~U\x6h"2a62C-\R4ZL&bu>'6?D c&,|i(Wtcpe/l}̪s""J!͚5j:!l={cRh zfFssr G64>2? Mƶ9xU Z e!H aakR\SUM|ƺ }.ѾQ豀vmZGX nPzNoRJY/>'!yUU5P9B`UX3(J!9,;AKskVTYE'GE"-qӏ-(܋l3i ̿bw cW5XPg;N\t@%ֳY,4r]<ܹmL&DC,^"bD?$n n\'F ;$\nYnVQt,Q{QPdlnBU'ʗgQ-#bbCMPwZ_#jԿcBp6l?õ#Z}?%vpw6pp0i>J1=s.B۷|> =)-䴧إ3d~+\,KܥX"*RzDZДފ-{0z8}kڙxhoiF2}v DWg+4ֵ`X3؏׋X/nQ~o|=M 8qu&.%y̽U()՘}ͪlke5Tn^ UUނ|XUzǢ;yp @^Ba ̪~\ b2]63S+5o]e`;8l auQN#+(Eė:g2pǽ "3E61Hs6gJ&SZ#TL,BMBwvt`8o!8bz{%!:Pj>߳CmNٟj|oV LW8' OsD NaZ<hFpKYP.ECV٥hJ`s9 >6"WMuQ8G:^Yr`6GOg;ZC܄u>D20W JF:eMH.Vtu@YS,bupg4.S?n\Vx\18p"2Bo܉RJثX6:1܉V?_?0EP c!sj*TZ:~iAaYKJXC'G⢖!( H} P/|žKNm<\Z>.*[PKтK6}.WC+عk^t\'CpQ I`jb`jNީFٹUGw"ǜiix2BC*{gyE fЏy4=5L:/(%YgMrCo+ô b:Ӎ[qX͝KR,+P7Y -Q~;W,O{qޥ8RǮD h:^t`VjӐPJBgI}) q,@ݜZM_PE/ߌ xRY`9NJQb<3gmm\E,֎ݡϥZͪ)"s{c&Ʒ>NgÛU" 򿍞8 IZ0WL*ngzGVUYQU+e툉Us#A%;6=h>YfX/N=Oy,$ 턂?g(ؿ_T5h@PM1в2IsC2BS*gg:>\}ݏ7\?[QWBw qd+W 7P,RGPtX8RPOyc"7)00S^Oz=u0<3r'v+: #y h{6\.E# }.g^Ǣ2vڄO6ם-9XRS#!:5+bc#ZXh9)sFX=GL\Ǩ1'RvK!+# zfN K%։0sc"-X˶n1ekWbiG=:hoѶ*ԴRVڅ;\ҍîƐBͭq (B#(:,KP.|ފdví(WKh"4cMd3~ySbR Uwb,ck66f:E_5D2ʹ8x^.~X/>Md y†x^Gfv =t-0^\B3zdtAS:< eUe}vT1SG.ǶM%brDy "pI2s R^yP~0/!ԹpY XDFUƋ4[low7+QGEޞpv^VX$^_Z: ޴]/Þd4P^(9!i$v ˫\"-6g[^^Tpٮs𩞖݄φ7#U[lN'16| 98t8KaJ@?Y]̍-Rd9rAEh07ܕ 98G( At!,x^k J_;p0.?_b u6Rp'\ϔ85x\r{$D׾.mˮƶKv37${4K_OPAѡ4g9A%&(0/2(pj=k`3 T_]K6;ZLg?byB鯜|[V pykGnW+:P &d$q( w&&[BksZ6^ǗJhoiB&q܉8V Ǡ ia7j69hmIZE^غu+nf$9و+z&&ko1lq'Z;j=#{};ּi? 7y. al+WoUon9C42DI]-\ MdT8C#R7~(e=q[0[ij%qnd _vQ}Q_6aˮsý׷}^L09> 7_W60_Q[vj"Aޚ rp`w0R BFHs''͈.fb~xmMX[[K𻎞+!Ց( 9cIDATj:mKӝXb,\hd_{\7_As%_3}KG7}YD͹e.ɺHBrC #(:4< `>>M CpU<|ҍ Re>e5xw*7Icv, (.Ec皊ſC-2n|nZB\:=ހݞR&dģ3HFq; !鼠{Yzͪy`][el5&YD*t:͎c31o'I2dzrf+[fޞEqmnW;p{3$HLHDCͺKS,nPqx\nu5<Ů&`WhJv{rj_5 (hC8j:0+ ӲY.W ǜkBP+b-_TF́Xlt)-?ԯfsg5+s?¶𐯱- M (JǢHg̟UUVDufN9.< :XP'9@NP$dh٣ ibl)Qq YT)شc;i$8~鈉]tU u6--uwbNOjeL{N4ۛ7W:pRpEPPZ:岘qEǴCpQ~l6c9>ZnB͘/ 6m] g8DiT@Kqr)Z_װKφiQQ ~vm?i5mAgݜ{(ۖǐǙT+9( :81O#.8eYYA"+C f"kHcI QV:۰vNdFrR-N4V- wbeЏՇ5AΨQGdEW`5ocPvr*j! jGPtX f<6A=D ٬9"Ssg_ipxoh^8́h:uRq1`4b" *K +17e oS6Dd0*֗ȞELt8~("Ŀ#HpB!^cjP?bs\ G\J'l<5qEpӼ~1(\?ΥVeŝhd}܉\כǫmz~VL+$hw%S\n",g@yOA.`w0J9?!st]LxA`E/N_7 I {p]^8h Uw6]YLOCMT+3/KT̯SMo7 bxUp-0[}uyq'\.k?ǻiP wA3| .F9ʂle{}y6.5Bg#`{p#ޱb)]F~:딏煨K:ZJU /;}c"&7>rZ\m=5VH_&ލ oNCYheΧ*ԚͺDWmdp0 puRV;K`kf!DS.VUBE4"Zs\LT\ĩi'Bhm?t Ku!&ڵ΢/0\XRgBwî|;m50gb[WoXDACz(bi~Bss3uXK4M,>,&-E a͸`*|dJq^klKѐۮp܊g/[O{D!DžpΎMAqެww-XUǩ{!1Wih8R7-^:xg(uD9>s,g d3*xލ\ESE:Tby,\ºK.'7oƸtfbE)7q|UPej;qu]faӤWg/ګqG҉%$vNnãރU6/T,1JT4n8C\Acӧ'qӈKuM“߷ީs[3GuXNX?KonȷuɍJ|+⯻Prpn yu ͉Q4PfK4WvL̠%H^E( LP ZմF-, ^l z $IDAS"H , Qp*D&Yr}nTooo$PهB?u -x8WњLYÈ;bb&PN4\dL#A|eiUt_ m.ٍt#<3~a<ÞBph 884(pK'oB4Hn ۓOx^yo=>[|+w~9bWD|3+-y.&+m{F+Oco׿Ú'zuh+IU5pD/%\xdVcc8vb>Oa.5YvCEV#;Y(?Gz\| #U(T.$LNLؕw34xх[v˘=*z8x,u5AğjbMwҙY|f~l-v90EڷS+36wb9˗;TW/umwiB׾.a!Ī>iXLAyZz<^v3bҥ Yavs2` -~>}Ӽt hJI(]ŶR,w6:iXIHO>TN[Fs*` *_d.q1QQ;h3Và =^~$L+z>Gj&U٬eXpTTg ?F&k9Ykס3fq039M#ɶP!$2J- ǧ 㭯FSg$UAL,gYbA֙;q'㎵2KXMCGSχ1Wa6/! :$YIP EE I@tI,||·| A 4,YB@/{FcG^`à_ז*S,yyf*OxO_U J[FɤP?BM8܏E) ‰_ݏ68qs,̸X\px|u(܈hyqOt&įl6BYdH.z[!C~I,pKdj$IW?_*f&ә 3',朌&2UopyE1Wϟd@)?уgcUP'Ɛf ;#XO8~A2j8|4vveM-q'BpUT ~joҡcjn{>i"-TUYuhzJXJ Aa ˡhڡQMl<>?shZS^s3_ƣK<([p!k(D6Kq1,'lgPQQqeYщhi¸4/ca^CXZst&f֎nSYSGL:x(42K r!)6:UB%L4zJ\gQ$_%dyfRhjkdžQ.WزGaԸqQW^` fC}Ӑ?ݶ͙, \}XJ/o.zڴ(f~wύ{[?AX\/wEZYĶaUe2-":mU|>3=I 984 KNa9Of6oJX'av1I&&,3w}o {L\s)/IGP?{mJⶱ}uIabv gʥh8<ظ,>_`;#giƿvvޥF,p KUBpϾzR&ηR(axl P 1eQˇH+Nx2l,h:G&02>)LEH&ShH&eɪzZ ,I罒g9y1So4r#9,|+\>gE!'6%A+{p(G(1 $i6c[\ݝmC_"i1 fJe%Zc#<5%jn*SwQĎ.R =йVDQBH^zy޸"RɅ$춇ë́Dd*iML1=>QLD%XBMfe ?ŜPqDD3R]q@ ќΡ8=$^?6 Ž1p<>!P ʞN47E YشV,gy2,tњZ&~ d4vd-Pin\x LK&bD]~j|d @r8>mF(CM` A;9<5Sg(GسKL,gY-CRswh}| _i"\GN^0cVsĻ$][HjA!P!K¦8CCC XQ0Q`.zq;{?G`qnTuTܡԫ֙cxAsr9qY.SPZu*Obtb8\)p.%!>EgJuì¾ 3/`[ \,D~27U<,9`&:׏Ñc8t Gid#,-X(2uJj僜 r(:C?iLObj:~` Ě>Z+ڂ0SYd:/`4Ǎ!Ԭ0"~x/g@g{k{3t܍n|vo*l:BL3ѵyCG<6 E+@J2Í^dE˟U'pa Lπ;+f#Pn2C[&V0璇Z}&/b|6(>]Ǭq[mip$lGPtXn8C1rU,=^/ZiНj[?|쮟!ҫxK`K1R×Y \;~[OC͡V l_=Bo_D"#NZ^ᾶe%"xpBRxlMm]\k4 cO=.#HYa'%͎O@tH$,t8p(9qIbN=|$)pդ =H.{Y5+8NO>p8ݝXz cU_7Z",Xlhsܰ5cxϫQ/| _H3hkۓ"ND~-/FN_cw\8C0rPLimxN2u+xuw+{*n;179i~FBqU"ob%܉+JWϝrpO__lU]^ąfq7=mkӣw~οض6QD tYN9! GPthdxBZ96<^>z-~]~;W0{W!~κZ9_tOÛcv0E$>Tt]fEJÂg#bʨزiEa Wa.[^_?|\Fͪp26m?% [ <<ظn5" ff^n(ͅ$OaM #DZo8p&繼 '+q~zXs?@ D4&f2YLMɉ)<t1⚁~GoG" Eێl?Ɠ)g4&M;pLTW.cWu'~2s+Vf&qk]9qK dZc.8zʸ pkΌo[˭Q<:7ƺ)(c1qr[&kH8Ӧ']Ӟ0*# /Őy kK/7VlJڜFUN=ڹ[wmsphAѡa+_4K J5⚛~]~֏y%L֭8$]o+{ؖɣ`&2>TХX= \|(oU8o[[&.ҦH@hHr`.,lچH[+R$$ǂi< |ַ-I:q=0B!/"^KR>9}qQwP5.Ȯ \ F0掝(d̲ :/ÓϾ B5CAt2q}hoEs$p|d*t&̈́JU!ߔz!|5^:&𮣣x:cqpE݋VBkl;b/F<v &1 ?3Н?⫶_ּv=`׵;US͊,`VXt:EeEL! H> ϧ`7Gշx[oqO *v!}KVW_V)QQ_Lp,,&j^$9fIn B3І̅H8'} kpgP#FA,+ +1<2}+cfa˒?N)s?DTfUw?}a ezhkaU;Z[ڌ0B>/<ϱqQ,0>9׏+3/RB=}'v}z+1`L8w 035d";V UYMeOڍ~F&GzȚqlD$l7F;qb.{IF_Rx4?\ʾ=n7^xm.BP\ Z GPthXDQeK"dEiOK*Gcvz S/`kmRrI [üϑ?Fʫy9 b;>24hOpd/@Fō3lx'K=[JL\ʉF:;{/ك1'⢈S]&&FZp†;XJA5 R'ay84,ɔR$ˬҨ>m.zG_Atv\q!1 VSdv fYŦY9 Mh#5`¸u* >₌{Eh)Wo.#,,r㶋?Ǐ [r)J =w^@bӚZ!H c8/>5 }6 QU@SL=8b׏G}<0 MQ24Nӳ!H%h֋ (O$݅ə(bd%ffc\_cdYb+˯Ǒ'ʤY1`ԊTPpԿ w#Uvfb7A{9pb\<D:,;Z' W s+>He(Bd}a/{=Eհ{*ƣ+GS< >7CWf<.(x%# aO&~xczrpĒS\(dD?>;~ovZ"a@dl+SX )VDUSbմZAM^ľc,#95ޥ 9<6| 7l;>gܭfuo^E C s^e^|dpq w$FЗ dzfqd[gXM+DK2DTLqV#ǧPgD YI[ EEk^, D~'ul74o֏G^ g8A-ZaY q.~tEu8<ˍt:F7Yq'DPx3@ ,G$P"UVU4iYfhfВMëW6 FUOO9I}r > C!$js\$usji=z{k܀GZ$Azj=~}̭N{f݊4 ƪZY.êλ2;YA8 аB\E",TorvuW01:|:'#Վw"9_:8;1yy߉άn9!9M6E%Yh[ڥ^!;6bWrH)kE")R$Epx= wwGdV4ntu?D2~I>,z^?cDZs{pūnDA>>o1 ;q !hrd:zrg߹3\pl1ۆm[9 MShZ!jjJU5ZFҚk{{h֝ o)0]|aQU~T!ol^0 Ն(7y C~Jt^@B#] MCT$؏_%yš**t_˄ ,*əmJQ;u ^;IZ<[RGa'“ǞDZ2=}%( LǁɂYPd6 <#bEQZ.˯4'.cK4ZD{F*ӋoWU/m3O<" k~?z8c&Fv#09dk*"{~6Hf2;$*!,FU< s^w1='qBJsV be_abcS%ƾC!q bsJ%z>-uu=La&nPA P(iArLy1cZmb^Z5>0 yNKiMM`vj B_b`xr(niјd- ҝF7 T{N ܈m F9a"!1:~]4l gq}( PlmC>EmSfv ^i,(2nEBx]X(|kUq|D W ) WT$6s(jFa,-S2k: xΞ=3g˗155ѫ8<<Ա1TKU>p/ + Ht%R]/aMb>7CnEyOQa3Aœ"ו2~:JYd7g/#"6[!sN<~I<CZ%." [&LQSմZB d5 LWc $Z>4ib1ߛ޶pbqaxdsn`MO' AX72mjg_Mυŋ?޺"H;6>O_~Yl)MOOR)* ꞇte#hM@ yDj.>$bOmSXPfSyY~VjB"v_7 #ă{NMR'#<&l+-0 qZ1UylXPd˲L!l3 ۴)wF^MӰ?-_K&W@kԷ}w{V|( 畓%Xg/7^N~8{Ip'[Nʴx:Q n/ "6oa2Wj&\ml4]СCؿ?nNb]X(ju=υD|yp 筞+ $fJa͙LT ltiRa0T/(pV2 qPUyu}Y>m{sk$H5Ltu&0Lr.v 4zY'݊ 2ɱ~#"u̬o),R/ SQf"tO?>_c'P.h0'ӷ]LΖ]3`vھEf"ӕk8kg0-f!':{$vݏ0vQku$,?| ;w2LXFW&z>œxSށa.ri4I2 zF⅟>^NbC:BfQ*UIDܶm;;v$a䶐H׭k"!n9s)R  K<ǦM088u]i9 ecff=Bۗ/(gQ*j }-f)GbaaT&KBFoD$ATȣ^IYAacl|BR)T:~,Y O#sNj/SŇ/c`V'/j8՜׆"ZN#J;s8Ht%B N_$ bY ȴl?z[ve|aA6YUבaj mwo3''[0`99>(7aYs 봹k"Gd+8[oٲa,i4մCU%[2M Erܴu5*eԪul_OP8t/@UK݅꾝h'ô>>KfO]=}>="G,B17KtV|KZl_(u[pJ%LO$la<#qdUVhkPh{zjUt}y^Õ(mسg}iZ5b('(^{E(8 } x(cZ6 v؇]wЖ0lnr1O z(:Lˢ"$‚3z~RB1k ͪVe}"E㊇W,.2 !`<ij [@n]~ڋ}WcA(g4GU$AUWa|PZ(!FE+ -(~BM'FTlL "ed^<('BKE}^y6/D#=op^=7`^wDZMMn+lYy(TՐPHuj{O˗?@yuwNޛbjjJ xp ?~*4I[T"- Fβ, njPmɓ+rLǸ뮻0<<ܲ0|KN^`;T,0;MJHZLuk0 a[v DDLA o!dz|N1uZ @c>aWN"Ot(f\#(=]$$ӕ\󓈽v Mٹăw?@A@-t$YNӀ\,pσ{? UUI(<Ɖ{!Wi\.7GD:/y ˲)X4Yzr hD|{zzpQ* N,yvsmyOC6lٺASCA&CAPӭHtUT>v  Z& 9B!s.м|lo?a fVi*¢d050co.sgwfˈE_o_\3.g}~r3s N)'aӵB%ڡ@+0$ yUpo۱b6Ny4b?? t9ep'@<$XfTdE{>oI0p$RIrgq[*ɉIh^Ҿ]ER^UT*Qѕᄏ Ey_躎zB2g横*C\~V6 "碏LO?uaLkIaеJČzJmJAc(ɺ!]x%(GK8Tp*f(b??I"um*$VH2Ӄ< 45t%}ZItXLPTZSPUU[70L"ӕ(bpēn$54]}̿78sx_V&>rd:GoR;P=AYg-Wgay*߈n߳w.A$3.2KANHd;3s]rAQ(Z7Llۆm".A@(_*(_ѣG;vrDv@u]3( ̇N\u;yf{Y'qN,T% 9 &aqg8>(8~2s?ӺZUQدث'ixkPSlGޏx O'QV{(jخ A9>%#9QGEm{G*978lN'TV !al}m9]f VLOlF/D*<[xK Piܙk  u333tC}m#L, |?,.r5lvzο)EqdBFFŧ` a`'?]w&|-9ezn[ AۉCX'Y8^JEIz*&&Y:񭑃#=B/ |k8+4xhaAųhwr`/U4.1F'Bɳ@zZV5Ha8tσ=\ybb+f(r|cܩP+i"$V(.T[u]F;BeCгKlT^)|'^2c-tռȡеsȵ"0B ;v>;;{1K 4{]r|a2}3s]W OPP)Hĕί8y,EL?e/}38x8mx(J f>u]<]+4{>G#Kg6Dٞ~ŲmZ\oE\?b[tEfÂ"ӕۛh '*ԑ  }5<ϟV* @m6{w3@< ܅h4ULEUi@*;āλF(IyR+͜ anzB=}xG?=gN/k/ʅQ)urI`T5S*oDCxA@ߧ~raٱy{K%t Hio93ML&\L[k!ϳ{ ŹEv,g⍸$'Raˆ@*!> UA"}4kĕ$p8$9*"k+pUEElNIl'=Gq8x[3@i0*۷<|t;$auJL9ss3MN`zr3ScNBCBOVn XBM&B,d~lۻ&[_ Ji$ikt*0(Ģi5V(c^G"h r?#G JyJ嶜Pmt ɍ9t8TMs7:OaZLR)t?a1 mYnzBPayr]8{̜{UTj^~Է ;.Iz"sVkMaq{'=;|*4˾mvj0쓓lW8߄FXMar ѦhΝ#ìQXPd]oopD8}K?N"fQ) [r{maoAj0xxe!srf91 a#ؽȪ:ӭ(tyD*wE[6r,ƽTQEUUaX6fe{SЈzt5n煋!J9P>\reZt̀k,z텟 q׬1AWVU wN&"!жfNC1jfͰJCQĕT*]>K@bF.W܅"L7&Ųcpbб>h- $-$T+k\EY8a^X9qN}fgt ЧgMBq<)(-r$lJEUFvwHf(䎐~jy88⻸4B")6ۍ,СCؼJN )VUj\kT;*̗Z&S fQ%k-9\-lOMA(89ՃX6 r+Qq[Eh$?3Mx2N6= }Fg[ Ⱌ8o;)|%V.AQ"-(bnRZ]79R>}hjQ.ɅxQ ^T*EgϞE<]áX U}Q@dXt؎,|ץ i;TGaa\wh:c$2 -"U]ph  q17=Eb"&*"._3r\5zz޷Act ?MGc4dA2?@]$&1Z*Sn}6fEYh".hǗK#E$Bv C[ y^:Om9͓EX+Txk ͎߳8cﳠlXPd0 !d;c0pR)+e;>$Ϝą3o|BVNW 93W!r@'p!- !-~n_Xf(ֵ-Ҫ9?8XѦcJ-VW,C+hKPKu݀O O"LQwc`x[v S0̊:5U s! Su|nU;P:"T c^$&"rW7E[N4MFXΝ;1229.BMk}v,ݲvmEu@"E, {UALfZG~F$aR.oH\Դblr3SȮ}ؾw?{MM`t9p?5zRr1*[Y7PlBeD<\M"#ycB`(+C 7B(zG9'IcZ=ծR .5PK4cvLF;a=TgǾ޲rW˶~zbjEDD>ǦID=X(WP5юkua9̆E<0M=ުHa ˶w&d9s(gQ.g98E;S?& `pV=y+3s3s;3mgPViw$(vB C+ۯ(Rױgux+ {.wE u޿-333mOaEy CwIđ u _kz7r{_/UN\U )AS\*ۗK0-$ڄwO==1Kp8 JQ.)WUFy]1JHƞwa4VsbqӘ vᶖ'R4(b,GmTboK'DlVYOh&b)e4!;;],M"Bؕ +&@av*ю;0L 7M#<ì5@ΫbL&gsX ws{ ]}rz* m/\ {Y0Ђ ubN|:ִufC7:uz .tر0W%g&Lm{2X.$ r)|,ri+;N)6!;LOnXYMS^8$*"*"UcA4갣V5(ft\K[{ mx"uݱcǢ&TUP90ӓmZ!*ϭ J$X DZߢhJSLLg[aLwcm[ -`{B-4ZjA}`;q om;qi\ cW.`y_jEx^-lkXh4u+X2E Als'Dfj ä6\(PN򥈈akL"!щC7 E׽[[QEfc"uz'Ƀ%s0݂`oކۚɁ(K~NiE]xG 7{s(2CUCQZw(hc;0Lm 0+ om.RNnf`Bn+%[Z- cZ ϫpj%imZ|`Ca", 99M7h ss) B xuu놎6rҡ}7)RU+J] B,7o^~;$BJ .:&&1==ίgZϡ(I> <9ڎő̲qhk%d#-'5k^eGZ r!DS7,C[cӶ]Vn%SMbvrƙQ*WJUJ#^CtT7pM/)'ۤX"IcD2MhzqOhGzƬ }&>% sD/9qZ0y@J3$i} p tغ(/K*@U6rP hrsUjrA[!6[ȭWL9U(@5F~ô)<*&TMPaYp*ˉ R>>gQ>/伆 sk0Vk)yO~kȹXeyenOJʍ-Az}2܈K==]0?J}4pbn>Ȏ%C&J'Gb,n ?9ެKr8M%aTV@cԆX|f!qka q3!:4MCDH~tݠ`ʹ)DXQrpޤpe޴,*4rF(d$aV TZ*JO4$qQ~k29?GEHô!ZtcɗU*ȡؚc2a .pE|҂'I.'j2>>֢_o"gG}mXLd:7\뒻VcE CoE(26 zr :9R^([i |DӂlBi)KE\y]Qj j+z33\a1NBC)KP~dLOH4 {a[\zRF_(~!{ƦeSvscnE}1@tf-Â"uX[c($Ή':MYaJ#,ѯr0Lw(?-Faѱ8ܤGzbj&6@ &Ԗm]Zi<"w~G|Ⱦopp/9E*\r(rbL8!3?$m#J E E BqrG.fE XEFp=eaRQF0%E@?(GEKaj ӦH]7ɔOx"Mi/XURӄBcUW#_+*-|Yijkk((bٱȎągaJ,UאC ,L!ڶzC%0 !J MQBUKErIMoB M3hȡ0Zj'U5 YI”'aHt(.z3R!Dqq|҈*֓;\۪+SGMכBk"A4 1t\NH CH75ka~\oFܺM7@E +`)gM霵FzàJSd Պf_Zysn( r{a[I\MiqH0m#O#:a4QUa nCUj &)7aY_PɣX~f,M 9&V#i#2QU\r|>ʣ}4&LM}}}O|LL-k26v5,^5UHبt3Y$śBì-1-,'ŧZn+Ź4F=in ~'MAiMNv#DXQ&bNdRru75T*rE!ɡ: 7 U"|]XisҴHͲ{T*ψ*=˯q3ìSXPd 9kuB 5\ ga&hGap=$fh"isM 9$MS#qFh EPx2&3Io2|Тy_GGG[ra| l{i oF!A1A*C ]dܧNdn'4r9ah9ۂ0lvn.o#"G[yEm\qP]0uH Nƾ8׽x_m QT"t(4iӉ]9ѼEf]Â"mh%( BN 0 s &r@4LDN>&M Db,ؠi*OrCQ\`K% ֐H,f yB} e+_a~llW\IrKEH&S3}obD.ìX"U\k#.Jp-ۍ%(<^ G mh8㮉4іFd7bxK n'v0k_BuGPˡ$lOdaCA B^4&Z@D4j5LOOQ0]QyL$re :"נ*ϥRiUK.`vv_~v,x<|"KٝȬi"\śUjX$*Jfяfu&.Jn7" 7-2CXQH3Y

    je;H\ڟnͽiD 3(M {g: P8X%9ī*Ǡ3"B ^_*6w 0̭ l/5+ 4#כēiY)[ط#(NS192qld,+6LR4&&&,"ϱX,Ҷ9֪0nDy%5MEo/-H8 >9UI6-;PH]t $0fŵ"Dtr"ێQQUi^%d5-FN&uf‚"UޖC19aaCNt]G: 7FNx"ErВA&T9J/ A42,+\(̺ĩFEÌڤsEAXE6<$2rNGI~Ze!eGjSen"j:}v؞¬{&g 4u@i- h&d<<:1 0KBЩU(f5{q¹Jz94 RW^Ç ÞqR)x®=jBUW w.5ZMB^dN"r6\v$j@PtR!(~3L:|rMdl+:'67psy5]!aND"Jgײtn%_N1L"Uk޲(5ˎd&ܗ3 0K$|ʱLgQhcqJPC,í('-m!+_N<}in@9igޒN=]].ZY*'OD>_m܊ӭHN&iBdgA٨4F "u"(4%'z`l.6 m,Ym0Mʅ ÂnZ4Xhخ(Ѕ30 >9q9GzafȾðl$RY3 nP6h"ܹaΜ9KaŎL@NkJݶ͖FbNLaD}>0  #,($۲zu)TC ͔ fQ[ԆDM"(\כO]7*Mѵ{FDEN it0u]בjgBNM 0r!GPOP)iR9yEJyݢҥKŽeMHۙRw>9W^z ZQy|ץ-wzV2! 7DFй 8ڸ!oʅ70\'kjPu܇Qo:5Y<\(bnAf_!v00& (ehuW>taYI%S4#L#7=d6azz gμm۶v&₢p]P$.]"Ia-.jr&n۳\kq 4&4ʻ ơ10LwfuIܛ ɵn[6έrVCUMkMW؉$\b, 0hVvL(Ց1Ek"haEaD.jaTuХ؃rBt A0(R,[:rDQB|+TpU= ē8zkΟ0 ,@tCG,df_'!̺Ek0Sߠt|p(0 T o݉#~.E144^zlj!H[YgrmXK%7;+?d/Y^JyAa%< -Hubf795x !Cv4O^0 ìOk$=+:˲ͦG򗿌>bh933C23[y1s).]3x}3UsV>T 0h,*҉H6%aA<m A ` ˂OnaΠhf&p]='P)(U<#מO?_3 SFPQeLNN.8Raѿ $Ɏ%T?-WUU S1hjPnafc#kMa _ضL&rL"nMSqߣO 7R!Daf'ej4olE)zNa EDND"AO:ǏSO}wu ;w<\//>˗/#[Y^06mڴLܹs8<^}5kx饗0::׭!Nchh13((J؂/QP2tDP BvɏŸ<5aa Xv aۛm)1!F,he6Mء0 ì$T$efC[S7ͯR*v_R%5!OAojya`*?hDytd2Ci~ڑIDATtLGr'V+G>ع.]>]a-0 : T E.¬kxt ڀHP ǦN@MaYEfg&?3!B;֛סӴۥ.5ܐEz(qwO2JY%aagVlߏ@;c5 3] { kAIw90 (uTkU|S<`(9_ Phsvp~H%Әe1aiME?E)u9Yװt BIEQںge`%; 1 0+V-v|{㗯D"ŖK/~ߏ+߆|aBPځYp3Q,5(vN 0 d@\Fߦү{ĕ+=2faUERFa6~W_,._0da:Rdu_Yߑd V,5jw";Jba D{}GaU*ҡEUQV0=1'> wEƅXaPNam#H v+%=NYװt +v;}0,r+2 0j"zJ'J4Me䵠0Rӓx೿;p5LS+aUDpM*1LÂ"-X;0!naۀ4r6o??R>I(V\MO\~ %ݮsaa!nEQpg;ApάkXPdіCQ;:{g_&ʦXqܪZo]j[֥}ZZkԊ6QBFY3LN4!NnNɝ{. 4n$"zм[~A3r|\뷳f+=S}d9?yI,:H*\: Nry9WbghxCP@ueHuw4v;|an9ߐ Ourj-jZY^58.:i)HD6 /h(B[!a.yi.AS#p0Lyy4isO Cfiay`, 5oyx5(JYx d4Z8RQkkDlV)+9"ɦyם3.z.{QvvYm6 "Ǧ: UyrHXyi5|rh -aHhB@҂V9CkhBPIo,G,j'_c=‣jLCO766PMe9U,R\Cռk` P @F9#nwB4lN7VYVp8چn=YbgX۰UU.5"D kjf#ov.t̴N>ƯEBMÂ2ꄞ C8X6^:E2u"M#EY|56PƺCXO V}:N$t A >>\UQ㾦FT;](*FN~ʹp-g6Z,YUՖ-Ϛ`LFM5պFP$Q~&b'=c"!0)!-\.UשK" ]4e4X Bd ?5r_0&B(8EBޜ.ZHi.Yo,?g9Pi |Ԥ]񻯩|vt\dI á` Zy=S8@"L P9F8& !,6g mfsFFa!"ۜZ]$5d923C_yN: ޮ F , 9\d6nkN`h OpH 窚1tM'+urD:O@sbl py9?ѝʺg%03!-l\žQtRU JXQ"[N!لJ(!iAׅAqPB' )}z,Pi!>#ő?!HUT @&ÓҁP-;у:&EQQ krI.O\&[(ҫW/4…"âEEwg8&Ţ4 OX(B:MY"_,V{c20rB,u]Z4#`F(B:BryHUѹ J!c!@nH@QCN Btt%nu=;"d,!(D"7DMYXQ5uEQ"kO FB(Fy :w|NB`  EH(,܋[DsaP"Ep]/B%@d 5ݤkDt:QC2t] ۜH4 E=-ϐ-+( E1t]'b%Nx= G<'ح 2$$L"i #0vr=R#Fja@_cq¡Eio_K0P(7kj<v8\k=dw8qp6Ms%2o9HmV9Y,V sq' EG>bג_S (nnCr=dTF?iQemCa7)QUd*1Z'hx6tbo:mtڨ~zW"A8qMkjsc%kl}@{8Z:`0-怛75q/ZM?|`Ɩ!~ &1*3"N96:N7ٝG~qo.7<; yurWeq#e1g SEmc$XH >4 Bd%r]9͊d!@ư urQ^s0NJ[lej}T7PelXA98$?X# 6&jjhl>`$.(@瀣3oCN\n9py8lVzv[2vJzyHsHa0$@Pt`^YzUaluqSy9a}(8XV]0.{Qujlk64 F-A¦`acE0@g58DqZ8ȃnOT5F[UDadd,y3%2:> K2`vBBBpOE8qs1/[ڣ֮]ˁy9t)iƌ4m4:Iazs!Ʌ%KxyB tBFC 3g9qBWXAӑ{tI'ф h<<ONJf0ӕk0V6QyMz@|4M3d˳ E0;H>ly8m-vߏ?3Zf mݺt=\\ǑqFO<eeeԩSyL>uqoҥK]#uޝ3g۶m_~%gb3g@ǖ駟4_AL[&k׮E nРAtw$Iuڼy3z'OnݣGs'Zr%o^t):gs'ƚw>'erEy;c~<^xy4l0>O23Vԫ *k@M${ۣLO7-Y.u A@N:[CQ4׿9ds:_ ^uT[SE+j*c i4mT1o>\8_|s&b~lw=ţ@a4{qر1t=Ҏ;ZE6ی3x[7B[o˖-]v%mxs%(k҆ xo#5vѣGtΗעyYN#v@(L9!0tR,( E0=!(B4HP5UTSYNZ_A5UP5VUR(СC3X{Ν;O>vZ?яhĈq^<?e֭<~irݼȌ{1n GV%K(J9,Dv y>)smK<7jO`0ȯSrOsISO~tE~ݳyHTV@Pn(Z4!b5vBD*[d!$|Gt!;:P0@Օ  +#ubix4k,"='\z5-_۷/cmذaPLZx1iȐ!E.Ǐ-mq8Cڽ{7吋sϗ:>}td4iRY޺7|PeӦM;vX?>g&J%m5yd`"/cdnz`,i0]RFUT^eV VP.C4d;[N0 TUQN5rTl.lo_w38ӽS.0ֽSRUth-g}%'Z,???c 0u][?䓖c@X,|#D8p`ǨLB>WUU%ermqx3 2`N|Ygq6G,Ŧ\dXGeeeR)p њd?'ƔdN!ݻ\˯pmSN孺ھ}{KGuzcYVz衇K/: >ׯ SN){QU+jhUVQ}SՀ"ަ,-Lj PWK`ar:N:$"Ξ= kΝ-;j9p@[>\\(wsqɓy/}q^{-@ @~iKљ7>Es38՞.>)|^7< >nfu zyX,Y 2$cDԿ;U6PYMU7Ren&@j i@$&U0g'ƛi^@Qy{.TU Yg#-QP֬Yҝx޽I>wcq:P<\SSSK Pׯ/2ًv{Ix[]V\I@deeqۙ3gy 777c۷g}5[o&>GnذCnS~zͿYfqX:Gwr֗޴ưJz*HMh`j`jF4R-VXlϥCU V4jbovQ"eڴityq6bvvv\_[[۲mwժU)yUWq}LTTTD?<΢t]~ݲeKҿH!Cd7.Zp3ʣY;vH\H~a3gרMRzyx^~5k^c5Nv >Z*ڻvEzP>׳7eutRT q0MFOl0]z].f"ѻ=/_*ݏ>GQ8L$H/rUuPEY),GRޖ59 "߿Q}]uzM-`&LtЧO:h'Ox۷˖-uu7&bɊԒ'wmofTYY5n P_s5twrgyk*8q"~`-_kŋ\ pRGA?UП,OnoVҾtk,Gdzu`0| ( ֵkW(i !8{lIt&(B Upp=XVJ#ʃi& ;x"ǦMFIl6ً 8Py En'O{ƍ@C 5 (ʟǥ^[5l0:3{^uEիssГ\{~X^im葻o2"X8߽~ԟ"ZnSjjjJ\A2<͛7/#gt9w[<ۜXYY9tF4D "7,%z#a(B&B@LgϞ,eCb4鴳߇45s@i1/͙e%{@rrYg%\Y,۷oHr1P\\y&ꫯÓrPCD}G/RR*}FmsN\%0spժU\\x!AloN.y SVNn0s9 ߉.ϐp(&É3:aV9`=]w3&MADyOpg߾}@۶mK<;W\`"5S:rzxJcƌSr1֟{׮]9+<~W(|?}b-vfΜɵU]]͍T iʕhwqٿb{r}H9~Q0}tMMM_k׶{H]Mm㫵-sy8g <  ]^/Y,V#vF( d(t,"Ѯ?g(ФY/PPJ6wӾ!2[ׯ_?\zԧO?/y/2n;xnn.}ᇔŜ9shI;~:kYLr)qwI4s0#;Φ;d(_~~~KC)Sƍ[>P> 6PO~ | .s=7bz7x$JnT0pHsD;T5)_ pQn^m:WscGՖaUUA#Z8lɲXL4n/>&N#C~uc1_~9/Dc ? +Vdt|…I &B***8EUU[ci٥K袋x7|Ӓ_f2;;vlKb{:744'|˗s#0ٳgs)x<~~N_p,fk=xҧOz\SF|G:X"EUt4X0p7M4Cnd,ˢmlj,|3,{>A줒o. mQF6޹sƵ/7|-Z)960?xxԩSy-GNNNǐan^/Y;{G.]Zs=79vґyݺu|cWo Jŋy뒳:;^O0ϓ)S𨯯_>G-=;x|drS3*p QP3$ ,*hW䢭h'Ie%(;;.bFbii)[H,**JD.Rb.]ܔCQ-ߏwu6l\\nBN$ÇoB5jT@ @k֬iʼwޤo߾t 7ПTOCqPP3;w.^zy.2[nϗɼ@7|#*G>2 F :;z6ZQl_Pyi11t˽Pc}-j5uPɮTg;C3L2J(u_{ /xZW\qop&9{177rQ|r0.]@dA E"Mz*[nq%zjC‘]C1*wg+B'Ogy&7 y_g˓E~CQ!éwA|i]Cnhl5!l & B9ITwm;rdvlYN,C?o޼kmذuztw쁔d:u*|\!mڴ5K,@;!Q iFǏ\ie˖і-[6WH ,HTRJ>?|9ppQ[p8Z2wɁ7|:aso_!YV"w0p;h(oy&\SMF];B2`jg/k~D[:TUw2i_.*:,޵0TO- 뫮S^T[ꫯ! ;xYG5kt첲^ˋG^LV΢d(l68qbV}}hOo;20 Ũ[otK|km@ _z%ꫯ>XtC  .yS=%H!])'7F[8kfoP]?"Љ@_=B7we xV*ڱ%ÎrBꫯq*~)g#~G|q {"dZ^L!Æ i̘1|n㡳>uV|F ٳgKqʔ)]?^[lm˖-fLy Zc#V.l|$ƍ_{GJbk}ڍ MO<IY]lnZ]QE( ))5+9pXkB;1G&+vjLW^yS5XsIHܼi&O=gL2e{t=b:Ή'oZr% 8-<t:i…Mmc>!Cp`qΜ9\*xixȿڍst1goxH8$8lՓHw(ɉoDvJ_1:_S#ٶvmВ}klH(k6m۷o;o/ 6gyS__MuP7n\LMEN'g!ڵիSZë5{СC4p@$&/+;9m˖-\l֭);\.(Ϝ9n?\yy9g!'|b ߜ9s_ꩤy֢?h<{tmqiymUZZasGEY)h ^}Ґ''Sø4!#:BV[ywAfCP0޽{^(|(WtM?e%)T,/|CnŻ}hb'NZlgώ"B4J<cZy;xAAAJ-B/Nc8N 0} ߒӞ={2׶n>1j( Cv 6pM6% N~Z\Wq{ݲe ^{3DGwy>_|AW\qK mѱ|n~,AXm4d,wN=z≣q&jTu/q=nP(|fYYAC' `-czD {Fڹk{oỏ^zAy\Q.Xp^{mJ,rPsmh'rfb[l6o~C%%%-ŕ+WƼ5jd=D<|;h޽<TV+g<#hE9VYYYQ[[K>`9DÆ {wz bYYYHD~~>_?k0~_gliӦ9p=ЭʻEԱ(cGosFQh%MɄ E0D3EҢb[Zf(n}Wmz~_CC߿?̻bVʳ>pV)''kMHBp88 0gm0کK,ז-[VnzţfnydEEȑ#yƍcF~+Vp֤9*..nȼvZy W3Cqh/o袋b#|M޽CL=zGOK} P̢ꃜXggPH; &X簦*Դ0gnz-̛)JNy8rfbWSSw_x>`"tn>!Ӈ3MۤGǰZ\Qjނd`ǻy[o6neV\ O̰}W~OrD;ll6>FcƌisVB7^3!8%;;_yTO%cɿ7cUW]ŵ[!!M]v]z|+SՁ"F;G0*`t{_o "n,0gu\S+(ȿ]+5]өˇ싯ʊc.WL[^A$u2Ŕ)S88s̘gNo 9zAX2 p,9aM>'ˆ xk|tKgu͝;7,UTTlc^j!۸!3!CßyvAN'g+^wu1]r%=䓜ٜIzLCGOc&Q>m$]p򍭇kmz-y۟T'VTT7t& E05] ޢ|qko"ĭ߬Jdg93θqb7SO=A.AnfS%dI±~^zݲ5zʔ)M /4RUUgt1zhڒ篿%i&Ck$|O~bfg̗_~ ,lD3׮]y+V&S<>~럔ӵ;HNM)DQUUR-ҴD_tՠ)!ڰSZ#T2..\ > UV%}~O\rIR?j͊!C|zgxA׾+S+>sw{B$VWWlF;w.Y޾}{iazyL7SO=ŋ_Xww5x{TOX~~>g.)Bn;(駟4[yUUg^x!w/,,כ.$7ly9Rgt7ҬYbzΝ;/ %3%x4bAFhɎ!Vg$  =ɛ%QxAF"ZAA[P "vLu9ۍb $E; ;vtH<E0|n;ON'pFlEjTܴiS 2gmټy3p\3D99TKtLfwV6r55UVV"2yVtǠn-< bg( ,p~mWTT!scMLQBY?5:R=-H rM?H۷a~ /lcذa;xg` 4b9~ v꩙N($K.P»ܼf\:!  vRgϦ;cW_ J=Nx<d0:iӦ'L_~eD| 7,~d6H#ǟJ'M8(]'!? 8=;C!#!-wjt #o3cԩr P|{ߣ_&r뭷z py (56 m ,km6zv^=zM.BJS=yiD}M=( CFL'//bo!pX`c-Hscǎ;SLiH4/f'eԩ4qD.y ,kX2GG4vXKԳO=i:45"P(hM,`:B\/8M@j9ynV01믿D[` !Kܢų>x6O8O<SLRV>|yz >[5զzZB'J.HO4KQw6&"J>}OwE5kVu-Zĝ.Mk׮NDS0ĉyݻN,;mKפq=t<͢hfz'[bu!TO+, bq  "`:"+ɡ4|dzǹx6۵^Kv=8.4e#r-&O?ݡO;>V]=\z饗8kCj yiiit񤪙Z0"Q82ҞNgp88ӟ^oOce+H4:ɓ9lݺn&ݽpB0aqkXꫯsғO>I?w|  ҆Wp4j4sT0`pfUU 9aȁL0#g0vV uEw/LjkR=vu3.ݞ,jc7|L1/ALGQlypSL?{1ۚ}]UVu!q;t6v 6,ӀvZ|9_{qmײ<kIDp3}g)H N! !; `2(@ׯoW_}ckkkYgEoa5L\tEܐ}?a u̞=IZ}#x_WoǦ=kܚiEk xP̄"iTz{e˖q7Azg3<)kdEQ&;tz 5πR= HP k38y B>OEvh4~h݊>jMd,u݃ d"<\CQnȱrJ]|3!}͜9wSB K1ρbyB ,]tE|M 齗^G/?5g3 PTA3[d2l'NkM6q'TZZasS= Gh޽|zWІ Z}~G 3}v%#G) ՙnL PQOm?uҥn?woғ^cv7r]ju=hȁLE0!&'+7o~Bz\KOgN4k;pk.}etwn=(=TޫPԯkԀXHxbyibC Z1=eeLd:s/KSsvvv`J_}(5>ZlYOM/ <昮jk_~ЁֳA'HpjSȈ5.d"vРA7 y<c;PZD_V|&}_p0рb]! fdX~hYfqEBқ7oygi;x/}݇mp8@JfC;|[n灼nF|}+hѢE4sc^;=t6Cv{pQC1W^@E?C?|wЗ.][7{Vn@fK#e:y={6/WX[.\HǏ/^y߿i:yyy?֭[ǯ3,D#Z+!vZZF^?SkjBzpCXF7눻@fRS=y!FzѬYxkĉ[}\uu5u]x(UUUhM4 /bNn;ˣK.:D7nLɜD."_J#FsGAAM:3u2 B2'LӦMK4rў={8K @^KTTTD&L yס9sݻ9a*޵V.UWQ><8g>(g7=6L5@ A<zݩw?;<=N=;ذlg @zPZ 5!5_̖yfg?k^z3_|yOT=zOxUtMiYmm-z)`?NjjGDt:Ill,f,_{TT饗^]WO\9s1cФIhĉl۶njLvZ>g/2sNnC׿.b~ᾇ,V+eFf]NI?zMeJLJ;˱I2-t@@Q_YYYxb˛+++xٲeO. P6$q5qD>'7O==Gt뭷/S%%%}} ѧuB1Cn)'' 畗sn:j3,Sl|"=_SsS#yY叛Z=}tK"f[-IR:.22 7xs YCIII<{W(f!Wkk+ꫯ_eРAq̙>䜽K!%Pc1ILLPqƌn}뭷VYV5&͜KѱqOFp/6egb:) E0͖'I$uYzz:ϒqٳt=ЪUt 7LӟD5şڰaۼUss|%&&ٳg^=rlٲG0?:Nt)``흭x񋾽 EWNg(66{(mll3l(l$nmSn?WW#IXw.;vE~,Dr_>`BH=z4͚5{iӦM[5kTh=?f s;KLLB+vx zsbiTV}PGa PAcvH4TtfӣGz')33SnG =.]* (++^`F3xڵmٲpx:j( I}7Υ[n Y=3{cܹtwMm`>ޯyh~~>---K 4CQ3R͛;Æ->!j--Zguu***Tpl6Iz# 0{9۷yG垊_}nA`3g2|b0,Dejjjy(ar( QC|O8!$pl"6gO :-Z䶧Çi0 'jl[kka3 <_O"O{4={|]+'g!zJ=G@^v-1s.**w}EfΝt%f埮Ջ{=~ [oZI̲,9,{ E0vRNDqqqr̙544ߏ+hֵkW/ES555n7+`"ᇳO:%$0 E֭[k]9sZ,[׿7\C 꺑UUU~, @wF5X4h-YwsVs2D0}ɓ 1  #&&G߿֬Y;0{|&33bc<|?|IJKKsy^NN7̟?ݫkJ z0J^.LM_~9Dr ~a_igт hĈ!(ߧ6m<+())Iti`xhRsΥ~[nݺ9ʹȘCt f%)Txx8/]vDNZ|n 6ye<#))g feeѸqLK8}޽{yiڵki׮]Gf\Lm6uTr8Kͥ|mw}'\Z?bwISg0ӭ[7z(==]bxw7o\tEK%$I4p@2e ]( ǭJUUU,be%f{4rH /GO=+2]k D" fͶCVV=Ӽ O?644Vju@TT;CI&a(-y֬Y|ȲL_}\T1 \3gE#Gpx2x`裏i dYrHPL J\\\|tt4㫘7o/X\OlmmZ׸q_]Ot k׮c4j( ]UVV:uѹsDp̺x~0S_qӟg q=pc==k,yjjj~- @g """G'jN<ɻرC̺Zsۮ}]@@IHH Cyߵkyyy܇QQ}?ѥɼk{n:99X,ӟZ.\HMMM$).,L!"`*ҹsdłf?ѹsg6tPma3gt /,,6nH:t]7*hĉ *]))ًբK2$3PTo[eI%%%OZ F|8***r~<&L9UUUK:s xt=, 2>Cnk.]k4#[ P0.-ZړnC=Do񆮵A>}@aaahVV]t]@PX,NO`1??6l@555K?i] TKK }t;$z7y{fp7 !PC$)Rt F I-XG*^_x+Srr2B2e oF};w.vۜmrVљͬY(߽_s_EWL࣏>J{Ҙ)MoA  "neur'5żg_L$IA9g!*jbӟmqF]"x)##l6.LN1w\zO>.S;vJwuZ,ybq^r(H||<+|fݺu<{V 8.Af~EƍqҤI| %%%.r>Z[[yb[b$I.^|Eѥ@8vS|'a+_|1ݷz+z|jpX‚`g06AGwު;S0fʔ)TZZ* ڵ+&O(9EgzCI<ٳg͙3GtDV+gm֢8|0|ARpPS]ǖm[Q`"᰺j lf<311QƢEhɒ%mرA&s3##ù+ڒ%.tWB[n1//C0A2ѥ@Yzœ͛G;vеFcDQ MBJ0 `4A7kvԩ /PDDs;e˖Z7llqqq4qDU3u64f>N*))p7x3Eɡ_~Ytd{?+V'11.]mtQ$7ew`:P,Kteŋ)$_J~WTTkmܬV+/cIKK1++nޏ]vkf*,,Q9=*<@}t zgDDD3<->#k $$9Dk[{U=~_ё#Gt @1l0JHH]nB}hԨQ"N2f|,\7ihXXXHK JCŲgfOW_u9Z<1>>σs8$lc;(Z,JW=+/;b馛 ަN*]EEE.)999 qر2ݻ/K>yItAA(ӦM^{Mt==X_|E^)]wˠqN"Ǡ" E0YEOV}Q+U+**պC bpQw#QqwʉkҚ5kxf%ZNNEĉt5poÇ<﷿-%%% ݮkҞ 2~`ntJ׿/V=/??1:ҧOѣ2L-::gfee Pٓ믿+7nQ9JKKEg:^x!^?}R UWWs+'|7seܹ;ID0`($rm_hh(-YU裏x9a3֭'O#G@m`1??mۆ@$IwyGt)xȇz.͜9g6ϟ??#IMYt(H._S/ې歷ޢ=G@`H߅fZ)##ùLO>> ۷/9{1//}|7#P#hmm?ꫯvyrOcwd%`6(22{ތ;V_~y \||<(l"""|>߄ x&X/@ AoϘ1c^t)|r}Mկ\7i$z繷BEnl(Ȳc]cbbhҥ4j(,YB-ҭ.5&LMBҜK?.>n&ł:u -,,ƏO+V] eoyʽ /@z+Z#E0Ikhziذa=3V;&M]ᅇsĬ,>RSSEpP߿߹Ost뭷ѣGu  IBB2@1cƈ.@3^IgjiiqyN׮]g{0CL"$?O Uϻ;i fS`vX j۶mt]w3|pzG^ "z(q_B'x>3j =!}'tRsrrro׭P$I@$Å7 ٳig}V|E$]hp8xSqq1/]4)22:t@]tݻS^hȐ!yP>}믿] @uԉf̘AnW)nu_dDk\4h-ZH-[… I1`}EDQ[[K+W|ڸqjCZ<1Əϛ1EEE^Ǹq(4DԲY9r$}@-uڕeE0(_唕EF)p^xv:x o&EGG~;mjfѣ^]x"^ Zno~iX @FxX=s+MMM***t ?v;=Sd<ŋ}{1bY,@&,!g$,iAwu/SsҞ={t (=C?g߾}teK/D~<Xׯ]!XBDخL"MY.b7o9wVG$ 87&owTn  9" !vDQ)K`($ k䔖F=Lׯ۷sUVq+@2b% ";w|IztlΨQhҥC赨V"| "w˳333u<뮻pO! >\t ͛|֭[|.x}_",KؔLPRSS7MJJӧ (44Teeepq۶mXh>sӧ2'hذaB>Gb ! ޹KP|!{MM |Y Ξ=[t@ %55"E&:: uԩsї_~ oWll,j ~өIϝ2e =쳺.x²gBDm< #vrrrкtn UV r Sn]b ?>ɲ~]@.zGt<J=z2"K[ZZ|Xt`0}dY纖``&Pl6&IF)))Ιcǎ|VVV]XXH~2T\Ɗ.8w=eքZ`pBzDѿ< k[[O8qo "f[-IR:|%&&9\ʢ(MP~~>ѧOǑ#GW_>z ./Hô-/Et BDx(c~+ @gPRSS?"KDaaaTnצ.?J7ov^DEܹsy'H<ռrWXX7(74`5jKz@_Gӧ.tQ /<9y$i PClKt:bСCy\p@EĽK\s2N<Ξ=KًἜk׮b"@;v,LB(^ccGeeeE~) @`(6yIn]zˢON#FQ ]zhȐn\"bk#|_"f{\?CD6m&MyfI[EePPPK!!!c ] /H>2"Eo!PCl$^uEDD?w199Yvl/JJJV+ߠA>]֭[k]x!b`@-`(;w^`X]Y,>|8/ViiiСCL999Zϋ@qZYYٗ>/@`(6m$I0+e6sq„ ڰaOgΜ[[sΥzHtL]F@\(|+Dt?Z%s)z7'Ҵi8`LNNv{rԩSeqX\\˯<ӿ%Ni05oBjZr%X#D \0C SNCBB]GX,,SccG:_A@bbbhҤI5kGI&a@9r$VSTTɓ%%yQ Pñl5$u]׻woO΃VŢzef> γ~$-~7]xih̘1ucȓ'OCUV͛" CcNJItM||/ @`86m$ICEӿ^Æ 4̙337l@ }ڵkqqтMXX=ڹJRR뛚h"Y***V+EE@ f$i:?yͯ###5] 6mO F~2@ ]f*S_FEEi\ZN5]H> ]OIiS Oz7n\T;wv{}xx8hTŞ={}ۇ^6?uiǀh˖- eضʨQ4(++qʕm6~[ܨ P#VAg*$I4dуn{ 4ng+^lڴg34% f q2V6movXX߿JJJxL.]" C#9= ɲ̽cd(''w';)))tWoV^M܇1a3տ%xjÝtMvj޽;ݛ?Jǎ9Dkאڀlg$I'#::(77z`0$$,˴c.[FS~DcE2IDATݻfϞ- M"""hر N24]& 4h4}<55y)?AcIGu~38D0aItٳTTT˥ArhUZZԥZZZj =;|1ΰaxqx8m4?~u""0\ }LDT,..懭˗/% ɬ,~owbcc9U miS4 px) sοX,ϊ'ICei&~b.Bdd$z*~=zp}ѡCA#xs-Μ9Hظq#hOdԓ8 *))[A<444IA(^Μ]xʕ+I^uݣԭ5}x2EE"oqI PIIIiZ# 8we9sFؾ `=o"""4]Y?γ4bΝ5Gۀz<@w x ~^{|v+I :3fhޙ y hx&mZ}4]k$III<2e .w3E@ sE| D, effr .hllA2S=Ǩ~F%$$h^(8p@u|7pqΝ>>o<aկ\VWt(iӦi~p6n}{3E/?껨u þqi y(:Ke7(A(ᤤD[Vv >9995PkqYXrӦMbss2EEﵶPKKG"P&f;$IRu}rZêa@!2S xp9r$̀T`{I˗/~dY;vʊhXZZ쇨+}\Zt:F,XRRvϋ"f!I)\AD$srrx9s>׶`KY$6AEHKKmgt~}kyvZlKkayRZZʛeffj~ٶzB9Z)S}]xv"f[+Iuj'ƹ155Uuuu)//7Nnݜdddh^j~Qx}^xEMa52Nغu+?Hҥ QZ+;w䱤2f9rjKJJr\3f .7".qI PCl$I!#%3gIk ~rJ hn7فcǎTo}"_uvl✉xIދg[Em}WZgΜ[ȻYII, E0$$IsD!JLL H<t}YYsз}v,a,""ƎMoll䙥[n''NeIZgGSS_޹\UU軸sNC@eŏKJ.yQ PClJt:ԩS'OCBB4]fժU026lsiցMX֭[˖2339`Ժjkk%Ί+^M۾Gu(|"Rjj꿈=z* iR߹ss&"z4M6 DgggS\\_jspCܼy3Zo.;wG}V PE0ԇuÀ8@9s&vg)>ew) ԩ3\5jO8.+[Z(ɢe?mŦ&6{}[Z9TE0`H;wbMt`Xx\u]PP< :tn<@^{-Z*.mKwz]D=`H6$=.O999SNpʕvZޔiԨQ>g Μ9ӣv=Te׮]/ݺus|̙%QQQ?껨uSV1P.z(:Ge}^ l6ۥ$}(IMM1f޽{!bqqOSt)`@7|3%_]ܱcsi_ZJ2YJJʲ|^ RRR&[5hӷo_*Æ t~!m镕NϘ֍ 8,\{=eU8`ܱc.z(n.))A2jnʗ^zz:3g@Q¿b ~vY C6me=sω.}+++}ׯ_/w"m,))A2j~gZVIm&bjj)??g"*[۷}}' R?8et}SSWw"BD.i\xx8o˛hUQQ_f+W/f NLL DpcǎK V__+i8`ڵ{)S!,13bcc;tu1115sLޑ,**JMUmfܺufΧ*eLZZ3\2dDv;f(E0T5HNN3fLqQhh:OҔ/={,uz:A:t0i|bÇ{P( E0,v\$wʿkD Y)@+. ,'' Xxȑ]t8ninn?#f(`"YOI(=="KӛN`ʗڵk}S@%u"Bqq1>G}{I7t?ب˯ !P#s r鍔/aqFjmiAcǎKSNo͇'}iܹ|"Y!P =z4͚5OO8}4+V[z<5 P"/iL.]^t5`(,t"]__?&**JǏ~ʗΝ; X PwDN7o~qv{$I4|p>,XTTTKF@WD/ _|?5ڳg0,f(B0;p< 8.=]}{E(P$}T($={pl2o_@,z(|ɓ[o}ۖFMnt,K PQ mFwy';vLDdd0Cxr<4sLzXNb]Ot>x D:t 08Ν;3%L"Mڋ~h%ʼn.s{E0`4<%Euc/(Ѩ.yԯbZ),,Lt`p @< E0)VuuuU@jbAPj02`4Lv~lf\q8c/BDf(fڱcٳʸ%HCCGJJ Ջ4  E`HKUD. EEɲLWOÇӸqhԽ{w Ɔ ]! PQf実@XdY>{9:v|nذG}kK.$Ii`l\kjjR}!| "V%_Mwq޽k.>}z(99Ƅp577. `J ^Ν0 .j#Jo!P040B?n>N8Aì -P"##E`H`.?07xC10C:. PQ{ AOL󨬬2gW>3! B``dh^Dp~VUt #O٥>V) BFS"gl6X Ѱ3@p5w+ju(Ԩ_%ѣ|iӄ|. R\sNuQ@@F(b`n\Zbb"p ~&&r(b"!PV{"ats8p Э?jhh(-Zu< cjU4(Ѩvر~lX`>f͢KR.]9=z7n_?C=gEEn@h(|gĈoMo&;vgݻwoiܹXd-f9Ϟ=[-F@ڋ U`t7~ڰa򿗗}"##iСRN: ׺5wNҭ#CF:C199YJ |׿@Ǐә3gɓȯQRRuܙCd .sb3(є"##yh(%{N- hxFMll%`dh;!55UJL ˞~=%%"$I5DTvN.]+ @Չ.Es(VUz02`D^޽~!֣G׏?[-F@hڋ{֯,?קOҭCFt@E,?׫W/׿9-˄t`*@0]@@s7yPq7oF@Hubbb"%$$W Ɗ.P:vj&Pyq1 P#GDj' 8Pj zss3}׺`tp$Ij%q `3cؿv`p(Q8h *Ss nϞ=(QX c555KX&޽[ZE0B{쉍Y~p. uؑzz(Q z_5W[[+ !!!K0C@խ@@ 黍Y@{ZDFF.0[ڵZZZt  P#۠^_%WWW';t P P#[ad;<{ts U[%`d,z1$$222Z[[hYE`=E1mt  PÒ$NeGAcƌѯ ,Eh/lѣG^TTě^,4ZKK(|7ڌ;V͛7/'IEL"Zee*HIII``ؘRͺuۏ "7\XSSI$I4i$}0(,yh?wΝ;w{=A&oH(}駎iWSLѯ khh]@R}=??Nt^Xv @BWq(,,L Jt  rKӭ@@αlV'DFFu- jjjDBm|  {H^ҕ*((е&@@ 3mp]խ]@@pwa<P@ O駟3e,{n]0ʽ^+VeU`xD-_|게:`3=PBEfʽrn+W:O޾ PÓ$j9w[|EVa3{fR}}Æ ?{X/I*7x@NED8m4էLf%^7@{G5z(9oH(DR/_|չ<1""f̘gmr(>Jg wz}}=Z/xwFDH( ~'_zz`8Kى.ח-[F ?_(ɲs爵;rHѣeEhN`ճgOgTGV@ CeӦMtQs 0jޑ@MmmꪫT_?vL"Ao9s̡Pj0RwZZZD0={9^Xd`*!K.ONLL,1 spf#ǻ|]]nXeYjA̙3n7gktH***DW]]-]{\Ξ=y(2z P@W^Q ##Ϛ "S__/]UYtx$I!޽ PS~l7J?6QXXHvRooet%a3믿^t (ɲl=drss)%%_eӧEL{BPىޗzUZ@@'|B'OtzHHԵ&0Cܩ]nn7tԩSlٲvw4KT(Bjii^zIkbccu @4Pwjk7^݆K.{Kw$w$ʎ/"$I.kTSShU`"6~0^022[ZU E0:Yeo/3 EpZt ~jx =E @)?+NXdNutW6éa4f(B0^^kz9V[y(I^7|S=͛O̮ΞE{pJt ~7Q=7ޠJչ+?mEwٻϝ ,T(QRAZA" [T bA@1Q-ŲXukW, a@Ifq4ssy>=s}^E8R9P+##ôUe˖RDϷ;`t(N;>gePP';Kqȑ@Aa"L_14tu 'XpV2l0KsPXXhw JJJN{GZh󊊊NZNoqq,Z4fذaҺuX8R ;PP-6mDy݉x _h8S^xb;vlr- ; )UgG;*+~TM₂"NuWVVܹsMc':tQz؝p( _r뭷ƤCE>Ep! kJvvv}>L2Ҝ+9rCq,)--XEo>yW-dJl8xJZ1ciLnݤgϞ'8P pCѡ/իt4f Q(8BAn:㗙4[r3'lwA8n<|V,St< ; ((RMN8KuuuĘs=W&Nc38v'Os9'Z/---[cJ$ c)//??/²_ѭؽ{wXk;wsf(sE$++4fʔ)ҵkWrA"n2b6l *&֥F֭[g, Ĉ8 NvWĉMc}]Yle9ŒRXRʘɱ{1~_222? AApbO>uKׯ1?KNzg\سgԡc }saEx EF'HiiiĘ͛ /)8޾}N@M:ղ`0hPU$ɱ;N͚5 kH5٘1c\~0*WPJ>%%ܨQLwA~鈇N@"Nw?k;vL233-&;p)?yza;vY[i ϡ|*;駟Mcz!iiilS6l庯-?H=ҭ[7Ә3gg/CYPPPUUUD$8_*Lc,C ,'t=zt>g*,,Gg1lyA,_\V^mYN梫|:fAA.i֛:uq4, 8f p&Mvmq܇-p믿^z!Ә>Hx r-;x}a*~mgر">]v-mݺuY\@RPctI͛gz:n8O lKsPP'%%EFm5;vh,x޽{NVZҥKe˖c5~*((47+ 'PPNӮ]dذaH;2m4Ә.H֮]kZ Gڝ^":t k֬ /0bL83gʂ , |0$iXءxK/cڶmkԩ!1l߾@pGtXi&b?~\ܬհzRJþҘ8E+"C. cZh!/},4rٻwinFc-b6]_ˌ5JyKss- ((“((•ޡ 6m&c7n,2tPKsm۶@l߾~ Dcذa<1fgYP( I$ 􇾾}Jnnn'=[o1N޲uVSk~XLbw8p|זR1?DA.E]NNӧC݊)))o ڝ1 hM 24n۶m?I:dYnvRG0<"EEE[~47#mֲMQ[Bر4Bs^Zza{w-%%%r~mA$ p-/u(~/ ʘ1cdŦq^zqKǎ- CAoٵk@] ._|iܒ%Kdرr8#O*O8L8G}T&O,>lYr|͖oٴi)e#+V0k4;w(&&4))"<"\KbIV\) ҈1gq̟?xS3NOnn; #q~L8(kHȰaÌQԢd $*}g^gw / ͛7,7x]xC8-[؝\@_3,ZHFa~0`((J((<ޤhɑ[nE>#Ӹ=z/,۷,7߶mN]4p]t1/{qׯ7ERRP'QPaMDK;;ɐ!C.D3^x+ҳgOrѡ7;8܍7h.Ӹ ;***,ÊE-$ pTY"t(~/ ɬYjM6 (;v-nlKE$`ɒ.)))7ΘTwF((³((5*fEvW>l7zhYl?,7OUUp9'"}-/M<(,rK YxϴHUΝ;w޲aӸJ^{5ԩe} mǎOď\yF3KeϞ=(a_9BA$fDII1W駟6moӦZJ瞄-lw )AgQFZ!222$55՘َRJ|5TYz\# 2oc K&MdϚ]wgra+~1brenٲJԟk(R-πgQ%T+wsAcO3|׿VZEmݺ 0@RRRd۶m%dիiعs13֤IYffG)YYYƼkX.RӴfC𐼼[PP딕oj̗D並I)%ݘSCbV+2Sg [$''8AdT=͛7۝p5Ȓ%K{sa'NTw NkBd,ӂG+6 ŦIENDB`go-bluetooth-bluez-5.60/hw/000077500000000000000000000000001420407601400156075ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/hw.go000066400000000000000000000013561420407601400165610ustar00rootroot00000000000000package hw import ( "github.com/muka/go-bluetooth/hw/linux" "github.com/muka/go-bluetooth/hw/linux/btmgmt" "github.com/muka/go-bluetooth/hw/linux/hciconfig" ) func GetAdapter(adapterID string) (a linux.AdapterInfo, err error) { return linux.GetAdapter(adapterID) } func GetAdapters() ([]linux.AdapterInfo, error) { return linux.GetAdapters() } func Up(adapterID string) error { return linux.Up(adapterID) } func Down(adapterID string) error { return linux.Down(adapterID) } func Reset(adapterID string) error { return linux.Reset(adapterID) } func NewBtMgmt(adapterID string) *btmgmt.BtMgmt { return btmgmt.NewBtMgmt(adapterID) } func NewHCIConfig(adapterID string) *hciconfig.HCIConfig { return hciconfig.NewHCIConfig(adapterID) } go-bluetooth-bluez-5.60/hw/linux/000077500000000000000000000000001420407601400167465ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/linux/btmgmt/000077500000000000000000000000001420407601400202405ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/linux/btmgmt/btmgmt.go000066400000000000000000000124121420407601400220610ustar00rootroot00000000000000package btmgmt import ( "errors" "fmt" "regexp" "strings" "github.com/muka/go-bluetooth/hw/linux/cmd" ) const ( DefaultBinPath = "btmgmt" ) //BtAdapter contains info about adapter from btmgmt type BtAdapter struct { ID string Name string ShortName string Addr string Version string Manufacturer string Class string SupportedSettings []string CurrentSettings []string } //GetAdapter return an adapter func GetAdapter(adapterID string) (*BtAdapter, error) { adapters, err := GetAdapters() if err != nil { return nil, err } for _, a := range adapters { if a.ID == adapterID { return a, nil } } return nil, fmt.Errorf("Adapter %s not found", adapterID) } //GetAdapters return a list of adapters func GetAdapters() ([]*BtAdapter, error) { raw, err := cmd.Exec("btmgmt", "info") if err != nil { return nil, err } if len(raw) == 0 { return nil, errors.New("btmgmt provided no response") } list := make([]*BtAdapter, 0) lines := strings.Split(raw, "\n") lines = lines[1:] // hci1: Primary controller re1 := regexp.MustCompile("([a-z0-9]+):[ ]*") // addr 10:08:B1:72:F5:98 version 6 manufacturer 93 class 0x000000 re2 := regexp.MustCompile("\taddr ([a-zA-z0-9:]+) version ([0-9]+) manufacturer ([0-9]+) class ([0-9a-zA-Zx]+)") // supported settings: re3 := regexp.MustCompile("\t.+: (.*)") // (short )name re4 := regexp.MustCompile("\t.*name (.*)") // track if parsing an adapter for i := 0; i < len(lines); i++ { if !re1.MatchString(lines[i]) { continue } el := new(BtAdapter) res := re1.FindStringSubmatch(lines[i]) if len(res) > 1 { el.ID = res[1] } i++ res = re2.FindStringSubmatch(lines[i]) if len(res) > 1 { el.Addr = res[1] el.Version = res[2] el.Manufacturer = res[3] el.Class = res[4] } i++ //supported settings res = re3.FindStringSubmatch(lines[i]) if len(res) > 1 { el.SupportedSettings = strings.Split(res[1], " ") } i++ //current settings res = re3.FindStringSubmatch(lines[i]) if len(res) > 1 { el.CurrentSettings = strings.Split(res[1], " ") } if lines[i] == "" { //empty line i++ } i++ //name res = re4.FindStringSubmatch(lines[i]) if len(res) > 1 { el.Name = res[1] } i++ //short name res = re4.FindStringSubmatch(lines[i]) if len(res) > 1 { el.ShortName = res[1] } list = append(list, el) } return list, nil } // NewBtMgmt init a new BtMgmt command func NewBtMgmt(adapterID string) *BtMgmt { return &BtMgmt{adapterID, DefaultBinPath} } // BtMgmt btmgmt command wrapper type BtMgmt struct { adapterID string // BinPath configure the CLI path to btmgmt BinPath string } // btmgmt cmd wrapper func (h *BtMgmt) cmd(args ...string) error { cmdArgs := []string{h.BinPath, "--index", h.adapterID} cmdArgs = append(cmdArgs, args...) _, err := cmd.Exec(cmdArgs...) if err != nil { return err } return nil } // Reset reset the power func (h *BtMgmt) Reset() error { err := h.SetPowered(false) if err != nil { return err } return h.SetPowered(true) } // SetDeviceID Set Device ID name func (h *BtMgmt) SetDeviceID(did string) error { return h.cmd("did", did) } // SetName Set local name func (h *BtMgmt) SetName(name string) error { return h.cmd("name", name) } // SetClass set device class func (h *BtMgmt) SetClass(major, minor string) error { return h.cmd("class", major, minor) } // SetPowered set power to adapter func (h *BtMgmt) setFlag(flag string, val bool) error { var v string if val { v = "on" } else { v = "off" } return h.cmd(flag, v) } // SetPowered set power to adapter func (h *BtMgmt) SetPowered(status bool) error { return h.setFlag("power", status) } // SetDiscoverable Set discoverable state func (h *BtMgmt) SetDiscoverable(status bool) error { return h.setFlag("discov", status) } // SetConnectable Set connectable state func (h *BtMgmt) SetConnectable(status bool) error { return h.setFlag("connectable", status) } // SetFastConnectable Set fast connectable state func (h *BtMgmt) SetFastConnectable(status bool) error { return h.setFlag("fast", status) } // SetBondable Set bondable state func (h *BtMgmt) SetBondable(status bool) error { return h.setFlag("bondable", status) } // SetPairable Set bondable state func (h *BtMgmt) SetPairable(status bool) error { return h.setFlag("pairable", status) } // SetLinkLevelSecurity Set link level security func (h *BtMgmt) SetLinkLevelSecurity(status bool) error { return h.setFlag("linksec", status) } // SetSsp Set SSP mode func (h *BtMgmt) SetSsp(status bool) error { return h.setFlag("ssp", status) } // SetSc Toogle SC support func (h *BtMgmt) SetSc(status bool) error { return h.setFlag("sc", status) } // SetHs Set HS support func (h *BtMgmt) SetHs(status bool) error { return h.setFlag("hs", status) } // SetLe Set LE support func (h *BtMgmt) SetLe(status bool) error { return h.setFlag("le", status) } // SetAdvertising Set LE advertising func (h *BtMgmt) SetAdvertising(status bool) error { return h.setFlag("advertising", status) } // SetBredr Set BR/EDR support func (h *BtMgmt) SetBredr(status bool) error { return h.setFlag("bredr", status) } // SetPrivacy Set privacy support func (h *BtMgmt) SetPrivacy(status bool) error { return h.setFlag("privacy", status) } go-bluetooth-bluez-5.60/hw/linux/btmgmt/btmgmt_test.go000066400000000000000000000006061420407601400231220ustar00rootroot00000000000000package btmgmt import "testing" import log "github.com/sirupsen/logrus" func TestGetAdapters(t *testing.T) { log.SetLevel(log.TraceLevel) list, err := GetAdapters() if err != nil { t.Fatal(err) } if len(list) == 0 { t.Fatal("At least an adapter should be available") } } func TestGetAdapter(t *testing.T) { _, err := GetAdapter("0") if err != nil { t.Fatal(err) } } go-bluetooth-bluez-5.60/hw/linux/cmd/000077500000000000000000000000001420407601400175115ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/linux/cmd/cmd.go000066400000000000000000000005451420407601400206070ustar00rootroot00000000000000package cmd import ( "os/exec" log "github.com/sirupsen/logrus" ) // Exec Execute a command and collect the output func Exec(args ...string) (string, error) { baseCmd := args[0] cmdArgs := args[1:] log.Tracef("Exec: %s %s", baseCmd, cmdArgs) cmd := exec.Command(baseCmd, cmdArgs...) res, err := cmd.CombinedOutput() return string(res), err } go-bluetooth-bluez-5.60/hw/linux/hci/000077500000000000000000000000001420407601400175115ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/linux/hci/hci.go000066400000000000000000000130451420407601400206060ustar00rootroot00000000000000// credits: https://github.com/go-ble/ble/blob/master/linux/hci/socket/socket.go // I attempted a PR but id not go through package hci import ( "fmt" "io" "sync" "unsafe" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) func ioR(t, nr, size uintptr) uintptr { return (2 << 30) | (t << 8) | nr | (size << 16) } func ioW(t, nr, size uintptr) uintptr { return (1 << 30) | (t << 8) | nr | (size << 16) } func ioctl(fd, op, arg uintptr) error { if _, _, ep := unix.Syscall(unix.SYS_IOCTL, fd, op, arg); ep != 0 { return ep } return nil } const ( ioctlSize = 4 hciMaxDevices = 16 typHCI = 72 // 'H' ) var ( hciUpDevice = ioW(typHCI, 201, ioctlSize) // HCIDEVUP hciDownDevice = ioW(typHCI, 202, ioctlSize) // HCIDEVDOWN hciResetDevice = ioW(typHCI, 203, ioctlSize) // HCIDEVRESET hciGetDeviceList = ioR(typHCI, 210, ioctlSize) // HCIGETDEVLIST hciGetDeviceInfo = ioR(typHCI, 211, ioctlSize) // HCIGETDEVINFO ) type devListRequest struct { devNum uint16 devRequest [hciMaxDevices]struct { id uint16 opt uint32 } } // Socket implements a HCI User Channel as ReadWriteCloser. type Socket struct { fd int closed chan struct{} rmu sync.Mutex wmu sync.Mutex } // NewSocket returns a HCI User Channel of specified device id. // If id is -1, the first available HCI device is returned. func NewSocket(id int) (*Socket, error) { var err error // Create RAW HCI Socket. fd, err := unix.Socket(unix.AF_BLUETOOTH, unix.SOCK_RAW, unix.BTPROTO_HCI) if err != nil { return nil, errors.Wrap(err, "can't create socket") } if id != -1 { return open(fd, id) } req := devListRequest{devNum: hciMaxDevices} if err = ioctl(uintptr(fd), hciGetDeviceList, uintptr(unsafe.Pointer(&req))); err != nil { return nil, errors.Wrap(err, "can't get device list") } var msg string for id := 0; id < int(req.devNum); id++ { s, err := open(fd, id) if err == nil { return s, nil } msg = msg + fmt.Sprintf("(hci%d: %s)", id, err) } return nil, errors.Errorf("no devices available: %s", msg) } func open(fd, id int) (*Socket, error) { // Reset the device in case previous session didn't cleanup properly. if err := ioctl(uintptr(fd), hciDownDevice, uintptr(id)); err != nil { return nil, errors.Wrap(err, "can't down device") } if err := ioctl(uintptr(fd), hciUpDevice, uintptr(id)); err != nil { return nil, errors.Wrap(err, "can't up device") } // HCI User Channel requires exclusive access to the device. // The device has to be down at the time of binding. if err := ioctl(uintptr(fd), hciDownDevice, uintptr(id)); err != nil { return nil, errors.Wrap(err, "can't down device") } // Bind the RAW socket to HCI User Channel sa := unix.SockaddrHCI{Dev: uint16(id), Channel: unix.HCI_CHANNEL_USER} if err := unix.Bind(fd, &sa); err != nil { return nil, errors.Wrap(err, "can't bind socket to hci user channel") } // poll for 20ms to see if any data becomes available, then clear it pfds := []unix.PollFd{{Fd: int32(fd), Events: unix.POLLIN}} _, err := unix.Poll(pfds, 20) if err != nil { log.Error(err) } if pfds[0].Revents&unix.POLLIN > 0 { b := make([]byte, 100) _, err = unix.Read(fd, b) if err != nil { log.Error(err) } } return &Socket{fd: fd, closed: make(chan struct{})}, nil } func (s *Socket) Read(p []byte) (int, error) { s.rmu.Lock() n, err := unix.Read(s.fd, p) s.rmu.Unlock() // Close always sends a dummy command to wake up Read // bad things happen to the HCI state machines if they receive // a reply from that command, so make sure no data is returned // on a closed socket. // // note that if Write and Close are called concurrently it's // indeterminate which replies get through. select { case <-s.closed: return 0, io.EOF default: } return n, errors.Wrap(err, "can't read hci socket") } func (s *Socket) Write(p []byte) (int, error) { s.wmu.Lock() defer s.wmu.Unlock() n, err := unix.Write(s.fd, p) return n, errors.Wrap(err, "can't write hci socket") } func (s *Socket) Close() error { close(s.closed) _, err := s.Write([]byte{0x01, 0x09, 0x10, 0x00}) // no-op command to wake up the Read call if it's blocked if err != nil { log.Error(err) } s.rmu.Lock() defer s.rmu.Unlock() return errors.Wrap(unix.Close(s.fd), "can't close hci socket") } //Up turn up a HCI device by ID func Up(id int) error { // Create RAW HCI Socket. fd, err := unix.Socket(unix.AF_BLUETOOTH, unix.SOCK_RAW, unix.BTPROTO_HCI) if err != nil { return errors.Wrap(err, "can't create socket") } if err := ioctl(uintptr(fd), hciUpDevice, uintptr(id)); err != nil { return errors.Wrap(err, "can't down device") } return unix.Close(fd) } //Down turn down a HCI device by ID func Down(id int) error { // Create RAW HCI Socket. fd, err := unix.Socket(unix.AF_BLUETOOTH, unix.SOCK_RAW, unix.BTPROTO_HCI) if err != nil { return errors.Wrap(err, "can't create socket") } if err := ioctl(uintptr(fd), hciDownDevice, uintptr(id)); err != nil { return errors.Wrap(err, "can't down device") } return unix.Close(fd) } //List List HCI devices func List() ([]int, error) { var err error // Create RAW HCI Socket. fd, err := unix.Socket(unix.AF_BLUETOOTH, unix.SOCK_RAW, unix.BTPROTO_HCI) if err != nil { return nil, errors.Wrap(err, "can't create socket") } req := devListRequest{devNum: hciMaxDevices} if err = ioctl(uintptr(fd), hciGetDeviceList, uintptr(unsafe.Pointer(&req))); err != nil { return nil, errors.Wrap(err, "can't get device list") } list := make([]int, 0) for id := 0; id < int(req.devNum); id++ { list = append(list, id) } return list, nil } go-bluetooth-bluez-5.60/hw/linux/hci/hci_test.go000066400000000000000000000011121420407601400216350ustar00rootroot00000000000000package hci import ( "testing" log "github.com/sirupsen/logrus" ) func TestHciList(t *testing.T) { log.SetLevel(log.DebugLevel) list, err := List() if err != nil { t.Fatal(err) } if len(list) == 0 { t.Fatal("At least an adapter should be available") } } func TestHciUp(t *testing.T) { log.SetLevel(log.DebugLevel) list, err := List() if err != nil { t.Fatal(err) } if len(list) == 0 { t.Fatal("At least an adapter should be available") } err = Up(list[0]) if err != nil { t.Fatal(err) } err = Down(list[0]) if err != nil { t.Fatal(err) } } go-bluetooth-bluez-5.60/hw/linux/hciconfig/000077500000000000000000000000001420407601400206775ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/linux/hciconfig/hciconfig.go000066400000000000000000000046611420407601400231660ustar00rootroot00000000000000package hciconfig import ( "errors" "strings" "github.com/muka/go-bluetooth/hw/linux/cmd" ) // GetAdapters return the list of available adapters func GetAdapters() ([]HCIConfigResult, error) { out, err := cmd.Exec("hciconfig") if err != nil { return nil, err } if len(out) == 0 { return nil, errors.New("hciconfig provided no response") } list := []HCIConfigResult{} parts := strings.Split(out, "\nhci") for i, el := range parts { if i > 0 { el = "hci" + el } cfg := parseControllerInfo(el) list = append(list, cfg) } // log.Debugf("%++v", list) return list, nil } // GetAdapter return an adapter func GetAdapter(adapterID string) (*HCIConfigResult, error) { h := NewHCIConfig(adapterID) return h.Status() } // NewHCIConfig initialize a new HCIConfig func NewHCIConfig(adapterID string) *HCIConfig { return &HCIConfig{adapterID} } //HCIConfigResult contains details for an adapter type HCIConfigResult struct { AdapterID string Enabled bool Address string Type string Bus string } // HCIConfig an hciconfig command wrapper type HCIConfig struct { adapterID string } func parseControllerInfo(out string) HCIConfigResult { cfg := HCIConfigResult{} cfg.AdapterID = strings.Trim(out[:6], " \t:") s := strings.Replace(out[6:], "\t", "", -1) lines := strings.Split(s, "\n") // var parts []string for i, line := range lines { if i > 2 { break } if i == 2 { pp := strings.Split(line, " ") cfg.Enabled = (pp[0] == "UP") continue } subparts := strings.Split(line, " ") for _, subpart := range subparts { pp := strings.Split(subpart, ": ") switch pp[0] { case "Type": cfg.Type = pp[1] continue case "Bus": cfg.Bus = pp[1] continue case "BD Address": cfg.Address = pp[1] continue } } } return cfg } //Status return status information for a hci device func (h *HCIConfig) Status() (*HCIConfigResult, error) { out, err := cmd.Exec("hciconfig", h.adapterID) if err != nil { return nil, err } cfg := parseControllerInfo(out) return &cfg, nil } // Up Turn on an HCI device func (h *HCIConfig) Up() (*HCIConfigResult, error) { _, err := cmd.Exec("hciconfig", h.adapterID, "up") if err != nil { return nil, err } return h.Status() } // Down Turn down an HCI device func (h *HCIConfig) Down() (*HCIConfigResult, error) { _, err := cmd.Exec("hciconfig", h.adapterID, "down") if err != nil { return nil, err } return h.Status() } go-bluetooth-bluez-5.60/hw/linux/hciconfig/hciconfig_test.go000066400000000000000000000010521420407601400242140ustar00rootroot00000000000000package hciconfig import ( "testing" log "github.com/sirupsen/logrus" ) func TestStatus(t *testing.T) { h := NewHCIConfig("hci0") _, err := h.Status() if err != nil { t.Fatal() } } func TestUpDown(t *testing.T) { h := NewHCIConfig("hci0") _, err := h.Status() if err != nil { t.Fatal(err) } _, err = h.Down() if err != nil { t.Fatal(err) } _, err = h.Up() if err != nil { t.Fatal(err) } } func TestGetAdapters(t *testing.T) { log.SetLevel(log.DebugLevel) _, err := GetAdapters() if err != nil { t.Fatal(err) } } go-bluetooth-bluez-5.60/hw/linux/hcitool/000077500000000000000000000000001420407601400204075ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/linux/hcitool/hcitool.go000066400000000000000000000021601420407601400223760ustar00rootroot00000000000000package hcitool import ( "regexp" "strings" "github.com/muka/go-bluetooth/hw/linux/cmd" ) type HcitoolDev struct { ID string Address string } // GetAdapter Return an adapter using hcitool as backend func GetAdapter(adapterID string) (*HcitoolDev, error) { list, err := GetAdapters() if err != nil { return nil, err } for _, a := range list { if a.ID == adapterID { return a, nil } } return nil, nil } // GetAdapters Return a list of adapters using hcitool as backend func GetAdapters() ([]*HcitoolDev, error) { list := make([]*HcitoolDev, 0) raw, err := cmd.Exec("hcitool", "dev") if err != nil { return nil, err } // raw: // Devices: // hci1 70:C9:4E:58:AA:7E lines := strings.Split(raw, "\n") lines = lines[1:] // hci1 70:C9:4E:58:AA:7E re1 := regexp.MustCompile("^[ \t]*([a-zA-Z0-9]+)[ \t]*([a-zA-Z0-9:]+)$") for i := 0; i < len(lines); i++ { if !re1.MatchString(lines[i]) { continue } el := new(HcitoolDev) res := re1.FindStringSubmatch(lines[i]) if len(res) > 1 { el.ID = res[1] el.Address = res[2] list = append(list, el) } } return list, nil } go-bluetooth-bluez-5.60/hw/linux/hcitool/hcitool_test.go000066400000000000000000000015151420407601400234400ustar00rootroot00000000000000package hcitool import ( "fmt" "testing" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) func TestHcitoolGetAdapters(t *testing.T) { log.SetLevel(log.DebugLevel) list, err := GetAdapters() if err != nil { t.Fatal(err) } assert.NotEmpty(t, list) } func TestHcitoolGetAdapter(t *testing.T) { log.SetLevel(log.DebugLevel) a, err := GetAdapter("hci0") if err != nil { t.Fatal(err) } if a == nil { t.Fatal("An adapter should be available") } } func TestHcitoolGetAdapterNotfound(t *testing.T) { log.SetLevel(log.DebugLevel) list, err := GetAdapters() if err != nil { t.Fatal(err) } size := len(list) devID := fmt.Sprintf("hci%d", (size + 1)) a, err := GetAdapter(devID) if err != nil { t.Fatal(err) } if a != nil { t.Fatal(fmt.Sprintf("%s should not be avail", devID)) } } go-bluetooth-bluez-5.60/hw/linux/linux.go000066400000000000000000000046751420407601400204500ustar00rootroot00000000000000package linux import ( "fmt" "strconv" "github.com/muka/go-bluetooth/hw/linux/btmgmt" "github.com/muka/go-bluetooth/hw/linux/hci" "github.com/muka/go-bluetooth/hw/linux/hciconfig" log "github.com/sirupsen/logrus" ) type BackendType string const ( BackendBtmgmt BackendType = "btmgmt" BackendHCI BackendType = "hci" BackendHCIConfig BackendType = "hciconfig" ) var Backend BackendType = BackendHCIConfig type AdapterInfo struct { AdapterID string Address string Type string Enabled bool } // GetAdapter return status information for a controller func GetAdapter(adapterID string) (a AdapterInfo, err error) { list, err := GetAdapters() if err != nil { return a, err } for _, a := range list { if a.AdapterID == adapterID { return a, err } } return a, fmt.Errorf("Adapter %s not found", adapterID) } // GetAdapters return a list of status information of available controllers func GetAdapters() ([]AdapterInfo, error) { list, err := hciconfig.GetAdapters() if err != nil { return nil, err } list1 := []AdapterInfo{} for _, info := range list { list1 = append(list1, AdapterInfo{ AdapterID: info.AdapterID, Enabled: info.Enabled, Type: info.Type, Address: info.Address, }) } return list1, err } func Up(adapterID string) error { status, err := GetAdapter(adapterID) if err != nil { return err } if status.Enabled { return nil } if Backend == BackendHCIConfig { _, err := hciconfig.NewHCIConfig(adapterID).Up() return err } if Backend == BackendBtmgmt { return btmgmt.NewBtMgmt(adapterID).SetPowered(true) } if Backend == BackendHCI { id, err := strconv.Atoi(adapterID[3:]) if err != nil { return err } return hci.Up(id) } return fmt.Errorf("Unsupported backend type: %s", Backend) } func Down(adapterID string) error { status, err := GetAdapter(adapterID) if err != nil { return err } if !status.Enabled { return nil } if Backend == BackendHCIConfig { _, err := hciconfig.NewHCIConfig(adapterID).Down() return err } if Backend == BackendBtmgmt { return btmgmt.NewBtMgmt(adapterID).SetPowered(false) } if Backend == BackendHCI { id, err := strconv.Atoi(adapterID[3:]) if err != nil { return err } return hci.Down(id) } return fmt.Errorf("Unsupported backend type: %s", Backend) } func Reset(adapterID string) error { err := Down(adapterID) if err != nil { log.Warnf("Down failed: %s", err) } return Up(adapterID) } go-bluetooth-bluez-5.60/hw/linux/linux_test.go000066400000000000000000000014501420407601400214730ustar00rootroot00000000000000package linux import ( "testing" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) func TestGetAdapters(t *testing.T) { log.SetLevel(log.DebugLevel) list, err := GetAdapters() if err != nil { t.Fatal(err) } assert.NotEmpty(t, list) } func TestGetAdapter(t *testing.T) { log.SetLevel(log.DebugLevel) _, err := GetAdapter("hci0") if err != nil { t.Fatal(err) } } func TestGetAdapterNotFound(t *testing.T) { _, err := GetAdapter("hci999") if err == nil { t.Fatal("adapter should not exists") } } func TestUp(t *testing.T) { err := Up("hci0") if err != nil { t.Fatal(err) } } func TestDown(t *testing.T) { err := Down("hci0") if err != nil { t.Fatal(err) } } func TestReset(t *testing.T) { err := Reset("hci0") if err != nil { t.Fatal(err) } } go-bluetooth-bluez-5.60/hw/linux/rfkill/000077500000000000000000000000001420407601400202315ustar00rootroot00000000000000go-bluetooth-bluez-5.60/hw/linux/rfkill/rfkill.go000066400000000000000000000106501420407601400220450ustar00rootroot00000000000000package rfkill // Code based on rfkill.go from skycoin/skycoin project // https://github.com/skycoin/skycoin/blob/master/src/aether/wifi/linux/rfkill.go import ( "fmt" "io/ioutil" "os/exec" "strconv" "strings" log "github.com/sirupsen/logrus" ) func limitText(text []byte) string { t := strings.TrimSpace(string(text)) if len(t) > 150 { t = t[0:150] + "..." } return "[" + t + "]" } // RFKill is a wrapper for linux utility: rfkill // Checks the status of kill switches. If either is set, the device will be disabled. // Soft = Software (set by software) // Hard = Hardware (physical on/off switch on the device) // Identifiers = all, wifi, wlan, bluetooth, uwb, ultrawideband, wimax, wwan, gps, fm // See: http://wireless.kernel.org/en/users/Documentation/rfkill type RFKill struct{} // NewRFKill Creates a new RFKill instance func NewRFKill() RFKill { return RFKill{} } // RFKillResult Result of rfkill request type RFKillResult struct { Index int IdentifierType string Description string SoftBlocked bool HardBlocked bool } // IsInstalled Checks if the program rfkill exists using PATH environment variable func (self RFKill) IsInstalled() bool { _, err := exec.LookPath("rfkill") // no log? really? return err == nil } // ListAll Returns a list of rfkill results for every identifier type func (self RFKill) ListAll() ([]RFKillResult, error) { rfks := []RFKillResult{} rfk := RFKillResult{} fq := self.fileQuery // instead of parsing "rfkill list", query the filesystem dirInfos, err := ioutil.ReadDir("/sys/class/rfkill/") if err != nil { return nil, fmt.Errorf( "RFKill: Error reading directory '/sys/class/rfkill/': %v", err) } for _, dirInfo := range dirInfos { // directory starts with "rfkill" if len(dirInfo.Name()) > 6 && dirInfo.Name()[0:6] == "rfkill" { qp := "/sys/class/rfkill/" + dirInfo.Name() rfk.Index, _ = strconv.Atoi(fq(qp + "/index")) rfk.IdentifierType = fq(qp + "/type") rfk.Description = fq(qp + "/name") rfk.SoftBlocked = false rfk.HardBlocked = false if fq(qp+"/soft") == "1" { rfk.SoftBlocked = true } if fq(qp+"/hard") == "1" { rfk.HardBlocked = true } rfks = append(rfks, rfk) rfk = RFKillResult{} } } return rfks, nil } // SoftBlock RFKill Sets a software block on an identifier func (self RFKill) SoftBlock(identifier string) error { cmd := exec.Command("rfkill", "block", identifier) out, err := cmd.CombinedOutput() if err != nil { log.Errorf("Command Error: %v : %v", err, limitText(out)) return err } return nil } //SoftUnblock Removes a software block on an identifier func (self RFKill) SoftUnblock(identifier string) error { cmd := exec.Command("rfkill", "unblock", identifier) out, err := cmd.CombinedOutput() if err != nil { log.Errorf("Command Error: %v : %v", err, limitText(out)) return err } return nil } //IsBlocked Checks if an identifier has a software or hardware block func (self RFKill) IsBlocked(identifier string) bool { rfks, _ := self.ListAll() for _, rfk := range rfks { if self.checkThis(rfk, identifier) { if rfk.SoftBlocked || rfk.HardBlocked { return true } } } return false } //IsSoftBlocked Checks if an identifier has a software block func (self RFKill) IsSoftBlocked(identifier string) bool { rfks, _ := self.ListAll() for _, rfk := range rfks { if self.checkThis(rfk, identifier) { if rfk.SoftBlocked { return true } } } return false } //IsHardBlocked Checks if an identifier has a hardware block func (self RFKill) IsHardBlocked(identifier string) bool { rfks, _ := self.ListAll() for _, rfk := range rfks { if self.checkThis(rfk, identifier) { if rfk.HardBlocked { return true } } } return false } //IsBlockedAfterUnblocking Checks if an identifier has a software or hardware block after // removing a software block if it exists func (self RFKill) IsBlockedAfterUnblocking(identifier string) bool { if self.IsBlocked(identifier) { err := self.SoftUnblock(identifier) if err != nil { log.Warn(err) } if self.IsBlocked(identifier) { return true } } return false } func (self RFKill) checkThis(rfk RFKillResult, identifier string) bool { switch identifier { case "": return true case "all": return true case rfk.IdentifierType: return true } return false } func (self RFKill) fileQuery(queryFile string) string { out, _ := ioutil.ReadFile(queryFile) outs := string(out) outs = strings.TrimSpace(outs) return outs } go-bluetooth-bluez-5.60/hw/linux/rfkill/rfkill_test.go000066400000000000000000000015151420407601400231040ustar00rootroot00000000000000package rfkill import "testing" var testAdapterID = "hci0" func TestGetAdapterStatus(t *testing.T) { _, err := GetAdapterStatus(testAdapterID) if err != nil { t.Fatal(err) } } func TestToggleAdapter(t *testing.T) { err := ToggleAdapter(testAdapterID) if err != nil { t.Fatal(err) } } func TestTurnOnAdapter(t *testing.T) { err := TurnOnAdapter(testAdapterID) if err != nil { t.Fatal(err) } } func TestTurnOffAdapter(t *testing.T) { err := TurnOffAdapter(testAdapterID) if err != nil { t.Fatal(err) } } func TestTurnOnBluetooth(t *testing.T) { err := TurnOnBluetooth() if err != nil { t.Fatal(err) } } func TestTurnOffBluetooth(t *testing.T) { err := TurnOffBluetooth() if err != nil { t.Fatal(err) } } func TestToggleBluetooth(t *testing.T) { err := ToggleBluetooth() if err != nil { t.Fatal(err) } } go-bluetooth-bluez-5.60/hw/linux/rfkill/switch.go000066400000000000000000000053161420407601400220660ustar00rootroot00000000000000package rfkill import ( "errors" "strconv" "github.com/muka/go-bluetooth/hw/linux/hciconfig" ) var rfclass = [...]string{ "bluetooth", "wifi", } var rfkillHandler = NewRFKill() // GetHCIConfig return an HCIConfig struct func GetHCIConfig(adapterID string) *hciconfig.HCIConfig { return hciconfig.NewHCIConfig(adapterID) } // GetAdapterStatus return the status of an adapter func GetAdapterStatus(adapterID string) (*RFKillResult, error) { if !rfkillHandler.IsInstalled() { return nil, errors.New("rfkill is not available") } list, err := rfkillHandler.ListAll() if err != nil { return nil, err } for _, adapter := range list { if adapter.Description == adapterID { // dbgSwitch("Got adapter index %d desc: %s type: %s hard-block: %t soft-block: %t", // adapter.Index, // adapter.Description, // adapter.IdentifierType, // adapter.HardBlocked, // adapter.SoftBlocked, // ) return &adapter, nil } } return nil, errors.New("Adapter not found") } // ToggleAdapter Swap Off/On a device func ToggleAdapter(adapterID string) error { err := TurnOffAdapter(adapterID) if err != nil { return err } return TurnOnAdapter(adapterID) } // TurnOnAdapter Enable a rfkill managed device func TurnOnAdapter(adapterID string) error { var identifier string if isRFClass(adapterID) { identifier = adapterID } else { adapter, err := GetAdapterStatus(adapterID) if err != nil { return err } identifier = strconv.Itoa(adapter.Index) } if rfkillHandler.IsSoftBlocked(adapterID) { err := rfkillHandler.SoftUnblock(identifier) if err != nil { return err } } if rfkillHandler.IsHardBlocked(adapterID) { return errors.New("Adapter is hard locked, check for a physical switch to enable it") } return nil } // TurnOffAdapter Enable a rfkill managed device func TurnOffAdapter(adapterID string) error { var identifier string if isRFClass(adapterID) { identifier = adapterID } else { adapter, err := GetAdapterStatus(adapterID) if err != nil { return err } identifier = strconv.Itoa(adapter.Index) } if !rfkillHandler.IsSoftBlocked(adapterID) { err := rfkillHandler.SoftBlock(identifier) if err != nil { return err } } return nil } func isRFClass(id string) bool { for _, class := range rfclass { if class == id { return true } } return false } // TurnOnBluetooth turn on bluetooth support func TurnOnBluetooth() error { return TurnOnAdapter("bluetooth") } // TurnOffBluetooth turn on bluetooth support func TurnOffBluetooth() error { return TurnOffAdapter("bluetooth") } // ToggleBluetooth toggle off/on the bluetooth support func ToggleBluetooth() error { err := TurnOffBluetooth() if err != nil { return err } return TurnOnBluetooth() } go-bluetooth-bluez-5.60/props/000077500000000000000000000000001420407601400163345ustar00rootroot00000000000000go-bluetooth-bluez-5.60/props/props.go000066400000000000000000000044501420407601400200310ustar00rootroot00000000000000package props import ( "reflect" "strings" "github.com/fatih/structs" "github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5/prop" "github.com/muka/go-bluetooth/bluez" log "github.com/sirupsen/logrus" ) type PropInfo struct { prop.Prop Skip bool } func ParseProperties(propertyVal bluez.Properties) map[string]*PropInfo { t := structs.New(propertyVal) res := map[string]*PropInfo{} for _, field := range t.Fields() { if !field.IsExported() { continue } // if _, ok := field.Value().(dbus.ObjectPath); ok && field.IsZero() { // log.Debugf("parseProperties: skip empty ObjectPath %s", field.Name()) // continue // } propInfo := new(PropInfo) propInfo.Value = field.Value() res[field.Name()] = propInfo tag := field.Tag("dbus") if tag == "" { continue } parts := strings.Split(tag, ",") for i := 0; i < len(parts); i++ { tagKey := parts[i] tagValue := "" if strings.Contains(parts[i], "=") { subpts := strings.Split(parts[i], "=") tagKey = subpts[0] tagValue = strings.Join(subpts[1:], "=") } if tagKey == "ignore" { if tagValue == "" { propInfo.Skip = true } else { checkField, ok := t.FieldOk(tagValue) if !ok { log.Warnf("%s: field not found, is it avaialable?", tagValue) continue } if !checkField.IsExported() { log.Warnf("%s: field must be exported. (add a tag `ignore` to avoid exposing it as property)", tagValue) continue } varKind := checkField.Kind() if varKind != reflect.Bool { log.Warnf("%s: ignore tag expect a bool property to check, %s given", tagValue, varKind) continue } if checkField.Value().(bool) { propInfo.Skip = true } } } // check if empty if tagKey == "omitEmpty" { if field.IsZero() { propInfo.Skip = true } } switch tagKey { case "emit": propInfo.Emit = prop.EmitTrue propInfo.Writable = true case "invalidates": propInfo.Emit = prop.EmitInvalidates propInfo.Writable = true case "writable": propInfo.Writable = true default: t := reflect.TypeOf(propertyVal) m, ok := t.MethodByName(tagKey) if ok { propInfo.Writable = true propInfo.Callback = m.Func.Interface().(func(*prop.Change) *dbus.Error) } } } } return res } go-bluetooth-bluez-5.60/props/to_map.go000066400000000000000000000005561420407601400201500ustar00rootroot00000000000000package props import ( "github.com/muka/go-bluetooth/bluez" ) // Convert a struct to map applying options from struct tag func ToMap(a bluez.Properties) map[string]interface{} { propsInfo := ParseProperties(a) res := make(map[string]interface{}) for name, info := range propsInfo { if info.Skip { continue } res[name] = info.Value } return res } go-bluetooth-bluez-5.60/src/000077500000000000000000000000001420407601400157605ustar00rootroot00000000000000go-bluetooth-bluez-5.60/src/bluez/000077500000000000000000000000001420407601400171015ustar00rootroot00000000000000go-bluetooth-bluez-5.60/tests/000077500000000000000000000000001420407601400163335ustar00rootroot00000000000000go-bluetooth-bluez-5.60/tests/watch_properties_routines_num.go000066400000000000000000000062711420407601400250610ustar00rootroot00000000000000/** * This script demonstrates the increase of go routines depending on the * UnwatchProperties change. The code is related to * https://github.com/muka/go-bluetooth/issues/113 and just documents * the issue to see if the fix brings any value. * * Functionally this script doesn't do anything beyond connecting to a * BLE device and repeatedly subscribing and unsubscribing to receive * notifications as fast as possible. Given the "as fast as possible" * part also caught a panic when the channel was close in inappropriate * moment of routine started in the WatchProperties which resulted in * an attempt to write to a closed channel */ package main import ( "errors" "flag" "fmt" "runtime" "time" "github.com/muka/go-bluetooth/api" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) func runWatchPropertiesTestIteration(char *gatt.GattCharacteristic1) (int, error) { ch, err := char.WatchProperties() if err != nil { return 0, err } err = char.StartNotify() if err != nil { fmt.Printf("Error: %s", err) return 0, err } go func() { for e := range ch { if e == nil { return } } }() err = char.UnwatchProperties(ch) if err != nil { return 0, err } err = char.StopNotify() if err != nil { fmt.Printf("Error: %s", err) return 0, err } // Optionally wait a little for the anonumous go routine to finish // If you don't wait here then the results in go routines count diff // will sometimes show +1 or -1 to average around 0 due to delay // in reception of nil on WatchProperties() created channel // time.Sleep(10 * time.Millisecond) return runtime.NumGoroutine(), nil } func main() { hciName := flag.String("hci", "hci1", "Name of your HCI device") devMac := flag.String("mac", "CA:AF:FE:00:BE:EF", "MAC of the device to connect for test") charUUID := flag.String("uuid", "76494b4a-305c-4368-aa02-923b1b709333", "UUID characteristic which notifies") flag.Parse() a, err := api.GetAdapter(*hciName) if err != nil { panic(err) } fmt.Println("Starting scan") err = a.StartDiscovery() if err != nil { panic(err) } time.Sleep(2 * time.Second) err = a.StopDiscovery() if err != nil { panic(err) } fmt.Println("Scan finished") dev, err := a.GetDeviceByAddress(*devMac) if err != nil { panic(err) } if dev == nil { msg := fmt.Sprintf("Device %s not found. Cannot connect\n", *devMac) panic(errors.New(msg)) } fmt.Printf("Connecting to %s\n", dev.Properties.Address) err = dev.Connect() if err != nil { panic(err) } char, err := dev.GetCharByUUID(*charUUID) if err != nil { panic("search device failed: " + err.Error()) } // Run test iterations iterCount := 100 prev := runtime.NumGoroutine() startGoRoutineCount := prev for i := 1; i < iterCount; i++ { result, err := runWatchPropertiesTestIteration(char) if err != nil { fmt.Printf("Error: %s\n", err) } diff := result - prev fmt.Printf("[Iteration %04d] Result: %d, diff: %d\n", i, result, diff) prev = result } endGoRoutineCount := runtime.NumGoroutine() diff := endGoRoutineCount - startGoRoutineCount fmt.Printf("Number of go routines changed by %d. Started with %d,"+ "finished with %d\n", diff, startGoRoutineCount, endGoRoutineCount) fmt.Printf("Done\n") } go-bluetooth-bluez-5.60/util/000077500000000000000000000000001420407601400161465ustar00rootroot00000000000000go-bluetooth-bluez-5.60/util/map_struct.go000066400000000000000000000071101420407601400206550ustar00rootroot00000000000000package util import ( "fmt" "reflect" "github.com/godbus/dbus/v5" log "github.com/sirupsen/logrus" ) func AssignMapVariantToInterface(mapVal reflect.Value, mapVariant reflect.Value) (bool, error) { if mapVal.Type().Kind() != reflect.Map { return false, nil } if mapVariant.Type().Kind() != reflect.Map { return false, nil } // map[*]interface{} mapValT := mapVal.Type() mapValKey := mapValT.Key() mapValValue := mapValT.Elem() // map[*]dbus.Variant mapVariantT := mapVariant.Type() mapVariantKey := mapVariantT.Key() mapVariantValue := mapVariantT.Elem() // keys must match if mapValKey.Kind() != mapVariantKey.Kind() { return false, fmt.Errorf( "Cannot set values on different types: map[%s] with map[%s]", mapValKey.Kind().String(), mapVariantKey.Kind().String(), ) } // receiving value is interface{} if mapValValue.Kind() != reflect.Interface { log.Debugf("val is not interface") return false, nil } // source value is dbus.Variant if mapVariantValue.Kind() != reflect.TypeOf(dbus.Variant{}).Kind() { log.Debugf("mapVariant value is not variant") return false, nil } mapValInstanceType := reflect.MapOf(mapValKey, mapValValue) mapValInstance := reflect.MakeMapWithSize(mapValInstanceType, mapVariant.Len()) for _, key := range mapVariant.MapKeys() { variantInnerValue := mapVariant.MapIndex(key).MethodByName("Value").Call([]reflect.Value{}) // log.Debugf("variantInnerValue %++v", variantInnerValue) mapValInstance.SetMapIndex(key, variantInnerValue[0]) } mapVal.Set(mapValInstance) return true, nil } func mapStructField(obj interface{}, name string, value dbus.Variant) error { structValue := reflect.ValueOf(obj).Elem() structFieldValue := structValue.FieldByName(name) if !structFieldValue.IsValid() { return fmt.Errorf("Field not found: %s", name) } if !structFieldValue.CanSet() { return fmt.Errorf("Cannot set value for: %s", name) } structFieldType := structFieldValue.Type() val := reflect.ValueOf(value.Value()) if structFieldType == val.Type() { structFieldValue.Set(val) return nil } // log.Debugf("structFieldType %++v", structFieldType) // log.Debugf("val.Type() %++v", val.Type()) if val.Type().Kind() == reflect.Map { structVal := structFieldType.Elem() structKey := structFieldType.Key() // mapVal := val.Type().Elem() mapKey := val.Type().Key() if mapKey.Kind() != structKey.Kind() { return fmt.Errorf("Field %s: map key mismatchig values object=%s props=%s", name, structKey.Kind(), mapKey.Kind()) } // Assign value if signture is map[*]interface{} if structVal.Kind() == reflect.Interface { val1MapType := reflect.MapOf(structKey, structVal) val1Map := reflect.MakeMapWithSize(val1MapType, val.Len()) for _, key := range val.MapKeys() { val1Map.SetMapIndex(key, val.MapIndex(key)) } structFieldValue.Set(val1Map) return nil } } if val.Type().Kind() == reflect.Array { log.Warn("@TODO type array to interface{} is not implemented") } return fmt.Errorf("Mismatching types for field=%s object=%s props=%s", name, structFieldType, val.Type()) } // MapToStruct converts a map[string]interface{} to a struct func MapToStruct(s interface{}, m map[string]dbus.Variant) error { for k, v := range m { err := mapStructField(s, k, v) if err != nil { return err } } return nil } // StructToMap converts a struct to a map[string]interface{} func StructToMap(s interface{}, m map[string]interface{}) { structValue := reflect.ValueOf(s).Elem() for i := 0; i < structValue.NumField(); i++ { m[structValue.Type().Field(i).Name] = structValue.Field(i).Interface() } } go-bluetooth-bluez-5.60/util/map_struct_test.go000066400000000000000000000011341420407601400217140ustar00rootroot00000000000000package util import ( "testing" "github.com/godbus/dbus/v5" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) func TestStructToMap(t *testing.T) { log.SetLevel(log.DebugLevel) struct1 := struct { ManufacturerData map[uint16]interface{} }{} val1 := map[uint16][]byte{ 0x00: {0x01, 0x02, 0x03}, } map1 := map[string]dbus.Variant{ "ManufacturerData": dbus.MakeVariant(val1), } err := MapToStruct(&struct1, map1) if err != nil { t.Fatal(err) } val2, ok := struct1.ManufacturerData[0x00] assert.True(t, ok) assert.Equal(t, val2.([]byte), val1[0x00]) }