diff --git a/src/announce.c b/src/announce.c index 8758acb..6a5789d 100644 --- a/src/announce.c +++ b/src/announce.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ #ifdef ENABLE_LOGGING #include extern FILE *log_fp; -#define LOG(fmt, ...) do { if (log_fp) { fprintf(log_fp, "[%s] " fmt "\n", __func__, ##__VA_ARGS__); fflush(log_fp); } } while(0) +#define LOG(fmt, ...) do { if (log_fp) openuf_log_emit(log_fp, __func__, fmt, ##__VA_ARGS__); } while(0) #else #define LOG(fmt, ...) do {} while(0) #endif @@ -199,7 +200,7 @@ int announce_init(announce_ctx_t *ctx, /* ── Socket for broadcast 255.255.255.255 ─────────────────── */ ctx->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (ctx->sockfd < 0) { - perror("[openuf] announce socket"); + LOGF(stderr, "announce socket: %s", strerror(errno)); return -1; } int on = 1; @@ -249,7 +250,7 @@ int announce_send(announce_ctx_t *ctx) }; if (sendto(ctx->sockfd, ctx->pkt, ctx->pkt_len, 0, (struct sockaddr *)&dest_bcast, sizeof(dest_bcast)) < 0) { - perror("[openuf] announce sendto broadcast"); + LOGF(stderr, "announce sendto broadcast: %s", strerror(errno)); ret = -1; } diff --git a/src/config.h b/src/config.h index e381051..d3c9d3e 100644 --- a/src/config.h +++ b/src/config.h @@ -21,10 +21,37 @@ #if ENABLE_LOGGING #include +#include +#include extern FILE *log_fp; -#define LOG(fmt, ...) do { if (log_fp) { fprintf(log_fp, "[%s] " fmt "\n", __func__, ##__VA_ARGS__); fflush(log_fp); } } while(0) + +static inline void openuf_log_emit(FILE *stream, const char *prefix, + const char *fmt, ...) +{ + char ts[32]; + time_t now = time(NULL); + struct tm tm; + localtime_r(&now, &tm); + strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", &tm); + + fprintf(stream, "[%s]", ts); + if (prefix && prefix[0]) + fprintf(stream, " [%s]", prefix); + fputc(' ', stream); + + va_list ap; + va_start(ap, fmt); + vfprintf(stream, fmt, ap); + va_end(ap); + fputc('\n', stream); + fflush(stream); +} + +#define LOG(fmt, ...) do { if (log_fp) openuf_log_emit(log_fp, __func__, fmt, ##__VA_ARGS__); } while(0) +#define LOGF(stream, fmt, ...) openuf_log_emit(stream, "openuf", fmt, ##__VA_ARGS__) #else #define LOG(fmt, ...) do {} while(0) +#define LOGF(stream, fmt, ...) do { (void)(stream); } while(0) #endif typedef struct { diff --git a/src/inform/inform.c b/src/inform/inform.c index 1662bcd..6b67573 100644 --- a/src/inform/inform.c +++ b/src/inform/inform.c @@ -158,7 +158,7 @@ int inform_send(openuf_state_t *st, LOG("Response action: %s", action); if (strcmp(action, "noop") != 0) - printf("[openuf] Action: %s\n", action); + LOGF(stdout, "Action: %s", action); return 0; } diff --git a/src/inform/response.c b/src/inform/response.c index e1baa57..de90669 100644 --- a/src/inform/response.c +++ b/src/inform/response.c @@ -338,7 +338,7 @@ void inform_handle_response(openuf_state_t *st, json_object_object_get_ex(resp, "vap_table", &vt); int apply_ok = 0; if (rt || vt) { - printf("[openuf] Applying controller WiFi configuration...\n"); + LOGF(stdout, "Applying controller WiFi configuration..."); apply_ok = wlan_apply_config(resp, model) == 0; } else { LOG("setstate contained neither radio_table nor vap_table"); diff --git a/src/main.c b/src/main.c index d8ae39e..1256d60 100644 --- a/src/main.c +++ b/src/main.c @@ -174,20 +174,19 @@ int main(int argc, char *argv[]) controller_ip); } else { state.inform_url[0] = '\0'; - fprintf(stderr, - "[openuf] No controller configured and no IPv4 default " - "gateway found\n"); + LOGF(stderr, + "No controller configured and no IPv4 default " + "gateway found"); } } state_save(&state); - printf("[openuf] Starting version=%s model=%-8s MAC=%s IP=%s\n", - OPENUF_VERSION, model->model, mac_str, ip_str); - printf("[openuf] Controller: %s\n", state.inform_url); - printf("[openuf] Adopted: %s\n", state.adopted ? "yes" : "no"); - printf("[openuf] LLDP available: %s\n", - lldp_available() ? "yes (lldpd)" : "no (transmit only)"); - fflush(stdout); + LOGF(stdout, "Starting version=%s model=%-8s MAC=%s IP=%s", + OPENUF_VERSION, model->model, mac_str, ip_str); + LOGF(stdout, "Controller: %s", state.inform_url); + LOGF(stdout, "Adopted: %s", state.adopted ? "yes" : "no"); + LOGF(stdout, "LLDP available: %s", + lldp_available() ? "yes (lldpd)" : "no (transmit only)"); LOG("Daemon started"); @@ -212,8 +211,7 @@ int main(int argc, char *argv[]) time_t last_inform = 0; time_t last_lldp = 0; - printf("[openuf] Main loop started\n"); - fflush(stdout); + LOGF(stdout, "Main loop started"); while (1) { time_t now = time(NULL); diff --git a/src/state.c b/src/state.c index 63948c9..0a056d5 100644 --- a/src/state.c +++ b/src/state.c @@ -8,7 +8,7 @@ #if ENABLE_LOGGING #include extern FILE *log_fp; -#define LOG(fmt, ...) do { if (log_fp) { fprintf(log_fp, "[%s] " fmt "\n", __func__, ##__VA_ARGS__); fflush(log_fp); } } while(0) +#define LOG(fmt, ...) do { if (log_fp) openuf_log_emit(log_fp, __func__, fmt, ##__VA_ARGS__); } while(0) #else #define LOG(fmt, ...) do {} while(0) #endif diff --git a/src/wlan/common.c b/src/wlan/common.c index 0bf0beb..6153ead 100644 --- a/src/wlan/common.c +++ b/src/wlan/common.c @@ -134,14 +134,14 @@ int wlan_ensure_vap_ids(struct json_object *vaps) char generated[25]; if (!id) { if (crypto_random_hex((unsigned char *)generated, 12) != 0) { - printf("[openuf] Failed to generate a VAP ID for '%s'\n", ssid); + LOGF(stdout, "Failed to generate a VAP ID for '%s'", ssid); if (pkg) uci_unload(ctx, pkg); if (ctx) uci_free_context(ctx); return -1; } id = generated; - printf("[openuf] Generated persistent VAP ID %s for '%s'\n", - id, ssid); + LOGF(stdout, "Generated persistent VAP ID %s for '%s'", + id, ssid); } json_object_object_add(vap, "id", json_object_new_string(id)); diff --git a/src/wlan/legacy.c b/src/wlan/legacy.c index 1b2e6e5..328ea36 100644 --- a/src/wlan/legacy.c +++ b/src/wlan/legacy.c @@ -262,8 +262,8 @@ int wlan_apply_system_cfg(const char *system_cfg, json_object_object_add(root, "radio_table", radios); json_object_object_add(root, "vap_table", vaps); - printf("[openuf] Parsed legacy system_cfg: %zu radios, %zu VAPs\n", - json_object_array_length(radios), json_object_array_length(vaps)); + LOGF(stdout, "Parsed legacy system_cfg: %zu radios, %zu VAPs", + json_object_array_length(radios), json_object_array_length(vaps)); int result = wlan_apply_config(root, model); json_object_put(root); return result; diff --git a/src/wlan/provision.c b/src/wlan/provision.c index b722017..b00cca3 100644 --- a/src/wlan/provision.c +++ b/src/wlan/provision.c @@ -63,7 +63,7 @@ static int apply_vap(struct uci_context *ctx, vid = json_object_get_int(v); if (vid > 0) { if (wlan_ensure_vlan_network(vid) != 0) { - printf("[openuf] Failed to configure VLAN network %d\n", vid); + LOGF(stdout, "Failed to configure VLAN network %d", vid); return -1; } snprintf(target_network, sizeof(target_network), "vlan%d", vid); @@ -76,7 +76,7 @@ static int apply_vap(struct uci_context *ctx, snprintf(sec_name, sizeof(sec_name), "openuf_%d_%s", vap_idx, safe); if (wlan_uci_ensure_section(ctx, pkg, sec_name, "wifi-iface") != 0) { - printf("[openuf] Failed to create VAP section '%s'\n", sec_name); + LOGF(stdout, "Failed to create VAP section '%s'", sec_name); return -1; } @@ -112,8 +112,8 @@ static int apply_vap(struct uci_context *ctx, if (enterprise) { if (!auth_server || !auth_server[0] || !auth_secret || !auth_secret[0]) { - printf("[openuf] Refusing Enterprise VAP '%s': missing RADIUS " - "authentication server or secret\n", essid); + LOGF(stdout, "Refusing Enterprise VAP '%s': missing RADIUS " + "authentication server or secret", essid); return -1; } @@ -125,15 +125,15 @@ static int apply_vap(struct uci_context *ctx, wlan_uci_set_required(ctx, pkg, sec_name, "auth_port", port) != 0 || wlan_uci_set_required(ctx, pkg, sec_name, "auth_secret", auth_secret) != 0) { - printf("[openuf] Failed to store RADIUS authentication for " - "VAP '%s'\n", essid); + LOGF(stdout, "Failed to store RADIUS authentication for " + "VAP '%s'", essid); return -1; } if (acct_server && acct_server[0]) { if (!acct_secret || !acct_secret[0]) { - printf("[openuf] Refusing Enterprise VAP '%s': accounting " - "server has no secret\n", essid); + LOGF(stdout, "Refusing Enterprise VAP '%s': accounting " + "server has no secret", essid); return -1; } snprintf(path, sizeof(path), "wireless.%s.acct_server", sec_name); @@ -143,8 +143,8 @@ static int apply_vap(struct uci_context *ctx, wlan_uci_set_required(ctx, pkg, sec_name, "acct_port", port) != 0 || wlan_uci_set_required(ctx, pkg, sec_name, "acct_secret", acct_secret) != 0) { - printf("[openuf] Failed to store RADIUS accounting for " - "VAP '%s'\n", essid); + LOGF(stdout, "Failed to store RADIUS accounting for " + "VAP '%s'", essid); return -1; } } @@ -202,8 +202,8 @@ static int apply_vap(struct uci_context *ctx, wlan_radio_uses_ath9k(device_name)) { WLAN_UCI_SET_INT(ctx, "wireless", sec_name, "openuf_ft_requested", 1); ft = 0; - printf("[openuf] Disabled FT on unsupported 2.4 GHz ath9k radio %s\n", - device_name); + LOGF(stdout, "Disabled FT on unsupported 2.4 GHz ath9k radio %s", + device_name); } if (ft) { @@ -256,34 +256,34 @@ static int apply_vap(struct uci_context *ctx, /* Reassert and validate every option required to start a secure AP. */ if (wlan_uci_set_required(ctx, pkg, sec_name, "device", device_name) != 0) { - printf("[openuf] Failed to bind VAP '%s' to %s\n", - essid, device_name); + LOGF(stdout, "Failed to bind VAP '%s' to %s", + essid, device_name); return -1; } if (wlan_uci_set_required(ctx, pkg, sec_name, "mode", "ap") != 0 || wlan_uci_set_required(ctx, pkg, sec_name, "ssid", essid) != 0 || wlan_uci_set_required(ctx, pkg, sec_name, "encryption", wlan_security_to_uci(security)) != 0) { - printf("[openuf] Refusing incomplete VAP '%s': core AP options " - "could not be stored\n", essid); + LOGF(stdout, "Refusing incomplete VAP '%s': core AP options " + "could not be stored", essid); return -1; } if (!enterprise && pass && pass[0] && strcmp(security, "open") != 0 && wlan_uci_set_required(ctx, pkg, sec_name, "key", pass) != 0) { - printf("[openuf] Refusing unsecured VAP '%s': key could not be stored\n", - essid); + LOGF(stdout, "Refusing unsecured VAP '%s': key could not be stored", + essid); return -1; } if (wlan_uci_set_required(ctx, pkg, sec_name, "network", target_network) != 0) { - printf("[openuf] Refusing unsafe VAP '%s': cannot bind to %s\n", - essid, target_network); + LOGF(stdout, "Refusing unsafe VAP '%s': cannot bind to %s", + essid, target_network); return -1; } - printf("[openuf] VAP '%s' -> %s device=%s network=%s enc=%s " - "ft=%d bs=%d handoff=%d pmf=%d\n", - essid, sec_name, device_name, target_network, wlan_security_to_uci(security), - ft, band_steer, handoff, pmf); + LOGF(stdout, "VAP '%s' -> %s device=%s network=%s enc=%s " + "ft=%d bs=%d handoff=%d pmf=%d", + essid, sec_name, device_name, target_network, wlan_security_to_uci(security), + ft, band_steer, handoff, pmf); return 0; } @@ -353,7 +353,7 @@ int wlan_apply_config(struct json_object *config_json, } /* Stop hostapd so a deleted BSS cannot survive a netifd reload race. */ - printf("[openuf] Stopping Wi-Fi before controller provisioning...\n"); + LOGF(stdout, "Stopping Wi-Fi before controller provisioning..."); system("wifi down >/dev/null 2>&1"); /* Replace prior openuf_ VAPs while preserving unrelated UCI sections. */ @@ -371,8 +371,8 @@ int wlan_apply_config(struct json_object *config_json, radio_band = json_object_get_string(v); const char *device_name = wlan_device_for_band(model, radio_band); if (!device_name) { - printf("[openuf] Ignoring settings for unknown radio '%s'\n", - radio_band); + LOGF(stdout, "Ignoring settings for unknown radio '%s'", + radio_band); continue; } wlan_apply_radio(r, device_name, @@ -386,15 +386,15 @@ int wlan_apply_config(struct json_object *config_json, */ struct uci_context *ctx = uci_alloc_context(); if (!ctx) { - printf("[openuf] Failed to allocate UCI context\n"); + LOGF(stdout, "Failed to allocate UCI context"); return -1; } struct uci_package *pkg = NULL; if (uci_load(ctx, "wireless", &pkg) != UCI_OK) { char *uci_error = NULL; uci_get_errorstr(ctx, &uci_error, "wireless"); - printf("[openuf] Failed to load UCI wireless configuration: %s\n", - uci_error ? uci_error : "unknown UCI error"); + LOGF(stdout, "Failed to load UCI wireless configuration: %s", + uci_error ? uci_error : "unknown UCI error"); free(uci_error); uci_free_context(ctx); return -1; @@ -416,8 +416,8 @@ int wlan_apply_config(struct json_object *config_json, } } if (disabled_defaults) - printf("[openuf] Disabled %d default OpenWrt VAPs\n", - disabled_defaults); + LOGF(stdout, "Disabled %d default OpenWrt VAPs", + disabled_defaults); /* 3. Create VAPs and determine whether any WLAN requests steering. */ int steering_policy_enabled = 0; @@ -472,8 +472,8 @@ int wlan_apply_config(struct json_object *config_json, applied++; } if (!applied) { - printf("[openuf] Ignoring VAP with unknown radio '%s'\n", - radio_band ? radio_band : ""); + LOGF(stdout, "Ignoring VAP with unknown radio '%s'", + radio_band ? radio_band : ""); uci_unload(ctx, pkg); uci_free_context(ctx); return -1; @@ -485,8 +485,8 @@ int wlan_apply_config(struct json_object *config_json, if (uci_commit(ctx, &pkg, false) != UCI_OK) { char *uci_error = NULL; uci_get_errorstr(ctx, &uci_error, "wireless"); - printf("[openuf] Failed to commit UCI wireless configuration: %s\n", - uci_error ? uci_error : "unknown UCI error"); + LOGF(stdout, "Failed to commit UCI wireless configuration: %s", + uci_error ? uci_error : "unknown UCI error"); free(uci_error); uci_unload(ctx, pkg); uci_free_context(ctx); @@ -496,7 +496,7 @@ int wlan_apply_config(struct json_object *config_json, uci_free_context(ctx); if (wlan_configure_band_steering(steering_policy_enabled) != 0) - printf("[openuf] Failed to configure the band steering policy\n"); + LOGF(stdout, "Failed to configure the band steering policy"); /* * Reload netifd for generated VLAN devices, then bring the radios up one @@ -504,7 +504,7 @@ int wlan_apply_config(struct json_object *config_json, * setup after ACS. Start and verify each PHY independently, retrying a failed radio so * provisioning cannot leave one band visible but unusable. */ - printf("[openuf] Starting controller-managed Wi-Fi sequentially...\n"); + LOGF(stdout, "Starting controller-managed Wi-Fi sequentially..."); system("ubus call network reload >/dev/null 2>&1"); for (int i = 0; i < model->radio_map_len; i++) { char command[256]; @@ -516,14 +516,14 @@ int wlan_apply_config(struct json_object *config_json, strspn(device, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-") != strlen(device)) { - printf("[openuf] Refusing invalid radio name\n"); + LOGF(stdout, "Refusing invalid radio name"); continue; } int radio_up = 0; for (int attempt = 1; attempt <= 2 && !radio_up; attempt++) { - printf("[openuf] Starting %s (%s), attempt %d...\n", - device, model->radio_map[i].band, attempt); + LOGF(stdout, "Starting %s (%s), attempt %d...", + device, model->radio_map[i].band, attempt); snprintf(command, sizeof(command), "wifi up %s >/dev/null 2>&1", device); system(command); @@ -547,12 +547,12 @@ int wlan_apply_config(struct json_object *config_json, } if (!radio_up) - printf("[openuf] %s did not reach the up state; retrying\n", - device); + LOGF(stdout, "%s did not reach the up state; retrying", + device); } if (!radio_up) - printf("[openuf] %s failed after 2 start attempts\n", device); + LOGF(stdout, "%s failed after 2 start attempts", device); } /* Enable management features only after hostapd has registered each BSS. @@ -573,9 +573,9 @@ int wlan_apply_config(struct json_object *config_json, "\"bss_transition\": true }%c >/dev/null 2>&1", phy_index, 39, 39); if (system(command) != 0) - printf("[openuf] hostapd on phy%d lacks runtime 802.11v " - "support; continuing without BSS Transition\n", - phy_index); + LOGF(stdout, "hostapd on phy%d lacks runtime 802.11v " + "support; continuing without BSS Transition", + phy_index); } } diff --git a/src/wlan/radio.c b/src/wlan/radio.c index 4a0082c..59eab99 100644 --- a/src/wlan/radio.c +++ b/src/wlan/radio.c @@ -126,9 +126,9 @@ static void resolve_radio_map(const uf_model_t *model) model->radio_map[i].device); } - printf("[openuf] Radio mapping: %s -> %s%s\n", - model->radio_map[i].band, resolved_devices[i], - best >= 0 ? " (detected)" : " (model fallback)"); + LOGF(stdout, "Radio mapping: %s -> %s%s", + model->radio_map[i].band, resolved_devices[i], + best >= 0 ? " (detected)" : " (model fallback)"); } } @@ -279,8 +279,8 @@ void wlan_apply_radio(struct json_object *radio_json, struct uci_ptr ptr; if (uci_lookup_ptr(ctx, &ptr, path, true) == UCI_OK) uci_set(ctx, &ptr); - printf("[openuf] Radio %s standard: %s%s\n", device_name, htmode, - force_wifi4 ? " (Force WiFi 4)" : " (newest supported)"); + LOGF(stdout, "Radio %s standard: %s%s", device_name, htmode, + force_wifi4 ? " (Force WiFi 4)" : " (newest supported)"); } /* Channel: 0 = auto in UniFi */ diff --git a/src/wlan/uci.c b/src/wlan/uci.c index 8cd958c..3158c1a 100644 --- a/src/wlan/uci.c +++ b/src/wlan/uci.c @@ -195,8 +195,8 @@ int wlan_ensure_vlan_network(int vid) uci_unload(ctx, pkg); uci_free_context(ctx); if (ok) - printf("[openuf] Configured VLAN %d on uplink %s as network '%s'\n", - vid, vlan_uplink, interface_section); + LOGF(stdout, "Configured VLAN %d on uplink %s as network '%s'", + vid, vlan_uplink, interface_section); return ok ? 0 : -1; } @@ -213,7 +213,7 @@ int wlan_configure_band_steering(int enabled) struct uci_package *pkg = NULL; if (uci_load(ctx, "usteer", &pkg) != UCI_OK) { - printf("[openuf] Cannot load /etc/config/usteer\n"); + LOGF(stdout, "Cannot load /etc/config/usteer"); uci_free_context(ctx); return -1; } @@ -257,8 +257,8 @@ int wlan_configure_band_steering(int enabled) int ok = uci_commit(ctx, &pkg, false) == UCI_OK; uci_unload(ctx, pkg); uci_free_context(ctx); - printf("[openuf] Band steering policy %s (usteer)\n", - enabled ? "enabled" : "disabled"); + LOGF(stdout, "Band steering policy %s (usteer)", + enabled ? "enabled" : "disabled"); return ok ? 0 : -1; } @@ -299,8 +299,8 @@ void wlan_clear(void) if (delete_count > 0) { uci_commit(ctx, &pkg, false); - printf("[openuf] wlan_clear: removed %d managed VAPs\n", - delete_count); + LOGF(stdout, "wlan_clear: removed %d managed VAPs", + delete_count); } uci_unload(ctx, pkg); diff --git a/src/wlan/wlan_internal.h b/src/wlan/wlan_internal.h index fdb34b4..f6f27b9 100644 --- a/src/wlan/wlan_internal.h +++ b/src/wlan/wlan_internal.h @@ -5,6 +5,7 @@ #include #include #include +#include "config.h" enum wifi_standard { WIFI_STANDARD_UNKNOWN = 0,