33
33
DEFAULT_PROBE_SIZE = 16
34
34
DEFAULT_TIMEOUT = 12
35
35
36
- def program_setup (configdir , destination_hexhash , size = None , full_name = None , verbosity = 0 , timeout = None ):
36
+ def program_setup (configdir , destination_hexhash , size = None , full_name = None , verbosity = 0 , timeout = None , probes = 1 ):
37
37
if size == None : size = DEFAULT_PROBE_SIZE
38
38
if full_name == None :
39
39
print ("The full destination name including application name aspects must be specified for the destination" )
@@ -96,90 +96,103 @@ def program_setup(configdir, destination_hexhash, size=None, full_name = None, v
96
96
* aspects
97
97
)
98
98
99
- try :
100
- probe = RNS .Packet (request_destination , os .urandom (size ))
101
- probe .pack ()
102
- except OSError :
103
- print ("Error: Probe packet size of " + str (len (probe .raw ))+ " bytes exceed MTU of " + str (RNS .Reticulum .MTU )+ " bytes" )
104
- exit (3 )
105
-
106
- receipt = probe .send ()
107
-
108
- if more_output :
109
- nhd = reticulum .get_next_hop (destination_hash )
110
- via_str = " via " + RNS .prettyhexrep (nhd ) if nhd != None else ""
111
- if_str = " on " + str (reticulum .get_next_hop_if_name (destination_hash )) if reticulum .get_next_hop_if_name (destination_hash ) != "None" else ""
112
- more = via_str + if_str
113
- else :
114
- more = ""
115
-
116
- print ("\r Sent " + str (size )+ " byte probe to " + RNS .prettyhexrep (destination_hash )+ more + " " , end = " " )
99
+ sent = 0
100
+ replies = 0
101
+ while probes :
117
102
118
- _timeout = time .time () + (timeout or DEFAULT_TIMEOUT + reticulum .get_first_hop_timeout (destination_hash ))
119
- i = 0
120
- while receipt .status == RNS .PacketReceipt .SENT and not time .time () > _timeout :
121
- time .sleep (0.1 )
122
- print (("\b \b " + syms [i ]+ " " ), end = "" )
123
- sys .stdout .flush ()
124
- i = (i + 1 )% len (syms )
125
-
126
- if time .time () > _timeout :
127
- print ("\r \r Probe timed out" )
128
- exit (2 )
129
-
130
- print ("\b \b " )
131
- sys .stdout .flush ()
132
-
133
- if receipt .status == RNS .PacketReceipt .DELIVERED :
134
- hops = RNS .Transport .hops_to (destination_hash )
135
- if hops != 1 :
136
- ms = "s"
103
+ try :
104
+ probe = RNS .Packet (request_destination , os .urandom (size ))
105
+ probe .pack ()
106
+ except OSError :
107
+ print ("Error: Probe packet size of " + str (len (probe .raw ))+ " bytes exceed MTU of " + str (RNS .Reticulum .MTU )+ " bytes" )
108
+ exit (3 )
109
+
110
+ receipt = probe .send ()
111
+ sent += 1
112
+
113
+ if more_output :
114
+ nhd = reticulum .get_next_hop (destination_hash )
115
+ via_str = " via " + RNS .prettyhexrep (nhd ) if nhd != None else ""
116
+ if_str = " on " + str (reticulum .get_next_hop_if_name (destination_hash )) if reticulum .get_next_hop_if_name (destination_hash ) != "None" else ""
117
+ more = via_str + if_str
137
118
else :
138
- ms = ""
119
+ more = ""
139
120
140
- rtt = receipt .get_rtt ()
141
- if (rtt >= 1 ):
142
- rtt = round (rtt , 3 )
143
- rttstring = str (rtt )+ " seconds"
144
- else :
145
- rtt = round (rtt * 1000 , 3 )
146
- rttstring = str (rtt )+ " milliseconds"
147
-
148
- reception_stats = ""
149
- if reticulum .is_connected_to_shared_instance :
150
- reception_rssi = reticulum .get_packet_rssi (receipt .proof_packet .packet_hash )
151
- reception_snr = reticulum .get_packet_snr (receipt .proof_packet .packet_hash )
152
- reception_q = reticulum .get_packet_q (receipt .proof_packet .packet_hash )
153
-
154
- if reception_rssi != None :
155
- reception_stats += " [RSSI " + str (reception_rssi )+ " dBm]"
156
-
157
- if reception_snr != None :
158
- reception_stats += " [SNR " + str (reception_snr )+ " dB]"
159
-
160
- if reception_q != None :
161
- reception_stats += " [Link Quality " + str (reception_q )+ "%]"
121
+ print ("\r Sent probe " + str (sent )+ " (" + str (size )+ " bytes) to " + RNS .prettyhexrep (destination_hash )+ more + " " , end = " " )
162
122
163
- else :
164
- if receipt .proof_packet != None :
165
- if receipt .proof_packet .rssi != None :
166
- reception_stats += " [RSSI " + str (receipt .proof_packet .rssi )+ " dBm]"
167
-
168
- if receipt .proof_packet .snr != None :
169
- reception_stats += " [SNR " + str (receipt .proof_packet .snr )+ " dB]"
170
-
171
- print (
172
- "Valid reply received from " +
173
- RNS .prettyhexrep (receipt .destination .hash )+
174
- "\n Round-trip time is " + rttstring +
175
- " over " + str (hops )+ " hop" + ms +
176
- reception_stats
177
- )
123
+ _timeout = time .time () + (timeout or DEFAULT_TIMEOUT + reticulum .get_first_hop_timeout (destination_hash ))
124
+ i = 0
125
+ while receipt .status == RNS .PacketReceipt .SENT and not time .time () > _timeout :
126
+ time .sleep (0.1 )
127
+ print (("\b \b " + syms [i ]+ " " ), end = "" )
128
+ sys .stdout .flush ()
129
+ i = (i + 1 )% len (syms )
178
130
179
- else :
180
- print ("\r \r Probe timed out" )
131
+ if time .time () > _timeout :
132
+ print ("\r \r Probe timed out" )
133
+
134
+ else :
135
+ print ("\b \b " )
136
+ sys .stdout .flush ()
137
+
138
+ if receipt .status == RNS .PacketReceipt .DELIVERED :
139
+ replies += 1
140
+ hops = RNS .Transport .hops_to (destination_hash )
141
+ if hops != 1 :
142
+ ms = "s"
143
+ else :
144
+ ms = ""
145
+
146
+ rtt = receipt .get_rtt ()
147
+ if (rtt >= 1 ):
148
+ rtt = round (rtt , 3 )
149
+ rttstring = str (rtt )+ " seconds"
150
+ else :
151
+ rtt = round (rtt * 1000 , 3 )
152
+ rttstring = str (rtt )+ " milliseconds"
153
+
154
+ reception_stats = ""
155
+ if reticulum .is_connected_to_shared_instance :
156
+ reception_rssi = reticulum .get_packet_rssi (receipt .proof_packet .packet_hash )
157
+ reception_snr = reticulum .get_packet_snr (receipt .proof_packet .packet_hash )
158
+ reception_q = reticulum .get_packet_q (receipt .proof_packet .packet_hash )
159
+
160
+ if reception_rssi != None :
161
+ reception_stats += " [RSSI " + str (reception_rssi )+ " dBm]"
162
+
163
+ if reception_snr != None :
164
+ reception_stats += " [SNR " + str (reception_snr )+ " dB]"
165
+
166
+ if reception_q != None :
167
+ reception_stats += " [Link Quality " + str (reception_q )+ "%]"
168
+
169
+ else :
170
+ if receipt .proof_packet != None :
171
+ if receipt .proof_packet .rssi != None :
172
+ reception_stats += " [RSSI " + str (receipt .proof_packet .rssi )+ " dBm]"
173
+
174
+ if receipt .proof_packet .snr != None :
175
+ reception_stats += " [SNR " + str (receipt .proof_packet .snr )+ " dB]"
176
+
177
+ print (
178
+ "Valid reply received from " +
179
+ RNS .prettyhexrep (receipt .destination .hash )+
180
+ "\n Round-trip time is " + rttstring +
181
+ " over " + str (hops )+ " hop" + ms +
182
+ reception_stats
183
+ )
184
+
185
+ else :
186
+ print ("\r \r Probe timed out" )
187
+
188
+ probes -= 1
189
+
190
+ loss = round ((1 - (replies / sent ))* 100 , 2 )
191
+ print (f"Sent { sent } , received { replies } , packet loss { loss } %" )
192
+ if loss > 0 :
181
193
exit (2 )
182
-
194
+ else :
195
+ exit (0 )
183
196
184
197
185
198
def main ():
@@ -188,6 +201,7 @@ def main():
188
201
189
202
parser .add_argument ("--config" , action = "store" , default = None , help = "path to alternative Reticulum config directory" , type = str )
190
203
parser .add_argument ("-s" , "--size" , action = "store" , default = None , help = "size of probe packet payload in bytes" , type = int )
204
+ parser .add_argument ("-n" , "--probes" , action = "store" , default = 1 , help = "number of probes to send" , type = int )
191
205
parser .add_argument ("-t" , "--timeout" , metavar = "seconds" , action = "store" , default = None , help = "timeout before giving up" , type = float )
192
206
parser .add_argument ("--version" , action = "version" , version = "rnprobe {version}" .format (version = __version__ ))
193
207
parser .add_argument ("full_name" , nargs = "?" , default = None , help = "full destination name in dotted notation" , type = str )
@@ -212,7 +226,8 @@ def main():
212
226
destination_hexhash = args .destination_hash ,
213
227
size = args .size ,
214
228
full_name = args .full_name ,
215
- verbosity = args .verbose
229
+ verbosity = args .verbose ,
230
+ probes = args .probes ,
216
231
)
217
232
218
233
except KeyboardInterrupt :
0 commit comments