@@ -292,9 +292,11 @@ def GetManagedObjects(self):
292292class BluetoothCommandService :
293293 """Bluetooth Command Service."""
294294
295- def __init__ (self , device_name = "ReachyMini" ):
295+ def __init__ (self , device_name = "ReachyMini" , pin_code = "00000" ):
296296 """Initialize the Bluetooth Command Service."""
297297 self .device_name = device_name
298+ self .pin_code = pin_code
299+ self .connected = False
298300 self .bus = None
299301 self .app = None
300302 self .adv = None
@@ -314,9 +316,18 @@ def _handle_command(self, value: bytes) -> str:
314316 except Exception as e :
315317 logger .error (f"Error executing command: { e } " )
316318 return "OK: System running"
319+ elif command_str .startswith ("PIN_" ):
320+ pin = command_str [4 :].strip ()
321+ if pin == self .pin_code :
322+ self .connected = True
323+ return "OK: Connected"
324+ else :
325+ return "ERROR: Incorrect PIN"
317326
318327 # else if command starts with "CMD_xxxxx" check if commands directory contains the said named script command xxxx.sh and run its, show output or/and send to read
319328 elif command_str .startswith ("CMD_" ):
329+ if not self .connected :
330+ return "ERROR: Not connected. Please authenticate first."
320331 try :
321332 script_name = command_str [4 :].strip () + ".sh"
322333 script_path = os .path .join ("commands" , script_name )
@@ -333,6 +344,8 @@ def _handle_command(self, value: bytes) -> str:
333344 except Exception as e :
334345 logger .error (f"Error processing command: { e } " )
335346 return "ERROR: Command execution failed"
347+ finally :
348+ self .connected = False # reset connection after command
336349 else :
337350 return f"ECHO: { command_str } "
338351
@@ -408,12 +421,32 @@ def run(self):
408421 self .mainloop .quit ()
409422
410423
424+ def get_pin () -> str :
425+ """Extract the last 5 digits of the serial number from dfu-util -l output."""
426+ default_pin = "46879"
427+ try :
428+ result = subprocess .run (["dfu-util" , "-l" ], capture_output = True , text = True )
429+ lines = result .stdout .splitlines ()
430+ for line in lines :
431+ if "serial=" in line :
432+ # Extract serial number
433+ serial_part = line .split ("serial=" )[- 1 ].strip ().strip ('"' )
434+ if len (serial_part ) >= 5 :
435+ return serial_part [- 5 :]
436+ return default_pin # fallback if not found
437+ except Exception as e :
438+ logger .error (f"Error getting pin from serial: { e } " )
439+ return default_pin
440+
441+
411442# =======================
412443# Main
413444# =======================
414445def main ():
415446 """Run the Bluetooth Command Service."""
416- bt_service = BluetoothCommandService (device_name = "ReachyMini" )
447+ pin = get_pin ()
448+
449+ bt_service = BluetoothCommandService (device_name = "ReachyMini" , pin_code = pin )
417450 bt_service .run ()
418451
419452
0 commit comments