Skip to content

Commit 59ab4cc

Browse files
micolousgpotter2
authored andcommitted
ble: de-duplicate beacon code for eddystone
(includes 1 fix-up; excludes iBeacon in #1893)
1 parent 32619f4 commit 59ab4cc

File tree

2 files changed

+59
-26
lines changed

2 files changed

+59
-26
lines changed

scapy/contrib/eddystone.py

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@
1313
# scapy.contrib.status = loads
1414

1515
from scapy.compat import orb
16-
from scapy.packet import bind_layers, Packet
1716
from scapy.fields import IntField, SignedByteField, StrField, BitField, \
1817
StrFixedLenField, ShortField, FixedPointField, ByteEnumField
1918
from scapy.layers.bluetooth import EIR_Hdr, EIR_ServiceData16BitUUID, \
20-
EIR_Flags, EIR_CompleteList16BitServiceUUIDs, HCI_Hdr, HCI_Command_Hdr, \
21-
HCI_Cmd_LE_Set_Advertising_Data, HCI_LE_Meta_Advertising_Report
19+
EIR_CompleteList16BitServiceUUIDs, LowEnergyBeaconHelper
2220
from scapy.modules import six
21+
from scapy.packet import bind_layers, Packet
2322

2423
EDDYSTONE_UUID = 0xfeaa
2524

@@ -93,7 +92,7 @@ def any2i(self, pkt, x):
9392
return x
9493

9594

96-
class Eddystone_Frame(Packet):
95+
class Eddystone_Frame(Packet, LowEnergyBeaconHelper):
9796
# https://github.com/google/eddystone/blob/master/protocol-specification.md
9897
name = "Eddystone Frame"
9998
fields_desc = [
@@ -104,33 +103,12 @@ class Eddystone_Frame(Packet):
104103
def build_eir(self):
105104
"""Builds a list of EIR messages to wrap this frame."""
106105

107-
return [
108-
EIR_Hdr() / EIR_Flags(flags=[
109-
"general_disc_mode", "br_edr_not_supported"]),
106+
return LowEnergyBeaconHelper.base_eir + [
110107
EIR_Hdr() / EIR_CompleteList16BitServiceUUIDs(svc_uuids=[
111108
EDDYSTONE_UUID]),
112109
EIR_Hdr() / EIR_ServiceData16BitUUID() / self
113110
]
114111

115-
def build_advertising_report(self):
116-
"""Builds HCI_LE_Meta_Advertising_Report containing this frame."""
117-
118-
return HCI_LE_Meta_Advertising_Report(
119-
type=0, # Undirected
120-
atype=1, # Random address
121-
data=self.build_eir()
122-
)
123-
124-
def build_set_advertising_data(self):
125-
"""Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame.
126-
127-
This includes the HCI_Hdr and HCI_Command_Hdr layers.
128-
"""
129-
130-
return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data(
131-
data=self.build_eir()
132-
)
133-
134112

135113
class Eddystone_UID(Packet):
136114
# https://github.com/google/eddystone/tree/master/eddystone-uid

scapy/layers/bluetooth.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,61 @@ class HCI_LE_Meta_Long_Term_Key_Request(Packet):
11921192
bind_layers(SM_Hdr, SM_Signing_Information, sm_command=0x0a)
11931193

11941194

1195+
###########
1196+
# Helpers #
1197+
###########
1198+
1199+
class LowEnergyBeaconHelper:
1200+
"""
1201+
Helpers for building packets for Bluetooth Low Energy Beacons.
1202+
1203+
Implementors provide a :meth:`build_eir` implementation.
1204+
1205+
This is designed to be used as a mix-in -- see
1206+
``scapy.contrib.eddystone`` and ``scapy.contrib.ibeacon`` for examples.
1207+
"""
1208+
1209+
# Basic flags that should be used by most beacons.
1210+
base_eir = [EIR_Hdr() / EIR_Flags(flags=[
1211+
"general_disc_mode", "br_edr_not_supported"]), ]
1212+
1213+
def build_eir(self):
1214+
"""
1215+
Builds a list of EIR messages to wrap this frame.
1216+
1217+
Users of this helper must implement this method.
1218+
1219+
:returns: List of HCI_Hdr with payloads that describe this beacon type
1220+
:rtype: list[HCI_Hdr]
1221+
"""
1222+
raise NotImplementedError("build_eir")
1223+
1224+
def build_advertising_report(self):
1225+
"""
1226+
Builds a HCI_LE_Meta_Advertising_Report containing this frame.
1227+
1228+
:rtype: HCI_LE_Meta_Advertising_Report
1229+
"""
1230+
1231+
return HCI_LE_Meta_Advertising_Report(
1232+
type=0, # Undirected
1233+
atype=1, # Random address
1234+
data=self.build_eir()
1235+
)
1236+
1237+
def build_set_advertising_data(self):
1238+
"""Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame.
1239+
1240+
This includes the :class:`HCI_Hdr` and :class:`HCI_Command_Hdr` layers.
1241+
1242+
:rtype: HCI_Hdr
1243+
"""
1244+
1245+
return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data(
1246+
data=self.build_eir()
1247+
)
1248+
1249+
11951250
###########
11961251
# Sockets #
11971252
###########

0 commit comments

Comments
 (0)