Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 40a181cc3e | |||
|
|
8871fc5d20 | ||
|
|
e5ed6f1dbb | ||
|
|
e838cacad1 | ||
|
|
ebc44c7537 | ||
|
|
f2f9ac38f4 | ||
|
|
be2583ce4e | ||
|
|
0d1085730b | ||
|
|
47a4c124f6 | ||
|
|
81d984efac | ||
|
|
a7312ad51c | ||
|
|
9ba9f2728b | ||
|
|
3a234b8080 | ||
|
|
1d3dd85eeb | ||
|
|
1639e1a22d | ||
|
|
ef5b84387f | ||
|
|
6f092344f5 | ||
|
|
7f15ea3d1e | ||
|
|
727f2d8953 | ||
|
|
b54a56b15b | ||
|
|
e43bfc1b82 | ||
|
|
e9c2f0d486 | ||
|
|
65b597ab29 | ||
|
|
92d6ee5241 | ||
|
|
54d0caf6c8 | ||
|
|
ec33fd7618 | ||
|
|
c6cece6acc | ||
|
|
1647ca1ec2 | ||
|
|
112bc00054 | ||
|
|
f483a0e24a | ||
|
|
51c9e5ca90 | ||
|
|
28f694f14b | ||
|
|
6946d05e9c | ||
|
|
8c0c0b4ebe | ||
|
|
459eb1d2d4 | ||
|
|
cb43be74ef | ||
|
|
201e4a6129 | ||
|
|
4e173659e9 | ||
|
|
eae8e9c776 | ||
|
|
ab6997b5af | ||
|
|
262fa72910 | ||
|
|
f68b2f5950 | ||
|
|
31f191b695 | ||
|
|
33f2a265f7 | ||
|
|
70169dc0b7 | ||
|
|
4fcbc7c468 | ||
|
|
9c04515a34 | ||
|
|
53138d5462 | ||
|
|
5f55a3ea45 | ||
|
|
56e27ffab1 | ||
|
|
67bc13a9c2 | ||
|
|
e838503792 | ||
|
|
bcfaa21fad | ||
|
|
cc58a76bc6 | ||
|
|
4792282b59 | ||
|
|
b0d65c08dd | ||
|
|
131ab06bfb | ||
|
|
cf48721d77 |
13
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
/bin
|
||||
/gen
|
||||
local.properties
|
||||
.idea/
|
||||
lint.xml
|
||||
/.apt_generated
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
documents/.~lock.Bluetooth_UUIDs.ods#
|
||||
22
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
3
.idea/copyright/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
||||
19
.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/library" />
|
||||
<option value="$PROJECT_DIR$/sample_app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
80
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State>
|
||||
<id />
|
||||
</State>
|
||||
<State>
|
||||
<id>Android</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android > Lint > Correctness</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android > Lint > Performance</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>CorrectnessLintAndroid</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>General</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>LintAndroid</id>
|
||||
</State>
|
||||
</expanded-state>
|
||||
<selected-state>
|
||||
<State>
|
||||
<id>Android</id>
|
||||
</State>
|
||||
</selected-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
10
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/bluetooth-le-library.iml" filepath="$PROJECT_DIR$/bluetooth-le-library.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/library/library.iml" filepath="$PROJECT_DIR$/library/library.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/sample_app/sample_app.iml" filepath="$PROJECT_DIR$/sample_app/sample_app.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
19
Bluetooth-LE-Library---Android.iml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="Bluetooth-LE-Library---Android" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
235
LICENSE-2.0.html
Normal file
@@ -0,0 +1,235 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="LICENSE-2.0_fichiers/style.css" type="text/css">
|
||||
<meta name="author" content="The Apache Software Foundation">
|
||||
<meta name="email" content="apache.AT.apache.DOT.org">
|
||||
<title>Apache License, Version 2.0 - The Apache Software Foundation</title>
|
||||
</head>
|
||||
<body>
|
||||
<p align="center">
|
||||
Apache License<br>
|
||||
Version 2.0, January 2004<br>
|
||||
<a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
</p>
|
||||
|
||||
<p><b><a name="definitions">1. Definitions</a></b>.</p>
|
||||
|
||||
<p>
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"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).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"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."
|
||||
</p>
|
||||
|
||||
<p>
|
||||
"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.
|
||||
</p>
|
||||
|
||||
<p><b><a name="copyright">2. Grant of Copyright License</a></b>.
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p><b><a name="patent">3. Grant of Patent License</a></b>.
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p><b><a name="redistribution">4. Redistribution</a></b>.
|
||||
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:
|
||||
</p>
|
||||
<ol type="a">
|
||||
<li>You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
<br> <br></li>
|
||||
|
||||
<li>You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
<br> <br></li>
|
||||
|
||||
<li>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
|
||||
<br> <br></li>
|
||||
|
||||
<li>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.
|
||||
</li>
|
||||
</ol>
|
||||
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.
|
||||
|
||||
<p><b><a name="contributions">5. Submission of Contributions</a></b>.
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p><b><a name="trademarks">6. Trademarks</a></b>.
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p><b><a name="no-warranty">7. Disclaimer of Warranty</a></b>.
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p><b><a name="no-liability">8. Limitation of Liability</a></b>.
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p><b><a name="additional">9. Accepting Warranty or Additional Liability</a></b>.
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
END OF TERMS AND CONDITIONS
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
103
README.md
@@ -9,49 +9,53 @@ It also offers:
|
||||
* For iBeacons: A decently inaccurate (due to real world issues) distance approximation.
|
||||
* All the new object types are Parcelable.
|
||||
|
||||
This will only work on Android 4.3 (API Level 18).
|
||||
This will only work on devices with Android 4.3 (API Level 18) and above.
|
||||
|
||||
Sample app available on the [Play Store](https://play.google.com/store/apps/details?id=uk.co.alt236.btlescan)
|
||||
<a href='https://play.google.com/store/apps/details?id=uk.co.alt236.btlescan&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'>
|
||||
<img alt='Get it on Google Play' height=100 src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png'/>
|
||||
</a>
|
||||
|
||||
## Including the Library in Your Project
|
||||
There are two ways to use this library:
|
||||
|
||||
* Download a copy of the Bluetooth LE Library project and reference it in your project.
|
||||
* Create a Jar file (see Jarification below) and add it into your project.
|
||||
This project is available as an artifact for use with Gradle. To use that, add the following blocks to your build.gradle file:
|
||||
```groovy
|
||||
repositories {
|
||||
maven {
|
||||
url "https://dl.bintray.com/alt236/maven"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
### Jarification
|
||||
|
||||
Type `ant jar` at the root of the Library Project to produce a Jar file.
|
||||
|
||||
The library jar along with it's javadoc jar will be found in the `dist` directory inside the library project.
|
||||
|
||||
You will need to provide your own `local.properties` inside the library project.
|
||||
dependencies {
|
||||
compile 'uk.co.alt236:bluetooth-le-library-android:1.0.0'
|
||||
}
|
||||
```
|
||||
If you *really* need a Jar file, fork the project and execute `./gradlew clean build generateRelease` at the root of the project.
|
||||
This will create a zip file under `<PROJECT_ROOT>/library/build/` the Jar can be found inside.
|
||||
|
||||
## Using the Library
|
||||
In the `onLeScan()` method of your `BluetoothAdapter.LeScanCallback()` create a new BluetoothLeDevice with the given information.
|
||||
|
||||
For example:
|
||||
|
||||
<pre>
|
||||
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
|
||||
|
||||
@Override
|
||||
```java
|
||||
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
|
||||
|
||||
@Override
|
||||
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||
|
||||
|
||||
final BluetoothLeDevice deviceLe = new BluetoothLeDevice(device, rssi, scanRecord, System.currentTimeMillis());
|
||||
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDeviceStore.addDevice(deviceLe);
|
||||
mLeDeviceListAdapter.replaceData(mDeviceStore.getDeviceList());
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
```
|
||||
|
||||
### Device Properties
|
||||
|
||||
@@ -71,7 +75,7 @@ Once you have created a device, you can access the following methods:
|
||||
**Note:** The Running Average RSSI is not updated automatically (i.e. the library does not monitor on its own in the background). To add another measurement, you need to call `updateRssiReading(long timestamp, int rssiReading)`.
|
||||
|
||||
|
||||
### Accessing the Advertisment (Ad) Records
|
||||
### Accessing the Advertisement (Ad) Records
|
||||
|
||||
Once you've created a BluetoothLe device, you can access the AdRecord store via the `leDevice.getAdRecordStore()`. Once you have the AdRecordStore you can use the following methods:
|
||||
|
||||
@@ -83,7 +87,17 @@ Once you've created a BluetoothLe device, you can access the AdRecord store via
|
||||
They are also declared as constants in `AdRecord.java`.
|
||||
|
||||
### Fun with iBeacons
|
||||
You can check if a device is an iBeacon by using `IBeaconUtils.isThisAnIBeacon(BluetootLeDevice device)`. Once you have confirmed that it is, you can create a new IBeaconDevice via the IBeaconDevice constructor.
|
||||
You can check if a device is an iBeacon by using `BeaconUtils.getBeaconType(BluetootLeDevice device)`. Once you have confirmed that it is, you can create a new IBeaconDevice via the IBeaconDevice constructor.
|
||||
|
||||
Example Flow:
|
||||
```java
|
||||
final BluetoothLeDevice device = ... // A generic BLE device
|
||||
|
||||
if (BeaconUtils.getBeaconType(device) == BeaconType.IBEACON) {
|
||||
final IBeaconDevice iBeacon = new IBeaconDevice(device);
|
||||
// DO STUFF
|
||||
}
|
||||
```
|
||||
|
||||
An IBeaconDevice extends BluetoothLeDevice, so you still have access to the same methods as before. In addition you can do the following:
|
||||
|
||||
@@ -103,21 +117,37 @@ You can also lookup values and convert them to human friendly strings:
|
||||
* `CompanyIdentifierResolver.getCompanyName(int companyId, String fallback)`: Will try to resolve a Company identifier to the company name
|
||||
* `GattAttributeResolver.getAttributeName(String uuid, String fallback)`: Will try to convert a UUID to its name.
|
||||
|
||||
**Note:** The data can be found as ODS (Open Office Spreadsheets) in the documents folder.
|
||||
**Note:** The data can be found as ODS (Open Office Spreadsheets) in the documents folder.
|
||||
|
||||
## Library Changelog
|
||||
* v0.0.1
|
||||
* v0.0.1
|
||||
* First public release
|
||||
* v0.0.2:
|
||||
* v0.0.2:
|
||||
* Attempting to create an iBeaconDevice from a device which is not an iBeacon will now throw an IllegalArgumentException exception.
|
||||
* Fixed a ConcurrentModificationException on getRunningAverageRssi()
|
||||
* Added some Estimote UUIDs
|
||||
* v1.0.0:
|
||||
* Migrated project to Android Studio/ gradle
|
||||
* Note that the API has slightly changed in this version.
|
||||
* We now use the more generic `BeaconUtils.getBeaconType()` method instead of `IBeaconUtils.isThisAnIBeacon()`
|
||||
* Fix for [issue 5](https://github.com/alt236/Bluetooth-LE-Library---Android/issues/5)
|
||||
* Fix for [issue 9](https://github.com/alt236/Bluetooth-LE-Library---Android/issues/9)
|
||||
|
||||
## Sample Application Changelog
|
||||
* v0.0.1
|
||||
* First public release
|
||||
* v0.0.2:
|
||||
* Can now export scanned devices as a CSV file.
|
||||
* v0.0.1
|
||||
* First public release
|
||||
* v0.0.2:
|
||||
* Can now export scanned devices as a CSV file.
|
||||
* v0.0.3:
|
||||
* UI Refresh.
|
||||
* v1.0.0:
|
||||
* Migrated project to Android Studio/ gradle
|
||||
* Using version v1.0.0 of the library project
|
||||
* v1.1.0:
|
||||
* App refactor and materialisation.
|
||||
* Added runtime permissions.
|
||||
* v1.1.1:
|
||||
* Fix for [issue 23](https://github.com/alt236/Bluetooth-LE-Library---Android/issues/23)
|
||||
|
||||
## Permission Explanation
|
||||
You will need the following permissions to access the Bluetooth Hardware
|
||||
@@ -125,17 +155,15 @@ You will need the following permissions to access the Bluetooth Hardware
|
||||
* `android.permission.BLUETOOTH`
|
||||
* `android.permission.BLUETOOTH_ADMIN`
|
||||
|
||||
In addition one of the following is needed from API 23 and above to scan for BT LE devices:
|
||||
* `android.permission.ACCESS_COARSE_LOCATION`
|
||||
* `android.permission.ACCESS_FINE_LOCATION `
|
||||
|
||||
## TODO
|
||||
|
||||
* Tidy up Javadoc. There is quite a lot of it that is template
|
||||
* Add parsers for common Ad Records.
|
||||
|
||||
## Sample App Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## Links
|
||||
* Github: [https://github.com/alt236/Bluetooth-LE-Library---Android]()
|
||||
|
||||
@@ -145,9 +173,10 @@ Author: [Alexandros Schillings](https://github.com/alt236).
|
||||
* The Accuracy calculation algorithm was taken from: http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing
|
||||
* The AdRecord parser was taken from: https://github.com/devunwired/accessory-samples
|
||||
* The sample application has been adapted from Android's Bluetooth LE example
|
||||
* Google Play and the Google Play logo are trademarks of Google Inc.
|
||||
|
||||
All logos are the property of their respective owners.
|
||||
|
||||
The code in this project is licensed under the Apache Software License 2.0.
|
||||
|
||||
Copyright (c) 2014 Alexandros Schillings.
|
||||
Copyright (c) 2014-2017 Alexandros Schillings.
|
||||
|
||||
19
bluetooth-le-library.iml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="bluetooth-le-library" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
21
build.gradle
Normal file
@@ -0,0 +1,21 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
ext.compileSdkVersion = 24
|
||||
ext.buildToolsVersion = "24.0.1"
|
||||
ext.minSdkVersion = 18
|
||||
ext.targetSdkVersion = 24
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
7
circle.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
test:
|
||||
override:
|
||||
- (echo "Running JUnit tests!")
|
||||
- ./gradlew test -PdisablePreDex
|
||||
post:
|
||||
- mkdir -p $CIRCLE_TEST_REPORTS/junit/
|
||||
- find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
|
||||
BIN
dist/BluetoothLeLibrary-0.0.1-javadoc.jar
vendored
Normal file
BIN
dist/BluetoothLeLibrary-0.0.1.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Wed Aug 24 14:15:35 BST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
||||
164
gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
BIN
image_assets/feature_graphic.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
image_assets/screenshots/phone_screenshot_1.png
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
image_assets/screenshots/phone_screenshot_2.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
image_assets/screenshots/phone_screenshot_3.png
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
image_assets/screenshots/phone_screenshot_4.png
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
image_assets/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
8
library/.gitignore
vendored
@@ -1,7 +1 @@
|
||||
/bin
|
||||
/gen
|
||||
local.properties
|
||||
.idea/
|
||||
lint.xml
|
||||
/.apt_generated
|
||||
/dist
|
||||
/build
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Bluetooth LE Library</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,4 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="uk.co.alt236.bluetoothlelib"
|
||||
android:versionCode="2"
|
||||
android:versionName="0.0.2" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="18"
|
||||
android:targetSdkVersion="18" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
53
library/build.gradle
Normal file
@@ -0,0 +1,53 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
final int versionMajor = 1
|
||||
final int versionMinor = 0
|
||||
final int versionPatch = 0
|
||||
final int androidVersionCode = 5
|
||||
|
||||
final int targetSdk = rootProject.targetSdkVersion;
|
||||
final int minSdkRed = rootProject.minSdkVersion;
|
||||
final String semanticVersion = "${versionMajor}.${versionMinor}.${versionPatch}"
|
||||
|
||||
|
||||
dependencies {
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile "org.mockito:mockito-core:1.9.5"
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
}
|
||||
|
||||
ext {
|
||||
PUBLISH_GROUP_ID = 'uk.co.alt236'
|
||||
PUBLISH_ARTIFACT_ID = 'bluetooth-le-library-android'
|
||||
PUBLISH_VERSION = "${semanticVersion}"
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.compileSdkVersion
|
||||
buildToolsVersion rootProject.buildToolsVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion minSdkRed
|
||||
targetSdkVersion targetSdk
|
||||
versionCode androidVersionCode
|
||||
versionName semanticVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
}
|
||||
}
|
||||
|
||||
// Script from https://github.com/blundell/release-android-library
|
||||
// execute: ./gradlew clean build generateRelease
|
||||
apply from: 'https://raw.githubusercontent.com/ArthurHub/release-android-library/master/android-release-jar.gradle'
|
||||
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project name="BluetoothLeLibrary" default="default">
|
||||
<loadproperties srcFile="local.properties" />
|
||||
<property file="ant.properties" />
|
||||
<loadproperties srcFile="project.properties" />
|
||||
|
||||
<!-- quick check on sdk.dir -->
|
||||
<fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
|
||||
|
||||
<!-- version-tag: 1 -->
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
|
||||
<!-- Read the Android Manifest -->
|
||||
<path id="android.antlibs">
|
||||
<pathelement path="${sdk.dir}/tools/lib/ant-tasks.jar" />
|
||||
</path>
|
||||
|
||||
<taskdef name="xpath" classname="com.android.ant.XPathTask" classpathref="android.antlibs" />
|
||||
<xpath input="./AndroidManifest.xml" expression="/manifest/@android:versionName" output="manifest.versionName" />
|
||||
|
||||
<!-- Setup the build properties -->
|
||||
<property name="versionedName" value="${ant.project.name}-${manifest.versionName}" />
|
||||
<property name="distLocation" location="dist" />
|
||||
<echo message="Running task(s) for ${versionedName}" />
|
||||
|
||||
<target name="default">
|
||||
<antcall target="jar"/>
|
||||
<antcall target="doc"/>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="debug" description="build the library as a jar">
|
||||
<jar destfile="${distLocation}/${versionedName}.jar" basedir="bin/classes" />
|
||||
</target>
|
||||
<target name="doc" description="generate documentation">
|
||||
<property name="temp" location="temp" />
|
||||
<javadoc sourcepath="${source.dir}" destdir="${temp}" />
|
||||
<jar destfile="${distLocation}/${versionedName}-javadoc.jar" basedir="temp" keepcompression="true" />
|
||||
<delete dir="${temp}" />
|
||||
</target>
|
||||
</project>
|
||||
111
library/library.iml
Normal file
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":library" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="bluetooth-le-library" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":library" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_TEST_ARTIFACT" value="_unit_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<afterSyncTasks>
|
||||
<task>generateDebugSources</task>
|
||||
</afterSyncTasks>
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
<option name="LIBRARY_PROJECT" value="true" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 24 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" scope="TEST" name="objenesis-1.0" level="project" />
|
||||
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
|
||||
<orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" />
|
||||
<orderEntry type="library" exported="" scope="TEST" name="mockito-core-1.9.5" level="project" />
|
||||
<orderEntry type="library" exported="" name="android-android-24" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,11 +1,8 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
# in /home/alex/Dev/android-sdk-linux/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
@@ -1,15 +0,0 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-19
|
||||
android.library=true
|
||||
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 9.2 KiB |
@@ -1,11 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Base application theme for API 11+. This theme completely replaces
|
||||
AppBaseTheme from res/values/styles.xml on API 11+ devices.
|
||||
-->
|
||||
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
|
||||
<!-- API 11 theme customizations can go here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -1,12 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Base application theme for API 14+. This theme completely replaces
|
||||
AppBaseTheme from BOTH res/values/styles.xml and
|
||||
res/values-v11/styles.xml on API 14+ devices.
|
||||
-->
|
||||
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
|
||||
<!-- API 14 theme customizations can go here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -1,5 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<string name="app_name">Bluetooth LE Library</string>
|
||||
|
||||
</resources>
|
||||
@@ -1,20 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Base application theme, dependent on API level. This theme is replaced
|
||||
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
|
||||
-->
|
||||
<style name="AppBaseTheme" parent="android:Theme.Light">
|
||||
<!--
|
||||
Theme customizations available in newer API levels can go in
|
||||
res/values-vXX/styles.xml, while customizations related to
|
||||
backward-compatibility can go here.
|
||||
-->
|
||||
</style>
|
||||
|
||||
<!-- Application theme. -->
|
||||
<style name="AppTheme" parent="AppBaseTheme">
|
||||
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
5
library/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
package="uk.co.alt236.bluetoothlelib">
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,422 @@
|
||||
package uk.co.alt236.bluetoothlelib.device;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecordStore;
|
||||
import uk.co.alt236.bluetoothlelib.resolvers.BluetoothClassResolver;
|
||||
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.LimitedLinkHashMap;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
|
||||
/**
|
||||
* This is a wrapper around the default BluetoothDevice object
|
||||
* As BluetoothDevice is final it cannot be extended, so to get it you
|
||||
* need to call {@link #getDevice()} method.
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*/
|
||||
public class BluetoothLeDevice implements Parcelable {
|
||||
/**
|
||||
* The Constant CREATOR.
|
||||
*/
|
||||
public static final Parcelable.Creator<BluetoothLeDevice> CREATOR = new Parcelable.Creator<BluetoothLeDevice>() {
|
||||
public BluetoothLeDevice createFromParcel(final Parcel in) {
|
||||
return new BluetoothLeDevice(in);
|
||||
}
|
||||
|
||||
public BluetoothLeDevice[] newArray(final int size) {
|
||||
return new BluetoothLeDevice[size];
|
||||
}
|
||||
};
|
||||
protected static final int MAX_RSSI_LOG_SIZE = 10;
|
||||
private static final String PARCEL_EXTRA_BLUETOOTH_DEVICE = "bluetooth_device";
|
||||
private static final String PARCEL_EXTRA_CURRENT_RSSI = "current_rssi";
|
||||
private static final String PARCEL_EXTRA_CURRENT_TIMESTAMP = "current_timestamp";
|
||||
private static final String PARCEL_EXTRA_DEVICE_RSSI_LOG = "device_rssi_log";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD = "device_scanrecord";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD_STORE = "device_scanrecord_store";
|
||||
private static final String PARCEL_EXTRA_FIRST_RSSI = "device_first_rssi";
|
||||
private static final String PARCEL_EXTRA_FIRST_TIMESTAMP = "first_timestamp";
|
||||
private static final long LOG_INVALIDATION_THRESHOLD = 10 * 1000;
|
||||
private final AdRecordStore mRecordStore;
|
||||
private final BluetoothDevice mDevice;
|
||||
private final Map<Long, Integer> mRssiLog;
|
||||
private final byte[] mScanRecord;
|
||||
private final int mFirstRssi;
|
||||
private final long mFirstTimestamp;
|
||||
private int mCurrentRssi;
|
||||
private long mCurrentTimestamp;
|
||||
private transient Set<BluetoothService> mServiceSet;
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device a standard android Bluetooth device
|
||||
* @param rssi the RSSI value of the Bluetooth device
|
||||
* @param scanRecord the scan record of the device
|
||||
* @param timestamp the timestamp of the RSSI reading
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
|
||||
mDevice = device;
|
||||
mFirstRssi = rssi;
|
||||
mFirstTimestamp = timestamp;
|
||||
mRecordStore = new AdRecordStore(AdRecordUtils.parseScanRecordAsSparseArray(scanRecord));
|
||||
mScanRecord = scanRecord;
|
||||
mRssiLog = new LimitedLinkHashMap<>(MAX_RSSI_LOG_SIZE);
|
||||
updateRssiReading(timestamp, rssi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device the device
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothLeDevice device) {
|
||||
mCurrentRssi = device.getRssi();
|
||||
mCurrentTimestamp = device.getTimestamp();
|
||||
mDevice = device.getDevice();
|
||||
mFirstRssi = device.getFirstRssi();
|
||||
mFirstTimestamp = device.getFirstTimestamp();
|
||||
mRecordStore = new AdRecordStore(
|
||||
AdRecordUtils.parseScanRecordAsSparseArray(device.getScanRecord()));
|
||||
mRssiLog = device.getRssiLog();
|
||||
mScanRecord = device.getScanRecord();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new bluetooth le device.
|
||||
*
|
||||
* @param in the in
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected BluetoothLeDevice(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
|
||||
mCurrentRssi = b.getInt(PARCEL_EXTRA_CURRENT_RSSI, 0);
|
||||
mCurrentTimestamp = b.getLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, 0);
|
||||
mDevice = b.getParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE);
|
||||
mFirstRssi = b.getInt(PARCEL_EXTRA_FIRST_RSSI, 0);
|
||||
mFirstTimestamp = b.getLong(PARCEL_EXTRA_FIRST_TIMESTAMP, 0);
|
||||
mRecordStore = b.getParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE);
|
||||
mRssiLog = (Map<Long, Integer>) b.getSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG);
|
||||
mScanRecord = b.getByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the to rssi log.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
private void addToRssiLog(final long timestamp, final int rssiReading) {
|
||||
synchronized (mRssiLog) {
|
||||
if (timestamp - mCurrentTimestamp > LOG_INVALIDATION_THRESHOLD) {
|
||||
mRssiLog.clear();
|
||||
}
|
||||
|
||||
mCurrentRssi = rssiReading;
|
||||
mCurrentTimestamp = timestamp;
|
||||
mRssiLog.put(timestamp, rssiReading);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final BluetoothLeDevice other = (BluetoothLeDevice) obj;
|
||||
if (mCurrentRssi != other.mCurrentRssi)
|
||||
return false;
|
||||
if (mCurrentTimestamp != other.mCurrentTimestamp)
|
||||
return false;
|
||||
if (mDevice == null) {
|
||||
if (other.mDevice != null)
|
||||
return false;
|
||||
} else if (!mDevice.equals(other.mDevice))
|
||||
return false;
|
||||
if (mFirstRssi != other.mFirstRssi)
|
||||
return false;
|
||||
if (mFirstTimestamp != other.mFirstTimestamp)
|
||||
return false;
|
||||
if (mRecordStore == null) {
|
||||
if (other.mRecordStore != null)
|
||||
return false;
|
||||
} else if (!mRecordStore.equals(other.mRecordStore))
|
||||
return false;
|
||||
if (mRssiLog == null) {
|
||||
if (other.mRssiLog != null)
|
||||
return false;
|
||||
} else if (!mRssiLog.equals(other.mRssiLog))
|
||||
return false;
|
||||
if (!Arrays.equals(mScanRecord, other.mScanRecord))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ad record store.
|
||||
*
|
||||
* @return the ad record store
|
||||
*/
|
||||
public AdRecordStore getAdRecordStore() {
|
||||
return mRecordStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address.
|
||||
*
|
||||
* @return the address
|
||||
*/
|
||||
public String getAddress() {
|
||||
return mDevice.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device bond state.
|
||||
*
|
||||
* @return the bluetooth device bond state
|
||||
*/
|
||||
public String getBluetoothDeviceBondState() {
|
||||
return resolveBondingState(mDevice.getBondState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device class name.
|
||||
*
|
||||
* @return the bluetooth device class name
|
||||
*/
|
||||
public String getBluetoothDeviceClassName() {
|
||||
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
|
||||
}
|
||||
|
||||
public Set<BluetoothService> getBluetoothDeviceKnownSupportedServices() {
|
||||
if (mServiceSet == null) {
|
||||
synchronized (this) {
|
||||
if (mServiceSet == null) {
|
||||
final Set<BluetoothService> serviceSet = new HashSet<>();
|
||||
for (final BluetoothService service : BluetoothService.values()) {
|
||||
|
||||
if (mDevice.getBluetoothClass().hasService(service.getAndroidConstant())) {
|
||||
serviceSet.add(service);
|
||||
}
|
||||
}
|
||||
mServiceSet = Collections.unmodifiableSet(serviceSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mServiceSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device major class name.
|
||||
*
|
||||
* @return the bluetooth device major class name
|
||||
*/
|
||||
public String getBluetoothDeviceMajorClassName() {
|
||||
return BluetoothClassResolver.resolveMajorDeviceClass(mDevice.getBluetoothClass().getMajorDeviceClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device.
|
||||
*
|
||||
* @return the device
|
||||
*/
|
||||
public BluetoothDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first rssi.
|
||||
*
|
||||
* @return the first rssi
|
||||
*/
|
||||
public int getFirstRssi() {
|
||||
return mFirstRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first timestamp.
|
||||
*
|
||||
* @return the first timestamp
|
||||
*/
|
||||
public long getFirstTimestamp() {
|
||||
return mFirstTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return mDevice.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rssi.
|
||||
*
|
||||
* @return the rssi
|
||||
*/
|
||||
public int getRssi() {
|
||||
return mCurrentRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rssi log.
|
||||
*
|
||||
* @return the rssi log
|
||||
*/
|
||||
protected Map<Long, Integer> getRssiLog() {
|
||||
synchronized (mRssiLog) {
|
||||
return mRssiLog;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the running average rssi.
|
||||
*
|
||||
* @return the running average rssi
|
||||
*/
|
||||
public double getRunningAverageRssi() {
|
||||
int sum = 0;
|
||||
int count = 0;
|
||||
|
||||
synchronized (mRssiLog) {
|
||||
|
||||
for (final Long aLong : mRssiLog.keySet()) {
|
||||
count++;
|
||||
sum += mRssiLog.get(aLong);
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
return sum / count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scan record.
|
||||
*
|
||||
* @return the scan record
|
||||
*/
|
||||
public byte[] getScanRecord() {
|
||||
return mScanRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timestamp.
|
||||
*
|
||||
* @return the timestamp
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return mCurrentTimestamp;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + mCurrentRssi;
|
||||
result = prime * result + (int) (mCurrentTimestamp ^ (mCurrentTimestamp >>> 32));
|
||||
result = prime * result + ((mDevice == null) ? 0 : mDevice.hashCode());
|
||||
result = prime * result + mFirstRssi;
|
||||
result = prime * result + (int) (mFirstTimestamp ^ (mFirstTimestamp >>> 32));
|
||||
result = prime * result + ((mRecordStore == null) ? 0 : mRecordStore.hashCode());
|
||||
result = prime * result + ((mRssiLog == null) ? 0 : mRssiLog.hashCode());
|
||||
result = prime * result + Arrays.hashCode(mScanRecord);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BluetoothLeDevice [mDevice=" + mDevice + ", mRssi=" + mFirstRssi + ", mScanRecord=" + ByteUtils.byteArrayToHexString(mScanRecord) + ", mRecordStore=" + mRecordStore + ", getBluetoothDeviceBondState()=" + getBluetoothDeviceBondState() + ", getBluetoothDeviceClassName()=" + getBluetoothDeviceClassName() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rssi reading.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
public void updateRssiReading(final long timestamp, final int rssiReading) {
|
||||
addToRssiLog(timestamp, rssiReading);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
b.putByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD, mScanRecord);
|
||||
|
||||
b.putInt(PARCEL_EXTRA_FIRST_RSSI, mFirstRssi);
|
||||
b.putInt(PARCEL_EXTRA_CURRENT_RSSI, mCurrentRssi);
|
||||
|
||||
b.putLong(PARCEL_EXTRA_FIRST_TIMESTAMP, mFirstTimestamp);
|
||||
b.putLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, mCurrentTimestamp);
|
||||
|
||||
b.putParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE, mDevice);
|
||||
b.putParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE, mRecordStore);
|
||||
b.putSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG, (Serializable) mRssiLog);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve bonding state.
|
||||
*
|
||||
* @param bondState the bond state
|
||||
* @return the string
|
||||
*/
|
||||
private static String resolveBondingState(final int bondState) {
|
||||
switch (bondState) {
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
return "Paired";
|
||||
case BluetoothDevice.BOND_BONDING:
|
||||
return "Pairing";
|
||||
case BluetoothDevice.BOND_NONE:
|
||||
return "Unbonded";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package uk.co.alt236.bluetoothlelib.device;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public enum BluetoothService {
|
||||
AUDIO(BluetoothClass.Service.AUDIO),
|
||||
CAPTURE(BluetoothClass.Service.CAPTURE),
|
||||
INFORMATION(BluetoothClass.Service.INFORMATION),
|
||||
LIMITED_DISCOVERABILITY(BluetoothClass.Service.LIMITED_DISCOVERABILITY),
|
||||
NETWORKING(BluetoothClass.Service.NETWORKING),
|
||||
OBJECT_TRANSFER(BluetoothClass.Service.OBJECT_TRANSFER),
|
||||
POSITIONING(BluetoothClass.Service.POSITIONING),
|
||||
RENDER(BluetoothClass.Service.RENDER),
|
||||
TELEPHONY(BluetoothClass.Service.TELEPHONY);
|
||||
|
||||
private final int mAndroidConstant;
|
||||
|
||||
BluetoothService(final int androidCode){
|
||||
mAndroidConstant = androidCode;
|
||||
}
|
||||
|
||||
public int getAndroidConstant(){
|
||||
return mAndroidConstant;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.adrecord;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created by Dave Smith
|
||||
* Double Encore, Inc.
|
||||
* <p>
|
||||
* Expanded by Alexandros Schillings
|
||||
*/
|
||||
public final class AdRecord implements Parcelable {
|
||||
// 02 # Number of bytes that follow in first AD structure
|
||||
// 01 # Flags AD type
|
||||
// 1A # Flags value 0x1A = 000011010
|
||||
// bit 0 (OFF) LE Limited Discoverable Mode
|
||||
// bit 1 (ON) LE General Discoverable Mode
|
||||
// bit 2 (OFF) BR/EDR Not Supported
|
||||
// bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
|
||||
// bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
|
||||
// 1A # Number of bytes that follow in second (and last) AD structure
|
||||
// FF # Manufacturer specific data AD type
|
||||
// 4C 00 # Company identifier code (0x004C == Apple)
|
||||
// 02 # Byte 0 of iBeacon advertisement indicator
|
||||
// 15 # Byte 1 of iBeacon advertisement indicator
|
||||
// e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon proximity uuid
|
||||
// 00 00 # major
|
||||
// 00 00 # minor
|
||||
// c5 # The 2's complement of the calibrated Tx Power
|
||||
|
||||
|
||||
/**
|
||||
* General FLAGS
|
||||
* <p>
|
||||
* Description: Flags
|
||||
* <p>
|
||||
* Information:
|
||||
* Bit 0: LE Limited Discoverable Mode
|
||||
* Bit 1: LE General Discoverable Mode
|
||||
* Bit 2: BR/EDR Not Supported (i.e. bit 37 of LMP Extended Feature bits Page 0)
|
||||
* Bit 3: Simultaneous LE and BR/EDR to Same Device Capable (Controller) (i.e. bit 49 of LMP Extended Feature bits Page 0)
|
||||
* Bit 4: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bits 5-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_FLAGS = 0x01;
|
||||
// SERVICE
|
||||
public static final int TYPE_UUID16_INC = 0x02;
|
||||
public static final int TYPE_UUID16 = 0x03;
|
||||
public static final int TYPE_UUID32_INC = 0x04;
|
||||
public static final int TYPE_UUID32 = 0x05;
|
||||
public static final int TYPE_UUID128_INC = 0x06;
|
||||
public static final int TYPE_UUID128 = 0x07;
|
||||
// Local name
|
||||
public static final int TYPE_LOCAL_NAME_SHORT = 0x08;
|
||||
public static final int TYPE_LOCAL_NAME_COMPLETE = 0x09;
|
||||
// TX Power Level
|
||||
public static final int TYPE_TX_POWER_LEVEL = 0x0A;
|
||||
// SIMPLE PAIRING OPTIONAL OOB TAGS
|
||||
public static final int TYPE_DEVICE_CLASS = 0x0D;
|
||||
public static final int TYPE_SIMPLE_PAIRING_HASH_C = 0x0E;
|
||||
public static final int TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F;
|
||||
// SECURITY MANAGER TK VALUE
|
||||
public static final int TYPE_TK_VALUE = 0x10;
|
||||
/* SECURITY MANAGER OOB FLAGS
|
||||
*
|
||||
* Description: Flag (1 octet)
|
||||
*
|
||||
* Information:
|
||||
* Bit 0: OOB Flags Field: (0 = OOB data not present, 1 = OOB data present)
|
||||
* Bit 1: LE supported (Host) (i.e. bit 65 of LMP Extended Feature bits Page 1
|
||||
* Bit 2: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bit 3: Address type (0 = Public Address, 1 = Random Address)
|
||||
* Bits 4-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11;
|
||||
/* SLAVE CONNECTION INTERVAL RANGE
|
||||
*
|
||||
* Description: Slave Connection Interval Range
|
||||
*
|
||||
* Information:
|
||||
* The first 2 octets defines the minimum value for the connection interval in the following manner:
|
||||
* connInterval min = Conn_Interval_Min * 1.25 ms
|
||||
* Conn_Interval_Min range: 0x0006 to 0x0C80
|
||||
* Value of 0xFFFF indicates no specific minimum.
|
||||
* Values outside the range are reserved. (excluding 0xFFFF)
|
||||
*
|
||||
* The second 2 octets defines the maximum value for the connection interval in the following manner:
|
||||
* connInterval max = Conn_Interval_Max * 1.25 ms
|
||||
* Conn_Interval_Max range: 0x0006 to 0x0C80
|
||||
* Conn_Interval_Max shall be equal to or greater
|
||||
* than the Conn_Interval_Min.
|
||||
* Value of 0xFFFF indicates no specific maximum.
|
||||
* Values outside the range are reserved (excluding 0xFFFF)
|
||||
*/
|
||||
public static final int TYPE_CONNECTION_INTERVAL_RANGE = 0x12;
|
||||
// SERVICE SOLICITATION
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_16BIT = 0x14;
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_128BIT = 0x15;
|
||||
/* SERVICE DATA
|
||||
*
|
||||
* Description: Service Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the 16 bit Service UUID followed by additional service data
|
||||
*/
|
||||
public static final int TYPE_SERVICE_DATA = 0x16;
|
||||
/* MANUFACTURER SPECIFIC DATA
|
||||
*
|
||||
* Description: Manufacturer Specific Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data
|
||||
*/
|
||||
public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
|
||||
public static final Parcelable.Creator<AdRecord> CREATOR = new Parcelable.Creator<AdRecord>() {
|
||||
public AdRecord createFromParcel(final Parcel in) {
|
||||
return new AdRecord(in);
|
||||
}
|
||||
|
||||
public AdRecord[] newArray(final int size) {
|
||||
return new AdRecord[size];
|
||||
}
|
||||
};
|
||||
private static final String PARCEL_RECORD_DATA = "record_data";
|
||||
private static final String PARCEL_RECORD_TYPE = "record_type";
|
||||
private static final String PARCEL_RECORD_LENGTH = "record_length";
|
||||
/* Model Object Definition */
|
||||
private final int mLength;
|
||||
private final int mType;
|
||||
private final byte[] mData;
|
||||
|
||||
public AdRecord(final int length, final int type, final byte[] data) {
|
||||
mLength = length;
|
||||
mType = type;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
public AdRecord(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mLength = b.getInt(PARCEL_RECORD_LENGTH);
|
||||
mType = b.getInt(PARCEL_RECORD_TYPE);
|
||||
mData = b.getByteArray(PARCEL_RECORD_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
public String getHumanReadableType() {
|
||||
return getHumanReadableAdType(mType);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecord [mLength=" + mLength + ", mType=" + mType + ", mData=" + Arrays.toString(mData) + ", getHumanReadableType()=" + getHumanReadableType() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
b.putInt(PARCEL_RECORD_LENGTH, mLength);
|
||||
b.putInt(PARCEL_RECORD_TYPE, mType);
|
||||
b.putByteArray(PARCEL_RECORD_DATA, mData);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
private static String getHumanReadableAdType(final int type) {
|
||||
switch (type) {
|
||||
case TYPE_CONNECTION_INTERVAL_RANGE:
|
||||
return "Slave Connection Interval Range";
|
||||
case TYPE_DEVICE_CLASS:
|
||||
return "Class of device";
|
||||
case TYPE_FLAGS:
|
||||
return "Flags";
|
||||
case TYPE_MANUFACTURER_SPECIFIC_DATA:
|
||||
return "Manufacturer Specific Data";
|
||||
case TYPE_LOCAL_NAME_COMPLETE:
|
||||
return "Name (Complete)";
|
||||
case TYPE_LOCAL_NAME_SHORT:
|
||||
return "Name (Short)";
|
||||
case TYPE_SECURITY_MANAGER_OOB_FLAGS:
|
||||
return "Security Manager OOB Flags";
|
||||
case TYPE_SERVICE_UUIDS_LIST_128BIT:
|
||||
return "Service UUIDs (128bit)";
|
||||
case TYPE_SERVICE_UUIDS_LIST_16BIT:
|
||||
return "Service UUIDs (16bit)";
|
||||
case TYPE_SERVICE_DATA:
|
||||
return "Service Data";
|
||||
case TYPE_SIMPLE_PAIRING_HASH_C:
|
||||
return "Simple Pairing Hash C";
|
||||
case TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
|
||||
return "Simple Pairing Randomizer R";
|
||||
case TYPE_TK_VALUE:
|
||||
return "TK Value";
|
||||
case TYPE_TX_POWER_LEVEL:
|
||||
return "Transmission Power Level";
|
||||
case TYPE_UUID128:
|
||||
return "Complete list of 128-bit UUIDs available";
|
||||
case TYPE_UUID128_INC:
|
||||
return "More 128-bit UUIDs available";
|
||||
case TYPE_UUID16:
|
||||
return "Complete list of 16-bit UUIDs available";
|
||||
case TYPE_UUID16_INC:
|
||||
return "More 16-bit UUIDs available";
|
||||
case TYPE_UUID32:
|
||||
return "Complete list of 32-bit UUIDs available";
|
||||
case TYPE_UUID32_INC:
|
||||
return "More 32-bit UUIDs available";
|
||||
default:
|
||||
return "Unknown AdRecord Structure: " + type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.adrecord;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
|
||||
|
||||
/**
|
||||
* The Class AdRecordStore.
|
||||
*/
|
||||
public class AdRecordStore implements Parcelable {
|
||||
public static final Parcelable.Creator<AdRecordStore> CREATOR = new Parcelable.Creator<AdRecordStore>() {
|
||||
public AdRecordStore createFromParcel(final Parcel in) {
|
||||
return new AdRecordStore(in);
|
||||
}
|
||||
|
||||
public AdRecordStore[] newArray(final int size) {
|
||||
return new AdRecordStore[size];
|
||||
}
|
||||
};
|
||||
private final SparseArray<AdRecord> mAdRecords;
|
||||
private final String mLocalNameComplete;
|
||||
private final String mLocalNameShort;
|
||||
|
||||
public AdRecordStore(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mAdRecords = b.getSparseParcelableArray("records_array");
|
||||
mLocalNameComplete = b.getString("local_name_complete");
|
||||
mLocalNameShort = b.getString("local_name_short");
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device Ad Record Store.
|
||||
*
|
||||
* @param adRecords the ad records
|
||||
*/
|
||||
public AdRecordStore(final SparseArray<AdRecord> adRecords) {
|
||||
mAdRecords = adRecords;
|
||||
|
||||
mLocalNameComplete = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_COMPLETE));
|
||||
|
||||
mLocalNameShort = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_SHORT));
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the short local device name.
|
||||
*
|
||||
* @return the local name complete
|
||||
*/
|
||||
public String getLocalNameComplete() {
|
||||
return mLocalNameComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete local device name.
|
||||
*
|
||||
* @return the local name short
|
||||
*/
|
||||
public String getLocalNameShort() {
|
||||
return mLocalNameShort;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves an individual record.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record
|
||||
*/
|
||||
public AdRecord getRecord(final int record) {
|
||||
return mAdRecords.get(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record data as string.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record data as string
|
||||
*/
|
||||
public String getRecordDataAsString(final int record) {
|
||||
return AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(record));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record as collection.
|
||||
*
|
||||
* @return the records as collection
|
||||
*/
|
||||
public Collection<AdRecord> getRecordsAsCollection() {
|
||||
return Collections.unmodifiableCollection(asList(mAdRecords));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is record present.
|
||||
*
|
||||
* @param record the record
|
||||
* @return true, if is record present
|
||||
*/
|
||||
public boolean isRecordPresent(final int record) {
|
||||
return mAdRecords.indexOfKey(record) >= 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecordStore [mLocalNameComplete=" + mLocalNameComplete + ", mLocalNameShort=" + mLocalNameShort + "]";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle();
|
||||
b.putString("local_name_complete", mLocalNameComplete);
|
||||
b.putString("local_name_short", mLocalNameShort);
|
||||
b.putSparseParcelableArray("records_array", mAdRecords);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* As list.
|
||||
*
|
||||
* @param <C> the generic type
|
||||
* @param sparseArray the sparse array
|
||||
* @return the collection
|
||||
*/
|
||||
public static <C> Collection<C> asList(final SparseArray<C> sparseArray) {
|
||||
if (sparseArray == null) return null;
|
||||
|
||||
final Collection<C> arrayList = new ArrayList<>(sparseArray.size());
|
||||
for (int i = 0; i < sparseArray.size(); i++) {
|
||||
arrayList.add(sparseArray.valueAt(i));
|
||||
}
|
||||
|
||||
return arrayList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface BeaconDevice {
|
||||
BeaconType getBeaconType();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class BeaconManufacturerData {
|
||||
private final BeaconType mBeaconType;
|
||||
private final byte[] mData;
|
||||
|
||||
protected BeaconManufacturerData(final BeaconType expectedType, final byte[] data){
|
||||
if (BeaconUtils.getBeaconType(data) != expectedType) {
|
||||
throw new IllegalArgumentException(
|
||||
"Manufacturer record '"
|
||||
+ Arrays.toString(data)
|
||||
+ "' is not from a " + expectedType);
|
||||
}
|
||||
|
||||
this.mData = data;
|
||||
this.mBeaconType = expectedType;
|
||||
}
|
||||
|
||||
public BeaconType getBeaconType(){
|
||||
return mBeaconType;
|
||||
}
|
||||
|
||||
public byte[] getData(){
|
||||
return mData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public enum BeaconType {
|
||||
NOT_A_BEACON,
|
||||
IBEACON,
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconConstants;
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class BeaconUtils {
|
||||
|
||||
private BeaconUtils(){
|
||||
// TO AVOID INSTANTIATION
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether a Manufacturer Data byte array belongs to a known Beacon type;
|
||||
*
|
||||
* @param manufacturerData a Bluetooth LE device's raw manufacturerData.
|
||||
* @return the {@link BeaconType}
|
||||
*/
|
||||
public static BeaconType getBeaconType(final byte[] manufacturerData) {
|
||||
if (manufacturerData == null || manufacturerData.length == 0) {
|
||||
return BeaconType.NOT_A_BEACON;
|
||||
}
|
||||
|
||||
if(isIBeacon(manufacturerData)){
|
||||
return BeaconType.IBEACON;
|
||||
} else {
|
||||
return BeaconType.NOT_A_BEACON;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} is an iBeacon;
|
||||
*
|
||||
* @param device a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} device.
|
||||
* @return the {@link BeaconType}
|
||||
*/
|
||||
public static BeaconType getBeaconType(final BluetoothLeDevice device) {
|
||||
final int key = AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA;
|
||||
return getBeaconType(device.getAdRecordStore().getRecordDataAsString(key).getBytes());
|
||||
}
|
||||
|
||||
private static boolean isIBeacon(final byte[] manufacturerData){
|
||||
// An iBeacon record must be at least 25 chars long
|
||||
if (!(manufacturerData.length >= 25)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ByteUtils.doesArrayBeginWith(manufacturerData, IBeaconConstants.MANUFACTURER_DATA_IBEACON_PREFIX)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class IBeaconConstants {
|
||||
public static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = {0x4C, 0x00, 0x02, 0x15};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
|
||||
|
||||
public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
|
||||
|
||||
/**
|
||||
* The m iBeacon data.
|
||||
*/
|
||||
private final IBeaconManufacturerData mIBeaconData;
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value
|
||||
* @param scanRecord the scanRecord
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
|
||||
super(device, rssi, scanRecord, 0);
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value of the RSSI measurement
|
||||
* @param scanRecord the scan record
|
||||
* @param timestamp the timestamp of the RSSI measurement
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
|
||||
super(device, rssi, scanRecord, timestamp);
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will try to convert a {@link BluetoothLeDevice} into an
|
||||
* iBeacon Device.
|
||||
*
|
||||
* @param device the device
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothLeDevice device) {
|
||||
super(device);
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
private IBeaconDevice(final Parcel in) {
|
||||
super(in);
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the estimated Accuracy of the reading in meters based on
|
||||
* a simple running average of the last {@link #MAX_RSSI_LOG_SIZE}
|
||||
* samples.
|
||||
*
|
||||
* @return the accuracy in meters
|
||||
*/
|
||||
public double getAccuracy() {
|
||||
return IBeaconUtils.calculateAccuracy(
|
||||
getCalibratedTxPower(),
|
||||
getRunningAverageRssi());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeaconType getBeaconType() {
|
||||
return BeaconType.IBEACON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the calibrated TX power of the iBeacon device as reported.
|
||||
*
|
||||
* @return the calibrated TX power
|
||||
*/
|
||||
public int getCalibratedTxPower() {
|
||||
return getIBeaconData().getCalibratedTxPower();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon company identifier.
|
||||
*
|
||||
* @return the company identifier
|
||||
*/
|
||||
public int getCompanyIdentifier() {
|
||||
return getIBeaconData().getCompanyIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the estimated Distance descriptor.
|
||||
*
|
||||
* @return the distance descriptor
|
||||
*/
|
||||
public IBeaconDistanceDescriptor getDistanceDescriptor() {
|
||||
return IBeaconUtils.getDistanceDescriptor(getAccuracy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon manufacturing data.
|
||||
*
|
||||
* @return the iBeacon data
|
||||
*/
|
||||
public IBeaconManufacturerData getIBeaconData() {
|
||||
return mIBeaconData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Major value.
|
||||
*
|
||||
* @return the Major value
|
||||
*/
|
||||
public int getMajor() {
|
||||
return getIBeaconData().getMajor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Minor value.
|
||||
*
|
||||
* @return the Minor value
|
||||
*/
|
||||
public int getMinor() {
|
||||
return getIBeaconData().getMinor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID() {
|
||||
return getIBeaconData().getUUID();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
public enum IBeaconDistanceDescriptor {
|
||||
IMMEDIATE,
|
||||
NEAR,
|
||||
FAR,
|
||||
UNKNOWN,
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
|
||||
/**
|
||||
* Parses the Manufactured Data field of an iBeacon
|
||||
* <p>
|
||||
* The parsing is based on the following schema:
|
||||
* <pre>
|
||||
* Byte|Value
|
||||
* -------------------------------------------------
|
||||
* 0 4C - Byte 1 (LSB) of Company identifier code
|
||||
* 1 00 - Byte 0 (MSB) of Company identifier code (0x004C == Apple)
|
||||
* 2 02 - Byte 0 of iBeacon advertisement indicator
|
||||
* 3 15 - Byte 1 of iBeacon advertisement indicator
|
||||
* 4 e2 |\
|
||||
* 5 c5 |\\
|
||||
* 6 6d |#\\
|
||||
* 7 b5 |##\\
|
||||
* 8 df |###\\
|
||||
* 9 fb |####\\
|
||||
* 10 48 |#####\\
|
||||
* 11 d2 |#####|| iBeacon
|
||||
* 12 b0 |#####|| Proximity UUID
|
||||
* 13 60 |#####//
|
||||
* 14 d0 |####//
|
||||
* 15 f5 |###//
|
||||
* 16 a7 |##//
|
||||
* 17 10 |#//
|
||||
* 18 96 |//
|
||||
* 19 e0 |/
|
||||
* 20 00 - major
|
||||
* 21 00
|
||||
* 22 00 - minor
|
||||
* 23 00
|
||||
* 24 c5 - The 2's complement of the calibrated Tx Power
|
||||
* </pre>
|
||||
* @author Alexandros Schillings
|
||||
*/
|
||||
|
||||
public final class IBeaconManufacturerData extends BeaconManufacturerData{
|
||||
private final int mCalibratedTxPower;
|
||||
private final int mCompanyIdentidier;
|
||||
private final int mIBeaconAdvertisment;
|
||||
private final int mMajor;
|
||||
private final int mMinor;
|
||||
private final String mUUID;
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon manufacturer data object.
|
||||
*
|
||||
* @param device a {@link BluetoothLeDevice}
|
||||
* @throws IllegalArgumentException if the data is not from an iBeacon.
|
||||
*/
|
||||
public IBeaconManufacturerData(final BluetoothLeDevice device) {
|
||||
this(device.getAdRecordStore().getRecord(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon manufacturer data object.
|
||||
*
|
||||
* @param manufacturerData the {@link AdRecord#TYPE_MANUFACTURER_SPECIFIC_DATA} data array
|
||||
* @throws IllegalArgumentException if the data is not from an iBeacon.
|
||||
*/
|
||||
public IBeaconManufacturerData(final byte[] manufacturerData) {
|
||||
super(BeaconType.IBEACON, manufacturerData);
|
||||
|
||||
final byte[] intArray = Arrays.copyOfRange(manufacturerData, 0, 2);
|
||||
ByteUtils.invertArray(intArray);
|
||||
|
||||
mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(intArray);
|
||||
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 2, 4));
|
||||
mUUID = IBeaconUtils.calculateUuidString(Arrays.copyOfRange(manufacturerData, 4, 20));
|
||||
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 20, 22));
|
||||
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 22, 24));
|
||||
mCalibratedTxPower = manufacturerData[24];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the calibrated TX power of the iBeacon device as reported.
|
||||
*
|
||||
* @return the calibrated TX power
|
||||
*/
|
||||
public int getCalibratedTxPower() {
|
||||
return mCalibratedTxPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon company identifier.
|
||||
*
|
||||
* @return the company identifier
|
||||
*/
|
||||
public int getCompanyIdentifier() {
|
||||
return mCompanyIdentidier;
|
||||
}
|
||||
|
||||
public int getIBeaconAdvertisement() {
|
||||
return mIBeaconAdvertisment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Major value.
|
||||
*
|
||||
* @return the Major value
|
||||
*/
|
||||
public int getMajor() {
|
||||
return mMajor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Minor value.
|
||||
*
|
||||
* @return the Minor value
|
||||
*/
|
||||
public int getMinor() {
|
||||
return mMinor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID() {
|
||||
return mUUID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
|
||||
final class IBeaconUtils {
|
||||
private static final double DISTANCE_THRESHOLD_WTF = 0.0;
|
||||
private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5;
|
||||
private static final double DISTANCE_THRESHOLD_NEAR = 3.0;
|
||||
|
||||
private IBeaconUtils(){
|
||||
// TO AVOID INSTANTIATION
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the accuracy of an RSSI reading.
|
||||
* <p/>
|
||||
* The code was taken from <a href="http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing" /a>
|
||||
*
|
||||
* @param txPower the calibrated TX power of an iBeacon
|
||||
* @param rssi the RSSI value of the iBeacon
|
||||
* @return the calculated Accuracy
|
||||
*/
|
||||
public static double calculateAccuracy(final int txPower, final double rssi) {
|
||||
if (rssi == 0) {
|
||||
return -1.0; // if we cannot determine accuracy, return -1.
|
||||
}
|
||||
|
||||
final double ratio = rssi * 1.0 / txPower;
|
||||
if (ratio < 1.0) {
|
||||
return Math.pow(ratio, 10);
|
||||
} else {
|
||||
return (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
|
||||
}
|
||||
}
|
||||
|
||||
public static String calculateUuidString(final byte[] uuid) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < uuid.length; i++) {
|
||||
if (i == 4) {
|
||||
sb.append('-');
|
||||
}
|
||||
if (i == 6) {
|
||||
sb.append('-');
|
||||
}
|
||||
if (i == 8) {
|
||||
sb.append('-');
|
||||
}
|
||||
if (i == 10) {
|
||||
sb.append('-');
|
||||
}
|
||||
|
||||
final int intFromByte = ByteUtils.getIntFromByte(uuid[i]);
|
||||
if(intFromByte <= 0xF){
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(Integer.toHexString(intFromByte));
|
||||
}
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static IBeaconDistanceDescriptor getDistanceDescriptor(final double accuracy) {
|
||||
if (accuracy < DISTANCE_THRESHOLD_WTF) {
|
||||
return IBeaconDistanceDescriptor.UNKNOWN;
|
||||
}
|
||||
|
||||
if (accuracy < DISTANCE_THRESHOLD_IMMEDIATE) {
|
||||
return IBeaconDistanceDescriptor.IMMEDIATE;
|
||||
}
|
||||
|
||||
if (accuracy < DISTANCE_THRESHOLD_NEAR) {
|
||||
return IBeaconDistanceDescriptor.NEAR;
|
||||
}
|
||||
|
||||
return IBeaconDistanceDescriptor.FAR;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package uk.co.alt236.bluetoothlelib.resolvers;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
|
||||
public class BluetoothClassResolver {
|
||||
|
||||
public static String resolveDeviceClass(final int btClass) {
|
||||
switch (btClass) {
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER:
|
||||
return "A/V, Camcorder";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||
return "A/V, Car Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||
return "A/V, Handsfree";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
|
||||
return "A/V, Headphones";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
|
||||
return "A/V, HiFi Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
|
||||
return "A/V, Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_MICROPHONE:
|
||||
return "A/V, Microphone";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
|
||||
return "A/V, Portable Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX:
|
||||
return "A/V, Set Top Box";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_UNCATEGORIZED:
|
||||
return "A/V, Uncategorized";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VCR:
|
||||
return "A/V, VCR";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CAMERA:
|
||||
return "A/V, Video Camera";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CONFERENCING:
|
||||
return "A/V, Video Conferencing";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER:
|
||||
return "A/V, Video Display and Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_GAMING_TOY:
|
||||
return "A/V, Video Gaming Toy";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_MONITOR:
|
||||
return "A/V, Video Monitor";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||
return "A/V, Video Wearable Headset";
|
||||
case BluetoothClass.Device.COMPUTER_DESKTOP:
|
||||
return "Computer, Desktop";
|
||||
case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
|
||||
return "Computer, Handheld PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_LAPTOP:
|
||||
return "Computer, Laptop";
|
||||
case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
|
||||
return "Computer, Palm Size PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_SERVER:
|
||||
return "Computer, Server";
|
||||
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
|
||||
return "Computer, Uncategorized";
|
||||
case BluetoothClass.Device.COMPUTER_WEARABLE:
|
||||
return "Computer, Wearable";
|
||||
case BluetoothClass.Device.HEALTH_BLOOD_PRESSURE:
|
||||
return "Health, Blood Pressure";
|
||||
case BluetoothClass.Device.HEALTH_DATA_DISPLAY:
|
||||
return "Health, Data Display";
|
||||
case BluetoothClass.Device.HEALTH_GLUCOSE:
|
||||
return "Health, Glucose";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_OXIMETER:
|
||||
return "Health, Pulse Oximeter";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_RATE:
|
||||
return "Health, Pulse Rate";
|
||||
case BluetoothClass.Device.HEALTH_THERMOMETER:
|
||||
return "Health, Thermometer";
|
||||
case BluetoothClass.Device.HEALTH_UNCATEGORIZED:
|
||||
return "Health, Uncategorized";
|
||||
case BluetoothClass.Device.HEALTH_WEIGHING:
|
||||
return "Health, Weighting";
|
||||
case BluetoothClass.Device.PHONE_CELLULAR:
|
||||
return "Phone, Cellular";
|
||||
case BluetoothClass.Device.PHONE_CORDLESS:
|
||||
return "Phone, Cordless";
|
||||
case BluetoothClass.Device.PHONE_ISDN:
|
||||
return "Phone, ISDN";
|
||||
case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
|
||||
return "Phone, Modem or Gateway";
|
||||
case BluetoothClass.Device.PHONE_SMART:
|
||||
return "Phone, Smart";
|
||||
case BluetoothClass.Device.PHONE_UNCATEGORIZED:
|
||||
return "Phone, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_CONTROLLER:
|
||||
return "Toy, Controller";
|
||||
case BluetoothClass.Device.TOY_DOLL_ACTION_FIGURE:
|
||||
return "Toy, Doll/Action Figure";
|
||||
case BluetoothClass.Device.TOY_GAME:
|
||||
return "Toy, Game";
|
||||
case BluetoothClass.Device.TOY_ROBOT:
|
||||
return "Toy, Robot";
|
||||
case BluetoothClass.Device.TOY_UNCATEGORIZED:
|
||||
return "Toy, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_VEHICLE:
|
||||
return "Toy, Vehicle";
|
||||
case BluetoothClass.Device.WEARABLE_GLASSES:
|
||||
return "Wearable, Glasses";
|
||||
case BluetoothClass.Device.WEARABLE_HELMET:
|
||||
return "Wearable, Helmet";
|
||||
case BluetoothClass.Device.WEARABLE_JACKET:
|
||||
return "Wearable, Jacket";
|
||||
case BluetoothClass.Device.WEARABLE_PAGER:
|
||||
return "Wearable, Pager";
|
||||
case BluetoothClass.Device.WEARABLE_UNCATEGORIZED:
|
||||
return "Wearable, Uncategorized";
|
||||
case BluetoothClass.Device.WEARABLE_WRIST_WATCH:
|
||||
return "Wearable, Wrist Watch";
|
||||
default:
|
||||
return "Unknown, Unknown (class=" + btClass + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public static String resolveMajorDeviceClass(final int majorBtClass) {
|
||||
switch (majorBtClass) {
|
||||
case BluetoothClass.Device.Major.AUDIO_VIDEO:
|
||||
return "Audio/ Video";
|
||||
case BluetoothClass.Device.Major.COMPUTER:
|
||||
return "Computer";
|
||||
case BluetoothClass.Device.Major.HEALTH:
|
||||
return "Health";
|
||||
case BluetoothClass.Device.Major.IMAGING:
|
||||
return "Imaging";
|
||||
case BluetoothClass.Device.Major.MISC:
|
||||
return "Misc";
|
||||
case BluetoothClass.Device.Major.NETWORKING:
|
||||
return "Networking";
|
||||
case BluetoothClass.Device.Major.PERIPHERAL:
|
||||
return "Peripheral";
|
||||
case BluetoothClass.Device.Major.PHONE:
|
||||
return "Phone";
|
||||
case BluetoothClass.Device.Major.TOY:
|
||||
return "Toy";
|
||||
case BluetoothClass.Device.Major.UNCATEGORIZED:
|
||||
return "Uncategorized";
|
||||
case BluetoothClass.Device.Major.WEARABLE:
|
||||
return "Wearable";
|
||||
default:
|
||||
return "Unknown (" +majorBtClass+ ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
package uk.co.alt236.bluetoothlelib.resolvers;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
public class CompanyIdentifierResolver {
|
||||
public static final int ERICSSON_TECHNOLOGY_LICENSING = 0x0000;
|
||||
public static final int NOKIA_MOBILE_PHONES = 0x0001;
|
||||
public static final int INTEL_CORP = 0x0002;
|
||||
public static final int IBM_CORP = 0x0003;
|
||||
public static final int TOSHIBA_CORP = 0x0004;
|
||||
public static final int THREE_COM = 0x0005;
|
||||
public static final int MICROSOFT = 0x0006;
|
||||
public static final int LUCENT = 0x0007;
|
||||
public static final int MOTOROLA = 0x0008;
|
||||
public static final int INFINEON_TECHNOLOGIES_AG = 0x0009;
|
||||
public static final int CAMBRIDGE_SILICON_RADIO = 0x000A;
|
||||
public static final int SILICON_WAVE = 0x000B;
|
||||
public static final int DIGIANSWER_A_S = 0x000C;
|
||||
public static final int TEXAS_INSTRUMENTS_INC = 0x000D;
|
||||
public static final int CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC = 0x000E;
|
||||
public static final int BROADCOM_CORPORATION = 0x000F;
|
||||
public static final int MITEL_SEMICONDUCTOR = 0x0010;
|
||||
public static final int WIDCOMM_INC = 0x0011;
|
||||
public static final int ZEEVO_INC = 0x0012;
|
||||
public static final int ATMEL_CORPORATION = 0x0013;
|
||||
public static final int MITSUBISHI_ELECTRIC_CORPORATION = 0x0014;
|
||||
public static final int RTX_TELECOM_A_S = 0x0015;
|
||||
public static final int KC_TECHNOLOGY_INC = 0x0016;
|
||||
public static final int NEWLOGIC = 0x0017;
|
||||
public static final int TRANSILICA_INC = 0x0018;
|
||||
public static final int ROHDE_SCHWARZ_GMBH_CO_KG = 0x0019;
|
||||
public static final int TTPCOM_LIMITED = 0x001A;
|
||||
public static final int SIGNIA_TECHNOLOGIES_INC = 0x001B;
|
||||
public static final int CONEXANT_SYSTEMS_INC = 0x001C;
|
||||
public static final int QUALCOMM = 0x001D;
|
||||
public static final int INVENTEL = 0x001E;
|
||||
public static final int AVM_BERLIN = 0x001F;
|
||||
public static final int BANDSPEED_INC = 0x0020;
|
||||
public static final int MANSELLA_LTD = 0x0021;
|
||||
public static final int NEC_CORPORATION = 0x0022;
|
||||
public static final int WAVEPLUS_TECHNOLOGY_CO_LTD = 0x0023;
|
||||
public static final int ALCATEL = 0x0024;
|
||||
public static final int PHILIPS_SEMICONDUCTORS = 0x0025;
|
||||
public static final int C_TECHNOLOGIES = 0x0026;
|
||||
public static final int OPEN_INTERFACE = 0x0027;
|
||||
public static final int R_F_MICRO_DEVICES = 0x0028;
|
||||
public static final int HITACHI_LTD = 0x0029;
|
||||
public static final int SYMBOL_TECHNOLOGIES_INC = 0x002A;
|
||||
public static final int TENOVIS = 0x002B;
|
||||
public static final int MACRONIX_INTERNATIONAL_CO_LTD = 0x002C;
|
||||
public static final int GCT_SEMICONDUCTOR = 0x002D;
|
||||
public static final int NORWOOD_SYSTEMS = 0x002E;
|
||||
public static final int MEWTEL_TECHNOLOGY_INC = 0x002F;
|
||||
public static final int ST_MICROELECTRONICS = 0x0030;
|
||||
public static final int SYNOPSIS = 0x0031;
|
||||
public static final int REDM_COMMUNICATIONS_LTD = 0x0032;
|
||||
public static final int COMMIL_LTD = 0x0033;
|
||||
public static final int COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC = 0x0034;
|
||||
public static final int ECLIPSE_HQ_ESPANA_SL = 0x0035;
|
||||
public static final int RENESAS_TECHNOLOGY_CORP = 0x0036;
|
||||
public static final int MOBILIAN_CORPORATION = 0x0037;
|
||||
public static final int TERAX = 0x0038;
|
||||
public static final int INTEGRATED_SYSTEM_SOLUTION_CORP = 0x0039;
|
||||
public static final int MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD = 0x003A;
|
||||
public static final int GENNUM_CORPORATION = 0x003B;
|
||||
public static final int RESEARCH_IN_MOTION = 0x003C;
|
||||
public static final int IPEXTREME_INC = 0x003D;
|
||||
public static final int SYSTEMS_AND_CHIPS_INC = 0x003E;
|
||||
public static final int BLUETOOTH_SIG_INC = 0x003F;
|
||||
public static final int SEIKO_EPSON_CORPORATION = 0x0040;
|
||||
public static final int INTEGRATED_SILICON_SOLUTION_TAIWAN_INC = 0x0041;
|
||||
public static final int CONWISE_TECHNOLOGY_CORPORATION_LTD = 0x0042;
|
||||
public static final int PARROT_SA = 0x0043;
|
||||
public static final int SOCKET_MOBILE = 0x0044;
|
||||
public static final int ATHEROS_COMMUNICATIONS_INC = 0x0045;
|
||||
public static final int MEDIATEK_INC = 0x0046;
|
||||
public static final int BLUEGIGA = 0x0047;
|
||||
public static final int MARVELL_TECHNOLOGY_GROUP_LTD = 0x0048;
|
||||
public static final int THREE_DSP_CORPORATION = 0x0049;
|
||||
public static final int ACCEL_SEMICONDUCTOR_LTD = 0x004A;
|
||||
public static final int CONTINENTAL_AUTOMOTIVE_SYSTEMS = 0x004B;
|
||||
public static final int APPLE_INC = 0x004C;
|
||||
public static final int STACCATO_COMMUNICATIONS_INC = 0x004D;
|
||||
public static final int AVAGO_TECHNOLOGIES = 0x004E;
|
||||
public static final int APT_LICENSING_LTD = 0x004F;
|
||||
public static final int SIRF_TECHNOLOGY = 0x0050;
|
||||
public static final int TZERO_TECHNOLOGIES_INC = 0x0051;
|
||||
public static final int JM_CORPORATION = 0x0052;
|
||||
public static final int FREE2MOVE_AB = 0x0053;
|
||||
public static final int THREE_DIJOY_CORPORATION = 0x0054;
|
||||
public static final int PLANTRONICS_INC = 0x0055;
|
||||
public static final int SONY_ERICSSON_MOBILE_COMMUNICATIONS = 0x0056;
|
||||
public static final int HARMAN_INTERNATIONAL_INDUSTRIES_INC = 0x0057;
|
||||
public static final int VIZIO_INC = 0x0058;
|
||||
public static final int NORDIC_SEMICONDUCTOR_ASA = 0x0059;
|
||||
public static final int EM_MICROELECTRONICMARIN_SA = 0x005A;
|
||||
public static final int RALINK_TECHNOLOGY_CORPORATION = 0x005B;
|
||||
public static final int BELKIN_INTERNATIONAL_INC = 0x005C;
|
||||
public static final int REALTEK_SEMICONDUCTOR_CORPORATION = 0x005D;
|
||||
public static final int STONESTREET_ONE_LLC = 0x005E;
|
||||
public static final int WICENTRIC_INC = 0x005F;
|
||||
public static final int RIVIERAWAVES_SAS = 0x0060;
|
||||
public static final int RDA_MICROELECTRONICS = 0x0061;
|
||||
public static final int GIBSON_GUITARS = 0x0062;
|
||||
public static final int MICOMMAND_INC = 0x0063;
|
||||
public static final int BAND_XI_INTERNATIONAL_LLC = 0x0064;
|
||||
public static final int HEWLETTPACKARD_COMPANY = 0x0065;
|
||||
public static final int NINE_SOLUTIONS_OY = 0x0066;
|
||||
public static final int GN_NETCOM_A_S = 0x0067;
|
||||
public static final int GENERAL_MOTORS = 0x0068;
|
||||
public static final int AD_ENGINEERING_INC = 0x0069;
|
||||
public static final int MINDTREE_LTD = 0x006A;
|
||||
public static final int POLAR_ELECTRO_OY = 0x006B;
|
||||
public static final int BEAUTIFUL_ENTERPRISE_CO_LTD = 0x006C;
|
||||
public static final int BRIARTEK_INC = 0x006D;
|
||||
public static final int SUMMIT_DATA_COMMUNICATIONS_INC = 0x006E;
|
||||
public static final int SOUND_ID = 0x006F;
|
||||
public static final int MONSTER_LLC = 0x0070;
|
||||
public static final int CONNECTBLUE_AB = 0x0071;
|
||||
public static final int SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD = 0x0072;
|
||||
public static final int GROUP_SENSE_LTD = 0x0073;
|
||||
public static final int ZOMM_LLC = 0x0074;
|
||||
public static final int SAMSUNG_ELECTRONICS_CO_LTD = 0x0075;
|
||||
public static final int CREATIVE_TECHNOLOGY_LTD = 0x0076;
|
||||
public static final int LAIRD_TECHNOLOGIES = 0x0077;
|
||||
public static final int NIKE_INC = 0x0078;
|
||||
public static final int LESSWIRE_AG = 0x0079;
|
||||
public static final int MSTAR_SEMICONDUCTOR_INC = 0x007A;
|
||||
public static final int HANLYNN_TECHNOLOGIES = 0x007B;
|
||||
public static final int A_R_CAMBRIDGE = 0x007C;
|
||||
public static final int SEERS_TECHNOLOGY_CO_LTD = 0x007D;
|
||||
public static final int SPORTS_TRACKING_TECHNOLOGIES_LTD = 0x007E;
|
||||
public static final int AUTONET_MOBILE = 0x007F;
|
||||
public static final int DELORME_PUBLISHING_COMPANY_INC = 0x0080;
|
||||
public static final int WUXI_VIMICRO = 0x0081;
|
||||
public static final int SENNHEISER_COMMUNICATIONS_A_S = 0x0082;
|
||||
public static final int TIMEKEEPING_SYSTEMS_INC = 0x0083;
|
||||
public static final int LUDUS_HELSINKI_LTD = 0x0084;
|
||||
public static final int BLUERADIOS_INC = 0x0085;
|
||||
public static final int EQUINOX_AG = 0x0086;
|
||||
public static final int GARMIN_INTERNATIONAL_INC = 0x0087;
|
||||
public static final int ECOTEST = 0x0088;
|
||||
public static final int GN_RESOUND_A_S = 0x0089;
|
||||
public static final int JAWBONE = 0x008A;
|
||||
public static final int TOPCORN_POSITIONING_SYSTEMS_LLC = 0x008B;
|
||||
public static final int QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC = 0x008C;
|
||||
public static final int ZSCAN_SOFTWARE = 0x008D;
|
||||
public static final int QUINTIC_CORP = 0x008E;
|
||||
public static final int STOLLMAN_EV_GMBH = 0x008F;
|
||||
public static final int FUNAI_ELECTRIC_CO_LTD = 0x0090;
|
||||
public static final int ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG = 0x0091;
|
||||
public static final int THINKOPTICS_INC = 0x0092;
|
||||
public static final int UNIVERSAL_ELECTRONICS_INC = 0x0093;
|
||||
public static final int AIROHA_TECHNOLOGY_CORP = 0x0094;
|
||||
public static final int NEC_LIGHTING_LTD = 0x0095;
|
||||
public static final int ODM_TECHNOLOGY_INC = 0x0096;
|
||||
public static final int CONNECTEDEVICE_LTD = 0x0097;
|
||||
public static final int ZER01TV_GMBH = 0x0098;
|
||||
public static final int ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD = 0x0099;
|
||||
public static final int ALPWISE = 0x009A;
|
||||
public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD = 0x009B;
|
||||
public static final int COLORFY_INC = 0x009C;
|
||||
public static final int GEOFORCE_INC = 0x009D;
|
||||
public static final int BOSE_CORPORATION = 0x009E;
|
||||
public static final int SUUNTO_OY = 0x009F;
|
||||
public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 0x00A0;
|
||||
public static final int SRMEDIZINELEKTRONIK = 0x00A1;
|
||||
public static final int VERTU_CORPORATION_LIMITED = 0x00A2;
|
||||
public static final int META_WATCH_LTD = 0x00A3;
|
||||
public static final int LINAK_A_S = 0x00A4;
|
||||
public static final int OTL_DYNAMICS_LLC = 0x00A5;
|
||||
public static final int PANDA_OCEAN_INC = 0x00A6;
|
||||
public static final int VISTEON_CORPORATION = 0x00A7;
|
||||
public static final int ARP_DEVICES_LIMITED = 0x00A8;
|
||||
public static final int MAGNETI_MARELLI_SPA = 0x00A9;
|
||||
public static final int CAEN_RFID_SRL = 0x00AA;
|
||||
public static final int INGENIEURSYSTEMGRUPPE_ZAHN_GMBH = 0x00AB;
|
||||
public static final int GREEN_THROTTLE_GAMES = 0x00AC;
|
||||
public static final int PETER_SYSTEMTECHNIK_GMBH = 0x00AD;
|
||||
public static final int OMEGAWAVE_OY = 0x00AE;
|
||||
public static final int CINETIX = 0x00AF;
|
||||
public static final int PASSIF_SEMICONDUCTOR_CORP = 0x00B0;
|
||||
public static final int SARIS_CYCLING_GROUP_INC = 0x00B1;
|
||||
public static final int BEKEY_A_S = 0x00B2;
|
||||
public static final int CLARINOX_TECHNOLOGIES_PTY_LTD = 0x00B3;
|
||||
public static final int BDE_TECHNOLOGY_CO_LTD = 0x00B4;
|
||||
public static final int SWIRL_NETWORKS = 0x00B5;
|
||||
public static final int MESO_INTERNATIONAL = 0x00B6;
|
||||
public static final int TRELAB_LTD = 0x00B7;
|
||||
public static final int QUALCOMM_INNOVATION_CENTER_INC_QUIC = 0x00B8;
|
||||
public static final int JOHNSON_CONTROLS_INC = 0x00B9;
|
||||
public static final int STARKEY_LABORATORIES_INC = 0x00BA;
|
||||
public static final int SPOWER_ELECTRONICS_LIMITED = 0x00BB;
|
||||
public static final int ACE_SENSOR_INC = 0x00BC;
|
||||
public static final int APLIX_CORPORATION = 0x00BD;
|
||||
public static final int AAMP_OF_AMERICA = 0x00BE;
|
||||
public static final int STALMART_TECHNOLOGY_LIMITED = 0x00BF;
|
||||
public static final int AMICCOM_ELECTRONICS_CORPORATION = 0x00C0;
|
||||
public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD = 0x00C1;
|
||||
public static final int GENEQ_INC = 0x00C2;
|
||||
public static final int ADIDAS_AG = 0x00C3;
|
||||
public static final int LG_ELECTRONICS = 0x00C4;
|
||||
public static final int ONSET_COMPUTER_CORPORATION = 0x00C5;
|
||||
public static final int SELFLY_BV = 0x00C6;
|
||||
public static final int QUUPPA_OY = 0x00C7;
|
||||
public static final int GELO_INC = 0x00C8;
|
||||
public static final int EVLUMA = 0x00C9;
|
||||
public static final int MC10 = 0x00CA;
|
||||
public static final int BINAURIC_SE = 0x00CB;
|
||||
public static final int BEATS_ELECTRONICS = 0x00CC;
|
||||
public static final int MICROCHIP_TECHNOLOGY_INC = 0x00CD;
|
||||
public static final int ELGATO_SYSTEMS_GMBH = 0x00CE;
|
||||
public static final int ARCHOS_SA = 0x00CF;
|
||||
public static final int DEXCOM_INC = 0x00D0;
|
||||
public static final int POLAR_ELECTRO_EUROPE_BV = 0x00D1;
|
||||
public static final int DIALOG_SEMICONDUCTOR_BV = 0x00D2;
|
||||
public static final int TAIXINGBANG_TECHNOLOGY_HK_CO_LTD = 0x00D3;
|
||||
public static final int KAWANTECH = 0x00D4;
|
||||
public static final int AUSTCO_COMMUNICATION_SYSTEMS = 0x00D5;
|
||||
public static final int TIMEX_GROUP_USA_INC = 0x00D6;
|
||||
public static final int QUALCOMM_TECHNOLOGIES_INC = 0x00D7;
|
||||
public static final int QUALCOMM_CONNECTED_EXPERIENCES_INC = 0x00D8;
|
||||
public static final int VOYETRA_TURTLE_BEACH = 0x00D9;
|
||||
public static final int TXTR_GMBH = 0x00DA;
|
||||
public static final int BIOSENTRONICS = 0x00DB;
|
||||
public static final int PROCTER_GAMBLE = 0x00DC;
|
||||
public static final int HOSIDEN_CORPORATION = 0x00DD;
|
||||
public static final int MUZIK_LLC = 0x00DE;
|
||||
public static final int MISFIT_WEARABLES_CORP = 0x00DF;
|
||||
public static final int GOOGLE = 0x00E0;
|
||||
public static final int DANLERS_LTD = 0x00E1;
|
||||
public static final int SEMILINK_INC = 0x00E2;
|
||||
public static final int INMUSIC_BRANDS_INC = 0x00E3;
|
||||
public static final int LS_RESEARCH_INC = 0x00E4;
|
||||
public static final int EDEN_SOFTWARE_CONSULTANTS_LTD = 0x00E5;
|
||||
public static final int FRESHTEMP = 0x00E6;
|
||||
public static final int KS_TECHNOLOGIES = 0x00E7;
|
||||
public static final int ACTS_TECHNOLOGIES = 0x00E8;
|
||||
public static final int VTRACK_SYSTEMS = 0x00E9;
|
||||
public static final int NIELSENKELLERMAN_COMPANY = 0x00EA;
|
||||
public static final int SERVER_TECHNOLOGY_INC = 0x00EB;
|
||||
public static final int BIORESEARCH_ASSOCIATES = 0x00EC;
|
||||
public static final int JOLLY_LOGIC_LLC = 0x00ED;
|
||||
public static final int ABOVE_AVERAGE_OUTCOMES_INC = 0x00EE;
|
||||
public static final int BITSPLITTERS_GMBH = 0x00EF;
|
||||
public static final int PAYPAL_INC = 0x00F0;
|
||||
public static final int WITRON_TECHNOLOGY_LIMITED = 0x00F1;
|
||||
public static final int MORSE_PROJECT_INC = 0x00F2;
|
||||
public static final int KENT_DISPLAYS_INC = 0x00F3;
|
||||
public static final int NAUTILUS_INC = 0x00F4;
|
||||
public static final int SMARTIFIER_OY = 0x00F5;
|
||||
public static final int ELCOMETER_LIMITED = 0x00F6;
|
||||
public static final int VSN_TECHNOLOGIES_INC = 0x00F7;
|
||||
public static final int ACEUNI_CORP_LTD = 0x00F8;
|
||||
public static final int STICKNFIND = 0x00F9;
|
||||
public static final int CRYSTAL_CODE_AB = 0x00FA;
|
||||
public static final int KOUKAAM_AS = 0x00FB;
|
||||
public static final int DELPHI_CORPORATION = 0x00FC;
|
||||
public static final int VALENCETECH_LIMITED = 0x00FD;
|
||||
public static final int RESERVED = 0x00FE;
|
||||
public static final int TYPO_PRODUCTS_LLC = 0x00FF;
|
||||
public static final int TOMTOM_INTERNATIONAL_BV = 0x0100;
|
||||
public static final int FUGOO_INC = 0x0101;
|
||||
public static final int KEISER_CORPORATION = 0x0102;
|
||||
public static final int BANG_OLUFSEN_A_S = 0x0103;
|
||||
public static final int PLUS_LOCATIONS_SYSTEMS_PTY_LTD = 0x0104;
|
||||
public static final int UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION = 0x0105;
|
||||
public static final int INNOVATIVE_YACHTTER_SOLUTIONS = 0x0106;
|
||||
public static final int WILLIAM_DEMANT_HOLDING_A_S = 0x0107;
|
||||
public static final int CHICONY_ELECTRONICS_CO_LTD = 0x0108;
|
||||
public static final int ATUS_BV = 0x0109;
|
||||
public static final int CODEGATE_LTD = 0x010A;
|
||||
public static final int ERI_INC = 0x010B;
|
||||
public static final int TRANSDUCERS_DIRECT_LLC = 0x010C;
|
||||
public static final int FUJITSU_TEN_LIMITED = 0x010D;
|
||||
public static final int AUDI_AG = 0x010E;
|
||||
public static final int HISILICON_TECHNOLOGIES_CO_LTD = 0x010F;
|
||||
public static final int NIPPON_SEIKI_CO_LTD = 0x0110;
|
||||
public static final int STEELSERIES_APS = 0x0111;
|
||||
public static final int VYZYBL_INC = 0x0112;
|
||||
public static final int OPENBRAIN_TECHNOLOGIES_CO_LTD = 0x0113;
|
||||
public static final int XENSR = 0x0114;
|
||||
public static final int ESOLUTIONS = 0x0115;
|
||||
public static final int ONE_OAK_TECHNOLOGIES = 0x0116;
|
||||
public static final int WIMOTO_TECHNOLOGIES_INC = 0x0117;
|
||||
public static final int RADIUS_NETWORKS_INC = 0x0118;
|
||||
public static final int WIZE_TECHNOLOGY_CO_LTD = 0x0119;
|
||||
public static final int QUALCOMM_LABS_INC = 0x011A;
|
||||
public static final int ARUBA_NETWORKS = 0x011B;
|
||||
public static final int BAIDU = 0x011C;
|
||||
public static final int ARENDI_AG = 0x011D;
|
||||
public static final int SKODA_AUTO_AS = 0x011E;
|
||||
public static final int VOLKSWAGON_AG = 0x011F;
|
||||
public static final int PORSCHE_AG = 0x0120;
|
||||
public static final int SINO_WEALTH_ELECTRONIC_LTD = 0x0121;
|
||||
public static final int AIRTURN_INC = 0x0122;
|
||||
public static final int KINSA_INC = 0x0123;
|
||||
public static final int HID_GLOBAL = 0x0124;
|
||||
public static final int SEAT_ES = 0x0125;
|
||||
public static final int PROMETHEAN_LTD = 0x0126;
|
||||
public static final int SALUTICA_ALLIED_SOLUTIONS = 0x0127;
|
||||
public static final int GPSI_GROUP_PTY_LTD = 0x0128;
|
||||
public static final int NIMBLE_DEVICES_OY = 0x0129;
|
||||
public static final int CHANGZHOU_YONGSE_INFOTECH_CO_LTD = 0x012A;
|
||||
public static final int SPORTIQ = 0x012B;
|
||||
public static final int TEMEC_INSTRUMENTS_BV = 0x012C;
|
||||
public static final int SONY_CORPORATION = 0x012D;
|
||||
public static final int ASSA_ABLOY = 0x012E;
|
||||
public static final int CLARION_CO_LTD = 0x012F;
|
||||
public static final int WAREHOUSE_INNOVATIONS = 0x0130;
|
||||
public static final int CYPRESS_SEMICONDUCTOR_CORPORATION = 0x0131;
|
||||
public static final int MADS_INC = 0x0132;
|
||||
public static final int BLUE_MAESTRO_LIMITED = 0x0133;
|
||||
public static final int RESOLUTION_PRODUCTS_INC = 0x0134;
|
||||
public static final int AIREWEAR_LLC = 0x0135;
|
||||
public static final int ETC_SP_ZOO = 0x0136;
|
||||
public static final int PRESTIGIO_PLAZA_LTD = 0x0137;
|
||||
|
||||
private static final SparseArray<String> COMPANY_NAME_MAP = populateCompanyNameMap();
|
||||
|
||||
public static String getCompanyName(final int companyId, final String fallback) {
|
||||
final String name = COMPANY_NAME_MAP.get(companyId);
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
|
||||
private static SparseArray<String> populateCompanyNameMap() {
|
||||
final SparseArray<String> map = new SparseArray<>();
|
||||
|
||||
map.put(ERICSSON_TECHNOLOGY_LICENSING, "Ericsson Technology Licensing");
|
||||
map.put(NOKIA_MOBILE_PHONES, "Nokia Mobile Phones");
|
||||
map.put(INTEL_CORP, "Intel Corp.");
|
||||
map.put(IBM_CORP, "IBM Corp.");
|
||||
map.put(TOSHIBA_CORP, "Toshiba Corp.");
|
||||
map.put(THREE_COM, "3Com");
|
||||
map.put(MICROSOFT, "Microsoft");
|
||||
map.put(LUCENT, "Lucent");
|
||||
map.put(MOTOROLA, "Motorola");
|
||||
map.put(INFINEON_TECHNOLOGIES_AG, "Infineon Technologies AG");
|
||||
map.put(CAMBRIDGE_SILICON_RADIO, "Cambridge Silicon Radio");
|
||||
map.put(SILICON_WAVE, "Silicon Wave");
|
||||
map.put(DIGIANSWER_A_S, "Digianswer A/S");
|
||||
map.put(TEXAS_INSTRUMENTS_INC, "Texas Instruments Inc.");
|
||||
map.put(CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC, "Ceva, Inc. (formerly Parthus Technologies, Inc.)");
|
||||
map.put(BROADCOM_CORPORATION, "Broadcom Corporation");
|
||||
map.put(MITEL_SEMICONDUCTOR, "Mitel Semiconductor");
|
||||
map.put(WIDCOMM_INC, "Widcomm, Inc");
|
||||
map.put(ZEEVO_INC, "Zeevo, Inc.");
|
||||
map.put(ATMEL_CORPORATION, "Atmel Corporation");
|
||||
map.put(MITSUBISHI_ELECTRIC_CORPORATION, "Mitsubishi Electric Corporation");
|
||||
map.put(RTX_TELECOM_A_S, "RTX Telecom A/S");
|
||||
map.put(KC_TECHNOLOGY_INC, "KC Technology Inc.");
|
||||
map.put(NEWLOGIC, "NewLogic");
|
||||
map.put(TRANSILICA_INC, "Transilica, Inc.");
|
||||
map.put(ROHDE_SCHWARZ_GMBH_CO_KG, "Rohde & Schwarz GmbH & Co. KG");
|
||||
map.put(TTPCOM_LIMITED, "TTPCom Limited");
|
||||
map.put(SIGNIA_TECHNOLOGIES_INC, "Signia Technologies, Inc.");
|
||||
map.put(CONEXANT_SYSTEMS_INC, "Conexant Systems Inc.");
|
||||
map.put(QUALCOMM, "Qualcomm");
|
||||
map.put(INVENTEL, "Inventel");
|
||||
map.put(AVM_BERLIN, "AVM Berlin");
|
||||
map.put(BANDSPEED_INC, "BandSpeed, Inc.");
|
||||
map.put(MANSELLA_LTD, "Mansella Ltd");
|
||||
map.put(NEC_CORPORATION, "NEC Corporation");
|
||||
map.put(WAVEPLUS_TECHNOLOGY_CO_LTD, "WavePlus Technology Co., Ltd.");
|
||||
map.put(ALCATEL, "Alcatel");
|
||||
map.put(PHILIPS_SEMICONDUCTORS, "Philips Semiconductors");
|
||||
map.put(C_TECHNOLOGIES, "C Technologies");
|
||||
map.put(OPEN_INTERFACE, "Open Interface");
|
||||
map.put(R_F_MICRO_DEVICES, "R F Micro Devices");
|
||||
map.put(HITACHI_LTD, "Hitachi Ltd");
|
||||
map.put(SYMBOL_TECHNOLOGIES_INC, "Symbol Technologies, Inc.");
|
||||
map.put(TENOVIS, "Tenovis");
|
||||
map.put(MACRONIX_INTERNATIONAL_CO_LTD, "Macronix International Co. Ltd.");
|
||||
map.put(GCT_SEMICONDUCTOR, "GCT Semiconductor");
|
||||
map.put(NORWOOD_SYSTEMS, "Norwood Systems");
|
||||
map.put(MEWTEL_TECHNOLOGY_INC, "MewTel Technology Inc.");
|
||||
map.put(ST_MICROELECTRONICS, "ST Microelectronics");
|
||||
map.put(SYNOPSIS, "Synopsis");
|
||||
map.put(REDM_COMMUNICATIONS_LTD, "Red-M (Communications) Ltd");
|
||||
map.put(COMMIL_LTD, "Commil Ltd");
|
||||
map.put(COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC, "Computer Access Technology Corporation (CATC)");
|
||||
map.put(ECLIPSE_HQ_ESPANA_SL, "Eclipse (HQ Espana) S.L.");
|
||||
map.put(RENESAS_TECHNOLOGY_CORP, "Renesas Technology Corp.");
|
||||
map.put(MOBILIAN_CORPORATION, "Mobilian Corporation");
|
||||
map.put(TERAX, "Terax");
|
||||
map.put(INTEGRATED_SYSTEM_SOLUTION_CORP, "Integrated System Solution Corp.");
|
||||
map.put(MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD, "Matsushita Electric Industrial Co., Ltd.");
|
||||
map.put(GENNUM_CORPORATION, "Gennum Corporation");
|
||||
map.put(RESEARCH_IN_MOTION, "Research In Motion");
|
||||
map.put(IPEXTREME_INC, "IPextreme, Inc.");
|
||||
map.put(SYSTEMS_AND_CHIPS_INC, "Systems and Chips, Inc.");
|
||||
map.put(BLUETOOTH_SIG_INC, "Bluetooth SIG, Inc.");
|
||||
map.put(SEIKO_EPSON_CORPORATION, "Seiko Epson Corporation");
|
||||
map.put(INTEGRATED_SILICON_SOLUTION_TAIWAN_INC, "Integrated Silicon Solution Taiwan, Inc.");
|
||||
map.put(CONWISE_TECHNOLOGY_CORPORATION_LTD, "CONWISE Technology Corporation Ltd");
|
||||
map.put(PARROT_SA, "PARROT SA");
|
||||
map.put(SOCKET_MOBILE, "Socket Mobile");
|
||||
map.put(ATHEROS_COMMUNICATIONS_INC, "Atheros Communications, Inc.");
|
||||
map.put(MEDIATEK_INC, "MediaTek, Inc.");
|
||||
map.put(BLUEGIGA, "Bluegiga");
|
||||
map.put(MARVELL_TECHNOLOGY_GROUP_LTD, "Marvell Technology Group Ltd.");
|
||||
map.put(THREE_DSP_CORPORATION, "3DSP Corporation");
|
||||
map.put(ACCEL_SEMICONDUCTOR_LTD, "Accel Semiconductor Ltd.");
|
||||
map.put(CONTINENTAL_AUTOMOTIVE_SYSTEMS, "Continental Automotive Systems");
|
||||
map.put(APPLE_INC, "Apple, Inc.");
|
||||
map.put(STACCATO_COMMUNICATIONS_INC, "Staccato Communications, Inc.");
|
||||
map.put(AVAGO_TECHNOLOGIES, "Avago Technologies");
|
||||
map.put(APT_LICENSING_LTD, "APT Licensing Ltd.");
|
||||
map.put(SIRF_TECHNOLOGY, "SiRF Technology");
|
||||
map.put(TZERO_TECHNOLOGIES_INC, "Tzero Technologies, Inc.");
|
||||
map.put(JM_CORPORATION, "J&M Corporation");
|
||||
map.put(FREE2MOVE_AB, "Free2move AB");
|
||||
map.put(THREE_DIJOY_CORPORATION, "3DiJoy Corporation");
|
||||
map.put(PLANTRONICS_INC, "Plantronics, Inc.");
|
||||
map.put(SONY_ERICSSON_MOBILE_COMMUNICATIONS, "Sony Ericsson Mobile Communications");
|
||||
map.put(HARMAN_INTERNATIONAL_INDUSTRIES_INC, "Harman International Industries, Inc.");
|
||||
map.put(VIZIO_INC, "Vizio, Inc.");
|
||||
map.put(NORDIC_SEMICONDUCTOR_ASA, "Nordic Semiconductor ASA");
|
||||
map.put(EM_MICROELECTRONICMARIN_SA, "EM Microelectronic-Marin SA");
|
||||
map.put(RALINK_TECHNOLOGY_CORPORATION, "Ralink Technology Corporation");
|
||||
map.put(BELKIN_INTERNATIONAL_INC, "Belkin International, Inc.");
|
||||
map.put(REALTEK_SEMICONDUCTOR_CORPORATION, "Realtek Semiconductor Corporation");
|
||||
map.put(STONESTREET_ONE_LLC, "Stonestreet One, LLC");
|
||||
map.put(WICENTRIC_INC, "Wicentric, Inc.");
|
||||
map.put(RIVIERAWAVES_SAS, "RivieraWaves S.A.S");
|
||||
map.put(RDA_MICROELECTRONICS, "RDA Microelectronics");
|
||||
map.put(GIBSON_GUITARS, "Gibson Guitars");
|
||||
map.put(MICOMMAND_INC, "MiCommand Inc.");
|
||||
map.put(BAND_XI_INTERNATIONAL_LLC, "Band XI International, LLC");
|
||||
map.put(HEWLETTPACKARD_COMPANY, "Hewlett-Packard Company");
|
||||
map.put(NINE_SOLUTIONS_OY, "9Solutions Oy");
|
||||
map.put(GN_NETCOM_A_S, "GN Netcom A/S");
|
||||
map.put(GENERAL_MOTORS, "General Motors");
|
||||
map.put(AD_ENGINEERING_INC, "A&D Engineering, Inc.");
|
||||
map.put(MINDTREE_LTD, "MindTree Ltd.");
|
||||
map.put(POLAR_ELECTRO_OY, "Polar Electro OY");
|
||||
map.put(BEAUTIFUL_ENTERPRISE_CO_LTD, "Beautiful Enterprise Co., Ltd.");
|
||||
map.put(BRIARTEK_INC, "BriarTek, Inc.");
|
||||
map.put(SUMMIT_DATA_COMMUNICATIONS_INC, "Summit Data Communications, Inc.");
|
||||
map.put(SOUND_ID, "Sound ID");
|
||||
map.put(MONSTER_LLC, "Monster, LLC");
|
||||
map.put(CONNECTBLUE_AB, "connectBlue AB");
|
||||
map.put(SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD, "ShangHai Super Smart Electronics Co. Ltd.");
|
||||
map.put(GROUP_SENSE_LTD, "Group Sense Ltd.");
|
||||
map.put(ZOMM_LLC, "Zomm, LLC");
|
||||
map.put(SAMSUNG_ELECTRONICS_CO_LTD, "Samsung Electronics Co. Ltd.");
|
||||
map.put(CREATIVE_TECHNOLOGY_LTD, "Creative Technology Ltd.");
|
||||
map.put(LAIRD_TECHNOLOGIES, "Laird Technologies");
|
||||
map.put(NIKE_INC, "Nike, Inc.");
|
||||
map.put(LESSWIRE_AG, "lesswire AG");
|
||||
map.put(MSTAR_SEMICONDUCTOR_INC, "MStar Semiconductor, Inc.");
|
||||
map.put(HANLYNN_TECHNOLOGIES, "Hanlynn Technologies");
|
||||
map.put(A_R_CAMBRIDGE, "A & R Cambridge");
|
||||
map.put(SEERS_TECHNOLOGY_CO_LTD, "Seers Technology Co. Ltd");
|
||||
map.put(SPORTS_TRACKING_TECHNOLOGIES_LTD, "Sports Tracking Technologies Ltd.");
|
||||
map.put(AUTONET_MOBILE, "Autonet Mobile");
|
||||
map.put(DELORME_PUBLISHING_COMPANY_INC, "DeLorme Publishing Company, Inc.");
|
||||
map.put(WUXI_VIMICRO, "WuXi Vimicro");
|
||||
map.put(SENNHEISER_COMMUNICATIONS_A_S, "Sennheiser Communications A/S");
|
||||
map.put(TIMEKEEPING_SYSTEMS_INC, "TimeKeeping Systems, Inc.");
|
||||
map.put(LUDUS_HELSINKI_LTD, "Ludus Helsinki Ltd.");
|
||||
map.put(BLUERADIOS_INC, "BlueRadios, Inc.");
|
||||
map.put(EQUINOX_AG, "equinox AG");
|
||||
map.put(GARMIN_INTERNATIONAL_INC, "Garmin International, Inc.");
|
||||
map.put(ECOTEST, "Ecotest");
|
||||
map.put(GN_RESOUND_A_S, "GN ReSound A/S");
|
||||
map.put(JAWBONE, "Jawbone");
|
||||
map.put(TOPCORN_POSITIONING_SYSTEMS_LLC, "Topcorn Positioning Systems, LLC");
|
||||
map.put(QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC, "Qualcomm Retail Solutions, Inc. (formerly Qualcomm Labs, Inc.)");
|
||||
map.put(ZSCAN_SOFTWARE, "Zscan Software");
|
||||
map.put(QUINTIC_CORP, "Quintic Corp.");
|
||||
map.put(STOLLMAN_EV_GMBH, "Stollman E+V GmbH");
|
||||
map.put(FUNAI_ELECTRIC_CO_LTD, "Funai Electric Co., Ltd.");
|
||||
map.put(ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG, "Advanced PANMOBIL Systems GmbH & Co. KG");
|
||||
map.put(THINKOPTICS_INC, "ThinkOptics, Inc.");
|
||||
map.put(UNIVERSAL_ELECTRONICS_INC, "Universal Electronics, Inc.");
|
||||
map.put(AIROHA_TECHNOLOGY_CORP, "Airoha Technology Corp.");
|
||||
map.put(NEC_LIGHTING_LTD, "NEC Lighting, Ltd.");
|
||||
map.put(ODM_TECHNOLOGY_INC, "ODM Technology, Inc.");
|
||||
map.put(CONNECTEDEVICE_LTD, "ConnecteDevice Ltd.");
|
||||
map.put(ZER01TV_GMBH, "zer01.tv GmbH");
|
||||
map.put(ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD, "i.Tech Dynamic Global Distribution Ltd.");
|
||||
map.put(ALPWISE, "Alpwise");
|
||||
map.put(JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD, "Jiangsu Toppower Automotive Electronics Co., Ltd.");
|
||||
map.put(COLORFY_INC, "Colorfy, Inc.");
|
||||
map.put(GEOFORCE_INC, "Geoforce Inc.");
|
||||
map.put(BOSE_CORPORATION, "Bose Corporation");
|
||||
map.put(SUUNTO_OY, "Suunto Oy");
|
||||
map.put(KENSINGTON_COMPUTER_PRODUCTS_GROUP, "Kensington Computer Products Group");
|
||||
map.put(SRMEDIZINELEKTRONIK, "SR-Medizinelektronik");
|
||||
map.put(VERTU_CORPORATION_LIMITED, "Vertu Corporation Limited");
|
||||
map.put(META_WATCH_LTD, "Meta Watch Ltd.");
|
||||
map.put(LINAK_A_S, "LINAK A/S");
|
||||
map.put(OTL_DYNAMICS_LLC, "OTL Dynamics LLC");
|
||||
map.put(PANDA_OCEAN_INC, "Panda Ocean Inc.");
|
||||
map.put(VISTEON_CORPORATION, "Visteon Corporation");
|
||||
map.put(ARP_DEVICES_LIMITED, "ARP Devices Limited");
|
||||
map.put(MAGNETI_MARELLI_SPA, "Magneti Marelli S.p.A");
|
||||
map.put(CAEN_RFID_SRL, "CAEN RFID srl");
|
||||
map.put(INGENIEURSYSTEMGRUPPE_ZAHN_GMBH, "Ingenieur-Systemgruppe Zahn GmbH");
|
||||
map.put(GREEN_THROTTLE_GAMES, "Green Throttle Games");
|
||||
map.put(PETER_SYSTEMTECHNIK_GMBH, "Peter Systemtechnik GmbH");
|
||||
map.put(OMEGAWAVE_OY, "Omegawave Oy");
|
||||
map.put(CINETIX, "Cinetix");
|
||||
map.put(PASSIF_SEMICONDUCTOR_CORP, "Passif Semiconductor Corp");
|
||||
map.put(SARIS_CYCLING_GROUP_INC, "Saris Cycling Group, Inc");
|
||||
map.put(BEKEY_A_S, "Bekey A/S");
|
||||
map.put(CLARINOX_TECHNOLOGIES_PTY_LTD, "Clarinox Technologies Pty. Ltd.");
|
||||
map.put(BDE_TECHNOLOGY_CO_LTD, "BDE Technology Co., Ltd.");
|
||||
map.put(SWIRL_NETWORKS, "Swirl Networks");
|
||||
map.put(MESO_INTERNATIONAL, "Meso international");
|
||||
map.put(TRELAB_LTD, "TreLab Ltd");
|
||||
map.put(QUALCOMM_INNOVATION_CENTER_INC_QUIC, "Qualcomm Innovation Center, Inc. (QuIC)");
|
||||
map.put(JOHNSON_CONTROLS_INC, "Johnson Controls, Inc.");
|
||||
map.put(STARKEY_LABORATORIES_INC, "Starkey Laboratories Inc.");
|
||||
map.put(SPOWER_ELECTRONICS_LIMITED, "S-Power Electronics Limited");
|
||||
map.put(ACE_SENSOR_INC, "Ace Sensor Inc");
|
||||
map.put(APLIX_CORPORATION, "Aplix Corporation");
|
||||
map.put(AAMP_OF_AMERICA, "AAMP of America");
|
||||
map.put(STALMART_TECHNOLOGY_LIMITED, "Stalmart Technology Limited");
|
||||
map.put(AMICCOM_ELECTRONICS_CORPORATION, "AMICCOM Electronics Corporation");
|
||||
map.put(SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD, "Shenzhen Excelsecu Data Technology Co.,Ltd");
|
||||
map.put(GENEQ_INC, "Geneq Inc.");
|
||||
map.put(ADIDAS_AG, "adidas AG");
|
||||
map.put(LG_ELECTRONICS, "LG Electronics");
|
||||
map.put(ONSET_COMPUTER_CORPORATION, "Onset Computer Corporation");
|
||||
map.put(SELFLY_BV, "Selfly BV");
|
||||
map.put(QUUPPA_OY, "Quuppa Oy.");
|
||||
map.put(GELO_INC, "GeLo Inc");
|
||||
map.put(EVLUMA, "Evluma");
|
||||
map.put(MC10, "MC10");
|
||||
map.put(BINAURIC_SE, "Binauric SE");
|
||||
map.put(BEATS_ELECTRONICS, "Beats Electronics");
|
||||
map.put(MICROCHIP_TECHNOLOGY_INC, "Microchip Technology Inc.");
|
||||
map.put(ELGATO_SYSTEMS_GMBH, "Elgato Systems GmbH");
|
||||
map.put(ARCHOS_SA, "ARCHOS SA");
|
||||
map.put(DEXCOM_INC, "Dexcom, Inc.");
|
||||
map.put(POLAR_ELECTRO_EUROPE_BV, "Polar Electro Europe B.V.");
|
||||
map.put(DIALOG_SEMICONDUCTOR_BV, "Dialog Semiconductor B.V.");
|
||||
map.put(TAIXINGBANG_TECHNOLOGY_HK_CO_LTD, "Taixingbang Technology (HK) Co,. LTD.");
|
||||
map.put(KAWANTECH, "Kawantech");
|
||||
map.put(AUSTCO_COMMUNICATION_SYSTEMS, "Austco Communication Systems");
|
||||
map.put(TIMEX_GROUP_USA_INC, "Timex Group USA, Inc.");
|
||||
map.put(QUALCOMM_TECHNOLOGIES_INC, "Qualcomm Technologies, Inc.");
|
||||
map.put(QUALCOMM_CONNECTED_EXPERIENCES_INC, "Qualcomm Connected Experiences, Inc.");
|
||||
map.put(VOYETRA_TURTLE_BEACH, "Voyetra Turtle Beach");
|
||||
map.put(TXTR_GMBH, "txtr GmbH");
|
||||
map.put(BIOSENTRONICS, "Biosentronics");
|
||||
map.put(PROCTER_GAMBLE, "Procter & Gamble");
|
||||
map.put(HOSIDEN_CORPORATION, "Hosiden Corporation");
|
||||
map.put(MUZIK_LLC, "Muzik LLC");
|
||||
map.put(MISFIT_WEARABLES_CORP, "Misfit Wearables Corp");
|
||||
map.put(GOOGLE, "Google");
|
||||
map.put(DANLERS_LTD, "Danlers Ltd");
|
||||
map.put(SEMILINK_INC, "Semilink Inc");
|
||||
map.put(INMUSIC_BRANDS_INC, "inMusic Brands, Inc");
|
||||
map.put(LS_RESEARCH_INC, "L.S. Research Inc.");
|
||||
map.put(EDEN_SOFTWARE_CONSULTANTS_LTD, "Eden Software Consultants Ltd.");
|
||||
map.put(FRESHTEMP, "Freshtemp");
|
||||
map.put(KS_TECHNOLOGIES, "KS Technologies");
|
||||
map.put(ACTS_TECHNOLOGIES, "ACTS Technologies");
|
||||
map.put(VTRACK_SYSTEMS, "Vtrack Systems");
|
||||
map.put(NIELSENKELLERMAN_COMPANY, "Nielsen-Kellerman Company");
|
||||
map.put(SERVER_TECHNOLOGY_INC, "Server Technology, Inc.");
|
||||
map.put(BIORESEARCH_ASSOCIATES, "BioResearch Associates");
|
||||
map.put(JOLLY_LOGIC_LLC, "Jolly Logic, LLC");
|
||||
map.put(ABOVE_AVERAGE_OUTCOMES_INC, "Above Average Outcomes, Inc.");
|
||||
map.put(BITSPLITTERS_GMBH, "Bitsplitters GmbH");
|
||||
map.put(PAYPAL_INC, "PayPal, Inc.");
|
||||
map.put(WITRON_TECHNOLOGY_LIMITED, "Witron Technology Limited");
|
||||
map.put(MORSE_PROJECT_INC, "Morse Project Inc.");
|
||||
map.put(KENT_DISPLAYS_INC, "Kent Displays Inc.");
|
||||
map.put(NAUTILUS_INC, "Nautilus Inc.");
|
||||
map.put(SMARTIFIER_OY, "Smartifier Oy");
|
||||
map.put(ELCOMETER_LIMITED, "Elcometer Limited");
|
||||
map.put(VSN_TECHNOLOGIES_INC, "VSN Technologies Inc.");
|
||||
map.put(ACEUNI_CORP_LTD, "AceUni Corp., Ltd.");
|
||||
map.put(STICKNFIND, "StickNFind");
|
||||
map.put(CRYSTAL_CODE_AB, "Crystal Code AB");
|
||||
map.put(KOUKAAM_AS, "KOUKAAM a.s.");
|
||||
map.put(DELPHI_CORPORATION, "Delphi Corporation");
|
||||
map.put(VALENCETECH_LIMITED, "ValenceTech Limited");
|
||||
map.put(RESERVED, "Reserved");
|
||||
map.put(TYPO_PRODUCTS_LLC, "Typo Products, LLC");
|
||||
map.put(TOMTOM_INTERNATIONAL_BV, "TomTom International BV");
|
||||
map.put(FUGOO_INC, "Fugoo, Inc");
|
||||
map.put(KEISER_CORPORATION, "Keiser Corporation");
|
||||
map.put(BANG_OLUFSEN_A_S, "Bang & Olufsen A/S");
|
||||
map.put(PLUS_LOCATIONS_SYSTEMS_PTY_LTD, "PLUS Locations Systems Pty Ltd");
|
||||
map.put(UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION, "Ubiquitous Computing Technology Corporation");
|
||||
map.put(INNOVATIVE_YACHTTER_SOLUTIONS, "Innovative Yachtter Solutions");
|
||||
map.put(WILLIAM_DEMANT_HOLDING_A_S, "William Demant Holding A/S");
|
||||
map.put(CHICONY_ELECTRONICS_CO_LTD, "Chicony Electronics Co., Ltd.");
|
||||
map.put(ATUS_BV, "Atus BV");
|
||||
map.put(CODEGATE_LTD, "Codegate Ltd.");
|
||||
map.put(ERI_INC, "ERi, Inc.");
|
||||
map.put(TRANSDUCERS_DIRECT_LLC, "Transducers Direct, LLC");
|
||||
map.put(FUJITSU_TEN_LIMITED, "Fujitsu Ten Limited");
|
||||
map.put(AUDI_AG, "Audi AG");
|
||||
map.put(HISILICON_TECHNOLOGIES_CO_LTD, "HiSilicon Technologies Co., Ltd.");
|
||||
map.put(NIPPON_SEIKI_CO_LTD, "Nippon Seiki Co., Ltd.");
|
||||
map.put(STEELSERIES_APS, "Steelseries ApS");
|
||||
map.put(VYZYBL_INC, "vyzybl Inc.");
|
||||
map.put(OPENBRAIN_TECHNOLOGIES_CO_LTD, "Openbrain Technologies, Co., Ltd.");
|
||||
map.put(XENSR, "Xensr");
|
||||
map.put(ESOLUTIONS, "e.solutions");
|
||||
map.put(ONE_OAK_TECHNOLOGIES, "1OAK Technologies");
|
||||
map.put(WIMOTO_TECHNOLOGIES_INC, "Wimoto Technologies Inc");
|
||||
map.put(RADIUS_NETWORKS_INC, "Radius Networks, Inc.");
|
||||
map.put(WIZE_TECHNOLOGY_CO_LTD, "Wize Technology Co., Ltd.");
|
||||
map.put(QUALCOMM_LABS_INC, "Qualcomm Labs, Inc.");
|
||||
map.put(ARUBA_NETWORKS, "Aruba Networks");
|
||||
map.put(BAIDU, "Baidu");
|
||||
map.put(ARENDI_AG, "Arendi AG");
|
||||
map.put(SKODA_AUTO_AS, "Skoda Auto a.s.");
|
||||
map.put(VOLKSWAGON_AG, "Volkswagon AG");
|
||||
map.put(PORSCHE_AG, "Porsche AG");
|
||||
map.put(SINO_WEALTH_ELECTRONIC_LTD, "Sino Wealth Electronic Ltd.");
|
||||
map.put(AIRTURN_INC, "AirTurn, Inc.");
|
||||
map.put(KINSA_INC, "Kinsa, Inc.");
|
||||
map.put(HID_GLOBAL, "HID Global");
|
||||
map.put(SEAT_ES, "SEAT es");
|
||||
map.put(PROMETHEAN_LTD, "Promethean Ltd.");
|
||||
map.put(SALUTICA_ALLIED_SOLUTIONS, "Salutica Allied Solutions");
|
||||
map.put(GPSI_GROUP_PTY_LTD, "GPSI Group Pty Ltd");
|
||||
map.put(NIMBLE_DEVICES_OY, "Nimble Devices Oy");
|
||||
map.put(CHANGZHOU_YONGSE_INFOTECH_CO_LTD, "Changzhou Yongse Infotech Co., Ltd");
|
||||
map.put(SPORTIQ, "SportIQ");
|
||||
map.put(TEMEC_INSTRUMENTS_BV, "TEMEC Instruments B.V.");
|
||||
map.put(SONY_CORPORATION, "Sony Corporation");
|
||||
map.put(ASSA_ABLOY, "ASSA ABLOY");
|
||||
map.put(CLARION_CO_LTD, "Clarion Co., Ltd.");
|
||||
map.put(WAREHOUSE_INNOVATIONS, "Warehouse Innovations");
|
||||
map.put(CYPRESS_SEMICONDUCTOR_CORPORATION, "Cypress Semiconductor Corporation");
|
||||
map.put(MADS_INC, "MADS Inc");
|
||||
map.put(BLUE_MAESTRO_LIMITED, "Blue Maestro Limited");
|
||||
map.put(RESOLUTION_PRODUCTS_INC, "Resolution Products, Inc.");
|
||||
map.put(AIREWEAR_LLC, "Airewear LLC");
|
||||
map.put(ETC_SP_ZOO, "ETC sp. z.o.o.");
|
||||
map.put(PRESTIGIO_PLAZA_LTD, "Prestigio Plaza Ltd.");
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
package uk.co.alt236.bluetoothlelib.resolvers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The UUIDS have been collected from the following sources:
|
||||
* <p>
|
||||
* - http://developer.nokia.com/community/wiki/Bluetooth_Services_for_Windows_Phone
|
||||
* - The Bluez project
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*/
|
||||
public class GattAttributeResolver {
|
||||
public static final String BASE_GUID = "00000000-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_PROTOCOL_SDP = "00000001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String USER_DATAGRAM_PROTOCOL_UDP = "00000002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM = "00000003-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCP = "00000004-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSBIN = "00000005-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSAT = "00000006-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBJECT_EXCHANGE_PROTOCOL_OBEX = "00000008-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IP = "00000009-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FTP = "0000000a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HTTP = "0000000c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WSP = "0000000e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BNEP_SVC = "0000000f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_PROTOCOL = "00000010-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HIDP = "00000011-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CONTROL_CHANNEL_PROTOCOL = "00000012-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_DATA_CHANNEL_PROTOCOL = "00000014-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_NOTIFICATION_PROTOCOL = "00000016-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VCTP_PROTOCOL = "00000017-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VDTP_PROTOCOL = "00000019-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CMPT_PROTOCOL = "0000001b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDI_C_PLANE_PROTOCOL = "0000001d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_CONTROL_CHANNEL = "0000001e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_DATA_CHANNEL = "0000001f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String L2CAP = "00000100-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_SERVER = "00001000-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BROWSE_GROUP_DESCRIPTOR = "00001001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PUBLIC_BROWSE_GROUP = "00001002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SPP = "00001101-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LAN_ACCESS_USING_PPP = "00001102-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DUN_GW = "00001103-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_SYNC = "00001104-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_OBJECT_PUSH = "00001105-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_FILE_TRANSFER = "00001106-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IRMC_SYNC_COMMAND = "00001107-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HSP_HS = "00001108-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CORDLESS_TELEPHONY = "00001109-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SOURCE = "0000110a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SINK = "0000110b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AV_REMOTE_CONTROL_TARGET = "0000110c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ADVANCED_AUDIO = "0000110d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AVRCP_REMOTE = "0000110e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING = "0000110f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERCOM = "00001110-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FAX = "00001111-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEADSET_PROFILE_HSP_AUDIO_GATEWAY = "00001112-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP = "00001113-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP_CLIENT = "00001114-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PANU = "00001115-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NAP = "00001116-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GN = "00001117-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING = "00001118-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_PRINTING = "00001119-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING = "0000111a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_RESPONDER = "0000111b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_AUTOMATIC_ARCHIVE = "0000111c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_REFERENCE_OBJECTS = "0000111d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP = "0000111e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY = "0000111f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING_REFERENCE_OBJECTS = "00001120-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFLECTED_UI = "00001121-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BASIC_PRINTING = "00001122-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PRINTING_STATUS = "00001123-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HID = "00001124-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CABLE_REPLACEMENT = "00001125-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_PRINT = "00001126-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_SCAN = "00001127-0000-1000-8000-00805f9b34fb";
|
||||
public static final String COMMON_ISDN_ACCESS = "00001128-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING_GATEWAY = "00001129-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDIMT = "0000112a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDITA = "0000112b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_VIDEO = "0000112c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SIM_ACCESS = "0000112d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PCE = "0000112e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PSE = "0000112f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PBAP = "00001130-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAS = "00001132-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MNS = "00001133-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAP = "00001134-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNP = "00001200-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_NETWORKING = "00001201-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_FILE_TRANSFER = "00001202-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_AUDIO = "00001203-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_TELEPHONY = "00001204-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP = "00001205-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_IP = "00001206-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_PAN = "00001300-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_LAP = "00001301-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_L2CAP = "00001302-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE = "00001303-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SINK = "00001304-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP = "00001305-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP = "00001400-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SOURCE = "00001401-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SINK = "00001402-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GAP = "00001800-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GATT = "00001801-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMMEDIATE_ALERT = "00001802-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LINK_LOSS = "00001803-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER = "00001804-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_THERMOMETER = "00001809-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_INFORMATION = "0000180a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE = "0000180d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CYCLING_SC = "00001816-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_NAME = "00002a00-0000-1000-8000-00805f9b34fb";
|
||||
public static final String APPEARANCE = "00002a01-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PRIVACY_FLAG = "00002a02-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RECONNECTION_ADDRESS = "00002a03-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS = "00002a04-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_CHANGED = "00002a05-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_LEVEL = "00002a06-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER_LEVEL = "00002a07-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DATE_TIME = "00002a08-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_OF_WEEK = "00002a09-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_DATE_TIME = "00002a0a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String EXACT_TIME_256 = "00002a0c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DST_OFFSET = "00002a0d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ZONE = "00002a0e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LOCAL_TIME_INFORMATION = "00002a0f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_WITH_DST = "00002a11-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ACCURACY = "00002a12-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_SOURCE = "00002a13-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_TIME_INFORMATION = "00002a14-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_CONTROL_POINT = "00002a16-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_STATE = "00002a17-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_MEASUREMENT = "00002a1c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_TYPE = "00002a1d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_TEMPERATURE = "00002a1e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MEASUREMENT_INTERVAL = "00002a21-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SYSTEM_ID = "00002a23-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MODEL_NUMBER_STRING = "00002a24-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERIAL_NUMBER_STRING = "00002a25-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FIRMWARE_REVISION_STRING = "00002a26-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDWARE_REVISION_STRING = "00002a27-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SOFTWARE_REVISION_STRING = "00002a28-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MANUFACTURER_NAME_STRING = "00002a29-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IEEE_1107320601_REGULATORY = "00002a2a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CURRENT_TIME = "00002a2b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_MEASUREMENT = "00002a35-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_CUFF_PRESSURE = "00002a36-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_MEASUREMENT = "00002a37-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BODY_SENSOR_LOCATION = "00002a38-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_CONTROL_POINT = "00002a39-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_STATUS = "00002a3f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_CONTROL_POINT = "00002a40-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_SETTING = "00002a41-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID_BIT_MASK = "00002a42-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID = "00002a43-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_NOTIFICATION_CONTROL_POINT = "00002a44-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UNREAD_ALERT_STATUS = "00002a45-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NEW_ALERT = "00002a46-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_NEW_ALERT_CATEGORY = "00002a47-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_UNREAD_ALERT_CATEGORY = "00002a48-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_FEATURE = "00002a49-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNPID = "00002a50-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SC_CONTROL_POINT = "00002a55-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_MEASUREMENT = "00002a5b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_FEATURE = "00002a5c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SENSOR_LOCATION = "00002a5d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ACTIVESYNC = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ESTIMOTE_SERVICE = "b9403000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_UUID = "b9403003-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MAJOR = "b9403001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MINOR = "b9403002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_BATTERY = "b9403041-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_TEMPERATURE = "b9403021-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_POWER = "b9403011-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_INTERVAL = "b9403012-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_VERSION_SERVICE = "b9404000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_SOFTWARE_VERSION = "b9404001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_HARDWARE_VERSION = "b9404002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_AUTHENTICATION_SERVICE = "b9402000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_SEED = "b9402001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_VECTOR = "b9402002-f5f8-466e-aff9-25556b57fe6d";
|
||||
|
||||
private final static Map<String, String> sGattAttributesMap = populateGattAttributesMap();
|
||||
|
||||
public static String getAttributeName(final String uuid, final String fallback) {
|
||||
final String name = sGattAttributesMap.get(uuid.toLowerCase(Locale.US));
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
|
||||
private static Map<String, String> populateGattAttributesMap() {
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
|
||||
map.put(BASE_GUID , "Base GUID");
|
||||
map.put(SERVICE_DISCOVERY_PROTOCOL_SDP , "Service Discovery Protocol (SDP)");
|
||||
map.put(USER_DATAGRAM_PROTOCOL_UDP , "User Datagram Protocol (UDP)");
|
||||
map.put(RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM , "Radio Frequency Communication Protocol (RFCOMM)");
|
||||
map.put(TCP , "TCP");
|
||||
map.put(TCSBIN , "TCSBIN");
|
||||
map.put(TCSAT , "TCSAT");
|
||||
map.put(OBJECT_EXCHANGE_PROTOCOL_OBEX , "Object Exchange Protocol (OBEX)");
|
||||
map.put(IP , "IP");
|
||||
map.put(FTP , "FTP");
|
||||
map.put(HTTP , "HTTP");
|
||||
map.put(WSP , "WSP");
|
||||
map.put(BNEP_SVC , "BNEP_SVC");
|
||||
map.put(UPNP_PROTOCOL , "UPNP Protocol");
|
||||
map.put(HIDP , "HIDP");
|
||||
map.put(HARDCOPY_CONTROL_CHANNEL_PROTOCOL , "Hardcopy Control Channel Protocol");
|
||||
map.put(HARDCOPY_DATA_CHANNEL_PROTOCOL , "Hardcopy Data Channel Protocol");
|
||||
map.put(HARDCOPY_NOTIFICATION_PROTOCOL , "Hardcopy Notification Protocol");
|
||||
map.put(VCTP_PROTOCOL , "VCTP Protocol");
|
||||
map.put(VDTP_PROTOCOL , "VDTP Protocol");
|
||||
map.put(CMPT_PROTOCOL , "CMPT Protocol");
|
||||
map.put(UDI_C_PLANE_PROTOCOL , "UDI C Plane Protocol");
|
||||
map.put(MCAP_CONTROL_CHANNEL , "MCAP Control Channel");
|
||||
map.put(MCAP_DATA_CHANNEL , "MCAP Data Channel");
|
||||
map.put(L2CAP , "L2CAP");
|
||||
map.put(SERVICE_DISCOVERY_SERVER , "Service Discovery Server");
|
||||
map.put(BROWSE_GROUP_DESCRIPTOR , "Browse Group Descriptor");
|
||||
map.put(PUBLIC_BROWSE_GROUP , "Public Browse Group");
|
||||
map.put(SPP , "SPP");
|
||||
map.put(LAN_ACCESS_USING_PPP , "LAN Access Using PPP");
|
||||
map.put(DUN_GW , "DUN_GW");
|
||||
map.put(OBEX_SYNC , "OBEX_SYNC");
|
||||
map.put(OBEX_OBJECT_PUSH , "OBEX Object Push");
|
||||
map.put(OBEX_FILE_TRANSFER , "OBEX File Transfer");
|
||||
map.put(IRMC_SYNC_COMMAND , "IrMC Sync Command");
|
||||
map.put(HSP_HS , "HSP_HS");
|
||||
map.put(CORDLESS_TELEPHONY , "Cordless Telephony");
|
||||
map.put(AUDIO_SOURCE , "Audio Source");
|
||||
map.put(AUDIO_SINK , "Audio Sink");
|
||||
map.put(AV_REMOTE_CONTROL_TARGET , "AV Remote Control Target");
|
||||
map.put(ADVANCED_AUDIO , "ADVANCED_AUDIO");
|
||||
map.put(AVRCP_REMOTE , "AVRCP_REMOTE");
|
||||
map.put(VIDEO_CONFERENCING , "Video Conferencing");
|
||||
map.put(INTERCOM , "Intercom");
|
||||
map.put(FAX , "FAX");
|
||||
map.put(HEADSET_PROFILE_HSP_AUDIO_GATEWAY , "Headset Profile (HSP) - Audio Gateway");
|
||||
map.put(WAP , "WAP");
|
||||
map.put(WAP_CLIENT , "WAP Client");
|
||||
map.put(PANU , "PANU");
|
||||
map.put(NAP , "NAP");
|
||||
map.put(GN , "GN");
|
||||
map.put(DIRECT_PRINTING , "Direct Printing");
|
||||
map.put(REFERENCE_PRINTING , "Reference Printing");
|
||||
map.put(IMAGING , "Imaging");
|
||||
map.put(IMAGING_RESPONDER , "Imaging Responder");
|
||||
map.put(IMAGING_AUTOMATIC_ARCHIVE , "Imaging Automatic Archive");
|
||||
map.put(IMAGING_REFERENCE_OBJECTS , "Imaging Reference Objects");
|
||||
map.put(HANDS_FREE_PROFILE_HFP , "Hands Free Profile (HFP)");
|
||||
map.put(HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY , "Hands Free Profile (HFP) – Audio Gateway");
|
||||
map.put(DIRECT_PRINTING_REFERENCE_OBJECTS , "Direct Printing Reference Objects");
|
||||
map.put(REFLECTED_UI , "Reflected UI");
|
||||
map.put(BASIC_PRINTING , "Basic Printing");
|
||||
map.put(PRINTING_STATUS , "Printing Status");
|
||||
map.put(HID , "HID");
|
||||
map.put(HARDCOPY_CABLE_REPLACEMENT , "Hardcopy Cable Replacement");
|
||||
map.put(HCR_PRINT , "HCR Print");
|
||||
map.put(HCR_SCAN , "HCR Scan");
|
||||
map.put(COMMON_ISDN_ACCESS , "Common ISDN Access");
|
||||
map.put(VIDEO_CONFERENCING_GATEWAY , "Video Conferencing Gateway");
|
||||
map.put(UDIMT , "UDIMT");
|
||||
map.put(UDITA , "UDITA");
|
||||
map.put(AUDIO_VIDEO , "Audio Video");
|
||||
map.put(SIM_ACCESS , "SIM Access");
|
||||
map.put(OBEX_PCE , "OBEX PCE");
|
||||
map.put(OBEX_PSE , "OBEX PSE");
|
||||
map.put(OBEX_PBAP , "OBEX PBAP");
|
||||
map.put(OBEX_MAS , "OBEX MAS");
|
||||
map.put(OBEX_MNS , "OBEX MNS");
|
||||
map.put(OBEX_MAP , "OBEX MAP");
|
||||
map.put(PNP , "PNP");
|
||||
map.put(GENERIC_NETWORKING , "Generic Networking");
|
||||
map.put(GENERIC_FILE_TRANSFER , "Generic File Transfer");
|
||||
map.put(GENERIC_AUDIO , "Generic Audio");
|
||||
map.put(GENERIC_TELEPHONY , "Generic Telephony");
|
||||
map.put(UPNP , "UPNP");
|
||||
map.put(UPNP_IP , "UPNP IP");
|
||||
map.put(ESDP_UPNP_IP_PAN , "ESDP UPnP IP PAN");
|
||||
map.put(ESDP_UPNP_IP_LAP , "ESDP UPnP IP LAP");
|
||||
map.put(ESDP_UPNP_L2CAP , "ESDP Upnp L2CAP");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE , "Video Distribution Profile (VDP) - Source");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SINK , "Video Distribution Profile (VDP) - Sink");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP , "Video Distribution Profile (VDP)");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP , "Health Device Profile (HDP)");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SOURCE , "Health Device Profile (HDP) - Source");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SINK , "Health Device Profile (HDP) - Sink");
|
||||
map.put(GAP , "GAP");
|
||||
map.put(GATT , "GATT");
|
||||
map.put(IMMEDIATE_ALERT , "IMMEDIATE_ALERT");
|
||||
map.put(LINK_LOSS , "LINK_LOSS");
|
||||
map.put(TX_POWER , "TX_POWER");
|
||||
map.put(HEALTH_THERMOMETER , "Health Thermometer");
|
||||
map.put(DEVICE_INFORMATION , "Device Information");
|
||||
map.put(HEART_RATE , "HEART_RATE");
|
||||
map.put(CYCLING_SC , "CYCLING_SC");
|
||||
map.put(CLIENT_CHARACTERISTIC_CONFIG , "CLIENT_CHARACTERISTIC_CONFIG");
|
||||
map.put(DEVICE_NAME , "Device Name");
|
||||
map.put(APPEARANCE , "Appearance");
|
||||
map.put(PERIPHERAL_PRIVACY_FLAG , "Peripheral Privacy Flag");
|
||||
map.put(RECONNECTION_ADDRESS , "Reconnection Address");
|
||||
map.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS , "Peripheral Preferred Connection Parameters");
|
||||
map.put(SERVICE_CHANGED , "Service Changed");
|
||||
map.put(ALERT_LEVEL , "Alert Level");
|
||||
map.put(TX_POWER_LEVEL , "Tx Power Level");
|
||||
map.put(DATE_TIME , "Date Time");
|
||||
map.put(DAY_OF_WEEK , "Day of Week");
|
||||
map.put(DAY_DATE_TIME , "Day Date Time");
|
||||
map.put(EXACT_TIME_256 , "Exact Time 256");
|
||||
map.put(DST_OFFSET , "DST Offset");
|
||||
map.put(TIME_ZONE , "Time Zone");
|
||||
map.put(LOCAL_TIME_INFORMATION , "Local Time Information");
|
||||
map.put(TIME_WITH_DST , "Time with DST");
|
||||
map.put(TIME_ACCURACY , "Time Accuracy");
|
||||
map.put(TIME_SOURCE , "Time Source");
|
||||
map.put(REFERENCE_TIME_INFORMATION , "Reference Time Information");
|
||||
map.put(TIME_UPDATE_CONTROL_POINT , "Time Update Control Point");
|
||||
map.put(TIME_UPDATE_STATE , "Time Update State");
|
||||
map.put(TEMPERATURE_MEASUREMENT , "Temperature Measurement");
|
||||
map.put(TEMPERATURE_TYPE , "Temperature Type");
|
||||
map.put(INTERMEDIATE_TEMPERATURE , "Intermediate Temperature");
|
||||
map.put(MEASUREMENT_INTERVAL , "Measurement Interval");
|
||||
map.put(SYSTEM_ID , "System ID");
|
||||
map.put(MODEL_NUMBER_STRING , "Model Number String");
|
||||
map.put(SERIAL_NUMBER_STRING , "Serial Number String");
|
||||
map.put(FIRMWARE_REVISION_STRING , "Firmware Revision String");
|
||||
map.put(HARDWARE_REVISION_STRING , "Hardware Revision String");
|
||||
map.put(SOFTWARE_REVISION_STRING , "Software Revision String");
|
||||
map.put(MANUFACTURER_NAME_STRING , "Manufacturer Name String");
|
||||
map.put(IEEE_1107320601_REGULATORY , "IEEE 11073-20601 Regulatory");
|
||||
map.put(CURRENT_TIME , "Current Time");
|
||||
map.put(BLOOD_PRESSURE_MEASUREMENT , "Blood Pressure Measurement");
|
||||
map.put(INTERMEDIATE_CUFF_PRESSURE , "Intermediate Cuff Pressure");
|
||||
map.put(HEART_RATE_MEASUREMENT , "Heart Rate Measurement");
|
||||
map.put(BODY_SENSOR_LOCATION , "Body Sensor Location");
|
||||
map.put(HEART_RATE_CONTROL_POINT , "Heart Rate Control Point");
|
||||
map.put(ALERT_STATUS , "Alert Status");
|
||||
map.put(RINGER_CONTROL_POINT , "Ringer Control Point");
|
||||
map.put(RINGER_SETTING , "Ringer Setting");
|
||||
map.put(ALERT_CATEGORY_ID_BIT_MASK , "Alert Category ID Bit Mask");
|
||||
map.put(ALERT_CATEGORY_ID , "Alert Category ID");
|
||||
map.put(ALERT_NOTIFICATION_CONTROL_POINT , "Alert Notification Control Point");
|
||||
map.put(UNREAD_ALERT_STATUS , "Unread Alert Status");
|
||||
map.put(NEW_ALERT , "New Alert");
|
||||
map.put(SUPPORTED_NEW_ALERT_CATEGORY , "Supported New Alert Category");
|
||||
map.put(SUPPORTED_UNREAD_ALERT_CATEGORY , "Supported Unread Alert Category");
|
||||
map.put(BLOOD_PRESSURE_FEATURE , "Blood Pressure Feature");
|
||||
map.put(PNPID , "PNPID");
|
||||
map.put(SC_CONTROL_POINT , "SC_CONTROL_POINT");
|
||||
map.put(CSC_MEASUREMENT , "CSC_MEASUREMENT");
|
||||
map.put(CSC_FEATURE , "CSC_FEATURE");
|
||||
map.put(SENSOR_LOCATION , "SENSOR_LOCATION");
|
||||
map.put(ACTIVESYNC , "ActiveSync");
|
||||
map.put(ESTIMOTE_SERVICE , "Estimote Service");
|
||||
map.put(ESTIMOTE_UUID , "Estimote UUID");
|
||||
map.put(ESTIMOTE_MAJOR , "Estimote Major");
|
||||
map.put(ESTIMOTE_MINOR , "Estimote Minor");
|
||||
map.put(ESTIMOTE_BATTERY , "Estimote Battery");
|
||||
map.put(ESTIMOTE_TEMPERATURE , "Estimote Temperature");
|
||||
map.put(ESTIMOTE_POWER , "Estimote Power");
|
||||
map.put(ESTIMOTE_ADVERTISING_INTERVAL , "Estimote Advertising Interval");
|
||||
map.put(ESTIMOTE_VERSION_SERVICE , "Estimote Version Service");
|
||||
map.put(ESTIMOTE_SOFTWARE_VERSION , "Estimote Software Version");
|
||||
map.put(ESTIMOTE_HARDWARE_VERSION , "Estimote Hardware Version");
|
||||
map.put(ESTIMOTE_AUTHENTICATION_SERVICE , "Estimote Authentication Service");
|
||||
map.put(ESTIMOTE_ADVERTISING_SEED , "Estimote Advertising Seed");
|
||||
map.put(ESTIMOTE_ADVERTISING_VECTOR , "Estimote Advertising Vector");
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
|
||||
public final class AdRecordUtils {
|
||||
|
||||
private AdRecordUtils(){
|
||||
// TO AVOID INSTANTIATION
|
||||
}
|
||||
|
||||
public static String getRecordDataAsString(final AdRecord nameRecord) {
|
||||
if (nameRecord == null) {
|
||||
return "";
|
||||
}
|
||||
return new String(nameRecord.getData());
|
||||
}
|
||||
|
||||
public static byte[] getServiceData(final AdRecord serviceData) {
|
||||
if (serviceData == null) {
|
||||
return null;
|
||||
}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return null;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Chop out the uuid
|
||||
return Arrays.copyOfRange(raw, 2, raw.length);
|
||||
}
|
||||
|
||||
public static int getServiceDataUuid(final AdRecord serviceData) {
|
||||
if (serviceData == null) {
|
||||
return -1;
|
||||
}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return -1;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Find UUID data in byte array
|
||||
int uuid = (raw[1] & 0xFF) << 8;
|
||||
uuid += (raw[0] & 0xFF);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read out all the AD structures from the raw scan record
|
||||
*/
|
||||
public static List<AdRecord> parseScanRecordAsList(final byte[] scanRecord) {
|
||||
final List<AdRecord> records = new ArrayList<>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.add(new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(records);
|
||||
}
|
||||
|
||||
@SuppressLint("UseSparseArrays")
|
||||
public static Map<Integer, AdRecord> parseScanRecordAsMap(final byte[] scanRecord) {
|
||||
final Map<Integer, AdRecord> records = new HashMap<>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(records);
|
||||
}
|
||||
|
||||
public static SparseArray<AdRecord> parseScanRecordAsSparseArray(final byte[] scanRecord) {
|
||||
final SparseArray<AdRecord> records = new SparseArray<>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ByteUtils {
|
||||
|
||||
/**
|
||||
* The Constant HEXES.
|
||||
*/
|
||||
private static final String HEXES = "0123456789ABCDEF";
|
||||
|
||||
private ByteUtils(){
|
||||
// TO AVOID INSTANTIATION
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pretty representation of a Byte Array as a HEX String.
|
||||
* <p>
|
||||
* Sample output: [01, 30, FF, AA]
|
||||
*
|
||||
* @param array the array
|
||||
* @return the string
|
||||
*/
|
||||
public static String byteArrayToHexString(final byte[] array) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean firstEntry = true;
|
||||
sb.append('[');
|
||||
|
||||
for (final byte b : array) {
|
||||
if (!firstEntry) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(HEXES.charAt((b & 0xF0) >> 4));
|
||||
sb.append(HEXES.charAt((b & 0x0F)));
|
||||
firstEntry = false;
|
||||
}
|
||||
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a byte array starts with another byte array.
|
||||
*
|
||||
* @param array the array
|
||||
* @param prefix the prefix
|
||||
* @return true, if successful
|
||||
*/
|
||||
public static boolean doesArrayBeginWith(final byte[] array, final byte[] prefix) {
|
||||
if (array.length < prefix.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < prefix.length; i++) {
|
||||
if (array[i] != prefix[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array with a length of 2 into an int
|
||||
*
|
||||
* @param input the input
|
||||
* @return the int from the array
|
||||
*/
|
||||
public static int getIntFrom2ByteArray(final byte[] input) {
|
||||
final byte[] result = new byte[4];
|
||||
|
||||
result[0] = 0;
|
||||
result[1] = 0;
|
||||
result[2] = input[0];
|
||||
result[3] = input[1];
|
||||
|
||||
return ByteUtils.getIntFromByteArray(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte to an int, preserving the sign.
|
||||
* <p>
|
||||
* For example, FF will be converted to 255 and not -1.
|
||||
*
|
||||
* @param bite the byte
|
||||
* @return the int from byte
|
||||
*/
|
||||
public static int getIntFromByte(final byte bite) {
|
||||
return bite & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array to an int.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the int from byte array
|
||||
*/
|
||||
public static int getIntFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array to a long.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the long from byte array
|
||||
*/
|
||||
public static long getLongFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getLong();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inverts an byte array in place.
|
||||
*
|
||||
* @param array the array
|
||||
*/
|
||||
public static void invertArray(final byte[] array) {
|
||||
final int size = array.length;
|
||||
byte temp;
|
||||
|
||||
for (int i = 0; i < size / 2; i++) {
|
||||
temp = array[i];
|
||||
array[i] = array[size - 1 - i];
|
||||
array[size - 1 - i] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LimitedLinkHashMap<K, V> extends LinkedHashMap<K, V> {
|
||||
private static final long serialVersionUID = -5375660288461724925L;
|
||||
|
||||
private final int mMaxSize;
|
||||
|
||||
public LimitedLinkHashMap(final int maxSize) {
|
||||
super(maxSize + 1, 1, false);
|
||||
mMaxSize = maxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeEldestEntry(final Map.Entry<K, V> eldest) {
|
||||
return this.size() > mMaxSize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class BeaconUtilsTest extends TestCase {
|
||||
|
||||
public void testGetBeaconTypeIBeacon() throws Exception {
|
||||
assertEquals(BeaconType.IBEACON, BeaconUtils.getBeaconType(new byte[]{
|
||||
0x4C, 0x00, 0x02, 0x15, 0x00, // <- Magic iBeacon header
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}));
|
||||
}
|
||||
|
||||
public void testGetBeaconTypeInvalid() throws Exception {
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType((byte[]) null));
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[0]));
|
||||
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[25]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class IBeaconManufacturerDataTest extends TestCase {
|
||||
private static final byte[] NON_BEACON =
|
||||
{2, 1, 26, 11, -1, 76, 0, 9, 6, 3, -32, -64, -88,
|
||||
1, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
public void testNonIBeaconData() throws Exception{
|
||||
try {
|
||||
BeaconManufacturerData data = new IBeaconManufacturerData(NON_BEACON);
|
||||
fail("Should have thrown an exception");
|
||||
} catch (final IllegalArgumentException e){
|
||||
// EXPECTED
|
||||
}
|
||||
|
||||
try {
|
||||
BeaconManufacturerData data = new IBeaconManufacturerData((byte[]) null);
|
||||
fail("Should have thrown an exception");
|
||||
} catch (final IllegalArgumentException e){
|
||||
// EXPECTED
|
||||
}
|
||||
|
||||
try {
|
||||
BeaconManufacturerData data = new IBeaconManufacturerData(new byte[0]);
|
||||
fail("Should have thrown an exception");
|
||||
} catch (final IllegalArgumentException e){
|
||||
// EXPECTED
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class IBeaconUtilsTest extends TestCase {
|
||||
|
||||
public void testCalculateUuidString() throws Exception {
|
||||
assertEquals("00", IBeaconUtils.calculateUuidString(new byte[]{0}));
|
||||
assertEquals("0a", IBeaconUtils.calculateUuidString(new byte[]{10}));
|
||||
assertEquals("0f", IBeaconUtils.calculateUuidString(new byte[]{15}));
|
||||
assertEquals("10", IBeaconUtils.calculateUuidString(new byte[]{16}));
|
||||
assertEquals("7f", IBeaconUtils.calculateUuidString(new byte[]{127}));
|
||||
assertEquals(
|
||||
"00000000-0000-0000-0000-00",
|
||||
IBeaconUtils.calculateUuidString(new byte[]{0,0,0,0,0,0,0,0,0,0,0}));
|
||||
}
|
||||
|
||||
public void testGetDistanceDescriptor() throws Exception {
|
||||
assertEquals(IBeaconDistanceDescriptor.UNKNOWN, IBeaconUtils.getDistanceDescriptor(-1));
|
||||
|
||||
assertEquals(IBeaconDistanceDescriptor.IMMEDIATE, IBeaconUtils.getDistanceDescriptor(0));
|
||||
assertEquals(IBeaconDistanceDescriptor.IMMEDIATE, IBeaconUtils.getDistanceDescriptor(0.4));
|
||||
|
||||
assertEquals(IBeaconDistanceDescriptor.NEAR, IBeaconUtils.getDistanceDescriptor(0.5));
|
||||
assertEquals(IBeaconDistanceDescriptor.NEAR, IBeaconUtils.getDistanceDescriptor(2.9));
|
||||
|
||||
assertEquals(IBeaconDistanceDescriptor.FAR, IBeaconUtils.getDistanceDescriptor(3));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package uk.co.alt236.bluetoothlelib.resolvers;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class GattAttributeResolverTest extends TestCase {
|
||||
private static final String UKNOWN = "unknown";
|
||||
|
||||
public void testGetAttributeName() throws Exception {
|
||||
assertEquals(UKNOWN, GattAttributeResolver.getAttributeName("foo", UKNOWN));
|
||||
assertEquals("Estimote Advertising Vector", GattAttributeResolver.getAttributeName("b9402002-f5f8-466e-aff9-25556b57fe6d", UKNOWN));
|
||||
assertEquals("LINK_LOSS", GattAttributeResolver.getAttributeName("00001803-0000-1000-8000-00805f9b34fb", UKNOWN));
|
||||
assertEquals("Base GUID", GattAttributeResolver.getAttributeName("00000000-0000-1000-8000-00805f9b34fb", UKNOWN));
|
||||
assertEquals("PNPID", GattAttributeResolver.getAttributeName("00002a50-0000-1000-8000-00805f9b34fb", UKNOWN));
|
||||
assertEquals("HTTP", GattAttributeResolver.getAttributeName("0000000c-0000-1000-8000-00805f9b34fb", UKNOWN));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class AdRecordUtilsTest extends TestCase {
|
||||
private static final byte[] NON_IBEACON =
|
||||
{2, 1, 26, 11, -1, 76, 0, 9, 6, 3, -32, -64, -88,
|
||||
1, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
public void testParseScanRecordAsList() throws Exception {
|
||||
final List<AdRecord> adRecords = AdRecordUtils.parseScanRecordAsList(NON_IBEACON);
|
||||
assertNotNull(adRecords);
|
||||
assertEquals(2, adRecords.size());
|
||||
|
||||
int type = AdRecord.TYPE_FLAGS;
|
||||
assertEquals(type, adRecords.get(0).getType());
|
||||
assertEquals(2, adRecords.get(0).getLength());
|
||||
|
||||
type = AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA;
|
||||
assertEquals(type, adRecords.get(1).getType());
|
||||
assertEquals(11, adRecords.get(1).getLength());
|
||||
}
|
||||
|
||||
public void testParseScanRecordAsMap() throws Exception {
|
||||
final Map<Integer, AdRecord> adRecords = AdRecordUtils.parseScanRecordAsMap(NON_IBEACON);
|
||||
assertNotNull(adRecords);
|
||||
assertEquals(2, adRecords.size());
|
||||
|
||||
int type = AdRecord.TYPE_FLAGS;
|
||||
assertEquals(type, adRecords.get(type).getType());
|
||||
assertEquals(2, adRecords.get(type).getLength());
|
||||
|
||||
type = AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA;
|
||||
assertEquals(type, adRecords.get(type).getType());
|
||||
assertEquals(11, adRecords.get(type).getLength());
|
||||
}
|
||||
|
||||
public void testParseScanRecordAsSparseArray() throws Exception {
|
||||
//
|
||||
// Cannot be tested here as it relies on Android code...
|
||||
//
|
||||
// final SparseArray<AdRecord> adRecords = AdRecordUtils.parseScanRecordAsSparseArray(NON_IBEACON);
|
||||
// assertNotNull(adRecords);
|
||||
// assertEquals(2, adRecords.size());
|
||||
// assertEquals(AdRecord.TYPE_FLAGS, adRecords.get(AdRecord.TYPE_FLAGS).getType());
|
||||
// assertEquals(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA, adRecords.get(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ByteUtilsTest extends TestCase {
|
||||
|
||||
public void testByteArrayToHexString() throws Exception {
|
||||
assertEquals("[]", ByteUtils.byteArrayToHexString(new byte[0]));
|
||||
|
||||
final byte[] one = {1, 10, 15, 127};
|
||||
assertEquals("[01, 0A, 0F, 7F]", ByteUtils.byteArrayToHexString(one));
|
||||
}
|
||||
|
||||
public void testDoesArrayBeginWith() throws Exception {
|
||||
|
||||
// If the prefix is longer than the array,
|
||||
// we automatically fail
|
||||
byte[] array = new byte[10];
|
||||
byte[] prefix = new byte[array.length * 2];
|
||||
assertFalse(ByteUtils.doesArrayBeginWith(array, prefix));
|
||||
|
||||
array = new byte[]{1, 2, 3};
|
||||
prefix = new byte[]{1, 3};
|
||||
assertFalse(ByteUtils.doesArrayBeginWith(array, prefix));
|
||||
|
||||
array = new byte[10];
|
||||
prefix = new byte[array.length];
|
||||
assertTrue(ByteUtils.doesArrayBeginWith(array, prefix));
|
||||
|
||||
array = new byte[]{1, 2, 3};
|
||||
prefix = new byte[]{1, 2};
|
||||
assertTrue(ByteUtils.doesArrayBeginWith(array, prefix));
|
||||
}
|
||||
|
||||
public void testGetIntFromByte() throws Exception {
|
||||
byte bite = 127;
|
||||
int integer = ByteUtils.getIntFromByte(bite);
|
||||
assertEquals(127, integer);
|
||||
|
||||
bite = -1;
|
||||
integer = ByteUtils.getIntFromByte(bite);
|
||||
assertEquals(255, integer);
|
||||
}
|
||||
|
||||
public void testInvertArray() throws Exception {
|
||||
final byte[] original = {1, 2 ,3 ,4};
|
||||
final byte[] out = new byte[original.length];
|
||||
|
||||
System.arraycopy( original, 0, out, 0, original.length);
|
||||
ByteUtils.invertArray(out);
|
||||
|
||||
assertEquals(original[0], out[3]);
|
||||
assertEquals(original[1], out[2]);
|
||||
assertEquals(original[2], out[1]);
|
||||
assertEquals(original[3], out[0]);
|
||||
}
|
||||
}
|
||||
@@ -1,395 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.device;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecordStore;
|
||||
import uk.co.alt236.bluetoothlelib.resolvers.BluetoothClassResolver;
|
||||
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.LimitedLinkHashMap;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
/**
|
||||
* This is a wrapper around the default BluetoothDevice object
|
||||
* As BluetoothDevice is final it cannot be extended, so to get it you
|
||||
* need to call {@link #getDevice()} method.
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*/
|
||||
public class BluetoothLeDevice implements Parcelable{
|
||||
private static final String PARCEL_EXTRA_BLUETOOTH_DEVICE = "bluetooth_device";
|
||||
private static final String PARCEL_EXTRA_CURRENT_RSSI = "current_rssi";
|
||||
private static final String PARCEL_EXTRA_CURRENT_TIMESTAMP = "current_timestamp";
|
||||
private static final String PARCEL_EXTRA_DEVICE_RSSI_LOG = "device_rssi_log";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD = "device_scanrecord";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD_STORE = "device_scanrecord_store";
|
||||
private static final String PARCEL_EXTRA_FIRST_RSSI = "device_first_rssi";
|
||||
private static final String PARCEL_EXTRA_FIRST_TIMESTAMP = "first_timestamp";
|
||||
private static final long LOG_INVALIDATION_THRESHOLD = 10 * 1000;
|
||||
protected static final int MAX_RSSI_LOG_SIZE = 10;
|
||||
|
||||
private final AdRecordStore mRecordStore;
|
||||
private final BluetoothDevice mDevice;
|
||||
private final Map<Long, Integer> mRssiLog;
|
||||
private final byte[] mScanRecord;
|
||||
private final int mFirstRssi;
|
||||
private final long mFirstTimestamp;
|
||||
|
||||
private int mCurrentRssi;
|
||||
private long mCurrentTimestamp;
|
||||
|
||||
/** The Constant CREATOR. */
|
||||
public static final Parcelable.Creator<BluetoothLeDevice> CREATOR = new Parcelable.Creator<BluetoothLeDevice>() {
|
||||
public BluetoothLeDevice createFromParcel(Parcel in) {
|
||||
return new BluetoothLeDevice(in);
|
||||
}
|
||||
|
||||
public BluetoothLeDevice[] newArray(int size) {
|
||||
return new BluetoothLeDevice[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device a standard android Bluetooth device
|
||||
* @param rssi the RSSI value of the Bluetooth device
|
||||
* @param scanRecord the scan record of the device
|
||||
* @param timestamp the timestamp of the RSSI reading
|
||||
*/
|
||||
public BluetoothLeDevice(BluetoothDevice device, int rssi, byte[] scanRecord, long timestamp){
|
||||
mDevice = device;
|
||||
mFirstRssi = rssi;
|
||||
mFirstTimestamp = timestamp;
|
||||
mRecordStore = new AdRecordStore(AdRecordUtils.parseScanRecordAsSparseArray(scanRecord));
|
||||
mScanRecord = scanRecord;
|
||||
mRssiLog = new LimitedLinkHashMap<Long, Integer>(MAX_RSSI_LOG_SIZE);
|
||||
updateRssiReading(timestamp, rssi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device the device
|
||||
*/
|
||||
public BluetoothLeDevice(BluetoothLeDevice device) {
|
||||
mCurrentRssi = device.getRssi();
|
||||
mCurrentTimestamp = device.getTimestamp();
|
||||
mDevice = device.getDevice();
|
||||
mFirstRssi = device.getFirstRssi();
|
||||
mFirstTimestamp = device.getFirstTimestamp();
|
||||
mRecordStore = new AdRecordStore(
|
||||
AdRecordUtils.parseScanRecordAsSparseArray(device.getScanRecord()));
|
||||
mRssiLog = device.getRssiLog();
|
||||
mScanRecord = device.getScanRecord();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new bluetooth le device.
|
||||
*
|
||||
* @param in the in
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected BluetoothLeDevice(Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
|
||||
mCurrentRssi = b.getInt(PARCEL_EXTRA_CURRENT_RSSI, 0);
|
||||
mCurrentTimestamp = b.getLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, 0);
|
||||
mDevice = b.getParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE);
|
||||
mFirstRssi = b.getInt(PARCEL_EXTRA_FIRST_RSSI, 0);
|
||||
mFirstTimestamp = b.getLong(PARCEL_EXTRA_FIRST_TIMESTAMP, 0);
|
||||
mRecordStore = b.getParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE);
|
||||
mRssiLog = (Map<Long, Integer>) b.getSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG);
|
||||
mScanRecord = b.getByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the to rssi log.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
private void addToRssiLog(long timestamp, int rssiReading){
|
||||
synchronized (mRssiLog) {
|
||||
if(timestamp - mCurrentTimestamp > LOG_INVALIDATION_THRESHOLD){
|
||||
mRssiLog.clear();
|
||||
}
|
||||
|
||||
mCurrentRssi = rssiReading;
|
||||
mCurrentTimestamp = timestamp;
|
||||
mRssiLog.put(timestamp, rssiReading);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BluetoothLeDevice other = (BluetoothLeDevice) obj;
|
||||
if (mCurrentRssi != other.mCurrentRssi)
|
||||
return false;
|
||||
if (mCurrentTimestamp != other.mCurrentTimestamp)
|
||||
return false;
|
||||
if (mDevice == null) {
|
||||
if (other.mDevice != null)
|
||||
return false;
|
||||
} else if (!mDevice.equals(other.mDevice))
|
||||
return false;
|
||||
if (mFirstRssi != other.mFirstRssi)
|
||||
return false;
|
||||
if (mFirstTimestamp != other.mFirstTimestamp)
|
||||
return false;
|
||||
if (mRecordStore == null) {
|
||||
if (other.mRecordStore != null)
|
||||
return false;
|
||||
} else if (!mRecordStore.equals(other.mRecordStore))
|
||||
return false;
|
||||
if (mRssiLog == null) {
|
||||
if (other.mRssiLog != null)
|
||||
return false;
|
||||
} else if (!mRssiLog.equals(other.mRssiLog))
|
||||
return false;
|
||||
if (!Arrays.equals(mScanRecord, other.mScanRecord))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address.
|
||||
*
|
||||
* @return the address
|
||||
*/
|
||||
public String getAddress(){
|
||||
return mDevice.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ad record store.
|
||||
*
|
||||
* @return the ad record store
|
||||
*/
|
||||
public AdRecordStore getAdRecordStore(){
|
||||
return mRecordStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device bond state.
|
||||
*
|
||||
* @return the bluetooth device bond state
|
||||
*/
|
||||
public String getBluetoothDeviceBondState(){
|
||||
return resolveBondingState(mDevice.getBondState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device class name.
|
||||
*
|
||||
* @return the bluetooth device class name
|
||||
*/
|
||||
public String getBluetoothDeviceClassName(){
|
||||
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device.
|
||||
*
|
||||
* @return the device
|
||||
*/
|
||||
public BluetoothDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first rssi.
|
||||
*
|
||||
* @return the first rssi
|
||||
*/
|
||||
public int getFirstRssi(){
|
||||
return mFirstRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first timestamp.
|
||||
*
|
||||
* @return the first timestamp
|
||||
*/
|
||||
public long getFirstTimestamp(){
|
||||
return mFirstTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName(){
|
||||
return mDevice.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rssi.
|
||||
*
|
||||
* @return the rssi
|
||||
*/
|
||||
public int getRssi() {
|
||||
return mCurrentRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rssi log.
|
||||
*
|
||||
* @return the rssi log
|
||||
*/
|
||||
protected Map<Long, Integer> getRssiLog() {
|
||||
synchronized (mRssiLog) {
|
||||
return mRssiLog;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the running average rssi.
|
||||
*
|
||||
* @return the running average rssi
|
||||
*/
|
||||
public double getRunningAverageRssi(){
|
||||
int sum = 0;
|
||||
int count = 0;
|
||||
|
||||
synchronized (mRssiLog) {
|
||||
final Iterator<Long> it1 = mRssiLog.keySet().iterator();
|
||||
|
||||
while(it1.hasNext()){
|
||||
count ++;
|
||||
sum += mRssiLog.get(it1.next());
|
||||
}
|
||||
}
|
||||
// for(final Map.Entry<Long,Integer> e : mRssiLog.entrySet()){
|
||||
// count ++;
|
||||
// sum += e.getValue();
|
||||
// }
|
||||
|
||||
if(count > 0){
|
||||
return sum/count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scan record.
|
||||
*
|
||||
* @return the scan record
|
||||
*/
|
||||
public byte[] getScanRecord() {
|
||||
return mScanRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timestamp.
|
||||
*
|
||||
* @return the timestamp
|
||||
*/
|
||||
public long getTimestamp(){
|
||||
return mCurrentTimestamp;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + mCurrentRssi;
|
||||
result = prime * result + (int) (mCurrentTimestamp ^ (mCurrentTimestamp >>> 32));
|
||||
result = prime * result + ((mDevice == null) ? 0 : mDevice.hashCode());
|
||||
result = prime * result + mFirstRssi;
|
||||
result = prime * result + (int) (mFirstTimestamp ^ (mFirstTimestamp >>> 32));
|
||||
result = prime * result + ((mRecordStore == null) ? 0 : mRecordStore.hashCode());
|
||||
result = prime * result + ((mRssiLog == null) ? 0 : mRssiLog.hashCode());
|
||||
result = prime * result + Arrays.hashCode(mScanRecord);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BluetoothLeDevice [mDevice=" + mDevice + ", mRssi=" + mFirstRssi + ", mScanRecord=" + ByteUtils.byteArrayToHexString(mScanRecord) + ", mRecordStore=" + mRecordStore + ", getBluetoothDeviceBondState()=" + getBluetoothDeviceBondState() + ", getBluetoothDeviceClassName()=" + getBluetoothDeviceClassName() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rssi reading.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
public void updateRssiReading(long timestamp, int rssiReading){
|
||||
addToRssiLog(timestamp, rssiReading);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
b.putByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD, mScanRecord);
|
||||
|
||||
b.putInt(PARCEL_EXTRA_FIRST_RSSI, mFirstRssi);
|
||||
b.putInt(PARCEL_EXTRA_CURRENT_RSSI, mCurrentRssi);
|
||||
|
||||
b.putLong(PARCEL_EXTRA_FIRST_TIMESTAMP, mFirstTimestamp);
|
||||
b.putLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, mCurrentTimestamp);
|
||||
|
||||
b.putParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE, mDevice);
|
||||
b.putParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE, mRecordStore);
|
||||
b.putSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG, (Serializable) mRssiLog);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve bonding state.
|
||||
*
|
||||
* @param bondState the bond state
|
||||
* @return the string
|
||||
*/
|
||||
private static String resolveBondingState(int bondState){
|
||||
switch (bondState){
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
return "Paired";
|
||||
case BluetoothDevice.BOND_BONDING:
|
||||
return "Pairing";
|
||||
case BluetoothDevice.BOND_NONE:
|
||||
return "Unbonded";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.device;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.mfdata.IBeaconManufacturerData;
|
||||
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils.IBeaconDistanceDescriptor;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
|
||||
public class IBeaconDevice extends BluetoothLeDevice{
|
||||
|
||||
/** The m iBeacon data. */
|
||||
private final IBeaconManufacturerData mIBeaconData;
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value
|
||||
* @param scanRecord the scanRecord
|
||||
* @throws IllegalArguementException if the passed device is not an iBecon
|
||||
*/
|
||||
public IBeaconDevice(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||
super(device, rssi, scanRecord, 0);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value of the RSSI measurement
|
||||
* @param scanRecord the scan record
|
||||
* @param timestamp the timestamp of the RSSI measurement
|
||||
* @throws IllegalArguementException if the passed device is not an iBecon
|
||||
*/
|
||||
public IBeaconDevice(BluetoothDevice device, int rssi, byte[] scanRecord, long timestamp){
|
||||
super(device, rssi, scanRecord, timestamp);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will try to convert a {@link BluetoothLeDevice} into an
|
||||
* iBeacon Device.
|
||||
*
|
||||
* @param device the device
|
||||
* @throws IllegalArguementException if the passed device is not an iBecon
|
||||
*/
|
||||
public IBeaconDevice(BluetoothLeDevice device){
|
||||
super(device);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
private IBeaconDevice(Parcel in) {
|
||||
super(in);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the estimated Accuracy of the reading in meters based on
|
||||
* a simple running average of the last {@link #MAX_RSSI_LOG_SIZE}
|
||||
* samples.
|
||||
*
|
||||
* @return the accuracy in meters
|
||||
*/
|
||||
public double getAccuracy(){
|
||||
return IBeaconUtils.calculateAccuracy(
|
||||
getCalibratedTxPower(),
|
||||
getRunningAverageRssi());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the calibrated TX power of the iBeacon device as reported.
|
||||
*
|
||||
* @return the calibrated TX power
|
||||
*/
|
||||
public int getCalibratedTxPower(){
|
||||
return getIBeaconData().getCalibratedTxPower();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon company identifier.
|
||||
*
|
||||
* @return the company identifier
|
||||
*/
|
||||
public int getCompanyIdentifier(){
|
||||
return getIBeaconData().getCompanyIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the estimated Distance descriptor.
|
||||
*
|
||||
* @return the distance descriptor
|
||||
*/
|
||||
public IBeaconDistanceDescriptor getDistanceDescriptor(){
|
||||
return IBeaconUtils.getDistanceDescriptor(getAccuracy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon manufacturing data.
|
||||
*
|
||||
* @return the iBeacon data
|
||||
*/
|
||||
public IBeaconManufacturerData getIBeaconData(){
|
||||
return mIBeaconData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Major value.
|
||||
*
|
||||
* @return the Major value
|
||||
*/
|
||||
public int getMajor(){
|
||||
return getIBeaconData().getMajor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Minor value.
|
||||
*
|
||||
* @return the Minor value
|
||||
*/
|
||||
public int getMinor(){
|
||||
return getIBeaconData().getMinor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID(){
|
||||
return getIBeaconData().getUUID();
|
||||
}
|
||||
|
||||
private void validate(){
|
||||
if(!IBeaconUtils.isThisAnIBeacon(this)){
|
||||
throw new IllegalArgumentException("Device " + getDevice() + " is not an iBeacon.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.adrecord;
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* Created by Dave Smith
|
||||
* Double Encore, Inc.
|
||||
*
|
||||
* Expanded by Alexandros Schillings
|
||||
*/
|
||||
public final class AdRecord implements Parcelable{
|
||||
|
||||
// 02 # Number of bytes that follow in first AD structure
|
||||
// 01 # Flags AD type
|
||||
// 1A # Flags value 0x1A = 000011010
|
||||
// bit 0 (OFF) LE Limited Discoverable Mode
|
||||
// bit 1 (ON) LE General Discoverable Mode
|
||||
// bit 2 (OFF) BR/EDR Not Supported
|
||||
// bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
|
||||
// bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
|
||||
// 1A # Number of bytes that follow in second (and last) AD structure
|
||||
// FF # Manufacturer specific data AD type
|
||||
// 4C 00 # Company identifier code (0x004C == Apple)
|
||||
// 02 # Byte 0 of iBeacon advertisement indicator
|
||||
// 15 # Byte 1 of iBeacon advertisement indicator
|
||||
// e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon proximity uuid
|
||||
// 00 00 # major
|
||||
// 00 00 # minor
|
||||
// c5 # The 2's complement of the calibrated Tx Power
|
||||
|
||||
|
||||
private static final String PARCEL_RECORD_DATA = "record_data";
|
||||
private static final String PARCEL_RECORD_TYPE = "record_type";
|
||||
private static final String PARCEL_RECORD_LENGTH = "record_length";
|
||||
|
||||
/**
|
||||
* General FLAGS
|
||||
*
|
||||
* Description: Flags
|
||||
*
|
||||
* Information:
|
||||
* Bit 0: LE Limited Discoverable Mode
|
||||
* Bit 1: LE General Discoverable Mode
|
||||
* Bit 2: BR/EDR Not Supported (i.e. bit 37 of LMP Extended Feature bits Page 0)
|
||||
* Bit 3: Simultaneous LE and BR/EDR to Same Device Capable (Controller) (i.e. bit 49 of LMP Extended Feature bits Page 0)
|
||||
* Bit 4: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bits 5-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_FLAGS = 0x01;
|
||||
|
||||
// SERVICE
|
||||
public static final int TYPE_UUID16_INC = 0x02;
|
||||
public static final int TYPE_UUID16 = 0x03;
|
||||
public static final int TYPE_UUID32_INC = 0x04;
|
||||
public static final int TYPE_UUID32 = 0x05;
|
||||
public static final int TYPE_UUID128_INC = 0x06;
|
||||
public static final int TYPE_UUID128 = 0x07;
|
||||
|
||||
// Local name
|
||||
public static final int TYPE_LOCAL_NAME_SHORT = 0x08;
|
||||
public static final int TYPE_LOCAL_NAME_COMPLETE = 0x09;
|
||||
|
||||
// TX Power Level
|
||||
public static final int TYPE_TX_POWER_LEVEL = 0x0A;
|
||||
|
||||
// SIMPLE PAIRING OPTIONAL OOB TAGS
|
||||
public static final int TYPE_DEVICE_CLASS = 0x0D;
|
||||
public static final int TYPE_SIMPLE_PAIRING_HASH_C = 0x0E;
|
||||
public static final int TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F;
|
||||
|
||||
// SECURITY MANAGER TK VALUE
|
||||
public static final int TYPE_TK_VALUE = 0x10;
|
||||
|
||||
|
||||
/* SECURITY MANAGER OOB FLAGS
|
||||
*
|
||||
* Description: Flag (1 octet)
|
||||
*
|
||||
* Information:
|
||||
* Bit 0: OOB Flags Field: (0 = OOB data not present, 1 = OOB data present)
|
||||
* Bit 1: LE supported (Host) (i.e. bit 65 of LMP Extended Feature bits Page 1
|
||||
* Bit 2: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bit 3: Address type (0 = Public Address, 1 = Random Address)
|
||||
* Bits 4-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11;
|
||||
|
||||
|
||||
/* SLAVE CONNECTION INTERVAL RANGE
|
||||
*
|
||||
* Description: Slave Connection Interval Range
|
||||
*
|
||||
* Information:
|
||||
* The first 2 octets defines the minimum value for the connection interval in the following manner:
|
||||
* connInterval min = Conn_Interval_Min * 1.25 ms
|
||||
* Conn_Interval_Min range: 0x0006 to 0x0C80
|
||||
* Value of 0xFFFF indicates no specific minimum.
|
||||
* Values outside the range are reserved. (excluding 0xFFFF)
|
||||
*
|
||||
* The second 2 octets defines the maximum value for the connection interval in the following manner:
|
||||
* connInterval max = Conn_Interval_Max * 1.25 ms
|
||||
* Conn_Interval_Max range: 0x0006 to 0x0C80
|
||||
* Conn_Interval_Max shall be equal to or greater
|
||||
* than the Conn_Interval_Min.
|
||||
* Value of 0xFFFF indicates no specific maximum.
|
||||
* Values outside the range are reserved (excluding 0xFFFF)
|
||||
*/
|
||||
public static final int TYPE_CONNECTION_INTERVAL_RANGE = 0x12;
|
||||
|
||||
// SERVICE SOLICITATION
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_16BIT = 0x14;
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_128BIT = 0x15;
|
||||
|
||||
/* SERVICE DATA
|
||||
*
|
||||
* Description: Service Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the 16 bit Service UUID followed by additional service data
|
||||
*/
|
||||
public static final int TYPE_SERVICE_DATA = 0x16;
|
||||
|
||||
|
||||
/* MANUFACTURER SPECIFIC DATA
|
||||
*
|
||||
* Description: Manufacturer Specific Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data
|
||||
*/
|
||||
public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
|
||||
|
||||
/* Model Object Definition */
|
||||
private final int mLength;
|
||||
private final int mType;
|
||||
private final byte[] mData;
|
||||
|
||||
|
||||
public static final Parcelable.Creator<AdRecord> CREATOR = new Parcelable.Creator<AdRecord>() {
|
||||
public AdRecord createFromParcel(Parcel in) {
|
||||
return new AdRecord(in);
|
||||
}
|
||||
|
||||
public AdRecord[] newArray(int size) {
|
||||
return new AdRecord[size];
|
||||
}
|
||||
};
|
||||
|
||||
public AdRecord(int length, int type, byte[] data) {
|
||||
mLength = length;
|
||||
mType = type;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
public AdRecord(Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mLength = b.getInt(PARCEL_RECORD_LENGTH);
|
||||
mType = b.getInt(PARCEL_RECORD_TYPE);
|
||||
mData = b.getByteArray(PARCEL_RECORD_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte[] getData(){
|
||||
return mData;
|
||||
}
|
||||
|
||||
public String getHumanReadableType(){
|
||||
return getHumanReadableAdType(mType);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecord [mLength=" + mLength + ", mType=" + mType + ", mData=" + Arrays.toString(mData) + ", getHumanReadableType()=" + getHumanReadableType() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
b.putInt(PARCEL_RECORD_LENGTH, mLength);
|
||||
b.putInt(PARCEL_RECORD_TYPE, mType);
|
||||
b.putByteArray(PARCEL_RECORD_DATA, mData);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
private static String getHumanReadableAdType(int type){
|
||||
switch(type){
|
||||
case TYPE_CONNECTION_INTERVAL_RANGE:
|
||||
return "Slave Connection Interval Range";
|
||||
case TYPE_DEVICE_CLASS:
|
||||
return "Class of device";
|
||||
case TYPE_FLAGS:
|
||||
return "Flags";
|
||||
case TYPE_MANUFACTURER_SPECIFIC_DATA:
|
||||
return "Manufacturer Specific Data";
|
||||
case TYPE_LOCAL_NAME_COMPLETE:
|
||||
return "Name (Complete)";
|
||||
case TYPE_LOCAL_NAME_SHORT:
|
||||
return "Name (Short)";
|
||||
case TYPE_SECURITY_MANAGER_OOB_FLAGS:
|
||||
return "Security Manager OOB Flags";
|
||||
case TYPE_SERVICE_UUIDS_LIST_128BIT:
|
||||
return "Service UUIDs (128bit)";
|
||||
case TYPE_SERVICE_UUIDS_LIST_16BIT:
|
||||
return "Service UUIDs (16bit)";
|
||||
case TYPE_SERVICE_DATA:
|
||||
return "Service Data";
|
||||
case TYPE_SIMPLE_PAIRING_HASH_C:
|
||||
return "Simple Pairing Hash C";
|
||||
case TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
|
||||
return "Simple Pairing Randomizer R";
|
||||
case TYPE_TK_VALUE:
|
||||
return "TK Value";
|
||||
case TYPE_TX_POWER_LEVEL:
|
||||
return "Transmission Power Level";
|
||||
case TYPE_UUID128:
|
||||
return "Complete list of 128-bit UUIDs available";
|
||||
case TYPE_UUID128_INC:
|
||||
return "More 128-bit UUIDs available";
|
||||
case TYPE_UUID16:
|
||||
return "Complete list of 16-bit UUIDs available";
|
||||
case TYPE_UUID16_INC:
|
||||
return "More 16-bit UUIDs available";
|
||||
case TYPE_UUID32:
|
||||
return "Complete list of 32-bit UUIDs available";
|
||||
case TYPE_UUID32_INC:
|
||||
return "More 32-bit UUIDs available";
|
||||
default:
|
||||
return "Unknown AdRecord Structure: " + type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.adrecord;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.SparseArray;
|
||||
|
||||
/**
|
||||
* The Class AdRecordStore.
|
||||
*/
|
||||
public class AdRecordStore implements Parcelable{
|
||||
private final SparseArray<AdRecord> mAdRecords;
|
||||
private final String mLocalNameComplete;
|
||||
private final String mLocalNameShort;
|
||||
|
||||
public static final Parcelable.Creator<AdRecordStore> CREATOR = new Parcelable.Creator<AdRecordStore>() {
|
||||
public AdRecordStore createFromParcel(Parcel in) {
|
||||
return new AdRecordStore(in);
|
||||
}
|
||||
|
||||
public AdRecordStore[] newArray(int size) {
|
||||
return new AdRecordStore[size];
|
||||
}
|
||||
};
|
||||
|
||||
public AdRecordStore(Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mAdRecords = b.getSparseParcelableArray("records_array");
|
||||
mLocalNameComplete = b.getString("local_name_complete");
|
||||
mLocalNameShort = b.getString("local_name_short");
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device Ad Record Store.
|
||||
*
|
||||
* @param adRecords the ad records
|
||||
*/
|
||||
public AdRecordStore(final SparseArray<AdRecord> adRecords){
|
||||
mAdRecords = adRecords;
|
||||
|
||||
mLocalNameComplete = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_COMPLETE));
|
||||
|
||||
mLocalNameShort = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_SHORT));
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the short local device name.
|
||||
*
|
||||
* @return the local name complete
|
||||
*/
|
||||
public String getLocalNameComplete() {
|
||||
return mLocalNameComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete local device name.
|
||||
*
|
||||
* @return the local name short
|
||||
*/
|
||||
public String getLocalNameShort() {
|
||||
return mLocalNameShort;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves an individual record.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record
|
||||
*/
|
||||
public AdRecord getRecord(int record){
|
||||
return mAdRecords.get(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record data as string.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record data as string
|
||||
*/
|
||||
public String getRecordDataAsString(int record){
|
||||
return AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(record));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record as collection.
|
||||
*
|
||||
* @return the records as collection
|
||||
*/
|
||||
public Collection<AdRecord> getRecordsAsCollection() {
|
||||
return Collections.unmodifiableCollection(asList(mAdRecords));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is record present.
|
||||
*
|
||||
* @param record the record
|
||||
* @return true, if is record present
|
||||
*/
|
||||
public boolean isRecordPresent(int record){
|
||||
return mAdRecords.indexOfKey(record) >= 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecordStore [mLocalNameComplete=" + mLocalNameComplete + ", mLocalNameShort=" + mLocalNameShort + "]";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int arg1) {
|
||||
final Bundle b = new Bundle();
|
||||
b.putString("local_name_complete", mLocalNameComplete);
|
||||
b.putString("local_name_short", mLocalNameShort);
|
||||
b.putSparseParcelableArray("records_array", mAdRecords);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* As list.
|
||||
*
|
||||
* @param <C> the generic type
|
||||
* @param sparseArray the sparse array
|
||||
* @return the collection
|
||||
*/
|
||||
public static <C> Collection<C> asList(SparseArray<C> sparseArray) {
|
||||
if (sparseArray == null) return null;
|
||||
|
||||
final Collection<C> arrayList = new ArrayList<C>(sparseArray.size());
|
||||
for (int i = 0; i < sparseArray.size(); i++){
|
||||
arrayList.add(sparseArray.valueAt(i));
|
||||
}
|
||||
|
||||
return arrayList;
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.mfdata;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
|
||||
/**
|
||||
* Parses the Manufactured Data field of an iBeacon
|
||||
*
|
||||
* The parsing is based on the following schema:
|
||||
*
|
||||
* <p>
|
||||
* 0 4C - Byte 1 (LSB) of Company identifier code
|
||||
* 1 00 - Byte 0 (MSB) of Company identifier code (0x004C == Apple)
|
||||
* 2 02 - Byte 0 of iBeacon advertisement indicator
|
||||
* 3 15 - Byte 1 of iBeacon advertisement indicator
|
||||
* 4 e2 |\
|
||||
* 5 c5 |\\
|
||||
* 6 6d |#\\
|
||||
* 7 b5 |##\\
|
||||
* 8 df |###\\
|
||||
* 9 fb |####\\
|
||||
* 10 48 |#####\\
|
||||
* 11 d2 |#####|| iBeacon proximity UUID
|
||||
* 12 b0 |#####||
|
||||
* 13 60 |#####//
|
||||
* 14 d0 |####//
|
||||
* 15 f5 |###//
|
||||
* 16 a7 |##//
|
||||
* 17 10 |#//
|
||||
* 18 96 |//
|
||||
* 19 e0 |/
|
||||
* 20 00 - major
|
||||
* 21 00
|
||||
* 22 00 - minor
|
||||
* 23 00
|
||||
* 24 c5 - The 2's complement of the calibrated Tx Power
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*
|
||||
*/
|
||||
|
||||
public final class IBeaconManufacturerData {
|
||||
private final byte[] mData;
|
||||
private final int mCalibratedTxPower;
|
||||
private final int mCompanyIdentidier;
|
||||
private final int mIBeaconAdvertisment;
|
||||
private final int mMajor;
|
||||
private final int mMinor;
|
||||
private final String mUUID;
|
||||
|
||||
public IBeaconManufacturerData(BluetoothLeDevice device){
|
||||
this(device.getAdRecordStore().getRecord(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon manufacturer data object.
|
||||
|
||||
* @param data the {@link #uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA} data array
|
||||
* @throws IndexOutOfBoundsException if the data array is shorter than expected
|
||||
*/
|
||||
public IBeaconManufacturerData(byte[] data){
|
||||
mData = data;
|
||||
|
||||
mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(
|
||||
ByteUtils.invertArray(Arrays.copyOfRange(mData, 0, 2)));
|
||||
|
||||
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 2, 4));
|
||||
mUUID = calculateUUIDString(Arrays.copyOfRange(mData, 4, 20));
|
||||
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22));
|
||||
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 22, 24));
|
||||
mCalibratedTxPower = data[24];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the calibrated TX power of the iBeacon device as reported.
|
||||
*
|
||||
* @return the calibrated TX power
|
||||
*/
|
||||
public int getCalibratedTxPower(){
|
||||
return mCalibratedTxPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon company identifier.
|
||||
*
|
||||
* @return the company identifier
|
||||
*/
|
||||
public int getCompanyIdentifier(){
|
||||
return mCompanyIdentidier;
|
||||
}
|
||||
|
||||
public int getIBeaconAdvertisement(){
|
||||
return mIBeaconAdvertisment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Major value.
|
||||
*
|
||||
* @return the Major value
|
||||
*/
|
||||
public int getMajor(){
|
||||
return mMajor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Minor value.
|
||||
*
|
||||
* @return the Minor value
|
||||
*/
|
||||
public int getMinor(){
|
||||
return mMinor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID(){
|
||||
return mUUID;
|
||||
}
|
||||
|
||||
private static String calculateUUIDString(final byte[] uuid){
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
|
||||
for(int i = 0 ; i< uuid.length; i++){
|
||||
if(i == 4){sb.append('-');}
|
||||
if(i == 6){sb.append('-');}
|
||||
if(i == 8){sb.append('-');}
|
||||
if(i == 10){sb.append('-');}
|
||||
|
||||
sb.append(
|
||||
Integer.toHexString(ByteUtils.getIntFromByte(uuid[i])));
|
||||
}
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.resolvers;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
|
||||
public class BluetoothClassResolver {
|
||||
|
||||
public static String resolveDeviceClass(int btClass){
|
||||
switch (btClass){
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER:
|
||||
return "A/V, Camcorder";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||
return "A/V, Car Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||
return "A/V, Handsfree";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
|
||||
return "A/V, Headphones";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
|
||||
return "A/V, HiFi Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
|
||||
return "A/V, Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_MICROPHONE:
|
||||
return "A/V, Microphone";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
|
||||
return "A/V, Portable Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX:
|
||||
return "A/V, Set Top Box";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_UNCATEGORIZED:
|
||||
return "A/V, Uncategorized";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VCR:
|
||||
return "A/V, VCR";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CAMERA:
|
||||
return "A/V, Video Camera";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CONFERENCING:
|
||||
return "A/V, Video Conferencing";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER:
|
||||
return "A/V, Video Display and Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_GAMING_TOY:
|
||||
return "A/V, Video Gaming Toy";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_MONITOR:
|
||||
return "A/V, Video Monitor";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||
return "A/V, Video Wearable Headset";
|
||||
case BluetoothClass.Device.COMPUTER_DESKTOP:
|
||||
return "Computer, Desktop";
|
||||
case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
|
||||
return "Computer, Handheld PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_LAPTOP:
|
||||
return "Computer, Laptop";
|
||||
case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
|
||||
return "Computer, Palm Size PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_SERVER:
|
||||
return "Computer, Server";
|
||||
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
|
||||
return "Computer, Uncategorized";
|
||||
case BluetoothClass.Device.COMPUTER_WEARABLE:
|
||||
return "Computer, Wearable";
|
||||
case BluetoothClass.Device.HEALTH_BLOOD_PRESSURE:
|
||||
return "Health, Blood Pressure";
|
||||
case BluetoothClass.Device.HEALTH_DATA_DISPLAY:
|
||||
return "Health, Data Display";
|
||||
case BluetoothClass.Device.HEALTH_GLUCOSE:
|
||||
return "Health, Glucose";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_OXIMETER :
|
||||
return "Health, Pulse Oximeter";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_RATE :
|
||||
return "Health, Pulse Rate";
|
||||
case BluetoothClass.Device.HEALTH_THERMOMETER :
|
||||
return "Health, Thermometer";
|
||||
case BluetoothClass.Device.HEALTH_UNCATEGORIZED :
|
||||
return "Health, Uncategorized";
|
||||
case BluetoothClass.Device.HEALTH_WEIGHING:
|
||||
return "Health, Weighting";
|
||||
case BluetoothClass.Device.PHONE_CELLULAR:
|
||||
return "Phone, Cellular";
|
||||
case BluetoothClass.Device.PHONE_CORDLESS:
|
||||
return "Phone, Cordless";
|
||||
case BluetoothClass.Device.PHONE_ISDN:
|
||||
return "Phone, ISDN";
|
||||
case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
|
||||
return "Phone, Modem or Gateway";
|
||||
case BluetoothClass.Device.PHONE_SMART:
|
||||
return "Phone, Smart";
|
||||
case BluetoothClass.Device.PHONE_UNCATEGORIZED:
|
||||
return "Phone, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_CONTROLLER:
|
||||
return "Toy, Controller";
|
||||
case BluetoothClass.Device.TOY_DOLL_ACTION_FIGURE:
|
||||
return "Toy, Doll/Action Figure";
|
||||
case BluetoothClass.Device.TOY_GAME:
|
||||
return "Toy, Game";
|
||||
case BluetoothClass.Device.TOY_ROBOT:
|
||||
return "Toy, Robot";
|
||||
case BluetoothClass.Device.TOY_UNCATEGORIZED:
|
||||
return "Toy, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_VEHICLE:
|
||||
return "Toy, Vehicle";
|
||||
case BluetoothClass.Device.WEARABLE_GLASSES:
|
||||
return "Wearable, Glasses";
|
||||
case BluetoothClass.Device.WEARABLE_HELMET:
|
||||
return "Wearable, Helmet";
|
||||
case BluetoothClass.Device.WEARABLE_JACKET:
|
||||
return "Wearable, Jacket";
|
||||
case BluetoothClass.Device.WEARABLE_PAGER:
|
||||
return "Wearable, Pager";
|
||||
case BluetoothClass.Device.WEARABLE_UNCATEGORIZED:
|
||||
return "Wearable, Uncategorized";
|
||||
case BluetoothClass.Device.WEARABLE_WRIST_WATCH:
|
||||
return "Wearable, Wrist Watch";
|
||||
default:
|
||||
return "Unknown, Unknown (class=" + btClass +")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,646 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.resolvers;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
public class CompanyIdentifierResolver {
|
||||
public static final int ERICSSON_TECHNOLOGY_LICENSING = 0x0000;
|
||||
public static final int NOKIA_MOBILE_PHONES = 0x0001;
|
||||
public static final int INTEL_CORP = 0x0002;
|
||||
public static final int IBM_CORP = 0x0003;
|
||||
public static final int TOSHIBA_CORP = 0x0004;
|
||||
public static final int THREE_COM = 0x0005;
|
||||
public static final int MICROSOFT = 0x0006;
|
||||
public static final int LUCENT = 0x0007;
|
||||
public static final int MOTOROLA = 0x0008;
|
||||
public static final int INFINEON_TECHNOLOGIES_AG = 0x0009;
|
||||
public static final int CAMBRIDGE_SILICON_RADIO = 0x000A;
|
||||
public static final int SILICON_WAVE = 0x000B;
|
||||
public static final int DIGIANSWER_A_S = 0x000C;
|
||||
public static final int TEXAS_INSTRUMENTS_INC = 0x000D;
|
||||
public static final int CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC = 0x000E;
|
||||
public static final int BROADCOM_CORPORATION = 0x000F;
|
||||
public static final int MITEL_SEMICONDUCTOR = 0x0010;
|
||||
public static final int WIDCOMM_INC = 0x0011;
|
||||
public static final int ZEEVO_INC = 0x0012;
|
||||
public static final int ATMEL_CORPORATION = 0x0013;
|
||||
public static final int MITSUBISHI_ELECTRIC_CORPORATION = 0x0014;
|
||||
public static final int RTX_TELECOM_A_S = 0x0015;
|
||||
public static final int KC_TECHNOLOGY_INC = 0x0016;
|
||||
public static final int NEWLOGIC = 0x0017;
|
||||
public static final int TRANSILICA_INC = 0x0018;
|
||||
public static final int ROHDE_SCHWARZ_GMBH_CO_KG = 0x0019;
|
||||
public static final int TTPCOM_LIMITED = 0x001A;
|
||||
public static final int SIGNIA_TECHNOLOGIES_INC = 0x001B;
|
||||
public static final int CONEXANT_SYSTEMS_INC = 0x001C;
|
||||
public static final int QUALCOMM = 0x001D;
|
||||
public static final int INVENTEL = 0x001E;
|
||||
public static final int AVM_BERLIN = 0x001F;
|
||||
public static final int BANDSPEED_INC = 0x0020;
|
||||
public static final int MANSELLA_LTD = 0x0021;
|
||||
public static final int NEC_CORPORATION = 0x0022;
|
||||
public static final int WAVEPLUS_TECHNOLOGY_CO_LTD = 0x0023;
|
||||
public static final int ALCATEL = 0x0024;
|
||||
public static final int PHILIPS_SEMICONDUCTORS = 0x0025;
|
||||
public static final int C_TECHNOLOGIES = 0x0026;
|
||||
public static final int OPEN_INTERFACE = 0x0027;
|
||||
public static final int R_F_MICRO_DEVICES = 0x0028;
|
||||
public static final int HITACHI_LTD = 0x0029;
|
||||
public static final int SYMBOL_TECHNOLOGIES_INC = 0x002A;
|
||||
public static final int TENOVIS = 0x002B;
|
||||
public static final int MACRONIX_INTERNATIONAL_CO_LTD = 0x002C;
|
||||
public static final int GCT_SEMICONDUCTOR = 0x002D;
|
||||
public static final int NORWOOD_SYSTEMS = 0x002E;
|
||||
public static final int MEWTEL_TECHNOLOGY_INC = 0x002F;
|
||||
public static final int ST_MICROELECTRONICS = 0x0030;
|
||||
public static final int SYNOPSIS = 0x0031;
|
||||
public static final int REDM_COMMUNICATIONS_LTD = 0x0032;
|
||||
public static final int COMMIL_LTD = 0x0033;
|
||||
public static final int COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC = 0x0034;
|
||||
public static final int ECLIPSE_HQ_ESPANA_SL = 0x0035;
|
||||
public static final int RENESAS_TECHNOLOGY_CORP = 0x0036;
|
||||
public static final int MOBILIAN_CORPORATION = 0x0037;
|
||||
public static final int TERAX = 0x0038;
|
||||
public static final int INTEGRATED_SYSTEM_SOLUTION_CORP = 0x0039;
|
||||
public static final int MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD = 0x003A;
|
||||
public static final int GENNUM_CORPORATION = 0x003B;
|
||||
public static final int RESEARCH_IN_MOTION = 0x003C;
|
||||
public static final int IPEXTREME_INC = 0x003D;
|
||||
public static final int SYSTEMS_AND_CHIPS_INC = 0x003E;
|
||||
public static final int BLUETOOTH_SIG_INC = 0x003F;
|
||||
public static final int SEIKO_EPSON_CORPORATION = 0x0040;
|
||||
public static final int INTEGRATED_SILICON_SOLUTION_TAIWAN_INC = 0x0041;
|
||||
public static final int CONWISE_TECHNOLOGY_CORPORATION_LTD = 0x0042;
|
||||
public static final int PARROT_SA = 0x0043;
|
||||
public static final int SOCKET_MOBILE = 0x0044;
|
||||
public static final int ATHEROS_COMMUNICATIONS_INC = 0x0045;
|
||||
public static final int MEDIATEK_INC = 0x0046;
|
||||
public static final int BLUEGIGA = 0x0047;
|
||||
public static final int MARVELL_TECHNOLOGY_GROUP_LTD = 0x0048;
|
||||
public static final int THREE_DSP_CORPORATION = 0x0049;
|
||||
public static final int ACCEL_SEMICONDUCTOR_LTD = 0x004A;
|
||||
public static final int CONTINENTAL_AUTOMOTIVE_SYSTEMS = 0x004B;
|
||||
public static final int APPLE_INC = 0x004C;
|
||||
public static final int STACCATO_COMMUNICATIONS_INC = 0x004D;
|
||||
public static final int AVAGO_TECHNOLOGIES = 0x004E;
|
||||
public static final int APT_LICENSING_LTD = 0x004F;
|
||||
public static final int SIRF_TECHNOLOGY = 0x0050;
|
||||
public static final int TZERO_TECHNOLOGIES_INC = 0x0051;
|
||||
public static final int JM_CORPORATION = 0x0052;
|
||||
public static final int FREE2MOVE_AB = 0x0053;
|
||||
public static final int THREE_DIJOY_CORPORATION = 0x0054;
|
||||
public static final int PLANTRONICS_INC = 0x0055;
|
||||
public static final int SONY_ERICSSON_MOBILE_COMMUNICATIONS = 0x0056;
|
||||
public static final int HARMAN_INTERNATIONAL_INDUSTRIES_INC = 0x0057;
|
||||
public static final int VIZIO_INC = 0x0058;
|
||||
public static final int NORDIC_SEMICONDUCTOR_ASA = 0x0059;
|
||||
public static final int EM_MICROELECTRONICMARIN_SA = 0x005A;
|
||||
public static final int RALINK_TECHNOLOGY_CORPORATION = 0x005B;
|
||||
public static final int BELKIN_INTERNATIONAL_INC = 0x005C;
|
||||
public static final int REALTEK_SEMICONDUCTOR_CORPORATION = 0x005D;
|
||||
public static final int STONESTREET_ONE_LLC = 0x005E;
|
||||
public static final int WICENTRIC_INC = 0x005F;
|
||||
public static final int RIVIERAWAVES_SAS = 0x0060;
|
||||
public static final int RDA_MICROELECTRONICS = 0x0061;
|
||||
public static final int GIBSON_GUITARS = 0x0062;
|
||||
public static final int MICOMMAND_INC = 0x0063;
|
||||
public static final int BAND_XI_INTERNATIONAL_LLC = 0x0064;
|
||||
public static final int HEWLETTPACKARD_COMPANY = 0x0065;
|
||||
public static final int NINE_SOLUTIONS_OY = 0x0066;
|
||||
public static final int GN_NETCOM_A_S = 0x0067;
|
||||
public static final int GENERAL_MOTORS = 0x0068;
|
||||
public static final int AD_ENGINEERING_INC = 0x0069;
|
||||
public static final int MINDTREE_LTD = 0x006A;
|
||||
public static final int POLAR_ELECTRO_OY = 0x006B;
|
||||
public static final int BEAUTIFUL_ENTERPRISE_CO_LTD = 0x006C;
|
||||
public static final int BRIARTEK_INC = 0x006D;
|
||||
public static final int SUMMIT_DATA_COMMUNICATIONS_INC = 0x006E;
|
||||
public static final int SOUND_ID = 0x006F;
|
||||
public static final int MONSTER_LLC = 0x0070;
|
||||
public static final int CONNECTBLUE_AB = 0x0071;
|
||||
public static final int SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD = 0x0072;
|
||||
public static final int GROUP_SENSE_LTD = 0x0073;
|
||||
public static final int ZOMM_LLC = 0x0074;
|
||||
public static final int SAMSUNG_ELECTRONICS_CO_LTD = 0x0075;
|
||||
public static final int CREATIVE_TECHNOLOGY_LTD = 0x0076;
|
||||
public static final int LAIRD_TECHNOLOGIES = 0x0077;
|
||||
public static final int NIKE_INC = 0x0078;
|
||||
public static final int LESSWIRE_AG = 0x0079;
|
||||
public static final int MSTAR_SEMICONDUCTOR_INC = 0x007A;
|
||||
public static final int HANLYNN_TECHNOLOGIES = 0x007B;
|
||||
public static final int A_R_CAMBRIDGE = 0x007C;
|
||||
public static final int SEERS_TECHNOLOGY_CO_LTD = 0x007D;
|
||||
public static final int SPORTS_TRACKING_TECHNOLOGIES_LTD = 0x007E;
|
||||
public static final int AUTONET_MOBILE = 0x007F;
|
||||
public static final int DELORME_PUBLISHING_COMPANY_INC = 0x0080;
|
||||
public static final int WUXI_VIMICRO = 0x0081;
|
||||
public static final int SENNHEISER_COMMUNICATIONS_A_S = 0x0082;
|
||||
public static final int TIMEKEEPING_SYSTEMS_INC = 0x0083;
|
||||
public static final int LUDUS_HELSINKI_LTD = 0x0084;
|
||||
public static final int BLUERADIOS_INC = 0x0085;
|
||||
public static final int EQUINOX_AG = 0x0086;
|
||||
public static final int GARMIN_INTERNATIONAL_INC = 0x0087;
|
||||
public static final int ECOTEST = 0x0088;
|
||||
public static final int GN_RESOUND_A_S = 0x0089;
|
||||
public static final int JAWBONE = 0x008A;
|
||||
public static final int TOPCORN_POSITIONING_SYSTEMS_LLC = 0x008B;
|
||||
public static final int QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC = 0x008C;
|
||||
public static final int ZSCAN_SOFTWARE = 0x008D;
|
||||
public static final int QUINTIC_CORP = 0x008E;
|
||||
public static final int STOLLMAN_EV_GMBH = 0x008F;
|
||||
public static final int FUNAI_ELECTRIC_CO_LTD = 0x0090;
|
||||
public static final int ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG = 0x0091;
|
||||
public static final int THINKOPTICS_INC = 0x0092;
|
||||
public static final int UNIVERSAL_ELECTRONICS_INC = 0x0093;
|
||||
public static final int AIROHA_TECHNOLOGY_CORP = 0x0094;
|
||||
public static final int NEC_LIGHTING_LTD = 0x0095;
|
||||
public static final int ODM_TECHNOLOGY_INC = 0x0096;
|
||||
public static final int CONNECTEDEVICE_LTD = 0x0097;
|
||||
public static final int ZER01TV_GMBH = 0x0098;
|
||||
public static final int ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD = 0x0099;
|
||||
public static final int ALPWISE = 0x009A;
|
||||
public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD = 0x009B;
|
||||
public static final int COLORFY_INC = 0x009C;
|
||||
public static final int GEOFORCE_INC = 0x009D;
|
||||
public static final int BOSE_CORPORATION = 0x009E;
|
||||
public static final int SUUNTO_OY = 0x009F;
|
||||
public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 0x00A0;
|
||||
public static final int SRMEDIZINELEKTRONIK = 0x00A1;
|
||||
public static final int VERTU_CORPORATION_LIMITED = 0x00A2;
|
||||
public static final int META_WATCH_LTD = 0x00A3;
|
||||
public static final int LINAK_A_S = 0x00A4;
|
||||
public static final int OTL_DYNAMICS_LLC = 0x00A5;
|
||||
public static final int PANDA_OCEAN_INC = 0x00A6;
|
||||
public static final int VISTEON_CORPORATION = 0x00A7;
|
||||
public static final int ARP_DEVICES_LIMITED = 0x00A8;
|
||||
public static final int MAGNETI_MARELLI_SPA = 0x00A9;
|
||||
public static final int CAEN_RFID_SRL = 0x00AA;
|
||||
public static final int INGENIEURSYSTEMGRUPPE_ZAHN_GMBH = 0x00AB;
|
||||
public static final int GREEN_THROTTLE_GAMES = 0x00AC;
|
||||
public static final int PETER_SYSTEMTECHNIK_GMBH = 0x00AD;
|
||||
public static final int OMEGAWAVE_OY = 0x00AE;
|
||||
public static final int CINETIX = 0x00AF;
|
||||
public static final int PASSIF_SEMICONDUCTOR_CORP = 0x00B0;
|
||||
public static final int SARIS_CYCLING_GROUP_INC = 0x00B1;
|
||||
public static final int BEKEY_A_S = 0x00B2;
|
||||
public static final int CLARINOX_TECHNOLOGIES_PTY_LTD = 0x00B3;
|
||||
public static final int BDE_TECHNOLOGY_CO_LTD = 0x00B4;
|
||||
public static final int SWIRL_NETWORKS = 0x00B5;
|
||||
public static final int MESO_INTERNATIONAL = 0x00B6;
|
||||
public static final int TRELAB_LTD = 0x00B7;
|
||||
public static final int QUALCOMM_INNOVATION_CENTER_INC_QUIC = 0x00B8;
|
||||
public static final int JOHNSON_CONTROLS_INC = 0x00B9;
|
||||
public static final int STARKEY_LABORATORIES_INC = 0x00BA;
|
||||
public static final int SPOWER_ELECTRONICS_LIMITED = 0x00BB;
|
||||
public static final int ACE_SENSOR_INC = 0x00BC;
|
||||
public static final int APLIX_CORPORATION = 0x00BD;
|
||||
public static final int AAMP_OF_AMERICA = 0x00BE;
|
||||
public static final int STALMART_TECHNOLOGY_LIMITED = 0x00BF;
|
||||
public static final int AMICCOM_ELECTRONICS_CORPORATION = 0x00C0;
|
||||
public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD = 0x00C1;
|
||||
public static final int GENEQ_INC = 0x00C2;
|
||||
public static final int ADIDAS_AG = 0x00C3;
|
||||
public static final int LG_ELECTRONICS = 0x00C4;
|
||||
public static final int ONSET_COMPUTER_CORPORATION = 0x00C5;
|
||||
public static final int SELFLY_BV = 0x00C6;
|
||||
public static final int QUUPPA_OY = 0x00C7;
|
||||
public static final int GELO_INC = 0x00C8;
|
||||
public static final int EVLUMA = 0x00C9;
|
||||
public static final int MC10 = 0x00CA;
|
||||
public static final int BINAURIC_SE = 0x00CB;
|
||||
public static final int BEATS_ELECTRONICS = 0x00CC;
|
||||
public static final int MICROCHIP_TECHNOLOGY_INC = 0x00CD;
|
||||
public static final int ELGATO_SYSTEMS_GMBH = 0x00CE;
|
||||
public static final int ARCHOS_SA = 0x00CF;
|
||||
public static final int DEXCOM_INC = 0x00D0;
|
||||
public static final int POLAR_ELECTRO_EUROPE_BV = 0x00D1;
|
||||
public static final int DIALOG_SEMICONDUCTOR_BV = 0x00D2;
|
||||
public static final int TAIXINGBANG_TECHNOLOGY_HK_CO_LTD = 0x00D3;
|
||||
public static final int KAWANTECH = 0x00D4;
|
||||
public static final int AUSTCO_COMMUNICATION_SYSTEMS = 0x00D5;
|
||||
public static final int TIMEX_GROUP_USA_INC = 0x00D6;
|
||||
public static final int QUALCOMM_TECHNOLOGIES_INC = 0x00D7;
|
||||
public static final int QUALCOMM_CONNECTED_EXPERIENCES_INC = 0x00D8;
|
||||
public static final int VOYETRA_TURTLE_BEACH = 0x00D9;
|
||||
public static final int TXTR_GMBH = 0x00DA;
|
||||
public static final int BIOSENTRONICS = 0x00DB;
|
||||
public static final int PROCTER_GAMBLE = 0x00DC;
|
||||
public static final int HOSIDEN_CORPORATION = 0x00DD;
|
||||
public static final int MUZIK_LLC = 0x00DE;
|
||||
public static final int MISFIT_WEARABLES_CORP = 0x00DF;
|
||||
public static final int GOOGLE = 0x00E0;
|
||||
public static final int DANLERS_LTD = 0x00E1;
|
||||
public static final int SEMILINK_INC = 0x00E2;
|
||||
public static final int INMUSIC_BRANDS_INC = 0x00E3;
|
||||
public static final int LS_RESEARCH_INC = 0x00E4;
|
||||
public static final int EDEN_SOFTWARE_CONSULTANTS_LTD = 0x00E5;
|
||||
public static final int FRESHTEMP = 0x00E6;
|
||||
public static final int KS_TECHNOLOGIES = 0x00E7;
|
||||
public static final int ACTS_TECHNOLOGIES = 0x00E8;
|
||||
public static final int VTRACK_SYSTEMS = 0x00E9;
|
||||
public static final int NIELSENKELLERMAN_COMPANY = 0x00EA;
|
||||
public static final int SERVER_TECHNOLOGY_INC = 0x00EB;
|
||||
public static final int BIORESEARCH_ASSOCIATES = 0x00EC;
|
||||
public static final int JOLLY_LOGIC_LLC = 0x00ED;
|
||||
public static final int ABOVE_AVERAGE_OUTCOMES_INC = 0x00EE;
|
||||
public static final int BITSPLITTERS_GMBH = 0x00EF;
|
||||
public static final int PAYPAL_INC = 0x00F0;
|
||||
public static final int WITRON_TECHNOLOGY_LIMITED = 0x00F1;
|
||||
public static final int MORSE_PROJECT_INC = 0x00F2;
|
||||
public static final int KENT_DISPLAYS_INC = 0x00F3;
|
||||
public static final int NAUTILUS_INC = 0x00F4;
|
||||
public static final int SMARTIFIER_OY = 0x00F5;
|
||||
public static final int ELCOMETER_LIMITED = 0x00F6;
|
||||
public static final int VSN_TECHNOLOGIES_INC = 0x00F7;
|
||||
public static final int ACEUNI_CORP_LTD = 0x00F8;
|
||||
public static final int STICKNFIND = 0x00F9;
|
||||
public static final int CRYSTAL_CODE_AB = 0x00FA;
|
||||
public static final int KOUKAAM_AS = 0x00FB;
|
||||
public static final int DELPHI_CORPORATION = 0x00FC;
|
||||
public static final int VALENCETECH_LIMITED = 0x00FD;
|
||||
public static final int RESERVED = 0x00FE;
|
||||
public static final int TYPO_PRODUCTS_LLC = 0x00FF;
|
||||
public static final int TOMTOM_INTERNATIONAL_BV = 0x0100;
|
||||
public static final int FUGOO_INC = 0x0101;
|
||||
public static final int KEISER_CORPORATION = 0x0102;
|
||||
public static final int BANG_OLUFSEN_A_S = 0x0103;
|
||||
public static final int PLUS_LOCATIONS_SYSTEMS_PTY_LTD = 0x0104;
|
||||
public static final int UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION = 0x0105;
|
||||
public static final int INNOVATIVE_YACHTTER_SOLUTIONS = 0x0106;
|
||||
public static final int WILLIAM_DEMANT_HOLDING_A_S = 0x0107;
|
||||
public static final int CHICONY_ELECTRONICS_CO_LTD = 0x0108;
|
||||
public static final int ATUS_BV = 0x0109;
|
||||
public static final int CODEGATE_LTD = 0x010A;
|
||||
public static final int ERI_INC = 0x010B;
|
||||
public static final int TRANSDUCERS_DIRECT_LLC = 0x010C;
|
||||
public static final int FUJITSU_TEN_LIMITED = 0x010D;
|
||||
public static final int AUDI_AG = 0x010E;
|
||||
public static final int HISILICON_TECHNOLOGIES_CO_LTD = 0x010F;
|
||||
public static final int NIPPON_SEIKI_CO_LTD = 0x0110;
|
||||
public static final int STEELSERIES_APS = 0x0111;
|
||||
public static final int VYZYBL_INC = 0x0112;
|
||||
public static final int OPENBRAIN_TECHNOLOGIES_CO_LTD = 0x0113;
|
||||
public static final int XENSR = 0x0114;
|
||||
public static final int ESOLUTIONS = 0x0115;
|
||||
public static final int ONE_OAK_TECHNOLOGIES = 0x0116;
|
||||
public static final int WIMOTO_TECHNOLOGIES_INC = 0x0117;
|
||||
public static final int RADIUS_NETWORKS_INC = 0x0118;
|
||||
public static final int WIZE_TECHNOLOGY_CO_LTD = 0x0119;
|
||||
public static final int QUALCOMM_LABS_INC = 0x011A;
|
||||
public static final int ARUBA_NETWORKS = 0x011B;
|
||||
public static final int BAIDU = 0x011C;
|
||||
public static final int ARENDI_AG = 0x011D;
|
||||
public static final int SKODA_AUTO_AS = 0x011E;
|
||||
public static final int VOLKSWAGON_AG = 0x011F;
|
||||
public static final int PORSCHE_AG = 0x0120;
|
||||
public static final int SINO_WEALTH_ELECTRONIC_LTD = 0x0121;
|
||||
public static final int AIRTURN_INC = 0x0122;
|
||||
public static final int KINSA_INC = 0x0123;
|
||||
public static final int HID_GLOBAL = 0x0124;
|
||||
public static final int SEAT_ES = 0x0125;
|
||||
public static final int PROMETHEAN_LTD = 0x0126;
|
||||
public static final int SALUTICA_ALLIED_SOLUTIONS = 0x0127;
|
||||
public static final int GPSI_GROUP_PTY_LTD = 0x0128;
|
||||
public static final int NIMBLE_DEVICES_OY = 0x0129;
|
||||
public static final int CHANGZHOU_YONGSE_INFOTECH_CO_LTD = 0x012A;
|
||||
public static final int SPORTIQ = 0x012B;
|
||||
public static final int TEMEC_INSTRUMENTS_BV = 0x012C;
|
||||
public static final int SONY_CORPORATION = 0x012D;
|
||||
public static final int ASSA_ABLOY = 0x012E;
|
||||
public static final int CLARION_CO_LTD = 0x012F;
|
||||
public static final int WAREHOUSE_INNOVATIONS = 0x0130;
|
||||
public static final int CYPRESS_SEMICONDUCTOR_CORPORATION = 0x0131;
|
||||
public static final int MADS_INC = 0x0132;
|
||||
public static final int BLUE_MAESTRO_LIMITED = 0x0133;
|
||||
public static final int RESOLUTION_PRODUCTS_INC = 0x0134;
|
||||
public static final int AIREWEAR_LLC = 0x0135;
|
||||
public static final int ETC_SP_ZOO = 0x0136;
|
||||
public static final int PRESTIGIO_PLAZA_LTD = 0x0137;
|
||||
|
||||
private static final SparseArray<String> COMPANY_NAME_MAP = populateCompanyNameMap();
|
||||
|
||||
public static String getCompanyName(int companyId, String fallback){
|
||||
final String name = COMPANY_NAME_MAP.get(companyId);
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
|
||||
private static SparseArray<String> populateCompanyNameMap() {
|
||||
final SparseArray<String> map = new SparseArray<String>();
|
||||
|
||||
map.put(ERICSSON_TECHNOLOGY_LICENSING , "Ericsson Technology Licensing");
|
||||
map.put(NOKIA_MOBILE_PHONES , "Nokia Mobile Phones");
|
||||
map.put(INTEL_CORP , "Intel Corp.");
|
||||
map.put(IBM_CORP , "IBM Corp.");
|
||||
map.put(TOSHIBA_CORP , "Toshiba Corp.");
|
||||
map.put(THREE_COM , "3Com");
|
||||
map.put(MICROSOFT , "Microsoft");
|
||||
map.put(LUCENT , "Lucent");
|
||||
map.put(MOTOROLA , "Motorola");
|
||||
map.put(INFINEON_TECHNOLOGIES_AG , "Infineon Technologies AG");
|
||||
map.put(CAMBRIDGE_SILICON_RADIO , "Cambridge Silicon Radio");
|
||||
map.put(SILICON_WAVE , "Silicon Wave");
|
||||
map.put(DIGIANSWER_A_S , "Digianswer A/S");
|
||||
map.put(TEXAS_INSTRUMENTS_INC , "Texas Instruments Inc.");
|
||||
map.put(CEVA_INC_FORMERLY_PARTHUS_TECHNOLOGIES_INC , "Ceva, Inc. (formerly Parthus Technologies, Inc.)");
|
||||
map.put(BROADCOM_CORPORATION , "Broadcom Corporation");
|
||||
map.put(MITEL_SEMICONDUCTOR , "Mitel Semiconductor");
|
||||
map.put(WIDCOMM_INC , "Widcomm, Inc");
|
||||
map.put(ZEEVO_INC , "Zeevo, Inc.");
|
||||
map.put(ATMEL_CORPORATION , "Atmel Corporation");
|
||||
map.put(MITSUBISHI_ELECTRIC_CORPORATION , "Mitsubishi Electric Corporation");
|
||||
map.put(RTX_TELECOM_A_S , "RTX Telecom A/S");
|
||||
map.put(KC_TECHNOLOGY_INC , "KC Technology Inc.");
|
||||
map.put(NEWLOGIC , "NewLogic");
|
||||
map.put(TRANSILICA_INC , "Transilica, Inc.");
|
||||
map.put(ROHDE_SCHWARZ_GMBH_CO_KG , "Rohde & Schwarz GmbH & Co. KG");
|
||||
map.put(TTPCOM_LIMITED , "TTPCom Limited");
|
||||
map.put(SIGNIA_TECHNOLOGIES_INC , "Signia Technologies, Inc.");
|
||||
map.put(CONEXANT_SYSTEMS_INC , "Conexant Systems Inc.");
|
||||
map.put(QUALCOMM , "Qualcomm");
|
||||
map.put(INVENTEL , "Inventel");
|
||||
map.put(AVM_BERLIN , "AVM Berlin");
|
||||
map.put(BANDSPEED_INC , "BandSpeed, Inc.");
|
||||
map.put(MANSELLA_LTD , "Mansella Ltd");
|
||||
map.put(NEC_CORPORATION , "NEC Corporation");
|
||||
map.put(WAVEPLUS_TECHNOLOGY_CO_LTD , "WavePlus Technology Co., Ltd.");
|
||||
map.put(ALCATEL , "Alcatel");
|
||||
map.put(PHILIPS_SEMICONDUCTORS , "Philips Semiconductors");
|
||||
map.put(C_TECHNOLOGIES , "C Technologies");
|
||||
map.put(OPEN_INTERFACE , "Open Interface");
|
||||
map.put(R_F_MICRO_DEVICES , "R F Micro Devices");
|
||||
map.put(HITACHI_LTD , "Hitachi Ltd");
|
||||
map.put(SYMBOL_TECHNOLOGIES_INC , "Symbol Technologies, Inc.");
|
||||
map.put(TENOVIS , "Tenovis");
|
||||
map.put(MACRONIX_INTERNATIONAL_CO_LTD , "Macronix International Co. Ltd.");
|
||||
map.put(GCT_SEMICONDUCTOR , "GCT Semiconductor");
|
||||
map.put(NORWOOD_SYSTEMS , "Norwood Systems");
|
||||
map.put(MEWTEL_TECHNOLOGY_INC , "MewTel Technology Inc.");
|
||||
map.put(ST_MICROELECTRONICS , "ST Microelectronics");
|
||||
map.put(SYNOPSIS , "Synopsis");
|
||||
map.put(REDM_COMMUNICATIONS_LTD , "Red-M (Communications) Ltd");
|
||||
map.put(COMMIL_LTD , "Commil Ltd");
|
||||
map.put(COMPUTER_ACCESS_TECHNOLOGY_CORPORATION_CATC , "Computer Access Technology Corporation (CATC)");
|
||||
map.put(ECLIPSE_HQ_ESPANA_SL , "Eclipse (HQ Espana) S.L.");
|
||||
map.put(RENESAS_TECHNOLOGY_CORP , "Renesas Technology Corp.");
|
||||
map.put(MOBILIAN_CORPORATION , "Mobilian Corporation");
|
||||
map.put(TERAX , "Terax");
|
||||
map.put(INTEGRATED_SYSTEM_SOLUTION_CORP , "Integrated System Solution Corp.");
|
||||
map.put(MATSUSHITA_ELECTRIC_INDUSTRIAL_CO_LTD , "Matsushita Electric Industrial Co., Ltd.");
|
||||
map.put(GENNUM_CORPORATION , "Gennum Corporation");
|
||||
map.put(RESEARCH_IN_MOTION , "Research In Motion");
|
||||
map.put(IPEXTREME_INC , "IPextreme, Inc.");
|
||||
map.put(SYSTEMS_AND_CHIPS_INC , "Systems and Chips, Inc.");
|
||||
map.put(BLUETOOTH_SIG_INC , "Bluetooth SIG, Inc.");
|
||||
map.put(SEIKO_EPSON_CORPORATION , "Seiko Epson Corporation");
|
||||
map.put(INTEGRATED_SILICON_SOLUTION_TAIWAN_INC , "Integrated Silicon Solution Taiwan, Inc.");
|
||||
map.put(CONWISE_TECHNOLOGY_CORPORATION_LTD , "CONWISE Technology Corporation Ltd");
|
||||
map.put(PARROT_SA , "PARROT SA");
|
||||
map.put(SOCKET_MOBILE , "Socket Mobile");
|
||||
map.put(ATHEROS_COMMUNICATIONS_INC , "Atheros Communications, Inc.");
|
||||
map.put(MEDIATEK_INC , "MediaTek, Inc.");
|
||||
map.put(BLUEGIGA , "Bluegiga");
|
||||
map.put(MARVELL_TECHNOLOGY_GROUP_LTD , "Marvell Technology Group Ltd.");
|
||||
map.put(THREE_DSP_CORPORATION , "3DSP Corporation");
|
||||
map.put(ACCEL_SEMICONDUCTOR_LTD , "Accel Semiconductor Ltd.");
|
||||
map.put(CONTINENTAL_AUTOMOTIVE_SYSTEMS , "Continental Automotive Systems");
|
||||
map.put(APPLE_INC , "Apple, Inc.");
|
||||
map.put(STACCATO_COMMUNICATIONS_INC , "Staccato Communications, Inc.");
|
||||
map.put(AVAGO_TECHNOLOGIES , "Avago Technologies");
|
||||
map.put(APT_LICENSING_LTD , "APT Licensing Ltd.");
|
||||
map.put(SIRF_TECHNOLOGY , "SiRF Technology");
|
||||
map.put(TZERO_TECHNOLOGIES_INC , "Tzero Technologies, Inc.");
|
||||
map.put(JM_CORPORATION , "J&M Corporation");
|
||||
map.put(FREE2MOVE_AB , "Free2move AB");
|
||||
map.put(THREE_DIJOY_CORPORATION , "3DiJoy Corporation");
|
||||
map.put(PLANTRONICS_INC , "Plantronics, Inc.");
|
||||
map.put(SONY_ERICSSON_MOBILE_COMMUNICATIONS , "Sony Ericsson Mobile Communications");
|
||||
map.put(HARMAN_INTERNATIONAL_INDUSTRIES_INC , "Harman International Industries, Inc.");
|
||||
map.put(VIZIO_INC , "Vizio, Inc.");
|
||||
map.put(NORDIC_SEMICONDUCTOR_ASA , "Nordic Semiconductor ASA");
|
||||
map.put(EM_MICROELECTRONICMARIN_SA , "EM Microelectronic-Marin SA");
|
||||
map.put(RALINK_TECHNOLOGY_CORPORATION , "Ralink Technology Corporation");
|
||||
map.put(BELKIN_INTERNATIONAL_INC , "Belkin International, Inc.");
|
||||
map.put(REALTEK_SEMICONDUCTOR_CORPORATION , "Realtek Semiconductor Corporation");
|
||||
map.put(STONESTREET_ONE_LLC , "Stonestreet One, LLC");
|
||||
map.put(WICENTRIC_INC , "Wicentric, Inc.");
|
||||
map.put(RIVIERAWAVES_SAS , "RivieraWaves S.A.S");
|
||||
map.put(RDA_MICROELECTRONICS , "RDA Microelectronics");
|
||||
map.put(GIBSON_GUITARS , "Gibson Guitars");
|
||||
map.put(MICOMMAND_INC , "MiCommand Inc.");
|
||||
map.put(BAND_XI_INTERNATIONAL_LLC , "Band XI International, LLC");
|
||||
map.put(HEWLETTPACKARD_COMPANY , "Hewlett-Packard Company");
|
||||
map.put(NINE_SOLUTIONS_OY , "9Solutions Oy");
|
||||
map.put(GN_NETCOM_A_S , "GN Netcom A/S");
|
||||
map.put(GENERAL_MOTORS , "General Motors");
|
||||
map.put(AD_ENGINEERING_INC , "A&D Engineering, Inc.");
|
||||
map.put(MINDTREE_LTD , "MindTree Ltd.");
|
||||
map.put(POLAR_ELECTRO_OY , "Polar Electro OY");
|
||||
map.put(BEAUTIFUL_ENTERPRISE_CO_LTD , "Beautiful Enterprise Co., Ltd.");
|
||||
map.put(BRIARTEK_INC , "BriarTek, Inc.");
|
||||
map.put(SUMMIT_DATA_COMMUNICATIONS_INC , "Summit Data Communications, Inc.");
|
||||
map.put(SOUND_ID , "Sound ID");
|
||||
map.put(MONSTER_LLC , "Monster, LLC");
|
||||
map.put(CONNECTBLUE_AB , "connectBlue AB");
|
||||
map.put(SHANGHAI_SUPER_SMART_ELECTRONICS_CO_LTD , "ShangHai Super Smart Electronics Co. Ltd.");
|
||||
map.put(GROUP_SENSE_LTD , "Group Sense Ltd.");
|
||||
map.put(ZOMM_LLC , "Zomm, LLC");
|
||||
map.put(SAMSUNG_ELECTRONICS_CO_LTD , "Samsung Electronics Co. Ltd.");
|
||||
map.put(CREATIVE_TECHNOLOGY_LTD , "Creative Technology Ltd.");
|
||||
map.put(LAIRD_TECHNOLOGIES , "Laird Technologies");
|
||||
map.put(NIKE_INC , "Nike, Inc.");
|
||||
map.put(LESSWIRE_AG , "lesswire AG");
|
||||
map.put(MSTAR_SEMICONDUCTOR_INC , "MStar Semiconductor, Inc.");
|
||||
map.put(HANLYNN_TECHNOLOGIES , "Hanlynn Technologies");
|
||||
map.put(A_R_CAMBRIDGE , "A & R Cambridge");
|
||||
map.put(SEERS_TECHNOLOGY_CO_LTD , "Seers Technology Co. Ltd");
|
||||
map.put(SPORTS_TRACKING_TECHNOLOGIES_LTD , "Sports Tracking Technologies Ltd.");
|
||||
map.put(AUTONET_MOBILE , "Autonet Mobile");
|
||||
map.put(DELORME_PUBLISHING_COMPANY_INC , "DeLorme Publishing Company, Inc.");
|
||||
map.put(WUXI_VIMICRO , "WuXi Vimicro");
|
||||
map.put(SENNHEISER_COMMUNICATIONS_A_S , "Sennheiser Communications A/S");
|
||||
map.put(TIMEKEEPING_SYSTEMS_INC , "TimeKeeping Systems, Inc.");
|
||||
map.put(LUDUS_HELSINKI_LTD , "Ludus Helsinki Ltd.");
|
||||
map.put(BLUERADIOS_INC , "BlueRadios, Inc.");
|
||||
map.put(EQUINOX_AG , "equinox AG");
|
||||
map.put(GARMIN_INTERNATIONAL_INC , "Garmin International, Inc.");
|
||||
map.put(ECOTEST , "Ecotest");
|
||||
map.put(GN_RESOUND_A_S , "GN ReSound A/S");
|
||||
map.put(JAWBONE , "Jawbone");
|
||||
map.put(TOPCORN_POSITIONING_SYSTEMS_LLC , "Topcorn Positioning Systems, LLC");
|
||||
map.put(QUALCOMM_RETAIL_SOLUTIONS_INC_FORMERLY_QUALCOMM_LABS_INC , "Qualcomm Retail Solutions, Inc. (formerly Qualcomm Labs, Inc.)");
|
||||
map.put(ZSCAN_SOFTWARE , "Zscan Software");
|
||||
map.put(QUINTIC_CORP , "Quintic Corp.");
|
||||
map.put(STOLLMAN_EV_GMBH , "Stollman E+V GmbH");
|
||||
map.put(FUNAI_ELECTRIC_CO_LTD , "Funai Electric Co., Ltd.");
|
||||
map.put(ADVANCED_PANMOBIL_SYSTEMS_GMBH_CO_KG , "Advanced PANMOBIL Systems GmbH & Co. KG");
|
||||
map.put(THINKOPTICS_INC , "ThinkOptics, Inc.");
|
||||
map.put(UNIVERSAL_ELECTRONICS_INC , "Universal Electronics, Inc.");
|
||||
map.put(AIROHA_TECHNOLOGY_CORP , "Airoha Technology Corp.");
|
||||
map.put(NEC_LIGHTING_LTD , "NEC Lighting, Ltd.");
|
||||
map.put(ODM_TECHNOLOGY_INC , "ODM Technology, Inc.");
|
||||
map.put(CONNECTEDEVICE_LTD , "ConnecteDevice Ltd.");
|
||||
map.put(ZER01TV_GMBH , "zer01.tv GmbH");
|
||||
map.put(ITECH_DYNAMIC_GLOBAL_DISTRIBUTION_LTD , "i.Tech Dynamic Global Distribution Ltd.");
|
||||
map.put(ALPWISE , "Alpwise");
|
||||
map.put(JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS_CO_LTD , "Jiangsu Toppower Automotive Electronics Co., Ltd.");
|
||||
map.put(COLORFY_INC , "Colorfy, Inc.");
|
||||
map.put(GEOFORCE_INC , "Geoforce Inc.");
|
||||
map.put(BOSE_CORPORATION , "Bose Corporation");
|
||||
map.put(SUUNTO_OY , "Suunto Oy");
|
||||
map.put(KENSINGTON_COMPUTER_PRODUCTS_GROUP , "Kensington Computer Products Group");
|
||||
map.put(SRMEDIZINELEKTRONIK , "SR-Medizinelektronik");
|
||||
map.put(VERTU_CORPORATION_LIMITED , "Vertu Corporation Limited");
|
||||
map.put(META_WATCH_LTD , "Meta Watch Ltd.");
|
||||
map.put(LINAK_A_S , "LINAK A/S");
|
||||
map.put(OTL_DYNAMICS_LLC , "OTL Dynamics LLC");
|
||||
map.put(PANDA_OCEAN_INC , "Panda Ocean Inc.");
|
||||
map.put(VISTEON_CORPORATION , "Visteon Corporation");
|
||||
map.put(ARP_DEVICES_LIMITED , "ARP Devices Limited");
|
||||
map.put(MAGNETI_MARELLI_SPA , "Magneti Marelli S.p.A");
|
||||
map.put(CAEN_RFID_SRL , "CAEN RFID srl");
|
||||
map.put(INGENIEURSYSTEMGRUPPE_ZAHN_GMBH , "Ingenieur-Systemgruppe Zahn GmbH");
|
||||
map.put(GREEN_THROTTLE_GAMES , "Green Throttle Games");
|
||||
map.put(PETER_SYSTEMTECHNIK_GMBH , "Peter Systemtechnik GmbH");
|
||||
map.put(OMEGAWAVE_OY , "Omegawave Oy");
|
||||
map.put(CINETIX , "Cinetix");
|
||||
map.put(PASSIF_SEMICONDUCTOR_CORP , "Passif Semiconductor Corp");
|
||||
map.put(SARIS_CYCLING_GROUP_INC , "Saris Cycling Group, Inc");
|
||||
map.put(BEKEY_A_S , "Bekey A/S");
|
||||
map.put(CLARINOX_TECHNOLOGIES_PTY_LTD , "Clarinox Technologies Pty. Ltd.");
|
||||
map.put(BDE_TECHNOLOGY_CO_LTD , "BDE Technology Co., Ltd.");
|
||||
map.put(SWIRL_NETWORKS , "Swirl Networks");
|
||||
map.put(MESO_INTERNATIONAL , "Meso international");
|
||||
map.put(TRELAB_LTD , "TreLab Ltd");
|
||||
map.put(QUALCOMM_INNOVATION_CENTER_INC_QUIC , "Qualcomm Innovation Center, Inc. (QuIC)");
|
||||
map.put(JOHNSON_CONTROLS_INC , "Johnson Controls, Inc.");
|
||||
map.put(STARKEY_LABORATORIES_INC , "Starkey Laboratories Inc.");
|
||||
map.put(SPOWER_ELECTRONICS_LIMITED , "S-Power Electronics Limited");
|
||||
map.put(ACE_SENSOR_INC , "Ace Sensor Inc");
|
||||
map.put(APLIX_CORPORATION , "Aplix Corporation");
|
||||
map.put(AAMP_OF_AMERICA , "AAMP of America");
|
||||
map.put(STALMART_TECHNOLOGY_LIMITED , "Stalmart Technology Limited");
|
||||
map.put(AMICCOM_ELECTRONICS_CORPORATION , "AMICCOM Electronics Corporation");
|
||||
map.put(SHENZHEN_EXCELSECU_DATA_TECHNOLOGY_COLTD , "Shenzhen Excelsecu Data Technology Co.,Ltd");
|
||||
map.put(GENEQ_INC , "Geneq Inc.");
|
||||
map.put(ADIDAS_AG , "adidas AG");
|
||||
map.put(LG_ELECTRONICS , "LG Electronics");
|
||||
map.put(ONSET_COMPUTER_CORPORATION , "Onset Computer Corporation");
|
||||
map.put(SELFLY_BV , "Selfly BV");
|
||||
map.put(QUUPPA_OY , "Quuppa Oy.");
|
||||
map.put(GELO_INC , "GeLo Inc");
|
||||
map.put(EVLUMA , "Evluma");
|
||||
map.put(MC10 , "MC10");
|
||||
map.put(BINAURIC_SE , "Binauric SE");
|
||||
map.put(BEATS_ELECTRONICS , "Beats Electronics");
|
||||
map.put(MICROCHIP_TECHNOLOGY_INC , "Microchip Technology Inc.");
|
||||
map.put(ELGATO_SYSTEMS_GMBH , "Elgato Systems GmbH");
|
||||
map.put(ARCHOS_SA , "ARCHOS SA");
|
||||
map.put(DEXCOM_INC , "Dexcom, Inc.");
|
||||
map.put(POLAR_ELECTRO_EUROPE_BV , "Polar Electro Europe B.V.");
|
||||
map.put(DIALOG_SEMICONDUCTOR_BV , "Dialog Semiconductor B.V.");
|
||||
map.put(TAIXINGBANG_TECHNOLOGY_HK_CO_LTD , "Taixingbang Technology (HK) Co,. LTD.");
|
||||
map.put(KAWANTECH , "Kawantech");
|
||||
map.put(AUSTCO_COMMUNICATION_SYSTEMS , "Austco Communication Systems");
|
||||
map.put(TIMEX_GROUP_USA_INC , "Timex Group USA, Inc.");
|
||||
map.put(QUALCOMM_TECHNOLOGIES_INC , "Qualcomm Technologies, Inc.");
|
||||
map.put(QUALCOMM_CONNECTED_EXPERIENCES_INC , "Qualcomm Connected Experiences, Inc.");
|
||||
map.put(VOYETRA_TURTLE_BEACH , "Voyetra Turtle Beach");
|
||||
map.put(TXTR_GMBH , "txtr GmbH");
|
||||
map.put(BIOSENTRONICS , "Biosentronics");
|
||||
map.put(PROCTER_GAMBLE , "Procter & Gamble");
|
||||
map.put(HOSIDEN_CORPORATION , "Hosiden Corporation");
|
||||
map.put(MUZIK_LLC , "Muzik LLC");
|
||||
map.put(MISFIT_WEARABLES_CORP , "Misfit Wearables Corp");
|
||||
map.put(GOOGLE , "Google");
|
||||
map.put(DANLERS_LTD , "Danlers Ltd");
|
||||
map.put(SEMILINK_INC , "Semilink Inc");
|
||||
map.put(INMUSIC_BRANDS_INC , "inMusic Brands, Inc");
|
||||
map.put(LS_RESEARCH_INC , "L.S. Research Inc.");
|
||||
map.put(EDEN_SOFTWARE_CONSULTANTS_LTD , "Eden Software Consultants Ltd.");
|
||||
map.put(FRESHTEMP , "Freshtemp");
|
||||
map.put(KS_TECHNOLOGIES , "KS Technologies");
|
||||
map.put(ACTS_TECHNOLOGIES , "ACTS Technologies");
|
||||
map.put(VTRACK_SYSTEMS , "Vtrack Systems");
|
||||
map.put(NIELSENKELLERMAN_COMPANY , "Nielsen-Kellerman Company");
|
||||
map.put(SERVER_TECHNOLOGY_INC , "Server Technology, Inc.");
|
||||
map.put(BIORESEARCH_ASSOCIATES , "BioResearch Associates");
|
||||
map.put(JOLLY_LOGIC_LLC , "Jolly Logic, LLC");
|
||||
map.put(ABOVE_AVERAGE_OUTCOMES_INC , "Above Average Outcomes, Inc.");
|
||||
map.put(BITSPLITTERS_GMBH , "Bitsplitters GmbH");
|
||||
map.put(PAYPAL_INC , "PayPal, Inc.");
|
||||
map.put(WITRON_TECHNOLOGY_LIMITED , "Witron Technology Limited");
|
||||
map.put(MORSE_PROJECT_INC , "Morse Project Inc.");
|
||||
map.put(KENT_DISPLAYS_INC , "Kent Displays Inc.");
|
||||
map.put(NAUTILUS_INC , "Nautilus Inc.");
|
||||
map.put(SMARTIFIER_OY , "Smartifier Oy");
|
||||
map.put(ELCOMETER_LIMITED , "Elcometer Limited");
|
||||
map.put(VSN_TECHNOLOGIES_INC , "VSN Technologies Inc.");
|
||||
map.put(ACEUNI_CORP_LTD , "AceUni Corp., Ltd.");
|
||||
map.put(STICKNFIND , "StickNFind");
|
||||
map.put(CRYSTAL_CODE_AB , "Crystal Code AB");
|
||||
map.put(KOUKAAM_AS , "KOUKAAM a.s.");
|
||||
map.put(DELPHI_CORPORATION , "Delphi Corporation");
|
||||
map.put(VALENCETECH_LIMITED , "ValenceTech Limited");
|
||||
map.put(RESERVED , "Reserved");
|
||||
map.put(TYPO_PRODUCTS_LLC , "Typo Products, LLC");
|
||||
map.put(TOMTOM_INTERNATIONAL_BV , "TomTom International BV");
|
||||
map.put(FUGOO_INC , "Fugoo, Inc");
|
||||
map.put(KEISER_CORPORATION , "Keiser Corporation");
|
||||
map.put(BANG_OLUFSEN_A_S , "Bang & Olufsen A/S");
|
||||
map.put(PLUS_LOCATIONS_SYSTEMS_PTY_LTD , "PLUS Locations Systems Pty Ltd");
|
||||
map.put(UBIQUITOUS_COMPUTING_TECHNOLOGY_CORPORATION , "Ubiquitous Computing Technology Corporation");
|
||||
map.put(INNOVATIVE_YACHTTER_SOLUTIONS , "Innovative Yachtter Solutions");
|
||||
map.put(WILLIAM_DEMANT_HOLDING_A_S , "William Demant Holding A/S");
|
||||
map.put(CHICONY_ELECTRONICS_CO_LTD , "Chicony Electronics Co., Ltd.");
|
||||
map.put(ATUS_BV , "Atus BV");
|
||||
map.put(CODEGATE_LTD , "Codegate Ltd.");
|
||||
map.put(ERI_INC , "ERi, Inc.");
|
||||
map.put(TRANSDUCERS_DIRECT_LLC , "Transducers Direct, LLC");
|
||||
map.put(FUJITSU_TEN_LIMITED , "Fujitsu Ten Limited");
|
||||
map.put(AUDI_AG , "Audi AG");
|
||||
map.put(HISILICON_TECHNOLOGIES_CO_LTD , "HiSilicon Technologies Co., Ltd.");
|
||||
map.put(NIPPON_SEIKI_CO_LTD , "Nippon Seiki Co., Ltd.");
|
||||
map.put(STEELSERIES_APS , "Steelseries ApS");
|
||||
map.put(VYZYBL_INC , "vyzybl Inc.");
|
||||
map.put(OPENBRAIN_TECHNOLOGIES_CO_LTD , "Openbrain Technologies, Co., Ltd.");
|
||||
map.put(XENSR , "Xensr");
|
||||
map.put(ESOLUTIONS , "e.solutions");
|
||||
map.put(ONE_OAK_TECHNOLOGIES , "1OAK Technologies");
|
||||
map.put(WIMOTO_TECHNOLOGIES_INC , "Wimoto Technologies Inc");
|
||||
map.put(RADIUS_NETWORKS_INC , "Radius Networks, Inc.");
|
||||
map.put(WIZE_TECHNOLOGY_CO_LTD , "Wize Technology Co., Ltd.");
|
||||
map.put(QUALCOMM_LABS_INC , "Qualcomm Labs, Inc.");
|
||||
map.put(ARUBA_NETWORKS , "Aruba Networks");
|
||||
map.put(BAIDU , "Baidu");
|
||||
map.put(ARENDI_AG , "Arendi AG");
|
||||
map.put(SKODA_AUTO_AS , "Skoda Auto a.s.");
|
||||
map.put(VOLKSWAGON_AG , "Volkswagon AG");
|
||||
map.put(PORSCHE_AG , "Porsche AG");
|
||||
map.put(SINO_WEALTH_ELECTRONIC_LTD , "Sino Wealth Electronic Ltd.");
|
||||
map.put(AIRTURN_INC , "AirTurn, Inc.");
|
||||
map.put(KINSA_INC , "Kinsa, Inc.");
|
||||
map.put(HID_GLOBAL , "HID Global");
|
||||
map.put(SEAT_ES , "SEAT es");
|
||||
map.put(PROMETHEAN_LTD , "Promethean Ltd.");
|
||||
map.put(SALUTICA_ALLIED_SOLUTIONS , "Salutica Allied Solutions");
|
||||
map.put(GPSI_GROUP_PTY_LTD , "GPSI Group Pty Ltd");
|
||||
map.put(NIMBLE_DEVICES_OY , "Nimble Devices Oy");
|
||||
map.put(CHANGZHOU_YONGSE_INFOTECH_CO_LTD , "Changzhou Yongse Infotech Co., Ltd");
|
||||
map.put(SPORTIQ , "SportIQ");
|
||||
map.put(TEMEC_INSTRUMENTS_BV , "TEMEC Instruments B.V.");
|
||||
map.put(SONY_CORPORATION , "Sony Corporation");
|
||||
map.put(ASSA_ABLOY , "ASSA ABLOY");
|
||||
map.put(CLARION_CO_LTD , "Clarion Co., Ltd.");
|
||||
map.put(WAREHOUSE_INNOVATIONS , "Warehouse Innovations");
|
||||
map.put(CYPRESS_SEMICONDUCTOR_CORPORATION , "Cypress Semiconductor Corporation");
|
||||
map.put(MADS_INC , "MADS Inc");
|
||||
map.put(BLUE_MAESTRO_LIMITED , "Blue Maestro Limited");
|
||||
map.put(RESOLUTION_PRODUCTS_INC , "Resolution Products, Inc.");
|
||||
map.put(AIREWEAR_LLC , "Airewear LLC");
|
||||
map.put(ETC_SP_ZOO , "ETC sp. z.o.o.");
|
||||
map.put(PRESTIGIO_PLAZA_LTD , "Prestigio Plaza Ltd.");
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,386 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.resolvers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* The UUIDS have been collected from the following sources:
|
||||
*
|
||||
* - http://developer.nokia.com/community/wiki/Bluetooth_Services_for_Windows_Phone
|
||||
* - The Bluez project
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*
|
||||
*/
|
||||
public class GattAttributeResolver {
|
||||
public static final String BASE_GUID = "00000001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_PROTOCOL_SDP = "00000002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String USER_DATAGRAM_PROTOCOL_UDP = "00000003-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM = "00000004-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCP = "00000005-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSBIN = "00000006-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSAT = "00000008-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBJECT_EXCHANGE_PROTOCOL_OBEX = "00000009-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IP = "0000000a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FTP = "0000000c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HTTP = "0000000e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WSP = "0000000f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BNEP_SVC = "00000010-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_PROTOCOL = "00000011-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HIDP = "00000012-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CONTROL_CHANNEL_PROTOCOL = "00000014-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_DATA_CHANNEL_PROTOCOL = "00000016-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_NOTIFICATION_PROTOCOL = "00000017-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VCTP_PROTOCOL = "00000019-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VDTP_PROTOCOL = "0000001b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CMPT_PROTOCOL = "0000001d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDI_C_PLANE_PROTOCOL = "0000001e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_CONTROL_CHANNEL = "0000001f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_DATA_CHANNEL = "00000100-0000-1000-8000-00805f9b34fb";
|
||||
public static final String L2CAP = "00001000-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_SERVER = "00001001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BROWSE_GROUP_DESCRIPTOR = "00001002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PUBLIC_BROWSE_GROUP = "00001101-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SPP = "00001102-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LAN_ACCESS_USING_PPP = "00001103-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DUN_GW = "00001104-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_SYNC = "00001105-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_OBJECT_PUSH = "00001106-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_FILE_TRANSFER = "00001107-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IRMC_SYNC_COMMAND = "00001108-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HSP_HS = "00001109-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CORDLESS_TELEPHONY = "0000110a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SOURCE = "0000110b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SINK = "0000110c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AV_REMOTE_CONTROL_TARGET = "0000110d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ADVANCED_AUDIO = "0000110e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AVRCP_REMOTE = "0000110f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING = "00001110-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERCOM = "00001111-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FAX = "00001112-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEADSET_PROFILE_HSP_AUDIO_GATEWAY = "00001113-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP = "00001114-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP_CLIENT = "00001115-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PANU = "00001116-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NAP = "00001117-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GN = "00001118-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING = "00001119-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_PRINTING = "0000111a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING = "0000111b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_RESPONDER = "0000111c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_AUTOMATIC_ARCHIVE = "0000111d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_REFERENCE_OBJECTS = "0000111e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP = "0000111f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY = "00001120-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING_REFERENCE_OBJECTS = "00001121-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFLECTED_UI = "00001122-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BASIC_PRINTING = "00001123-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PRINTING_STATUS = "00001124-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HID = "00001125-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CABLE_REPLACEMENT = "00001126-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_PRINT = "00001127-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_SCAN = "00001128-0000-1000-8000-00805f9b34fb";
|
||||
public static final String COMMON_ISDN_ACCESS = "00001129-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING_GATEWAY = "0000112a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDIMT = "0000112b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDITA = "0000112c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_VIDEO = "0000112d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SIM_ACCESS = "0000112e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PCE = "0000112f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PSE = "00001130-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PBAP = "00001132-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAS = "00001133-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MNS = "00001134-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAP = "00001200-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNP = "00001201-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_NETWORKING = "00001202-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_FILE_TRANSFER = "00001203-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_AUDIO = "00001204-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_TELEPHONY = "00001205-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP = "00001206-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_IP = "00001300-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_PAN = "00001301-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_LAP = "00001302-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_L2CAP = "00001303-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE = "00001304-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SINK = "00001305-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP = "00001400-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP = "00001401-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SOURCE = "00001402-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SINK = "00001800-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GAP = "00001801-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GATT = "00001802-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMMEDIATE_ALERT = "00001803-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LINK_LOSS = "00001804-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER = "00001809-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_THERMOMETER = "0000180a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_INFORMATION = "0000180d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE = "00001816-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CYCLING_SC = "00002902-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002a00-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_NAME = "00002a01-0000-1000-8000-00805f9b34fb";
|
||||
public static final String APPEARANCE = "00002a02-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PRIVACY_FLAG = "00002a03-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RECONNECTION_ADDRESS = "00002a04-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS = "00002a05-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_CHANGED = "00002a06-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_LEVEL = "00002a07-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER_LEVEL = "00002a08-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DATE_TIME = "00002a09-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_OF_WEEK = "00002a0a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_DATE_TIME = "00002a0c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String EXACT_TIME_256 = "00002a0d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DST_OFFSET = "00002a0e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ZONE = "00002a0f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LOCAL_TIME_INFORMATION = "00002a11-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_WITH_DST = "00002a12-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ACCURACY = "00002a13-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_SOURCE = "00002a14-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_TIME_INFORMATION = "00002a16-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_CONTROL_POINT = "00002a17-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_STATE = "00002a1c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_MEASUREMENT = "00002a1d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_TYPE = "00002a1e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_TEMPERATURE = "00002a21-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MEASUREMENT_INTERVAL = "00002a23-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SYSTEM_ID = "00002a24-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MODEL_NUMBER_STRING = "00002a25-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERIAL_NUMBER_STRING = "00002a26-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FIRMWARE_REVISION_STRING = "00002a27-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDWARE_REVISION_STRING = "00002a28-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SOFTWARE_REVISION_STRING = "00002a29-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MANUFACTURER_NAME_STRING = "00002a2a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IEEE_1107320601_REGULATORY = "00002a2b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CURRENT_TIME = "00002a35-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_MEASUREMENT = "00002a36-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_CUFF_PRESSURE = "00002a37-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_MEASUREMENT = "00002a38-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BODY_SENSOR_LOCATION = "00002a39-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_CONTROL_POINT = "00002a3f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_STATUS = "00002a40-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_CONTROL_POINT = "00002a41-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_SETTING = "00002a42-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID_BIT_MASK = "00002a43-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID = "00002a44-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_NOTIFICATION_CONTROL_POINT = "00002a45-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UNREAD_ALERT_STATUS = "00002a46-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NEW_ALERT = "00002a47-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_NEW_ALERT_CATEGORY = "00002a48-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_UNREAD_ALERT_CATEGORY = "00002a49-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_FEATURE = "00002a50-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNPID = "00002a55-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SC_CONTROL_POINT = "00002a5b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_MEASUREMENT = "00002a5c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_FEATURE = "00002a5d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SENSOR_LOCATION = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ACTIVESYNC = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ESTIMOTE_SERVICE = "b9403000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_UUID = "b9403003-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MAJOR = "b9403001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MINOR = "b9403002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_BATTERY = "b9403041-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_TEMPERATURE = "b9403021-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_POWER = "b9403011-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_INTERVAL = "b9403012-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_VERSION_SERVICE = "b9404000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_SOFTWARE_VERSION = "b9404001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_HARDWARE_VERSION = "b9404002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_AUTHENTICATION_SERVICE = "b9402000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_SEED = "b9402001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_VECTOR = "b9402002-f5f8-466e-aff9-25556b57fe6d";
|
||||
|
||||
|
||||
|
||||
private final static Map<String, String> sGattAttributesMap = populateGattAttributesMap();
|
||||
|
||||
public static String getAttributeName(String uuid, String fallback){
|
||||
final String name = sGattAttributesMap.get(uuid.toLowerCase(Locale.US));
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
|
||||
private static Map<String, String> populateGattAttributesMap() {
|
||||
final Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
map.put(BASE_GUID , "Service Discovery Protocol (SDP)");
|
||||
map.put(SERVICE_DISCOVERY_PROTOCOL_SDP , "User Datagram Protocol (UDP)");
|
||||
map.put(USER_DATAGRAM_PROTOCOL_UDP , "Radio Frequency Communication Protocol (RFCOMM)");
|
||||
map.put(RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM , "TCP");
|
||||
map.put(TCP , "TCSBIN");
|
||||
map.put(TCSBIN , "TCSAT");
|
||||
map.put(TCSAT , "Object Exchange Protocol (OBEX)");
|
||||
map.put(OBJECT_EXCHANGE_PROTOCOL_OBEX , "IP");
|
||||
map.put(IP , "FTP");
|
||||
map.put(FTP , "HTTP");
|
||||
map.put(HTTP , "WSP");
|
||||
map.put(WSP , "BNEP_SVC");
|
||||
map.put(BNEP_SVC , "UPNP Protocol");
|
||||
map.put(UPNP_PROTOCOL , "HIDP");
|
||||
map.put(HIDP , "Hardcopy Control Channel Protocol");
|
||||
map.put(HARDCOPY_CONTROL_CHANNEL_PROTOCOL , "Hardcopy Data Channel Protocol");
|
||||
map.put(HARDCOPY_DATA_CHANNEL_PROTOCOL , "Hardcopy Notification Protocol");
|
||||
map.put(HARDCOPY_NOTIFICATION_PROTOCOL , "VCTP Protocol");
|
||||
map.put(VCTP_PROTOCOL , "VDTP Protocol");
|
||||
map.put(VDTP_PROTOCOL , "CMPT Protocol");
|
||||
map.put(CMPT_PROTOCOL , "UDI C Plane Protocol");
|
||||
map.put(UDI_C_PLANE_PROTOCOL , "MCAP Control Channel");
|
||||
map.put(MCAP_CONTROL_CHANNEL , "MCAP Data Channel");
|
||||
map.put(MCAP_DATA_CHANNEL , "L2CAP");
|
||||
map.put(L2CAP , "Service Discovery Server");
|
||||
map.put(SERVICE_DISCOVERY_SERVER , "Browse Group Descriptor");
|
||||
map.put(BROWSE_GROUP_DESCRIPTOR , "Public Browse Group");
|
||||
map.put(PUBLIC_BROWSE_GROUP , "SPP");
|
||||
map.put(SPP , "LAN Access Using PPP");
|
||||
map.put(LAN_ACCESS_USING_PPP , "DUN_GW");
|
||||
map.put(DUN_GW , "OBEX_SYNC");
|
||||
map.put(OBEX_SYNC , "OBEX Object Push");
|
||||
map.put(OBEX_OBJECT_PUSH , "OBEX File Transfer");
|
||||
map.put(OBEX_FILE_TRANSFER , "IrMC Sync Command");
|
||||
map.put(IRMC_SYNC_COMMAND , "HSP_HS");
|
||||
map.put(HSP_HS , "Cordless Telephony");
|
||||
map.put(CORDLESS_TELEPHONY , "Audio Source");
|
||||
map.put(AUDIO_SOURCE , "Audio Sink");
|
||||
map.put(AUDIO_SINK , "AV Remote Control Target");
|
||||
map.put(AV_REMOTE_CONTROL_TARGET , "ADVANCED_AUDIO");
|
||||
map.put(ADVANCED_AUDIO , "AVRCP_REMOTE");
|
||||
map.put(AVRCP_REMOTE , "Video Conferencing");
|
||||
map.put(VIDEO_CONFERENCING , "Intercom");
|
||||
map.put(INTERCOM , "FAX");
|
||||
map.put(FAX , "Headset Profile (HSP) - Audio Gateway");
|
||||
map.put(HEADSET_PROFILE_HSP_AUDIO_GATEWAY , "WAP");
|
||||
map.put(WAP , "WAP Client");
|
||||
map.put(WAP_CLIENT , "PANU");
|
||||
map.put(PANU , "NAP");
|
||||
map.put(NAP , "GN");
|
||||
map.put(GN , "Direct Printing");
|
||||
map.put(DIRECT_PRINTING , "Reference Printing");
|
||||
map.put(REFERENCE_PRINTING , "Imaging");
|
||||
map.put(IMAGING , "Imaging Responder");
|
||||
map.put(IMAGING_RESPONDER , "Imaging Automatic Archive");
|
||||
map.put(IMAGING_AUTOMATIC_ARCHIVE , "Imaging Reference Objects");
|
||||
map.put(IMAGING_REFERENCE_OBJECTS , "Hands Free Profile (HFP)");
|
||||
map.put(HANDS_FREE_PROFILE_HFP , "Hands Free Profile (HFP) – Audio Gateway");
|
||||
map.put(HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY , "Direct Printing Reference Objects");
|
||||
map.put(DIRECT_PRINTING_REFERENCE_OBJECTS , "Reflected UI");
|
||||
map.put(REFLECTED_UI , "Basic Printing");
|
||||
map.put(BASIC_PRINTING , "Printing Status");
|
||||
map.put(PRINTING_STATUS , "HID");
|
||||
map.put(HID , "Hardcopy Cable Replacement");
|
||||
map.put(HARDCOPY_CABLE_REPLACEMENT , "HCR Print");
|
||||
map.put(HCR_PRINT , "HCR Scan");
|
||||
map.put(HCR_SCAN , "Common ISDN Access");
|
||||
map.put(COMMON_ISDN_ACCESS , "Video Conferencing Gateway");
|
||||
map.put(VIDEO_CONFERENCING_GATEWAY , "UDIMT");
|
||||
map.put(UDIMT , "UDITA");
|
||||
map.put(UDITA , "Audio Video");
|
||||
map.put(AUDIO_VIDEO , "SIM Access");
|
||||
map.put(SIM_ACCESS , "OBEX PCE");
|
||||
map.put(OBEX_PCE , "OBEX PSE");
|
||||
map.put(OBEX_PSE , "OBEX PBAP");
|
||||
map.put(OBEX_PBAP , "OBEX MAS");
|
||||
map.put(OBEX_MAS , "OBEX MNS");
|
||||
map.put(OBEX_MNS , "OBEX MAP");
|
||||
map.put(OBEX_MAP , "PNP");
|
||||
map.put(PNP , "Generic Networking");
|
||||
map.put(GENERIC_NETWORKING , "Generic File Transfer");
|
||||
map.put(GENERIC_FILE_TRANSFER , "Generic Audio");
|
||||
map.put(GENERIC_AUDIO , "Generic Telephony");
|
||||
map.put(GENERIC_TELEPHONY , "UPNP");
|
||||
map.put(UPNP , "UPNP IP");
|
||||
map.put(UPNP_IP , "ESDP UPnP IP PAN");
|
||||
map.put(ESDP_UPNP_IP_PAN , "ESDP UPnP IP LAP");
|
||||
map.put(ESDP_UPNP_IP_LAP , "ESDP Upnp L2CAP");
|
||||
map.put(ESDP_UPNP_L2CAP , "Video Distribution Profile (VDP) - Source");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE , "Video Distribution Profile (VDP) - Sink");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SINK , "Video Distribution Profile (VDP)");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP , "Health Device Profile (HDP)");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP , "Health Device Profile (HDP) - Source");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SOURCE , "Health Device Profile (HDP) - Sink");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SINK , "GAP");
|
||||
map.put(GAP , "GATT");
|
||||
map.put(GATT , "IMMEDIATE_ALERT");
|
||||
map.put(IMMEDIATE_ALERT , "LINK_LOSS");
|
||||
map.put(LINK_LOSS , "TX_POWER");
|
||||
map.put(TX_POWER , "Health Thermometer");
|
||||
map.put(HEALTH_THERMOMETER , "Device Information");
|
||||
map.put(DEVICE_INFORMATION , "HEART_RATE");
|
||||
map.put(HEART_RATE , "CYCLING_SC");
|
||||
map.put(CYCLING_SC , "CLIENT_CHARACTERISTIC_CONFIG");
|
||||
map.put(CLIENT_CHARACTERISTIC_CONFIG , "Device Name");
|
||||
map.put(DEVICE_NAME , "Appearance");
|
||||
map.put(APPEARANCE , "Peripheral Privacy Flag");
|
||||
map.put(PERIPHERAL_PRIVACY_FLAG , "Reconnection Address");
|
||||
map.put(RECONNECTION_ADDRESS , "Peripheral Preferred Connection Parameters");
|
||||
map.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS , "Service Changed");
|
||||
map.put(SERVICE_CHANGED , "Alert Level");
|
||||
map.put(ALERT_LEVEL , "Tx Power Level");
|
||||
map.put(TX_POWER_LEVEL , "Date Time");
|
||||
map.put(DATE_TIME , "Day of Week");
|
||||
map.put(DAY_OF_WEEK , "Day Date Time");
|
||||
map.put(DAY_DATE_TIME , "Exact Time 256");
|
||||
map.put(EXACT_TIME_256 , "DST Offset");
|
||||
map.put(DST_OFFSET , "Time Zone");
|
||||
map.put(TIME_ZONE , "Local Time Information");
|
||||
map.put(LOCAL_TIME_INFORMATION , "Time with DST");
|
||||
map.put(TIME_WITH_DST , "Time Accuracy");
|
||||
map.put(TIME_ACCURACY , "Time Source");
|
||||
map.put(TIME_SOURCE , "Reference Time Information");
|
||||
map.put(REFERENCE_TIME_INFORMATION , "Time Update Control Point");
|
||||
map.put(TIME_UPDATE_CONTROL_POINT , "Time Update State");
|
||||
map.put(TIME_UPDATE_STATE , "Temperature Measurement");
|
||||
map.put(TEMPERATURE_MEASUREMENT , "Temperature Type");
|
||||
map.put(TEMPERATURE_TYPE , "Intermediate Temperature");
|
||||
map.put(INTERMEDIATE_TEMPERATURE , "Measurement Interval");
|
||||
map.put(MEASUREMENT_INTERVAL , "System ID");
|
||||
map.put(SYSTEM_ID , "Model Number String");
|
||||
map.put(MODEL_NUMBER_STRING , "Serial Number String");
|
||||
map.put(SERIAL_NUMBER_STRING , "Firmware Revision String");
|
||||
map.put(FIRMWARE_REVISION_STRING , "Hardware Revision String");
|
||||
map.put(HARDWARE_REVISION_STRING , "Software Revision String");
|
||||
map.put(SOFTWARE_REVISION_STRING , "Manufacturer Name String");
|
||||
map.put(MANUFACTURER_NAME_STRING , "IEEE 11073-20601 Regulatory");
|
||||
map.put(IEEE_1107320601_REGULATORY , "Current Time");
|
||||
map.put(CURRENT_TIME , "Blood Pressure Measurement");
|
||||
map.put(BLOOD_PRESSURE_MEASUREMENT , "Intermediate Cuff Pressure");
|
||||
map.put(INTERMEDIATE_CUFF_PRESSURE , "Heart Rate Measurement");
|
||||
map.put(HEART_RATE_MEASUREMENT , "Body Sensor Location");
|
||||
map.put(BODY_SENSOR_LOCATION , "Heart Rate Control Point");
|
||||
map.put(HEART_RATE_CONTROL_POINT , "Alert Status");
|
||||
map.put(ALERT_STATUS , "Ringer Control Point");
|
||||
map.put(RINGER_CONTROL_POINT , "Ringer Setting");
|
||||
map.put(RINGER_SETTING , "Alert Category ID Bit Mask");
|
||||
map.put(ALERT_CATEGORY_ID_BIT_MASK , "Alert Category ID");
|
||||
map.put(ALERT_CATEGORY_ID , "Alert Notification Control Point");
|
||||
map.put(ALERT_NOTIFICATION_CONTROL_POINT , "Unread Alert Status");
|
||||
map.put(UNREAD_ALERT_STATUS , "New Alert");
|
||||
map.put(NEW_ALERT , "Supported New Alert Category");
|
||||
map.put(SUPPORTED_NEW_ALERT_CATEGORY , "Supported Unread Alert Category");
|
||||
map.put(SUPPORTED_UNREAD_ALERT_CATEGORY , "Blood Pressure Feature");
|
||||
map.put(BLOOD_PRESSURE_FEATURE , "PNPID");
|
||||
map.put(PNPID , "SC_CONTROL_POINT");
|
||||
map.put(SC_CONTROL_POINT , "CSC_MEASUREMENT");
|
||||
map.put(CSC_MEASUREMENT , "CSC_FEATURE");
|
||||
map.put(CSC_FEATURE , "SENSOR_LOCATION");
|
||||
map.put(SENSOR_LOCATION , "ActiveSync");
|
||||
map.put(ACTIVESYNC , "ActiveSync");
|
||||
map.put(ESTIMOTE_SERVICE , "Estimote Service");
|
||||
map.put(ESTIMOTE_UUID , "Estimote UUID");
|
||||
map.put(ESTIMOTE_MAJOR , "Estimote Major");
|
||||
map.put(ESTIMOTE_MINOR , "Estimote Minor");
|
||||
map.put(ESTIMOTE_BATTERY , "Estimote Battery");
|
||||
map.put(ESTIMOTE_TEMPERATURE , "Estimote Temperature");
|
||||
map.put(ESTIMOTE_POWER , "Estimote Power");
|
||||
map.put(ESTIMOTE_ADVERTISING_INTERVAL , "Estimote Advertising Interval");
|
||||
map.put(ESTIMOTE_VERSION_SERVICE , "Estimote Version Service");
|
||||
map.put(ESTIMOTE_SOFTWARE_VERSION , "Estimote Software Version");
|
||||
map.put(ESTIMOTE_HARDWARE_VERSION , "Estimote Hardware Version");
|
||||
map.put(ESTIMOTE_AUTHENTICATION_SERVICE , "Estimote Authentication Service");
|
||||
map.put(ESTIMOTE_ADVERTISING_SEED , "Estimote Advertising Seed");
|
||||
map.put(ESTIMOTE_ADVERTISING_VECTOR , "Estimote Advertising Vector");
|
||||
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.SparseArray;
|
||||
|
||||
public class AdRecordUtils {
|
||||
|
||||
public static String getRecordDataAsString(final AdRecord nameRecord) {
|
||||
if(nameRecord == null){return new String();}
|
||||
return new String(nameRecord.getData());
|
||||
}
|
||||
|
||||
public static byte[] getServiceData(final AdRecord serviceData) {
|
||||
if (serviceData == null) {return null;}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return null;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Chop out the uuid
|
||||
return Arrays.copyOfRange(raw, 2, raw.length);
|
||||
}
|
||||
|
||||
public static int getServiceDataUuid(final AdRecord serviceData) {
|
||||
if (serviceData == null) {return -1;}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return -1;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Find UUID data in byte array
|
||||
int uuid = (raw[1] & 0xFF) << 8;
|
||||
uuid += (raw[0] & 0xFF);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read out all the AD structures from the raw scan record
|
||||
*/
|
||||
public static List<AdRecord> parseScanRecordAsList(final byte[] scanRecord) {
|
||||
final List<AdRecord> records = new ArrayList<AdRecord>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length);
|
||||
|
||||
records.add(new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(records);
|
||||
}
|
||||
|
||||
@SuppressLint("UseSparseArrays")
|
||||
public static Map<Integer, AdRecord> parseScanRecordAsMap(final byte[] scanRecord) {
|
||||
final Map<Integer, AdRecord> records = new HashMap<Integer, AdRecord>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(records);
|
||||
}
|
||||
|
||||
public static SparseArray<AdRecord> parseScanRecordAsSparseArray(byte[] scanRecord) {
|
||||
final SparseArray<AdRecord> records = new SparseArray<AdRecord>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ByteUtils {
|
||||
|
||||
/** The Constant HEXES. */
|
||||
private static final String HEXES = "0123456789ABCDEF";
|
||||
|
||||
/**
|
||||
* Gets a pretty representation of a Byte Array as a HEX String.
|
||||
*
|
||||
* Sample output: [01, 30, FF, AA]
|
||||
*
|
||||
* @param array the array
|
||||
* @return the string
|
||||
*/
|
||||
public static String byteArrayToHexString(final byte[] array){
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
boolean firstEntry = true;
|
||||
sb.append('[');
|
||||
|
||||
for ( final byte b : array ) {
|
||||
if(!firstEntry){
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(HEXES.charAt((b & 0xF0) >> 4));
|
||||
sb.append(HEXES.charAt((b & 0x0F)));
|
||||
firstEntry = false;
|
||||
}
|
||||
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a byte arry starts with another byte array.
|
||||
*
|
||||
* @param array the array
|
||||
* @param prefix the prefix
|
||||
* @return true, if successful
|
||||
*/
|
||||
public static boolean doesArrayBeginWith(byte[] array, byte[] prefix){
|
||||
if(array.length < prefix.length){return false;}
|
||||
|
||||
for(int i = 0; i < prefix.length; i++){
|
||||
if(array[i] != prefix[i]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array with a length of 2 into an int
|
||||
*
|
||||
* @param input the input
|
||||
* @return the int from the array
|
||||
*/
|
||||
public static int getIntFrom2ByteArray(byte[] input){
|
||||
final byte[] result = new byte[4];
|
||||
|
||||
result[0] = 0;
|
||||
result[1] = 0;
|
||||
result[2] = input[0];
|
||||
result[3] = input[1];
|
||||
|
||||
return ByteUtils.getIntFromByteArray(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte to an int, preserving the sign.
|
||||
*
|
||||
* For example, FF will be converted to 255 and not -1.
|
||||
*
|
||||
* @param bite the bite
|
||||
* @return the int from byte
|
||||
*/
|
||||
public static int getIntFromByte(final byte bite){
|
||||
return Integer.valueOf(bite & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array to an int.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the int from byte array
|
||||
*/
|
||||
public static int getIntFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array to a long.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the long from byte array
|
||||
*/
|
||||
public static long getLongFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getLong();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inverts an array
|
||||
*
|
||||
* @param array the array
|
||||
* @return the byte[]
|
||||
*/
|
||||
public static byte[] invertArray(byte[] array){
|
||||
final int size = array.length;
|
||||
byte temp;
|
||||
|
||||
for (int i = 0; i < size/2; i++)
|
||||
{
|
||||
temp = array[i];
|
||||
array[i] = array[size-1 - i];
|
||||
array[size-1 - i] = temp;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
|
||||
public class IBeaconUtils {
|
||||
private static final double DISTANCE_THRESHOLD_WTF = 0.0;
|
||||
private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5;
|
||||
private static final double DISTANCE_THRESHOLD_NEAR = 3.0;
|
||||
|
||||
private static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = new byte[]{0x4C, 0x00, 0x02, 0x15};
|
||||
|
||||
public static IBeaconDistanceDescriptor getDistanceDescriptor(double accuracy){
|
||||
if(accuracy < DISTANCE_THRESHOLD_WTF){
|
||||
return IBeaconDistanceDescriptor.UNKNOWN;
|
||||
}
|
||||
|
||||
if(accuracy < DISTANCE_THRESHOLD_IMMEDIATE){
|
||||
return IBeaconDistanceDescriptor.IMMEDIATE;
|
||||
}
|
||||
|
||||
if(accuracy < DISTANCE_THRESHOLD_NEAR){
|
||||
return IBeaconDistanceDescriptor.NEAR;
|
||||
}
|
||||
|
||||
return IBeaconDistanceDescriptor.FAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the accuracy of an RSSI reading.
|
||||
*
|
||||
* The code was taken from {@link http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing}
|
||||
*
|
||||
* @param txPower the calibrated TX power of an iBeacon
|
||||
* @param rssi the RSSI value of the iBeacon
|
||||
* @return
|
||||
*/
|
||||
public static double calculateAccuracy(int txPower, double rssi) {
|
||||
if (rssi == 0) {
|
||||
return -1.0; // if we cannot determine accuracy, return -1.
|
||||
}
|
||||
|
||||
double ratio = rssi*1.0/txPower;
|
||||
if (ratio < 1.0) {
|
||||
return Math.pow(ratio,10);
|
||||
}
|
||||
else {
|
||||
final double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
|
||||
return accuracy;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} is an iBeacon;
|
||||
*
|
||||
* @param device a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} device.
|
||||
* @return
|
||||
*/
|
||||
public static boolean isThisAnIBeacon(BluetoothLeDevice device){
|
||||
return isThisAnIBeacon(
|
||||
device.getAdRecordStore().getRecordDataAsString(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether a Manufacturer Data byte array belongs to an iBeacon;
|
||||
*
|
||||
* @param scanRecord a Bluetooth LE device's manufacturerData.
|
||||
* @return
|
||||
*/
|
||||
public static boolean isThisAnIBeacon(byte[] manufacturerData){
|
||||
if(manufacturerData == null){return false;}
|
||||
|
||||
// An iBeacon record must be at least 25 chars long
|
||||
if(!(manufacturerData.length >= 25)){return false;}
|
||||
|
||||
if(ByteUtils.doesArrayBeginWith(manufacturerData, MANUFACTURER_DATA_IBEACON_PREFIX)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public enum IBeaconDistanceDescriptor{
|
||||
IMMEDIATE,
|
||||
NEAR,
|
||||
FAR,
|
||||
UNKNOWN,
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LimitedLinkHashMap<K, V> extends LinkedHashMap<K, V>{
|
||||
private static final long serialVersionUID = -5375660288461724925L;
|
||||
|
||||
private final int mMaxSize;
|
||||
|
||||
public LimitedLinkHashMap(int maxSize){
|
||||
super(maxSize + 1, 1, false);
|
||||
mMaxSize = maxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
|
||||
return this.size() > mMaxSize;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="src" path=".apt_generated">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
@@ -1,3 +0,0 @@
|
||||
<factorypath>
|
||||
<factorypathentry kind="WKSPJAR" id="/Bluetooth LE Scanner/libs/butterknife-4.0.1.jar" enabled="true" runInBatchMode="false"/>
|
||||
</factorypath>
|
||||
7
sample_app/.gitignore
vendored
@@ -1,6 +1 @@
|
||||
/bin
|
||||
/gen
|
||||
local.properties
|
||||
.idea/
|
||||
lint.xml
|
||||
/.apt_generated
|
||||
/build
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Bluetooth LE Scanner</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,4 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.apt.aptEnabled=true
|
||||
org.eclipse.jdt.apt.genSrcDir=.apt_generated
|
||||
org.eclipse.jdt.apt.reconcileEnabled=true
|
||||
@@ -1,5 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.processAnnotations=enabled
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
64
sample_app/build.gradle
Normal file
@@ -0,0 +1,64 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
final int versionMajor = 1
|
||||
final int versionMinor = 1
|
||||
final int versionPatch = 1
|
||||
final int androidVersionCode = 7
|
||||
|
||||
final int targetSdk = rootProject.targetSdkVersion;
|
||||
final int minSdkRed = rootProject.minSdkVersion;
|
||||
final String semanticVersion = "${versionMajor}.${versionMinor}.${versionPatch}"
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "https://repo.commonsware.com.s3.amazonaws.com"
|
||||
}
|
||||
|
||||
maven {
|
||||
url "https://s3.amazonaws.com/repo.commonsware.com"
|
||||
}
|
||||
|
||||
maven {
|
||||
url "https://dl.bintray.com/alt236/maven"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
compile project(':library')
|
||||
|
||||
compile 'com.jakewharton:butterknife:7.0.1'
|
||||
compile 'com.android.support:appcompat-v7:24.2.0'
|
||||
compile 'com.android.support:recyclerview-v7:24.2.0'
|
||||
compile 'com.anthonycr.grant:permissions:1.0'
|
||||
compile 'uk.co.alt236:easycursor-android:1.0.0'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-all:1.9.5'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.compileSdkVersion
|
||||
buildToolsVersion rootProject.buildToolsVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion minSdkRed
|
||||
targetSdkVersion targetSdk
|
||||
versionCode androidVersionCode
|
||||
versionName semanticVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 41 KiB |
@@ -1,11 +1,8 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
# in /home/alex/Dev/android-sdk-linux/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
@@ -1,15 +0,0 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=Google Inc.:Google APIs:19
|
||||
android.library.reference.1=../library
|
||||
|
Before Width: | Height: | Size: 445 B |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 295 B |