# ble_observe_0.py Zeigt Botschaft (MSG) eines Boradcasters auf dem Display an,
# in diesem Fall einen kurzen Text

# Benutze einen weiteren TTGO als Broadcaster

# Stand 12.04.2021

from time import sleep
from ubluetooth import BLE
from micropython import const

_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)

_ADV_TYP_FLAGS = const(1)
_ADV_TYP_NAME = const(9)
_ADV_TYP_MSG = const(250) # Eigener ADV_Typ
_TX_POWER_LEVEL = const(10)


def find_adv(adv_type, data): 
    i = 0
    while i + 1 < len(data): 
        ad_structure_len = data[i]  
        ad_structure_type = data[i + 1] 
        ad_structure_payload = data[i + 2: i + ad_structure_len + 1] 
        if ad_structure_type == adv_type: 
            return ad_structure_payload 
        i += ad_structure_len + 1 
    return None


def find_adv_name(data):
    n = find_adv(_ADV_TYP_NAME, data)   
    if n:
        return str(n, 'UTF-8') # Text
    return None


def find_adv_msg(data):
    n = find_adv(_ADV_TYP_MSG, data)   
    if n:
        return str(n, 'UTF-8') # Text
    return None


def bt_irq_handler(event, data):
  if event == _IRQ_SCAN_RESULT: # Advertiser-Datenpaket erhalten
    addr_type, addr, adv_type, rssi, adv_data = data # data ist ein Tupel
    name = find_adv_name(adv_data)
    if name == 'ESP32':
      print('-----------------------------------------------------------')
      print('ADV-Data (Name): ', name)
      print('ADV_Data (Text): ', find_adv_msg(adv_data))
      print()
  elif event == _IRQ_SCAN_DONE: # Scan beendet
    print('-----------------------------------------------------------')
    print('scan complete')


# Hauptptrogramm:

print('Please start the Broadcaster and input some short texts...')
print('Observer will now run for 30 s.\n')

ble = BLE()
ble.active(True)
ble.irq(bt_irq_handler)
ble.gap_scan(30000, 100000, 25000, True) # Observer ist 30 Sekunden lang aktiv
sleep(30)
ble.active(False) # Bluetooth aus



