webrepl.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. # This module should be imported from REPL, not run from command line.
  2. import socket
  3. import uos
  4. import network
  5. import uwebsocket
  6. import websocket_helper
  7. import _webrepl
  8. listen_s = None
  9. client_s = None
  10. def setup_conn(port, accept_handler):
  11. global listen_s
  12. listen_s = socket.socket()
  13. listen_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  14. ai = socket.getaddrinfo("0.0.0.0", port)
  15. addr = ai[0][4]
  16. listen_s.bind(addr)
  17. listen_s.listen(1)
  18. if accept_handler:
  19. listen_s.setsockopt(socket.SOL_SOCKET, 20, accept_handler)
  20. for i in (network.AP_IF, network.STA_IF):
  21. iface = network.WLAN(i)
  22. if iface.active():
  23. print("WebREPL daemon started on ws://%s:%d" % (iface.ifconfig()[0], port))
  24. return listen_s
  25. def accept_conn(listen_sock):
  26. global client_s
  27. cl, remote_addr = listen_sock.accept()
  28. prev = uos.dupterm(None)
  29. uos.dupterm(prev)
  30. if prev:
  31. print("\nConcurrent WebREPL connection from", remote_addr, "rejected")
  32. cl.close()
  33. return
  34. print("\nWebREPL connection from:", remote_addr)
  35. client_s = cl
  36. websocket_helper.server_handshake(cl)
  37. ws = uwebsocket.websocket(cl, True)
  38. ws = _webrepl._webrepl(ws)
  39. cl.setblocking(False)
  40. # notify REPL on socket incoming data (ESP32/ESP8266-only)
  41. if hasattr(uos, 'dupterm_notify'):
  42. cl.setsockopt(socket.SOL_SOCKET, 20, uos.dupterm_notify)
  43. uos.dupterm(ws)
  44. def stop():
  45. global listen_s, client_s
  46. uos.dupterm(None)
  47. if client_s:
  48. client_s.close()
  49. if listen_s:
  50. listen_s.close()
  51. def start(port=8266, password=None):
  52. stop()
  53. if password is None:
  54. try:
  55. import webrepl_cfg
  56. _webrepl.password(webrepl_cfg.PASS)
  57. setup_conn(port, accept_conn)
  58. print("Started webrepl in normal mode")
  59. except:
  60. print("WebREPL is not configured, run 'import webrepl_setup'")
  61. else:
  62. _webrepl.password(password)
  63. setup_conn(port, accept_conn)
  64. print("Started webrepl in manual override mode")
  65. def start_foreground(port=8266):
  66. stop()
  67. s = setup_conn(port, None)
  68. accept_conn(s)