@@ -154,7 +154,11 @@ async def process_event_message(mc, ev, json_output, end="\n", above=False):
154154
155155 elif (data ['type' ] == "CHAN" ) :
156156 path_str = f"{ ANSI_YELLOW } ({ path_str } ){ ANSI_END } "
157- if data ["channel_idx" ] == 0 : #public
157+ if hasattr (mc , "channels" ):
158+ ch_name = mc .channels [data ['channel_idx' ]]['channel_name' ]
159+ disp = f"{ ANSI_GREEN } { ch_name } { path_str } "
160+ process_event_message .last_node = {"adv_name" : ch_name , "type" : 0 , "chan_nb" : data ['channel_idx' ]}
161+ elif data ["channel_idx" ] == 0 : #public
158162 disp = f"{ ANSI_GREEN } public { path_str } "
159163 process_event_message .last_node = {"adv_name" : "public" , "type" : 0 , "chan_nb" : 0 }
160164 else :
@@ -287,7 +291,7 @@ async def subscribe_to_msgs(mc, json_output=False, above=False):
287291 CS = mc .subscribe (EventType .CHANNEL_MSG_RECV , handle_message )
288292 await mc .start_auto_message_fetching ()
289293
290- def make_completion_dict (contacts , pending = {}, to = None ):
294+ def make_completion_dict (contacts , pending = {}, to = None , channels = None ):
291295 contact_list = {}
292296 pending_list = {}
293297 to_list = {}
@@ -312,6 +316,11 @@ def make_completion_dict(contacts, pending={}, to=None):
312316 to_list ["ch" ] = None
313317 to_list ["ch0" ] = None
314318
319+ if not channels is None :
320+ for c in channels :
321+ if c ["channel_name" ] != "" :
322+ to_list [c ["channel_name" ]] = None
323+
315324 completion_list = {
316325 "to" : to_list ,
317326 "public" : None ,
@@ -357,6 +366,8 @@ def make_completion_dict(contacts, pending={}, to=None):
357366 "self_telemetry" : None ,
358367 "get_channel" : None ,
359368 "set_channel" : None ,
369+ "get_channels" : None ,
370+ "remove_channel" : None ,
360371 "set" : {
361372 "name" : None ,
362373 "pin" : None ,
@@ -461,9 +472,9 @@ def make_completion_dict(contacts, pending={}, to=None):
461472 "neighbors" : None ,
462473 "req_acl" :None ,
463474 "setperm" :contact_list ,
464- "gps" : {"on" : None , "off" : None , "sync" : None , "setloc" : None ,
475+ "gps" : {"on" :None ,"off" :None ,"sync" :None ,"setloc" :None ,
465476 "advert" : {"none" : None , "share" : None , "prefs" : None },
466- }
477+ },
467478 "sensor" : {"list" : None , "set" : {"gps" : None }, "get" : {"gps" : None }},
468479 "get" : {"name" : None ,
469480 "role" :None ,
@@ -512,7 +523,7 @@ def make_completion_dict(contacts, pending={}, to=None):
512523 "lon" : None ,
513524 "timeout" : None ,
514525 "perm" :contact_list ,
515- "bridge.enabled" : {"on" : None , "off" : None },
526+ "bridge.enabled" :{"on" : None , "off" : None },
516527 "bridge.delay" :None ,
517528 "bridge.source" :None ,
518529 "bridge.baud" :None ,
@@ -552,6 +563,7 @@ async def interactive_loop(mc, to=None) :
552563 prev_contact = None
553564
554565 await mc .ensure_contacts ()
566+ await get_channels (mc )
555567 await subscribe_to_msgs (mc , above = True )
556568
557569 handle_new_contact .print_new_contacts = True
@@ -644,7 +656,8 @@ def _(event):
644656 completer = NestedCompleter .from_nested_dict (
645657 make_completion_dict (mc .contacts ,
646658 mc .pending_contacts ,
647- to = contact ))
659+ to = contact ,
660+ channels = mc .channels ))
648661
649662 line = await session .prompt_async (ANSI (prompt ),
650663 complete_while_typing = False ,
@@ -667,18 +680,28 @@ def _(event):
667680 if nc is None :
668681 if dest == "public" :
669682 nc = {"adv_name" : "public" , "type" : 0 , "chan_nb" : 0 }
683+ if hasattr (mc , "channels" ):
684+ nc ["adv_name" ] = mc .channels [0 ]["channel_name" ]
670685 elif dest .startswith ("ch" ):
671686 dest = int (dest [2 :])
672687 nc = {"adv_name" : "chan" + str (dest ), "type" : 0 , "chan_nb" : dest }
688+ if hasattr (mc , "channels" ):
689+ nc ["adv_name" ] = mc .channels [dest ]["channel_name" ]
673690 elif dest == ".." : # previous recipient
674691 nc = prev_contact
675692 elif dest == "~" or dest == "/" or dest == mc .self_info ['name' ]:
676693 nc = None
677694 elif dest == "!" :
678695 nc = process_event_message .last_node
679696 else :
680- print (f"Contact '{ dest } ' not found in contacts." )
681- nc = contact
697+ chan = await get_channel_by_name (mc , dest )
698+ if chan is None :
699+ print (f"Contact '{ dest } ' not found in contacts." )
700+ nc = contact
701+ else :
702+ nc = {"adv_name" : chan ["channel_name" ],
703+ "type" : 0 ,
704+ "chan_nb" : chan ["channel_idx" ],}
682705 if nc != contact :
683706 last_ack = True
684707 prev_contact = contact
@@ -898,6 +921,75 @@ async def msg_ack (mc, contact, msg) :
898921msg_ack .flood_after = 2
899922msg_ack .max_flood_attempts = 1
900923
924+ async def get_channel (mc , chan ) :
925+ if not chan .isnumeric ():
926+ return await get_channel_by_name (mc , chan )
927+
928+ nb = int (chan )
929+ if hasattr (mc , 'channels' ) and nb < len (mc .channels ) :
930+ return mc .channels [nb ]
931+
932+ res = await mc .commands .get_channel (nb )
933+ if res .type == EventType .ERROR :
934+ return None
935+
936+ info = res .payload
937+ info ["channel_secret" ] = info ["channel_secret" ].hex ()
938+ return info
939+
940+ async def set_channel (mc , chan , name , key = None ):
941+
942+ if chan .isnumeric ():
943+ nb = int (chan )
944+ else :
945+ c = await get_channel_by_name (mc , chan )
946+ if c is None :
947+ return None
948+ nb = c ['channel_idx' ]
949+
950+ res = await mc .commands .set_channel (nb , name , key )
951+
952+ if res .type == EventType .ERROR :
953+ return None
954+
955+ res = await mc .commands .get_channel (nb )
956+ if res .type == EventType .ERROR :
957+ return None
958+
959+ info = res .payload
960+ info ["channel_secret" ] = info ["channel_secret" ].hex ()
961+
962+ if hasattr (mc ,'channels' ) :
963+ mc .channels [nb ] = info
964+
965+ return info
966+
967+ async def get_channel_by_name (mc , name ):
968+ if not hasattr (mc , 'channels' ) :
969+ get_channels (mc )
970+
971+ for c in mc .channels :
972+ if c ['channel_name' ] == name :
973+ return c
974+
975+ return None
976+
977+ async def get_channels (mc ) :
978+ if hasattr (mc , 'channels' ) :
979+ return mc .channels
980+
981+ ch = 0 ;
982+ mc .channels = []
983+ while True :
984+ res = await mc .commands .get_channel (ch )
985+ if res .type == EventType .ERROR :
986+ break
987+ info = res .payload
988+ info ["channel_secret" ] = info ["channel_secret" ].hex ()
989+ mc .channels .append (info )
990+ ch = ch + 1
991+ return mc .channels
992+
901993async def next_cmd (mc , cmds , json_output = False ):
902994 """ process next command """
903995 try :
@@ -1419,25 +1511,38 @@ async def next_cmd(mc, cmds, json_output=False):
14191511
14201512 case "get_channel" :
14211513 argnum = 1
1422- res = await mc .commands .get_channel (int (cmds [1 ]))
1423- logger .debug (res )
1424- if res .type == EventType .ERROR :
1514+ res = await get_channel (mc , cmds [1 ])
1515+ if res is None :
14251516 print (f"Error while requesting channel info" )
14261517 else :
1427- info = res .payload
1428- info ["channel_secret" ] = info ["channel_secret" ].hex ()
1429- print (json .dumps (info ))
1518+ print (res )
1519+
1520+ case "get_channels" :
1521+ res = await get_channels (mc )
1522+ if json_output :
1523+ print (json .dumps (res ))
1524+ else :
1525+ for c in mc .channels :
1526+ if c ["channel_name" ] != "" :
1527+ print (f"{ c ['channel_idx' ]} : { c ['channel_name' ]} [{ c ['channel_secret' ]} ]" )
14301528
14311529 case "set_channel" :
14321530 argnum = 3
14331531 if cmds [2 ].startswith ("#" ) or len (cmds ) == 3 :
14341532 argnum = 2
1435- res = await mc .commands .set_channel (int (cmds [1 ]), cmds [2 ])
1436- else :
1437- res = await mc .commands .set_channel (int (cmds [1 ]), cmds [2 ], bytes .fromhex (cmds [3 ]))
1438- logger .debug (res )
1439- if res .type == EventType .ERROR :
1440- print (f"Error while setting channel" )
1533+ res = await set_channel (mc , cmds [1 ], cmds [2 ])
1534+ elif len (cmds [3 ]) != 32 :
1535+ res = None
1536+ else :
1537+ res = await set_channel (mc , cmds [1 ], cmds [2 ], bytes .fromhex (cmds [3 ]))
1538+ if res is None :
1539+ print ("Error setting channel" )
1540+
1541+ case "remove_channel" :
1542+ argnum = 1
1543+ res = await set_channel (mc , cmds [1 ], "" , bytes .fromhex (16 * "00" ))
1544+ if res is None :
1545+ print ("Error deleting channel" )
14411546
14421547 case "reboot" :
14431548 res = await mc .commands .reboot ()
@@ -2126,8 +2231,10 @@ def command_help():
21262231 wait_msg : wait for a message and read it wm
21272232 sync_msgs : gets all unread msgs from the node sm
21282233 msgs_subscribe : display msgs as they arrive ms
2129- get_channel <n> : get info for channel n
2234+ get_channels : prints all channel info
2235+ get_channel <n> : get info for channel (by number or name)
21302236 set_channel n nm k : set channel info (nb, name, key)
2237+ remove_channel <n> : remove channel (by number or name)
21312238 Management
21322239 advert : sends advert a
21332240 floodadv : flood advert
@@ -2323,7 +2430,10 @@ async def main(argv):
23232430 # Store device address in configuration
23242431 if os .path .isdir (MCCLI_CONFIG_DIR ) :
23252432 with open (MCCLI_ADDRESS , "w" , encoding = "utf-8" ) as f :
2326- f .write (address )
2433+ if not device is None :
2434+ f .write (device .address )
2435+ elif not address is None :
2436+ f .write (address )
23272437
23282438 handle_message .mc = mc # connect meshcore to handle_message
23292439 handle_advert .mc = mc
0 commit comments