From e55d8ddb21ca171810e8971251161678363015a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Tue, 15 Apr 2025 15:15:41 +0200 Subject: [PATCH] feat: finalizing comptime settings --- src/httpClient.zig | 11 ++++++++--- src/main.zig | 27 ++++++++++++++++++++++++--- src/platform.zig | 25 +++++++++++++++++++++---- src/utils.zig | 20 ++++++++++++++++++++ 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/httpClient.zig b/src/httpClient.zig index 9c82d2c..5e2e294 100644 --- a/src/httpClient.zig +++ b/src/httpClient.zig @@ -69,8 +69,7 @@ fn send_http_request(pcb: ?*cNet.tcp_pcb, context: *HttpContext) !void { const request_data = .{ @tagName(context.request.method), path_string, host_string, context.request.body.len, context.request.body }; - // const raw_request = try std.fmt.allocPrint(context.client.allocator, "{} {} HTTP/1.1\r\nHost: {}\r\nContent-Length: {}\r\n\r\n{}", request_data); - const raw_request = try std.fmt.allocPrint(context.client.allocator, "{s} {s} HTTP/1.1\r\nHost: {s}\r\nTitle: Csengo\r\nContent-Length: {}\r\n\r\n{s}", request_data); + const raw_request = try std.fmt.allocPrint(context.client.allocator, "{s} {s} HTTP/1.1\r\nHost: {s}\r\nTitle: Csengo\r\nPriority: 5\r\nX-Tags: bell\r\nContent-Length: {}\r\n\r\n{s}", request_data); print("Sending request"); print(raw_request); @@ -78,6 +77,7 @@ fn send_http_request(pcb: ?*cNet.tcp_pcb, context: *HttpContext) !void { _ = cNet.tcp_write(pcb, raw_request.ptr, @intCast(raw_request.len), cNet.TCP_WRITE_FLAG_COPY); _ = cNet.tcp_output(pcb); + print("Sent"); } fn tcp_connected_callback(context: ?*anyopaque, pcb: ?*cNet.tcp_pcb, err: cNet.err_t) callconv(.C) cNet.err_t { print("tcp_connected_callback"); @@ -119,10 +119,13 @@ fn open_tcp_connection(ipaddr: [*c]const cNet.struct_ip4_addr, context: *const H fn dns_callback(_: [*c]const u8, ipaddr: [*c]const cNet.struct_ip4_addr, context: ?*anyopaque) callconv(.C) void { print("DNS resolution returned!"); + const http_context: *HttpContext = @ptrCast(@alignCast(context)); if (ipaddr) |addr| { print("DNS resolution successful!"); - const http_context: *HttpContext = @ptrCast(@alignCast(context)); open_tcp_connection(addr, http_context, context); + } else { + print("DNS resolution failed"); + http_context.finished = true; } } @@ -148,6 +151,8 @@ pub const Client = struct { host_c_string[i] = host_string[i]; } + print("Sending DNS resolution for host"); + print(host_string); const result = cNet.dns_gethostbyname(@ptrCast(host_c_string), &cached_address, dns_callback, @ptrCast(@alignCast(&context))); if (result == cNet.ERR_OK) { diff --git a/src/main.zig b/src/main.zig index 8ef3899..d947caf 100644 --- a/src/main.zig +++ b/src/main.zig @@ -10,7 +10,7 @@ const httpClient = @import("httpClient.zig"); const platform = @import("platform.zig"); const utils = @import("utils.zig"); -const BUTTON_PIN = 15; +const BUTTON_PIN = 28; const GPIO_IN = false; pub const std_options: std.Options = .{ .page_size_max = 4 * 1024, .page_size_min = 4 * 1024 }; @@ -19,6 +19,27 @@ fn print(text: []const u8) void { utils.print(text); } +const AppSettings = struct { + ssid: []const u8, + password: []const u8, + ntfy_url: []const u8, +}; + +const appSettings: AppSettings = x: { + var buf: [8192]u8 = undefined; + var fba = std.heap.FixedBufferAllocator.init(&buf); + const res = std.json.parseFromSliceLeaky( + AppSettings, + fba.allocator(), + @embedFile("settings.json"), + .{}, + ); + break :x res catch |e| { + std.debug.print("Error parsing setting.json: {e}", .{e}); + unreachable; + }; +}; + // Basically the pico_w blink sample export fn main() c_int { _ = p.stdio_init_all(); @@ -42,7 +63,7 @@ export fn main() c_int { platform.set_cyw43_led(true); print("Connecting to wifi..."); - platform.connect_wifi(@embedFile("wifi.txt"), @embedFile("password.txt")); + platform.connect_wifi(appSettings.ssid, appSettings.password) catch unreachable; print("Connected!"); send_doorbell_notification() catch unreachable; @@ -69,7 +90,7 @@ pub fn send_doorbell_notification() !void { var client = &httpClient.Client{ .allocator = allocator }; - const request = &httpClient.HttpRequest{ .method = .POST, .url = try std.Uri.parse(@embedFile("ntfy_url.txt")), .body = "Csengo", .headers = &[_]httpClient.HttpHeader{ + const request = &httpClient.HttpRequest{ .method = .POST, .url = try std.Uri.parse(appSettings.ntfy_url), .body = "Csengo", .headers = &[_]httpClient.HttpHeader{ httpClient.HttpHeader{ .name = "Title", .value = "Csengo" }, } }; const response = try client.sendRequest(request); diff --git a/src/platform.zig b/src/platform.zig index 26f1a87..46377b2 100644 --- a/src/platform.zig +++ b/src/platform.zig @@ -1,3 +1,4 @@ +const std = @import("std"); pub const p = @cImport({ @cInclude("pico.h"); @cInclude("stdio.h"); @@ -20,13 +21,29 @@ pub fn init_arch() void { } } -pub fn connect_wifi(ssid: []const u8, password: []const u8) void { +const ConnectToWifiError = error{ + WifiError, +}; +pub fn connect_wifi(ssid: []const u8, password: []const u8) !void { + var buffer: [4096]u8 = undefined; + var fba = std.heap.FixedBufferAllocator.init(&buffer); + const allocator = fba.allocator(); + + const c_ssid = try utils.toSentinel(ssid, allocator, null); + defer allocator.free(c_ssid); + + const c_password = try utils.toSentinel(password, allocator, null); + defer allocator.free(c_password); + p.cyw43_arch_enable_sta_mode(); - if (p.cyw43_arch_wifi_connect_timeout_ms(ssid.ptr, password.ptr, p.CYW43_AUTH_WPA2_AES_PSK, 10000) == 1) { + const connect_wifi_result = p.cyw43_arch_wifi_connect_timeout_ms(c_ssid.ptr, c_password.ptr, p.CYW43_AUTH_WPA2_AES_PSK, 10000); + if (connect_wifi_result != 0) { p.cyw43_arch_gpio_put(p.CYW43_WL_GPIO_LED_PIN, true); - //TODO: error + print("error in connect_wifi"); - return; + utils.print_i8(@intCast(connect_wifi_result)); + + return error.WifiError; } } diff --git a/src/utils.zig b/src/utils.zig index 9ecf451..d276840 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -5,6 +5,16 @@ const c = @cImport({ @cInclude("pico/stdlib.h"); }); +pub fn toSentinel(text: []const u8, allocator: std.mem.Allocator, sentinel: ?u8) ![]const u8 { + const sentinel_text = try allocator.alloc(u8, text.len + 1); + + for (0..text.len) |i| { + sentinel_text[i] = text[i]; + } + sentinel_text[sentinel_text.len - 1] = sentinel orelse 0; + return sentinel_text; +} + pub fn print(text: []const u8) void { var buffer: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buffer); @@ -27,3 +37,13 @@ pub fn print_i8(number: i8) void { _ = c.printf(data.ptr); _ = c.printf("\r\n"); } + +pub fn print_u8_nocr(number: u8) void { + var buf: [10]u8 = undefined; + const data = std.fmt.bufPrint(&buf, "{d} \x00", .{number}) catch unreachable; + _ = c.printf(data.ptr); +} + +pub fn print_newline() void { + _ = c.printf("\r\n"); +}