Download a stream of data to a peripheral over BLE.
Dependencies: BLE_API mbed nRF51822
A simple demonstration of downloading a stream onto a peripheral over BLE. There's a corresponding Python script to driver the client.
Diff: sendStream.py
- Revision:
- 0:4eaf82806f06
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sendStream.py Mon Aug 18 16:03:22 2014 +0000 @@ -0,0 +1,91 @@ +#!/usr/bin/python +# +# This is a very simple test driver for demonstrating the StreamDownloader. + +import pexpect +import sys +import time +import select +import re +import struct + +class StreamDownloaderClient(object): + """docstring for StreamDownloaderClient""" + def __init__(self, bluetoothAddr, length): + super(StreamDownloaderClient, self).__init__() + self.bluetoothAddr = bluetoothAddr + + self.con = pexpect.spawn('gatttool -b ' + bluetoothAddr + ' --interactive -t random') + self.con.expect('\[LE\]>', timeout=600) + + self.con.sendline('connect') + self.con.expect('\[CON\]\[.+\]\[LE\]>') + print('connected') + + # ensure that we've got the correct primary service available + self.con.sendline('primary') + self.con.expect('\[CON\]\[.+\]\[LE\]>') + self.con.expect('\[CON\]\[.+\]\[LE\]>') + + emptyString = re.compile('^\s*$') + for line in self.con.before.decode('utf-8').split('\r\n'): + m = re.match('^attr handle: (0x[\dabcdef]{4}).*adc710c2-acdc-4bf5-8244-3ceaaa0f87f5.*', line) + if m: + break + if not m: + self.disconnect() + + self.serviceHandle = m.group(1) + print('discovered service handle as ' + self.serviceHandle) + + self.discoverCharHandles() + self.sendFileInfoBlock(length) + for blocknum in range(64): + self.sendFileDataBlock(blocknum) + + self.disconnect() + + def discoverCharHandles(self): + self.con.sendline('characteristics ' + self.serviceHandle) + self.con.expect('\[CON\]\[.+\]\[LE\]>') + self.con.expect('\[CON\]\[.+\]\[LE\]>') + for line in self.con.before.decode('utf-8').split('\r\n'): + uuidRe = re.compile('.* char value handle: (0x[\dabcdef]{4}).*uuid: adc710c2\-(\w{4}).*') + m = uuidRe.match(line) + if m: + if m.group(2) == 'acdf': + self.transferFileInfoHandle = m.group(1) + print("transferFileInfoHandle: " + self.transferFileInfoHandle) + elif m.group(2) == 'ace0': + self.transferFileBlockHandle = m.group(1) + print("transferFileBlockHandle: " + self.transferFileBlockHandle) + + def sendFileInfoBlock(self, length): + print("setup fileInfoBlock for transferring {} bytes".format(length)) + + writeCommand = 'char-write-req ' + self.transferFileInfoHandle + ' ' + for c in struct.pack('<HH', length, 0): + writeCommand = writeCommand + '{:02x}'.format(c) + self.con.sendline(writeCommand) + self.con.expect('\[CON\]\[.+\]\[LE\]> Characteristic value was written successfully', timeout=200) + + def sendFileDataBlock(self, blocknum): + print("will send command for block {}".format(blocknum)) + + writeCommand = 'char-write-req ' + self.transferFileBlockHandle + ' ' + for c in struct.pack('<HBBBBBBBBBBBBBBBB', blocknum, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15): + writeCommand = writeCommand + '{:02x}'.format(c) + self.con.sendline(writeCommand) + self.con.expect('\[CON\]\[.+\]\[LE\]> Characteristic value was written successfully', timeout=200) + + def disconnect(self): + self.con.sendline('disconnect') + self.con.expect('\[\s+\]\[.+\]\[LE\]>') + +def main(): + bluetoothAddr = "CC:59:FD:D8:3B:A9" # update as necessary + + target = StreamDownloaderClient(bluetoothAddr, 1024) + +if __name__ == "__main__": + main()