-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathintegrate-your-mobile-app.html
255 lines (255 loc) · 20.7 KB
/
integrate-your-mobile-app.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
<!DOCTYPE HTML>
<html>
<head>
<title>diyActive: Integrate your Mobile App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Use reelyActive open source mobile SDKs to make your app discoverable via Bluetooth Low Energy (BLE). Eddystone works too!">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="style/main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="js/diyactive.js"></script>
</head>
<body>
<body ng-app="diyActive">
<div ng-controller="InteractionCtrl">
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle"
ng-init="navCollapsed = true"
ng-click="navCollapsed = !navCollapsed">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="https://www.reelyactive.com">
<strong>reely</strong>Active
</a>
</div>
<div class="collapse navbar-collapse" ng-class="!navCollapsed && 'in'"
ng-click="navCollapsed = true">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="index.html"> diyActive </a></li>
<li class="dropdown" dropdown on-toggle="toggled(open)">
<a href class="dropdown-toggle" dropdown-toggle role="button"
data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
Quick links <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>
<a href="https://github.com/reelyactive/" target="_blank">
reelyActive on GitHub
</a>
</li>
<li>
<a href="https://www.npmjs.com/~reelyactive" target="_blank">
reelyActive on npmjs
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="https://www.reelyactive.com" target="_blank">
reelyActive website
</a>
</li>
<li>
<a href="https://getpareto.com" target="_blank">
Pareto by reelyActive
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="https://shop.reelyactive.com" target="_blank">
Our online store
</a>
</li>
<li>
<a href="https://reelyactive.com/blog/" target="_blank">
Our blog
</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-xs-0 col-sm-1 col-md-2 col-lg-3"></div>
<div class="col-xs-12 col-sm-10 col-md-8 col-lg-6">
<h1> Integrate your Mobile App </h1>
<p> Mobile applications can seamlessly integrate with reelyActive Smart Spaces using Bluetooth Low Energy (BLE) technology. Apple devices since the iPhone 4S support BLE, and more recent Android devices, as well as those of other platforms, also support this technology. </p>
<h2> Get started with reelyApp </h2>
<p> Our mobile app, called reelyApp, demonstrates the functionality of our <a href="#mobileSDKs">mobile SDKs</a> for iOS and Android. </p>
<p class="text-center">
<a href="https://play.google.com/store/apps/details?id=com.reelyactive.reelyapp&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"><img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" height="60px"/></a>
<a href="https://itunes.apple.com/us/app/reelyapp-for-ios/id1121042765"><img alt="Download on the App Store" src="images/Download_on_the_App_Store_Badge_US-UK_135x40.svg"/></a>
</p>
<a id="mobileSDKs"></a>
<h2> Our mobile SDKs </h2>
<p> <i>Who doesn't love open source SDKs?</i> Ours are maintained by our partners at <a href="http://sidereo.com" target="_blank">Sidereo</a> and currently support the following mobile platforms:
<ul>
<li> <b>Android:</b>
<a href="https://github.com/reelyactive/ble-android-sdk/" target="_blank">SDK</a> |
<a href="http://reelyactive.github.io/ble-android-sdk/" target="_blank">Documentation</a>
<li> <b>iOS:</b>
<a href="https://github.com/reelyactive/ble-ios-sdk/" target="_blank">SDK</a>
</ul>
Read on to understand what these SDKs are doing behind the scenes.
</p>
<h2> Toward Mutual Assured Detection </h2>
<p> This tutorial is divided based on how the mobile device and the reelyActive infrastructure discover one another, either:
<ul>
<li> <a href="#reelToMobile">the reelyActive infrastructure advertises itself to the mobile device</a>, <i>or</i>
<li> <a href="#mobileToReel">the mobile device advertises itself to the reelyActive infrastructure</a>, <i>or</i>
<li> <a href="#reelMobileHybrid">both happen in harmony</a>
</ul>
Confused? First watch this two-minute video:
</p>
<div class="embed-container"><iframe src="https://www.youtube.com/embed/CsYNHXSlVQY?rel=0&controls=0&showinfo=0&modestbranding" frameborder="0" allowfullscreen></iframe></div>
<p> For even more detail, read our blog post: <a href="http://reelyactive.com/blog/archives/158" target="_blank">Radio location demystified</a>. </p>
<a id="reelToMobile"></a>
<h2> reelyActive advertises ➞ mobile device </h2>
<img src="images/reelToMobile.png"
class="img-responsive center-block">
<p> Our Bluetooth Low Energy reelceivers continuously advertise the following information which can be decoded by any listening Bluetooth Low Energy devices in range: </p>
<code> completeLocalName: reelyActive </code> <br>
<code> 128-bit UUID: 7265656c794163746976652055554944 </code> <br>
<code> EUI-64 identifier (Service Data): 001bc5094xxxxxxx </code> <br>
<code> MAC address: xx:xx:xx:xx:xx:xx </code> <br>
<p> The completeLocalName and 128-bit UUID are generic to all reelceivers, while the EUI-64 and MAC uniquely identify each reelceiver (hence the x values above). </p>
<h3> How do I make use of this in my app? </h3>
<p> Your app can discover the context of its current location and all the other devices present in just four steps:
<ol>
<li> subscribe to the reelyActive 128-bit UUID
<li> when a reelceiver is detected (by its UUID)
<ul>
<li> determine which reelceiver is detected with the greatest signal strength (RSSI)
<li> take the EUI-64 identifier of that reelceiver
</ul>
<li> query our contextual API (<a href="https://www.npmjs.org/package/chickadee" target="_blank">chickadee</a>) based on that EUI-64 identifier
<li> extract all the data of interest from the query response
</ol>
</p>
<p> There are third-party apps which detect Bluetooth Low Energy devices in range, such as our reelceivers. For iOS devices, you can use the <a href="https://itunes.apple.com/ca/app/lightblue-bluetooth-low-energy/id557428110" target="_blank">LightBlue app</a> for inspiration, and for Android devices try <a href="https://play.google.com/store/apps/details?id=uk.co.alt236.btlescan">Bluetooth LE Scanner</a>.
<a id="mobileToReel"></a>
<h2> Mobile device advertises ➞ reelyActive </h2>
<img src="images/mobileToReel.png"
class="img-responsive center-block">
<p> Currently, iOS devices since the iPhone 4S and more recent Android devices support Bluetooth Low Energy peripheral mode which allows the spontaneous transmission of advertising packets (which can be detected by our reelceivers). <i>Nonetheless,</i> there's still a clever way to get devices from other platforms to integrate with reelyActive infrastructure: <a href="#reelMobileHybrid">read the next section!</a> </p>
<p> In order for the mobile device to fully integrate with our infrastructure, it needs to transmit advertising data that allows it to be uniquely identified. There are a few options, each described in a subsection below. </p>
<a id="advertiseAService"></a>
<h3> Advertise a service </h3>
<p> Our mobile SDKs allow you to specify a 128-bit UUID, also known as a service, to identify your app, or even individual users. This can be accompanied by another <a href="https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile" target="_blank">Advertising Data Type</a>. For instance, the completeLocalName Advertising Data Type could complement the UUID as follows: </p>
<code> UUID: 128-bits </code> <br>
<code> completeLocalName: an ASCII string </code> <br>
<p> Our Bluetooth Low Energy reelceivers decipher each of these, so the app need only transmit some combination of the two which makes the device uniquely identifiable. In this case, here's what our API will return (some fields trimmed for clarity): </p>
<code> identifier: { </code> <br>
<code> type: "ADVA-48", </code> <br>
<code> value: "123456789abc", </code> <br>
<code> advHeader: { txAdd: "random" }, </code> <br>
<code> advData: { </code> <br>
<code> complete128BitUUIDs: "a114b00bie5888a114b00bie5888caca" </code> <br>
<code> completeLocalName: "barnowl" </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<p> For Android, consult the documentation related to the <a href="https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html#startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback)" target="_blank">startAdvertising()</a> function. </p>
<p> As you can see, the API allows the mobile device to be uniquely identified by the UUID and completeLocalName. Notice also that it identifies the mobile device by its 48-bit advertiser address (123456789abc), however, the <i>txAdd: "random"</i> flag indicates that this address isn't constant. In other words, the advertiser address can be expected to change over time. </p>
<p> To complete the integration, you would <a href="http://www.reelyactive.com/contact/" target="_blank">contact us</a> so that we can update <a href="https://www.npmjs.org/package/chickadee" target="_blank">chickadee</a> (our contextual API) to associate your UUID with the URL of an API that <i>you</i> would host. Users of our API would then be pointed to, for example, <i>http://yourapi.com/completeLocalName</i> to access metadata associated with your app user. </p>
<h4> reelyApp UUIDs </h4>
<p> reelyApp for Android advertises <tt>7265656c7941707020416e64726f6964</tt> </p>
<p> reelyApp for iOS advertises <tt>7265656c7941707020666f7220694f53</tt> </p>
<p> Both of these feature defined associations in <a href="https://www.npmjs.org/package/chickadee" target="_blank">chickadee</a>. </p>
<a id="iBeacons"></a>
<h3> iBeacons </h3>
<p> An iOS device can send iBeacons packets which contain, among other things, the following data: </p>
<code> UUID: 128-bits </code> <br>
<code> Major ID: 16-bits </code> <br>
<code> Minor ID: 16-bits </code> <br>
<p> Our Bluetooth Low Energy reelceivers decipher each of these identifiers, so the app need only transmit some combination of the three which makes the device uniquely identifiable. An app will typically use a single UUID and then assign non-conflicting major and minor values to all participating devices. </p>
<p> For instance, if you use the <a href="https://itunes.apple.com/ca/app/locate-beacon/id738709014" target="_blank">Radius Networks Locate Beacon app</a> and select the iBeacon Transmitter option with major set to 0 and minor set to 1, our API will return the following (some fields trimmed for clarity): </p>
<code> identifier: { </code> <br>
<code> type: "ADVA-48", </code> <br>
<code> value: "123456789abc", </code> <br>
<code> advHeader: { txAdd: "random" }, </code> <br>
<code> advData: { </code> <br>
<code> manufacturerSpecificData: { </code> <br>
<code> iBeacon: { </code> <br>
<code> uuid: "1675e3a3932a458c9ed907a290622635", </code> <br>
<code> major: "0000", </code> <br>
<code> minor: "0001", </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<p> As you can see, the API allows the mobile device to be uniquely identified by the UUID, major and minor. Notice also that it identifies the mobile device by its 48-bit advertiser address (123456789abc), however, the <i>txAdd: "random"</i> flag indicates that this address isn't constant. In other words, the advertiser address can be expected to change over time. </p>
<p> To complete the integration, you would <a href="http://www.reelyactive.com/contact/" target="_blank">contact us</a> so that we can update <a href="https://www.npmjs.org/package/chickadee" target="_blank">chickadee</a> (our contextual API) to associate your UUID with the URL of an API that <i>you</i> would host. Users of our API would then be pointed to, for example, <i>http://yourapi.com/majorminor</i> to access metadata associated with your app user. </p>
<a id="uriBeacon"></a>
<h3> UriBeacon </h3>
<p> An appealing alternative which avoids vendor-lock-in and seamlessly integrates with our platform is the UriBeacon service. This service includes a URL in the advertising packet, which <a href="https://www.npmjs.org/package/barnowl" target="_blank">barnowl</a> can automatically decode, eliminating the need for creating an explicit association via <a href="https://www.npmjs.org/package/chickadee" target="_blank">chickadee</a>. The UriBeacon packet includes: </p>
<code> 16-bit UUID: fed8 </code> <br>
<code> Service data: an encoded URI/URL </code> <br>
<p> The UriBeacon service is part of <a href="http://google.github.io/physical-web/" target="_blank">the Google Physical Web project</a>, and you can find source code for mobile applications on their <a href="https://github.com/google/physical-web" target="_blank">GitHub page</a>. Here's what our API will return (some fields trimmed for clarity): </p>
<code> identifier: { </code> <br>
<code> type: "ADVA-48", </code> <br>
<code> value: "123456789abc", </code> <br>
<code> advHeader: { txAdd: "random" }, </code> <br>
<code> advData: { </code> <br>
<code> serviceData: { </code> <br>
<code> uuid: "fed8" </code> <br>
<code> data: "00f2027265656c7961637469766507" </code> <br>
<code> uriBeacon: { </code> <br>
<code> invisibleHint: false </code> <br>
<code> txPower: "-14dBm" </code> <br>
<code> url: "http://reelyactive.com" </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<p> As you can see, the URL is right there in the packet. How convenient! </p>
<a id="eddystone"></a>
<h3> Eddystone </h3>
<p> Eddystone is another Google project which is an evolution of UriBeacon. It features a variety of frame types including <a href="https://github.com/google/eddystone/tree/master/eddystone-eid" target="_blank">Ephemeral ID (EID)</a> with enhanced security and privacy. Documentation can be found <a href="https://github.com/google/eddystone" target="_blank">here</a>. </p>
<a id="reelMobileHybrid"></a>
<h2> Hybrid bliss: reelyActive ⇄ mobile device </h2>
<img src="images/reelMobileHybrid.png"
class="img-responsive center-block">
<p> Our Bluetooth Low Energy reelceivers continuously advertise themselves to mobile devices in range using an ADV_DISCOVER_IND packet. What's special about this type of packet is that it encourages nearby "curious" devices, like smartphones, to send a SCAN_REQ packet, which the reelceiver quickly follows up with a SCAN_RESP packet. This mechanism is part of the Bluetooth Core Specification. </p>
<p> <i>Why should we care?</i> Well, the SCAN_REQ packet contains the mobile device's 48-bit advertiser address, and, in many cases, this is the device's static Bluetooth MAC address. If so, the reelyActive platform can uniquely identify the device simply because it scanned for Bluetooth devices! </p>
<p> For instance, here's what our API will return when a mobile device sends a SCAN_REQ (some fields trimmed for clarity): </p>
<code> identifier: { </code> <br>
<code> type: "ADVA-48", </code> <br>
<code> value: "123456789abc", </code> <br>
<code> advHeader: { </code> <br>
<code> type: "SCAN_REQ", </code> <br>
<code> txAdd: "public" </code> <br>
<code> } </code> <br>
<code> } </code> <br>
<p> As you can see, the API allows the mobile device to be uniquely identified by its 48-bit advertiser address (123456789abc) because, in this case, the <i>txAdd: "public"</i> flag indicates that this address is constant (it is uniquely assigned by the IEEE). All your app needs to do is to periodically run a Bluetooth scan (like <a href="https://play.google.com/store/apps/details?id=uk.co.alt236.btlescan">Bluetooth LE Scanner</a> does) so that it can be discovered by nearby reelceivers. </p>
<p> For Android, consult the documentation related to the <a href="https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html#startScan(android.bluetooth.le.ScanCallback)" target="_blank">startScan()</a> function. </p>
<div class="embed-container"><iframe src="https://www.youtube.com/embed/eamCXiNkUuE?rel=0&controls=0&showinfo=0&modestbranding" frameborder="0" allowfullscreen></iframe></div>
<h2> What's next? </h2>
<p> Platform-specific instructions will continue to be added, be sure to check back! </p>
<p class="text-center">
<a class="btn btn-default" href="integrate-your-service.html"
role="button"> Integrate your Service </a>
<a class="btn btn-default" href="integrate-your-product.html"
role="button"> Integrate your Product </a>
<a class="btn btn-success" href="index.html"
role="button"> Return to diyActive </a>
</p>
</div>
<div class="col-xs-0 col-sm-1 col-md-2 col-lg-3"></div>
</div>
</div>
<footer class="footer">
<a href="/"> diyActive </a> |
<a href="https://www.reelyactive.com">
© reelyActive 2014-2018
</a>
</footer>
</div>
</body>
</html>