diff --git a/README.md b/README.md index b7e5718..b4c13ed 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,104 @@ # mc-cli -Command line interface to MeshCore node + +mc-cli.py : CLI interface to MeschCore BLE companion app + +## Usage + +
+$ mc-cli.py <args> <commands>
+
+ +### Arguments + +Arguments mostly deals with ble connection + +
+    -h : prints this help
+    -a <address> : specifies device address
+    -s : forces ble scan for a MeshCore device
+
+ +### Available Commands + +Commands are given after arguments, they can be chained. + +
+    infos               : print informations a²²bout the node
+    send <key> <msg>    : sends msg to the node with pubkey starting by key
+    sendto <name> <msg> : sends msg to the node with given name
+    recv                : reads next msg
+    sync_msgs           : gets all unread msgs from the node
+    advert              : sends advert
+    contacts            : gets contact list
+    sync_time           : sync time with system
+    set_time <epoch>    : sets time to given epoch
+    get_time            : gets current time
+    set_name <name>     : sets node name
+    sleep <secs>        : sleeps for a given amount of secs
+
+ +### Examples + +
+$ ./mc-cli.py -s infos
+Scanning for devices
+Found device : F0:F5:BD:4F:9B:AD: MeshCore
+Connexion started
+{'adv_type': 1, 'public_key': '54c11cff0c2a861cfc5b0bd6e4b81cd5e6ca85e058bf53932d86c87dc7a20011', 'device_loc': '000000000000000000000000', 'radio_freq': 867500, 'radio_bw': 250000, 'radio_sf': 10, 'radio_cr': 5, 'name': 'toto'}
+cmd ['infos'] processed ...
+
+$ ./mc-cli.py -a F0:F5:BD:4F:9B:AD get_time
+Connexion started
+Current time : 2024-05-15 12:52:53 (1715770373)
+cmd ['get_time'] processed ...
+
+$ date
+Tue Feb  4 12:55:05 CET 2025
+
+$ ./mc-cli.py -a F0:F5:BD:4F:9B:AD sync_time get_time
+Connexion started
+True
+cmd ['sync_time'] processed ...
+Current time : 2025-02-04 12:55:24 (1738670124)
+cmd ['get_time'] processed ...
+
+$ ./mc-cli.py -a F0:F5:BD:4F:9B:AD contacts
+Connexion started
+{}
+cmd ['contacts'] processed ...
+
+$ ./mc-cli.py -a F0:F5:BD:4F:9B:AD sleep 10 contacts
+Connexion started
+Advertisment received
+cmd ['sleep', '10'] processed ...
+{
+    "flo2": {
+        "public_key": "d6e43f8e9ef26b801d6f5fee39f55ad6dfabfc939c84987256532d8b94aa25dd",
+        "type": 1,
+        "flags": 0,
+        "out_path_len": 255,
+        "out_path": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        "adv_name": "flo2",
+        "last_advert": 1738670344,
+        "adv_lat": 0,
+        "adv_lon": 0,
+        "lastmod": 1738670354
+    }
+}
+cmd ['contacts'] processed ...
+
+$ ./mc-cli.py -a F0:F5:BD:4F:9B:AD sendto flo2 "Hello flo2" sleep 10
+Connexion started
+{'type': 1, 'expected_ack': b'9\x05\x0c\x12', 'suggested_timeout': 3260}
+cmd ['sendto', 'flo2', 'Hello flo2'] processed ...
+Code path update
+Received ACK
+Msgs are waiting
+cmd ['sleep', '10'] processed ...
+
+$ ./mc-cli.py -a F0:F5:BD:4F:9B:AD recv
+Connexion started
+{'type': 'PRIV', 'pubkey_prefix': 'd6e43f8e9ef2', 'path_len': 255, 'txt_type': 0, 'sender_timestamp': 1738670421, 'text': 'hi'}
+cmd ['recv'] processed ...
+
+ diff --git a/mc-cli.py b/mc-cli.py index 0cf26ef..751a71f 100755 --- a/mc-cli.py +++ b/mc-cli.py @@ -15,7 +15,7 @@ UART_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" UART_RX_CHAR_UUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" UART_TX_CHAR_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" -# BLE adress of the device +# BLE adress of the device # if None or "" then a scan is performed #ADDRESS = "F0:F5:BD:4F:9B:AD" ADDRESS = "" @@ -32,8 +32,6 @@ class MeshCore: self.client = None async def connect(self): - - def match_meshcore_device(device: BLEDevice, adv: AdvertisementData): if adv.local_name == "MeshCore" : return True @@ -58,12 +56,12 @@ class MeshCore: await self.send_appstart() - print("Connexion started") + print("Connexion started") def handle_rx(self, charac: BleakGATTCharacteristic, data: bytearray): match data[0]: case 0: # ok - if len(data) == 5 : # an integer + if len(data) == 5 : # an integer self.result.set_result(int.from_bytes(data[1:5], byteorder='little')) else: self.result.set_result(True) @@ -72,7 +70,7 @@ class MeshCore: case 2: # contact start self.contact_nb = int.from_bytes(data[1:5], byteorder='little') self.contacts={} - case 3: # contact + case 3: # contact c = {} c["public_key"] = data[1:33].hex() c["type"] = data[33] @@ -178,25 +176,9 @@ class MeshCore: async def get_msg(self): return await self.send(b"\x0A", 1) - -async def test(mc): - print("\nGetting timestamp") - print(await mc.get_time()) - - print("\nSetting name") - print(await mc.set_name("node0")) - - print("\nGetting Contacts") - print(await mc.get_contacts()) - - print("\nSending msg") - print(await mc.send_msg( b"\xd6\xe4?\x8e\x9e\xf2","coucou")) - async def next_cmd(mc, cmds): argnum = 0 match cmds[0] : - case "test" : - await test(mc) case "get_time" : timestamp = await mc.get_time() print('Current time :' @@ -207,7 +189,7 @@ async def next_cmd(mc, cmds): case "set_time" : argnum = 1 print(await mc.set_time(cmds[1])) - case "send" : + case "send" : argnum = 2 print(await mc.send_msg(bytes.fromhex(cmds[1]), cmds[2])) case "sendto" : # sends to a name (need to get contacts first so can take time, contacts should be cached to file ...) @@ -237,10 +219,34 @@ async def next_cmd(mc, cmds): print (f"cmd {cmds[0:argnum+1]} processed ...") return cmds[argnum+1:] +def usage () : + print("""mc-cli.py : CLI interface to MeschCore BLE companion app + + Usage : mc-cli.py + + Arguments : + -h : prints this help + -a
: specifies device address + -s : forces ble scan for a MeshCore device + + Available Commands (can be chained) : + infos : print informations a²²bout the node + send : sends msg to the node with pubkey starting by key + sendto : sends msg to the node with given name + recv : reads next msg + sync_msgs : gets all unread msgs from the node + advert : sends advert + contacts : gets contact list + sync_time : sync time with system + set_time : sets time to given epoch + get_time : gets current time + set_name : sets node name + sleep : sleeps for a given amount of secs"""); + async def main(argv): address = ADDRESS - opts, args = getopt.getopt(sys.argv[1:], "a:s") + opts, args = getopt.getopt(sys.argv[1:], "a:sh") for opt, arg in opts : match opt: case "-a" : # address specified on cmdline @@ -249,7 +255,7 @@ async def main(argv): address = None if len(args) == 0 : - print("Commands : send, sendto, recv, contacts, infos") + usage() return mc = MeshCore(address)