Skip to content

Commit

Permalink
sync
Browse files Browse the repository at this point in the history
  • Loading branch information
andete committed Mar 4, 2014
1 parent 5553a52 commit 387526b
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 38 deletions.
12 changes: 5 additions & 7 deletions ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,14 @@ def data_to_string(self, data):
def read_handle(self, handle, chandle):
self.send_command(self.ble.ble_cmd_attclient_read_by_handle(handle, chandle))

def read_handles(self, handle, h1, h2):
for x in range(h1, h2+1):
self.send_command(self.ble.ble_cmd_attclient_read_by_handle(handle, x))

def handle_attclient_attribute_value(self, sender, args):
chandle = args['atthandle']
handle = args['connection']
t = args['type']
value = args['value']
self.attr_value.emit(handle, chandle, t, value)

# https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
GAP_AD_TYPE_FLAGS = 0x01
GAP_AD_TYPE_LOCALNAME_COMPLETE = 0x09
GAP_AD_TYPE_TX_POWER = 0x0A
GAP_AD_TYPE_SLAVE_CON_INTERVAL_RANGE = 0x12
GAP_AD_TYPE_VENDOR = 0xFF
self.ble.check_activity(self.ser, 1)
11 changes: 7 additions & 4 deletions data/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import services, productize, texas_instruments
from printers import print_default
from printers import print_default, print_uuid

class UUID:

Expand All @@ -15,9 +15,9 @@ def __init__(self):
self.attr_by_uuid = {}
for v in self.attr.values():
if len(v) == 2:
self.attr_by_uuid[v[0]] = (v[1], print_default)
self.attr_by_uuid[print_uuid(v[0])] = (v[1], print_default)
else:
self.attr_by_uuid[v[0]] = (v[1], v[2])
self.attr_by_uuid[print_uuid(v[0])] = (v[1], v[2])

def vendor_to_string(self, data):
vendor_id = data[0] + 256*data[1]
Expand All @@ -27,4 +27,7 @@ def vendor_to_string(self, data):
return "vendor:%04X" % vendor_id

def value_to_string_by_uuid(self, uuid, value):
return self.attr_by_uuid[uuid][2](value)
return self.attr_by_uuid[print_uuid(uuid)][1](value)

def name_by_uuid(self, uuid):
return self.attr_by_uuid[print_uuid(uuid)][0]
15 changes: 14 additions & 1 deletion data/printers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
def print_uuid(val):
return ''.join(["%02X" % x for x in val])
return ''.join(["%02X" % x for x in reversed(val)])

def print_string(val):
return ''.join(["%c" % x for x in val])

def print_default(val):
return str(val)

def print_char(val):
prop = val[0]
props = []
if prop & 0x1 > 0: props += ['Broadcast']
if prop & 0x2 > 0: props += ['Read']
if prop & 0x4 > 0: props += ['WriteNR']
if prop & 0x8 > 0: props += ['Write']
if prop & 0x10 > 0: props += ['Notify']
if prop & 0x20 > 0: props += ['Indicate']
if prop & 0x40 > 0: props += ['SWrite']
if prop & 0x80 > 0: props += ['EProp']
prop = '|'.join(props)
return "%s %d %s" % (prop, val[1] + 256*val[2], print_uuid(val[3:]))
7 changes: 4 additions & 3 deletions data/services.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from import printers import print_uuid, print_string
from printers import print_uuid, print_string, print_char

service = dict(

Expand Down Expand Up @@ -32,10 +32,10 @@
primary = ([0x28, 0x00], "Primary", print_uuid),
secundary = ([0x28, 0x01], "Secundary", print_uuid),
include = ([0x28, 0x02], "Include", print_uuid),
char = ([0x28, 0x03], "Characteristic"),
char = ([0x28, 0x03], "Characteristic", print_char),

chr_e_pro = ([0x29, 0x00], "Characteristic Extented Properties"),
chr_u_dsc = ([0x29, 0x01], "Characteristic User Description"),
chr_u_dsc = ([0x29, 0x01], "Characteristic User Description", print_string),
chr_c_cnf = ([0x29, 0x02], "Client Characteristic Configuration"),
chr_s_cnf = ([0x29, 0x03], "Server Characteristic Configuration"),
chr_p_for = ([0x29, 0x04], "Characteristic Presentation Format"),
Expand All @@ -49,6 +49,7 @@
per_pri_f = ([0x2A, 0x02], "Peripheral Privacy Flag"),
reconnect = ([0x2A, 0x03], "Reconnection Address"),
per_pref_ = ([0x2A, 0x04], "Peripheral Preferred Connection Parameters"),
service_c = ([0x2A, 0x05], "Service Changed"),
)

class Vendor:
Expand Down
57 changes: 34 additions & 23 deletions gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ def _add(text, slot = None):
if slot != None: action.triggered.connect(slot)
else: action.setDisabled(True)
_add('&Read', self.read)
_add('&Write', self.write)
self.view.setRootIsDecorated(False)
self.model = QtGui.QStandardItemModel()
self.model.setColumnCount(5)
self.model.setHorizontalHeaderLabels(['type', 'service/type','name','handle', 'value'])
self.root = self.model.invisibleRootItem()
self.view.setModel(self.model)
#self.view.doubleClicked.connect(self.double_click)
self.view.doubleClicked.connect(self.double_click)
self.selection_model = QtGui.QItemSelectionModel(self.model, self.view)
self.view.setSelectionModel(self.selection_model)
self.selection_model.currentRowChanged.connect(self.row_changed)
Expand All @@ -43,26 +44,35 @@ def row_changed(self, current, previous):
self.current = current

def read(self):
return self.read2(False)

def double_click(self):
return self.read2(True)

def read2(self, double_click):
parent = self.model.itemFromIndex(self.current.parent())
if parent is None:
if double_click: return
t = self.root.child(self.current.row(), 0).data(Qt.DisplayRole)
else:
t = parent.child(self.current.row(), 0).data(Qt.DisplayRole)
if t == 'attr':
chandle = int(parent.child(self.current.row(), 3).data(Qt.DisplayRole))
self.ble.read_handle(self.handle, chandle)
elif t == 'primary':
handles = self.root.child(self.current.row(), 3).data(Qt.DisplayRole)
[h1, h2] = handles.split('-')
h1 = int(h1)
h2 = int(h2)
self.ble.read_handles(self.handle, h1, h2)

def write(self):
parent = self.model.itemFromIndex(self.current.parent())
if parent is None: return
t = parent.child(self.current.row(), 0).data(Qt.DisplayRole)
if t == 'char':
if t == 'attr':
chandle = int(parent.child(self.current.row(), 3).data(Qt.DisplayRole))
self.ble.read_handle(self.handle, chandle)

"""
def double_click(self):
if self.current is None: return
current = self.current
print current, current.parent()
while current.parent() != QtCore.QModelIndex():
current = current.parent()
print current, current.parent()
for i in range(self.root.rowCount()):
child = self.root.child(i, 0).index()
print "child: ", child, current
self.view.setExpanded(child, child == current)
"""
print "write to ", chandle

def primary(self):
self.type = 'primary'
Expand Down Expand Up @@ -120,15 +130,14 @@ def s(x):
y.setEditable(False)
return y
uuids = ''.join(["%02X" % c for c in uuid])
name = ''
for (i, n) in self.ble.uuid.attr.values():
if i == uuid:
name = n
break
try:
name = self.ble.uuid.name_by_uuid(uuid)
except:
name = ''
svalue = s('')
self.chandle_to_value_item[char] = svalue
self.chandle_to_uuid[char] = uuid
self.model.item(self.scan_pos).appendRow([s("char"), s(uuids), s(name), s(str(char)), svalue])
self.model.item(self.scan_pos).appendRow([s("attr"), s(uuids), s(name), s(str(char)), svalue])
#self.view.expandAll()

def attr_value(self, chandle, t, value):
Expand Down Expand Up @@ -284,6 +293,7 @@ def connection_status(self, handle, mac, status):
self.handle_to_mac[handle] = mac
self.qtab.setCurrentIndex(idx)
self.running = self.PROC_PRIMARY
QtGui.QApplication.setOverrideCursor(Qt.WaitCursor)
device.primary()
self.status("service discovery running")
self.ble.primary_service_discovery(handle)
Expand Down Expand Up @@ -317,6 +327,7 @@ def procedure_completed(self, handle):
device.scan()
elif self.running == self.PROC_ATTR:
if not device.continue_scan():
QtGui.QApplication.restoreOverrideCursor()
self.running = self.PROC_IDLE
self.status("Idle.")

Expand Down

0 comments on commit 387526b

Please sign in to comment.