Skip to content

Commit 46f0c53

Browse files
committed
examples/usercmodule/iperf3_lwip: Return statistics dict from transfer().
Modified all four transfer modes to return structured statistics instead of None: - bytes: Total bytes transferred - seconds: Elapsed time as float - packets_sent: UDP client packet count, 0 for TCP - packets_received: UDP server packet count, 0 for TCP - packet_loss: UDP server lost packets, 0 for TCP - jitter_ms: UDP server jitter in milliseconds, 0.0 for TCP Enables Python wrapper to process results programmatically while maintaining console output for direct REPL usage. Example usage: stats = iperf3_lwip.transfer('tcp_client', '192.168.0.8', 5201, 10) throughput_mbps = stats['bytes'] * 8 / stats['seconds'] / 1e6 Foundation for Phase 3 Python iperf3.py integration. Signed-off-by: Andrew Leech <[email protected]>
1 parent b53623d commit 46f0c53

File tree

1 file changed

+83
-4
lines changed

1 file changed

+83
-4
lines changed

examples/usercmodule/iperf3_lwip/iperf3_lwip.c

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,49 @@ static void iperf3_init_buffers(void) {
257257
iperf3_buffers_initialized = true;
258258
}
259259

260+
/*
261+
* Create statistics dictionary for return to Python
262+
*
263+
* Returns dict with keys:
264+
* - bytes: Total bytes transferred (int)
265+
* - seconds: Elapsed time (float)
266+
* - packets_sent: Packet count for UDP client, 0 for others (int)
267+
* - packets_received: Packet count for UDP server, 0 for others (int)
268+
* - packet_loss: Packets lost for UDP server, 0 for others (int)
269+
* - jitter_ms: Jitter in milliseconds for UDP server, 0.0 for others (float)
270+
*/
271+
static mp_obj_t iperf3_create_stats_dict(uint64_t bytes, float seconds,
272+
uint32_t packets_sent, uint32_t packets_received,
273+
uint32_t packets_lost, float jitter_ms) {
274+
mp_obj_t dict = mp_obj_new_dict(6);
275+
276+
// Bytes transferred
277+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_bytes),
278+
mp_obj_new_int_from_ull(bytes));
279+
280+
// Duration in seconds
281+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_seconds),
282+
mp_obj_new_float(seconds));
283+
284+
// Packets sent (UDP client only, 0 for others)
285+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_packets_sent),
286+
mp_obj_new_int(packets_sent));
287+
288+
// Packets received (UDP server only, 0 for others)
289+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_packets_received),
290+
mp_obj_new_int(packets_received));
291+
292+
// Packet loss (UDP server only)
293+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_packet_loss),
294+
mp_obj_new_int(packets_lost));
295+
296+
// Jitter in milliseconds (UDP server only)
297+
mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(MP_QSTR_jitter_ms),
298+
mp_obj_new_float(jitter_ms));
299+
300+
return dict;
301+
}
302+
260303
/*
261304
* TCP server implementation (internal)
262305
*/
@@ -320,6 +363,7 @@ static mp_obj_t iperf3_lwip_tcp_server_impl(uint16_t port, uint32_t duration_ms)
320363
float mbytes = iperf3_state.bytes_transferred / (1024.0f * 1024.0f);
321364
float mbits_per_sec = (iperf3_state.bytes_transferred * 8.0f) / (elapsed_sec * 1000000.0f);
322365

366+
// Print results (keep for console visibility)
323367
mp_printf(&mp_plat_print, "\nReceived %.2f MB in %.2f sec = %.2f Mbits/sec\n",
324368
(double)mbytes, (double)elapsed_sec, (double)mbits_per_sec);
325369

@@ -341,7 +385,15 @@ static mp_obj_t iperf3_lwip_tcp_server_impl(uint16_t port, uint32_t duration_ms)
341385
iperf3_state.listen_pcb = NULL;
342386
}
343387

344-
return mp_const_none;
388+
// Return statistics dict
389+
return iperf3_create_stats_dict(
390+
iperf3_state.bytes_transferred, // bytes
391+
elapsed_sec, // seconds
392+
0, // packets_sent (TCP doesn't track)
393+
0, // packets_received (TCP doesn't track)
394+
0, // packet_loss (TCP doesn't have)
395+
0.0f // jitter_ms (TCP doesn't measure)
396+
);
345397
}
346398

347399
/*
@@ -413,6 +465,7 @@ static mp_obj_t iperf3_lwip_tcp_client_impl(const char *host, uint16_t port, uin
413465
float mbytes = iperf3_state.bytes_transferred / (1024.0f * 1024.0f);
414466
float mbits_per_sec = (iperf3_state.bytes_transferred * 8.0f) / (elapsed_sec * 1000000.0f);
415467

468+
// Print results (keep for console visibility)
416469
mp_printf(&mp_plat_print, "\nSent %.2f MB in %.2f sec = %.2f Mbits/sec\n",
417470
(double)mbytes, (double)elapsed_sec, (double)mbits_per_sec);
418471

@@ -425,7 +478,15 @@ static mp_obj_t iperf3_lwip_tcp_client_impl(const char *host, uint16_t port, uin
425478
iperf3_state.pcb = NULL;
426479
}
427480

428-
return mp_const_none;
481+
// Return statistics dict
482+
return iperf3_create_stats_dict(
483+
iperf3_state.bytes_transferred, // bytes
484+
elapsed_sec, // seconds
485+
0, // packets_sent (TCP doesn't track)
486+
0, // packets_received (TCP doesn't track)
487+
0, // packet_loss (TCP doesn't have)
488+
0.0f // jitter_ms (TCP doesn't measure)
489+
);
429490
}
430491

431492
/*
@@ -543,6 +604,7 @@ static mp_obj_t iperf3_lwip_udp_server_impl(uint16_t port, uint32_t duration_ms)
543604
(iperf3_udp_state.packets_lost * 100.0f) / total_packets : 0.0f;
544605
float jitter_ms = iperf3_udp_state.jitter / 1000.0f;
545606

607+
// Print results (keep for console visibility)
546608
mp_printf(&mp_plat_print, "\nReceived %.2f MB in %.2f sec = %.2f Mbits/sec\n",
547609
(double)mbytes, (double)elapsed_sec, (double)mbits_per_sec);
548610
mp_printf(&mp_plat_print, "Packets: %lu received, %lu lost (%.2f%%), jitter %.3f ms\n",
@@ -554,7 +616,15 @@ static mp_obj_t iperf3_lwip_udp_server_impl(uint16_t port, uint32_t duration_ms)
554616
udp_remove(pcb);
555617
iperf3_udp_state.pcb = NULL;
556618

557-
return mp_const_none;
619+
// Return statistics dict
620+
return iperf3_create_stats_dict(
621+
iperf3_udp_state.bytes_transferred,
622+
elapsed_sec,
623+
0, // packets_sent (server doesn't track sends)
624+
iperf3_udp_state.packets_received,
625+
iperf3_udp_state.packets_lost,
626+
jitter_ms
627+
);
558628
}
559629

560630
/*
@@ -657,6 +727,7 @@ static mp_obj_t iperf3_lwip_udp_client_impl(const char *host, uint16_t port, uin
657727
float mbytes = iperf3_udp_state.bytes_transferred / (1024.0f * 1024.0f);
658728
float mbits_per_sec = (iperf3_udp_state.bytes_transferred * 8.0f) / (elapsed_sec * 1000000.0f);
659729

730+
// Print results (keep for console visibility)
660731
mp_printf(&mp_plat_print, "\nSent %.2f MB in %.2f sec = %.2f Mbits/sec\n",
661732
(double)mbytes, (double)elapsed_sec, (double)mbits_per_sec);
662733
mp_printf(&mp_plat_print, "Packets sent: %lu\n", (unsigned long)iperf3_udp_state.packets_sent);
@@ -665,7 +736,15 @@ static mp_obj_t iperf3_lwip_udp_client_impl(const char *host, uint16_t port, uin
665736
udp_remove(pcb);
666737
iperf3_udp_state.pcb = NULL;
667738

668-
return mp_const_none;
739+
// Return statistics dict
740+
return iperf3_create_stats_dict(
741+
iperf3_udp_state.bytes_transferred,
742+
elapsed_sec,
743+
iperf3_udp_state.packets_sent,
744+
0, // packets_received (client doesn't receive)
745+
0, // packet_loss (client doesn't measure)
746+
0.0f // jitter_ms (client doesn't measure)
747+
);
669748
}
670749

671750
/*

0 commit comments

Comments
 (0)