Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2016 The Cellule
Copyright (c) 2017 The Cellule

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
71 changes: 70 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,72 @@
=============
python-bleson
=============
=============

Status
======

Experimental.


Public API
==========

Outline of the 'bleson' Python packages an end-user would use to play with Bluetooth LE.

.. code:: python

bleson
get_provider() # Obtain the provider for the current platfrom (currently Linux HCI only)

bleson.core.types # Value objects representing Bluetooth Core Spec data types (not HCI specific)
BDAddress
Device
Advertisement

bleson.core.roles # Core Bluetooth roles
Advertiser
Observer

bleson.beacons.eddystone
EddystoneBeacon # Physical Web beacon, is a subclass of Advertiser role

bleson.logger
log # Simple convenience wrapper around Python's standard logging.



Examples
========

Please see 'examples' folder for more details.
Examples prefixed with 'basic_' shows basic Bleson API usage.
Examples prefixed with 'context_' shows Blesons context maanger ('with' keyword) API usage.


Example - Advertiser
--------------------

Shows how to create custom advertisement.

Example - Eddystone Beacon
--------------------------

Shows how to setup a Physical Web beacon

Example - Observer
------------------

Shows how to scan for local devices.


Tests
=====

Please see the 'tests' folder.


Internal API
============

To be continued...

7 changes: 7 additions & 0 deletions bleson/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from .providers import get_provider
from .core.roles import *
from .core.types import *
from .beacons.eddystone import *
from .logger import set_level
from .core.hci.constants import *

Empty file added bleson/beacons/__init__.py
Empty file.
103 changes: 103 additions & 0 deletions bleson/beacons/eddystone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from bleson.core.roles import Advertiser
from bleson.core.types import Advertisement
from bleson.logger import log


class EddystoneBeacon(Advertiser):

def __init__(self, adapter, url=None):
super().__init__(adapter)
self.advertisement=Advertisement()
self.url = url

@property
def url(self):
return self._url

@url.setter
def url(self, url):
self._url = url
if url:
self.advertisement.raw_data=self.eddystone_url_adv_data(url)
log.debug("Beacon Adv raw data = {}".format(self.advertisement.raw_data))

# -------------------------------------------
# Eddystone (pretty much as-is from the Google source)
# see: https://github.com/google/eddystone/blob/master/eddystone-url/implementations/PyBeacon/PyBeacon/PyBeacon.py

schemes = [
"http://www.",
"https://www.",
"http://",
"https://",
]

extensions = [
".com/", ".org/", ".edu/", ".net/", ".info/", ".biz/", ".gov/",
".com", ".org", ".edu", ".net", ".info", ".biz", ".gov",
]

@classmethod
def encode_url(cls, url):
i = 0
data = []

for s in range(len(cls.schemes)):
scheme = cls.schemes[s]
if url.startswith(scheme):
data.append(s)
i += len(scheme)
break
else:
raise Exception("Invalid url scheme")

while i < len(url):
if url[i] == '.':
for e in range(len(cls.extensions)):
expansion = cls.extensions[e]
if url.startswith(expansion, i):
data.append(e)
i += len(expansion)
break
else:
data.append(0x2E)
i += 1
else:
data.append(ord(url[i]))
i += 1

return data

@classmethod
def eddystone_url_adv_data(cls, url):
log.info("Encoding URL for Eddystone beacon: '{}'".format(url))
encodedurl = cls.encode_url(url)
encodedurlLength = len(encodedurl)

if encodedurlLength > 18:
raise ValueError("Encoded url length {} is > 18 maximum length.".format(encodedurlLength))

message = [
0x02, # Flags length
0x01, # Flags data type value
0x1a, # Flags data

0x03, # Service UUID length
0x03, # Service UUID data type value
0xaa, # 16-bit Eddystone UUID
0xfe, # 16-bit Eddystone UUID

5 + len(encodedurl), # Service Data length
0x16, # Service Data data type value
0xaa, # 16-bit Eddystone UUID
0xfe, # 16-bit Eddystone UUID

0x10, # Eddystone-url frame type
0xed, # txpower
]

message += encodedurl

return bytearray(message)


Empty file added bleson/core/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions bleson/core/hci/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .constants import *
from .types import *


Loading