Skip to content

Commit

Permalink
ntp example
Browse files Browse the repository at this point in the history
  • Loading branch information
kassane authored and ikskuh committed Jul 9, 2023
1 parent 04fc378 commit 7b5f76e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ jobs:
- name: Compile and test udp broadcast
run: |
zig build udp-broadcast
- name: Compile and test ntp client
run: |
zig build ntp-client
13 changes: 12 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,18 @@ pub fn build(b: *std.build.Builder) !void {
});
discovery_server.addModule("network", module);

const ntp_client = b.addExecutable(.{
.name = "ntp_client",
.root_source_file = .{ .path = "examples/ntp_client.zig" },
.target = target,
.optimize = optimize,
});
ntp_client.addModule("network", module);

const test_step = b.step("test", "Runs the test suite.");
var run = b.addRunArtifact(test_runner);

test_step.dependOn(&run.step);


const sync_examples_step = b.step("sync-examples", "Builds the examples");
sync_examples_step.dependOn(&b.addInstallArtifact(echo_example).step);
Expand All @@ -85,6 +92,9 @@ pub fn build(b: *std.build.Builder) !void {
discovery_examples_step.dependOn(&b.addInstallArtifact(discovery_client).step);
discovery_examples_step.dependOn(&b.addInstallArtifact(discovery_server).step);

const ntp_example_step = b.step("ntp-client", "Builds NTP client example");
ntp_example_step.dependOn(&b.addInstallArtifact(ntp_client).step);

const all_examples_step = b.step("examples", "Builds all examples");
all_examples_step.dependOn(&b.addInstallArtifact(echo_example).step);
// TODO: uncomment once async is implemented
Expand All @@ -93,4 +103,5 @@ pub fn build(b: *std.build.Builder) !void {
all_examples_step.dependOn(&b.addInstallArtifact(udp_broadcast_example).step);
all_examples_step.dependOn(&b.addInstallArtifact(discovery_client).step);
all_examples_step.dependOn(&b.addInstallArtifact(discovery_server).step);
all_examples_step.dependOn(&b.addInstallArtifact(ntp_client).step);
}
59 changes: 59 additions & 0 deletions examples/ntp_client.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const std = @import("std");
const network = @import("network");
const debug = std.debug;

pub fn main() !void {
try network.init();
defer network.deinit();
var request: [48]u8 = std.mem.zeroes([48]u8);
request[0] = 0b00100011; // NTP version 4, mode 3 (client)

var sock = try network.connectToHost(std.heap.page_allocator, "pool.ntp.org", 123, .udp);
defer sock.close();

try sock.writer().writeAll(&request);

var response: [48]u8 = undefined;
_ = try sock.reader().readAll(&response);

// The timestamp is stored in bytes 40-43 of the response
const seconds = @divFloor(std.time.milliTimestamp(), std.time.ms_per_s);

// zig fmt: off
const fractionalSeconds = @as(u64, @intCast(response[40])) << 24
| @as(u64, @intCast(response[41])) << 16
| @as(u64, @intCast(response[42])) << 8
| @as(u64, @intCast(response[43]));

var timestamp = @divFloor(seconds, 2_208_988_800) * std.time.ms_per_s + fractionalSeconds * (std.time.ns_per_s / 4_294_967_296);

debug.print("NTP timestamp: {}\n", .{timestamp}); //0

// result: 1970 -1 -1 0: 0: 0 (UTC 1970-01-01)
debug.print("{s}\n", .{try convertTimestampToTime(@as(u64, @intCast(timestamp)))});
}

pub const secs_per_day: u17 = 24 * 60 * 60;

pub const EpochSeconds = struct {
secs: u64,

pub fn getEpochDay(self: EpochSeconds) std.time.epoch.EpochDay {
return .{ .day = @as(u47, @intCast(self.secs / secs_per_day)) };
}

pub fn getDaySeconds(self: EpochSeconds) std.time.epoch.DaySeconds {
return .{ .secs = std.math.comptimeMod(self.secs, secs_per_day) };
}
};

pub fn convertTimestampToTime(timestamp: u64) ![]const u8 {
const epochSeconds = EpochSeconds{ .secs = timestamp };
const epochDay = epochSeconds.getEpochDay();
const daySeconds = epochSeconds.getDaySeconds();
const yearDay = epochDay.calculateYearDay();
const monthDay = yearDay.calculateMonthDay();
var buf: [80:0]u8 = undefined;

return std.fmt.bufPrint(&buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}", .{ yearDay.year, monthDay.month.numeric(), monthDay.day_index + 1, daySeconds.getHoursIntoDay(), daySeconds.getMinutesIntoHour(), daySeconds.getSecondsIntoMinute() });
}

0 comments on commit 7b5f76e

Please sign in to comment.