Skip to content

Commit db9b383

Browse files
committed
sntpc: Update README
Expanded the README to include a detailed usage example, updated links for clarity, and outlined support for `async`, `sync`, and `no_std` features. Acknowledged new contributors for recent enhancements.
1 parent 87c2303 commit db9b383

File tree

1 file changed

+89
-29
lines changed

1 file changed

+89
-29
lines changed

sntpc/README.md

+89-29
Original file line numberDiff line numberDiff line change
@@ -17,82 +17,140 @@ Supported SNTP protocol versions:
1717

1818
-----------------
1919

20-
https://docs.rs/sntpc
20+
More information about this crate can be found in the [crate documentation](https://docs.rs/sntpc)
2121

22-
### Installation
22+
### Usage example
2323

24-
----------------
25-
26-
This crate works with Cargo and is on
27-
[crates.io](https://crates.io/crates/sntpc). Add it to your `Cargo.toml`
28-
like so:
24+
- dependency for the app
2925

3026
```toml
3127
[dependencies]
32-
sntpc = "0.4.0"
28+
sntpc = { version = "0.5", features = ["sync"] }
3329
```
3430

35-
By calling the `get_time()` method and providing a proper NTP pool or server you
36-
should get a valid synchronization timestamp:
31+
- application code
3732

3833
```rust
39-
use std::net::UdpSocket;
34+
use sntpc::{sync::get_time, NtpContext, StdTimestampGen};
35+
36+
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
37+
use std::thread;
4038
use std::time::Duration;
4139

40+
#[allow(dead_code)]
41+
const POOL_NTP_ADDR: &str = "pool.ntp.org:123";
42+
#[allow(dead_code)]
43+
const GOOGLE_NTP_ADDR: &str = "time.google.com:123";
44+
4245
fn main() {
46+
#[cfg(feature = "log")]
47+
if cfg!(debug_assertions) {
48+
simple_logger::init_with_level(log::Level::Trace).unwrap();
49+
} else {
50+
simple_logger::init_with_level(log::Level::Info).unwrap();
51+
}
52+
4353
let socket =
4454
UdpSocket::bind("0.0.0.0:0").expect("Unable to crate UDP socket");
4555
socket
4656
.set_read_timeout(Some(Duration::from_secs(2)))
4757
.expect("Unable to set UDP socket read timeout");
48-
let result = sntpc::simple_get_time("time.google.com:123", &socket);
49-
match result {
50-
Ok(time) => {
51-
println!("Got time: {}.{}", time.sec(), sntpc::fraction_to_milliseconds(time.sec_fraction()));
58+
59+
for addr in POOL_NTP_ADDR.to_socket_addrs().unwrap() {
60+
let ntp_context = NtpContext::new(StdTimestampGen::default());
61+
let result = get_time(addr, &socket, ntp_context);
62+
63+
match result {
64+
Ok(time) => {
65+
assert_ne!(time.sec(), 0);
66+
let seconds = time.sec();
67+
let microseconds = u64::from(time.sec_fraction()) * 1_000_000
68+
/ u64::from(u32::MAX);
69+
println!("Got time from [{POOL_NTP_ADDR}] {addr}: {seconds}.{microseconds}");
70+
71+
break;
72+
}
73+
Err(err) => println!("Err: {err:?}"),
5274
}
53-
Err(err) => println!("Err: {:?}", err),
75+
76+
thread::sleep(Duration::new(2, 0));
5477
}
5578
}
5679
```
5780

81+
You can find this [example](examples/simple-request) as well as other example projects in the
82+
[example directory](examples).
83+
5884
## `no_std` support
5985

6086
-------------------
6187

62-
Currently, there are basic `no_std` support available, thanks to [`no-std-net`](https://crates.io/crates/no-std-net)
63-
crate. There is an example available on how to use [`smoltcp`][smoltcp] stack and that should provide
88+
There is an example available on how to use [`smoltcp`](examples/smoltcp-request) stack and that should provide
6489
general idea on how to bootstrap `no_std` networking and timestamping tools for `sntpc` library usage
6590

6691
## `async` support
6792

6893
-------------------
6994

70-
Feature `async_tokio` allows to use crate together with [tokio](https://docs.rs/tokio/latest/tokio/).
71-
Example available in the [repository](https://github.com/vpetrigo/sntpc).
95+
Starting version `0.5` the default interface is `async`. If you want to use synchronous interface, read about `sync`
96+
feature below.
97+
98+
`tokio` example: [`examples/tokio`](examples/tokio)
7299

73100
There is also `no_std` support with feature `async`, but it requires Rust >= `1.75-nightly` version.
74101
The example can be found in [separate repository](https://github.com/vpikulik/sntpc_embassy).
75102

76-
# Examples
103+
## `sync` support
104+
105+
-------------------
106+
107+
`sntpc` crate is `async` by default, since most of the frameworks (I have seen) for embedded systems utilize
108+
asynchronous approach, e.g.:
109+
110+
- [RTIC](https://github.com/rtic-rs/rtic)
111+
- [embassy](https://github.com/embassy-rs/embassy)
112+
113+
If you need fully synchronous interface it is available in the `sntpc::sync` submodule and respective `sync`-feature
114+
enabled. In the case someone needs a synchronous socket support the currently async `NtpUdpSocket` trait can be
115+
implemented in a fully synchronous manner. This is an example for the `std::net::UdpSocket` that is available in the
116+
crate:
77117

78-
----------
118+
```rust
119+
#[cfg(feature = "std")]
120+
impl NtpUdpSocket for UdpSocket {
121+
async fn send_to(&self, buf: &[u8], addr: SocketAddr) -> Result<usize> {
122+
match self.send_to(buf, addr) {
123+
Ok(usize) => Ok(usize),
124+
Err(_) => Err(Error::Network),
125+
}
126+
}
127+
128+
async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
129+
match self.recv_from(buf) {
130+
Ok((size, addr)) => Ok((size, addr)),
131+
Err(_) => Err(Error::Network),
132+
}
133+
}
134+
}
135+
```
79136

80-
You can find several examples that shows how to use the library in details under [examples/] folder.
81-
Currently, there are examples that show:
137+
As you can see, you may implement everything as synchronous, `sntpc` synchronous interface handles `async`-like stuff
138+
internally.
82139

83-
- usage of SNTP library in `std` environment
84-
- usage of SNTP library with [`smoltcp`][smoltcp] TCP/IP stack. Some `std` dependencies
85-
required only due to smoltcp available interfaces
140+
That approach also allows to avoid issues with [`maybe_async`](https://docs.rs/maybe-async/latest/maybe_async/) when the
141+
sync/async feature [violates Cargo requirements](https://doc.rust-lang.org/cargo/reference/features.html):
142+
> That is, enabling a feature should not disable functionality, and it should usually be safe to enable any combination
143+
> of features.
86144
87-
[smoltcp]: https://github.com/smoltcp-rs/smoltcp
145+
Small overhead introduced by creating an executor should be negligible.
88146

89147
# Contribution
90148

91149
--------------
92150

93151
Contributions are always welcome! If you have an idea, it's best to float it by me before working on it to ensure no
94152
effort is wasted. If there's already an open issue for it, knock yourself out. See the
95-
[**contributing section**](https://github.com/vpetrigo/sntpc/blob/master/CONTRIBUTING.md) for additional details
153+
[**contributing section**](CONTRIBUTING.md) for additional details
96154

97155
## Thanks
98156

@@ -105,6 +163,8 @@ effort is wasted. If there's already an open issue for it, knock yourself out. S
105163
5. [Vitali Pikulik](https://github.com/vpikulik): for adding `async` support
106164
6. [tsingwong](https://github.com/tsingwong): for fixing invalid link in the `README.md`
107165
7. [Robert Bastian](https://github.com/robertbastian): for fixing the overflow issue in the `calculate_offset`
166+
8. [oleid](https://github.com/oleid): for bringing `embassy` socket support
167+
9. [Damian Peckett](https://github.com/dpeckett): for adding `defmt` support and elaborating on `embassy` example
108168

109169
Really appreciate all your efforts! Please [let me know](mailto:vladimir.petrigo@gmail.com) if I forgot someone.
110170

0 commit comments

Comments
 (0)