73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
#!/usr/bin/python2
|
|
|
|
# Dennis Heinze
|
|
|
|
import binascii
|
|
import struct
|
|
|
|
from pwnlib import log
|
|
|
|
from internalblue.utils.packing import p16
|
|
|
|
|
|
class L2CAPManager:
|
|
def __init__(self, btconn, mtu=0x30):
|
|
self.connection = btconn
|
|
|
|
self.connection.registerACLHandler(self._receptionHandler)
|
|
|
|
# cidHandlers is a map from CID -> function array
|
|
self.cidHandlers = {}
|
|
self.handlers = []
|
|
self.mtu = mtu
|
|
|
|
def sendData(self, data, cid):
|
|
data_len = len(data)
|
|
# if data_len > mtu
|
|
log.debug("Sent L2CAP data to channel: %d, data: %s", cid, binascii.hexlify(data))
|
|
self.connection.sendACL(p16(data_len) + p16(cid) + data)
|
|
|
|
def registerHandler(self, handler):
|
|
self.handlers.append(handler)
|
|
log.debug("Registered L2CAP handler")
|
|
|
|
def registerCIDHandler(self, handler, cid):
|
|
if cid not in self.cidHandlers:
|
|
self.cidHandlers[cid] = []
|
|
|
|
self.cidHandlers[cid].append(handler)
|
|
log.debug("Registered L2CAP handler for CID %d", cid)
|
|
|
|
def _receptionHandler(self, data):
|
|
if len(data) > 5:
|
|
l2cap_data = data[5:]
|
|
else:
|
|
log.debug("Received invalid L2CAP data at handler: %s", data)
|
|
return
|
|
|
|
# prioritize specific CID handlers
|
|
(length, cid) = struct.unpack_from("hh", l2cap_data)
|
|
log.debug("Received L2CAP data for cid: %d, %s", cid, binascii.hexlify(l2cap_data))
|
|
if cid in self.cidHandlers:
|
|
for handler in self.cidHandlers[cid]:
|
|
handler(l2cap_data[4:])
|
|
|
|
for handler in self.handlers:
|
|
handler(l2cap_data[4:])
|
|
|
|
|
|
class L2CAPSignalChannel:
|
|
def __init__(self, chanman):
|
|
self.chanman = chanman
|
|
self.chanman.registerCIDHandler(0x01, self._receptionHandler)
|
|
|
|
def sendCFrameRaw(self, code, identifier, length, data):
|
|
self.chanman.sendData(code + identifier + length + data)
|
|
|
|
def sendCFrame(self, code, identifier, data):
|
|
data_len = len(data) / 2
|
|
self.sendCFrameRaw(code, identifier, p16(data_len), data)
|
|
|
|
def _receptionHandler(self, data):
|
|
pass
|