Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to disable random MAC address in client mode #403

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.cache
/build
/build_emu
linux-4.9
Expand Down
1 change: 1 addition & 0 deletions mkapp/app/script/wlan_stop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/mnt/app/app/record/gogglecmd -live quit
sleep 1
killall rtspLive
killall wpa_supplicant
killall hostapd
killall udhcpd
killall dropbear
Expand Down
15 changes: 8 additions & 7 deletions src/core/defines.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#define DIAL_SENSITIVITY 1 // number of clicks before dial event is triggered
#define DIAL_SENSITIVITY 1 // number of clicks before dial event is triggered
#define DIAL_SENSITIVTY_TIMEOUT_MS 1000 // ms
#define CHANNEL_SHOWTIME 30 // must <= 127
#define CHANNEL_SHOWTIME 30 // must <= 127

#define GPIO_BEEP 131

Expand All @@ -20,8 +20,9 @@
#define DEV_SPI_VRX_L "/dev/mtd9"
#define DEV_SPI_VA "/dev/mtd10"

#define SELF_TEST_FILE "/mnt/extsd/self_test.txt"
#define NO_DIAL_FILE "/mnt/extsd/no_dial.txt"
#define APP_LOG_FILE "/mnt/extsd/HDZGOGGLE.log"
#define APP_BIN_FILE "/mnt/extsd/HDZGOGGLE"
#define DEVELOP_SCRIPT "/mnt/extsd/develop.sh"
#define SELF_TEST_FILE "/mnt/extsd/self_test.txt"
#define NO_DIAL_FILE "/mnt/extsd/no_dial.txt"
#define APP_LOG_FILE "/mnt/extsd/HDZGOGGLE.log"
#define APP_BIN_FILE "/mnt/extsd/HDZGOGGLE"
#define DEVELOP_SCRIPT "/mnt/extsd/develop.sh"
#define MAC_OVERRIDE_FILE "/mnt/extsd/macaddr.txt"
7 changes: 2 additions & 5 deletions src/core/settings.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#include "settings.h"

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <log/log.h>
#include <minIni.h>

#include "core/self_test.h"
#include "ui/page_common.h"
#include "util/filesystem.h"
#include "util/system.h"
Expand Down Expand Up @@ -197,7 +195,6 @@ const setting_t g_setting_defaults = {
.wifi = {
.enable = false,
.mode = 0,
.clientid = {""},
.ssid = {"HDZero", "MySSID"},
.passwd = {"divimath", "MyPassword"},
.dhcp = true,
Expand Down Expand Up @@ -435,7 +432,6 @@ void settings_load(void) {
// wifi
g_setting.wifi.enable = settings_get_bool("wifi", "enable", g_setting_defaults.wifi.enable);
g_setting.wifi.mode = ini_getl("wifi", "mode", g_setting_defaults.wifi.mode, SETTING_INI);
ini_gets("wifi", "clientid", g_setting_defaults.wifi.clientid, g_setting.wifi.clientid, WIFI_CLIENTID_MAX, SETTING_INI);
ini_gets("wifi", "ap_ssid", g_setting_defaults.wifi.ssid[0], g_setting.wifi.ssid[0], WIFI_SSID_MAX, SETTING_INI);
ini_gets("wifi", "ap_passwd", g_setting_defaults.wifi.passwd[0], g_setting.wifi.passwd[0], WIFI_PASSWD_MAX, SETTING_INI);
ini_gets("wifi", "sta_ssid", g_setting_defaults.wifi.ssid[1], g_setting.wifi.ssid[1], WIFI_SSID_MAX, SETTING_INI);
Expand All @@ -448,6 +444,7 @@ void settings_load(void) {
g_setting.wifi.rf_channel = ini_getl("wifi", "rf_channel", g_setting_defaults.wifi.rf_channel, SETTING_INI);
ini_gets("wifi", "root_pw", g_setting_defaults.wifi.root_pw, g_setting.wifi.root_pw, WIFI_PASSWD_MAX, SETTING_INI);
g_setting.wifi.ssh = settings_get_bool("wifi", "ssh", g_setting_defaults.wifi.ssh);
ini_gets("wifi", "mac", "", g_setting.wifi.mac, 18, SETTING_INI);

// no dial under video mode
g_setting.ease.no_dial = fs_file_exists(NO_DIAL_FILE);
Expand All @@ -466,4 +463,4 @@ void settings_load(void) {
unlink(APP_LOG_FILE);
g_setting.storage.logging = log_file_open(APP_LOG_FILE);
}
}
}
4 changes: 3 additions & 1 deletion src/core/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ enum {
typedef struct {
bool enable;
uint8_t mode; // 0 == WIFI_MODE_AP, 1 == WIFI_MODE_STA
char clientid[WIFI_CLIENTID_MAX];
char ssid[WIFI_MODE_COUNT][WIFI_SSID_MAX];
char passwd[WIFI_MODE_COUNT][WIFI_PASSWD_MAX];
bool dhcp;
Expand All @@ -220,6 +219,7 @@ typedef struct {
uint8_t rf_channel;
char root_pw[WIFI_SSID_MAX];
bool ssh;
char mac[18];
} wifi_t;

typedef struct {
Expand Down Expand Up @@ -291,6 +291,8 @@ int settings_put_osd_element_pos_y(const setting_osd_goggle_element_positions_t
int settings_put_osd_element_pos_x(const setting_osd_goggle_element_positions_t *pos, char *config_name);
int settings_put_osd_element_shown(bool show, char *config_name);

static bool is_valid_mac_address(const char mac_address[]);

#ifdef __cplusplus
}
#endif
118 changes: 106 additions & 12 deletions src/ui/page_wifi.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "page_wifi.h"

#include <arpa/inet.h>
#include <errno.h>
#include <linux/if.h>
#include <stdlib.h>
#include <sys/ioctl.h>
Expand All @@ -15,8 +14,8 @@
#include "core/common.hh"
#include "core/dvr.h"
#include "core/settings.h"
#include "lvgl/src/core/lv_obj.h"
#include "ui/page_common.h"
#include "ui/ui_attribute.h"
#include "ui/ui_keyboard.h"
#include "ui/ui_style.h"
#include "util/filesystem.h"
Expand Down Expand Up @@ -143,15 +142,18 @@ static void page_wifi_update_services() {
if ((fp = fopen(WIFI_STA_ON, "w"))) {
fprintf(fp, "#!/bin/sh\n");
fprintf(fp, "insmod /mnt/app/ko/xradio_mac.ko\n");
fprintf(fp, "insmod /mnt/app/ko/xradio_mac.ko\n");
fprintf(fp, "insmod /mnt/app/ko/xradio_core.ko\n");
fprintf(fp, "insmod /mnt/app/ko/xradio_wlan.ko\n");
fprintf(fp, "ifconfig wlan0 hw ether %s\n", g_setting.wifi.mac);

fprintf(fp, "ifconfig wlan0 up\n");

if (g_setting.wifi.dhcp) {
fprintf(fp,
"udhcpc -x hostname:%s -x 0x3d:%s -r %s -i wlan0 -b&\n",
g_setting.wifi.ssid[WIFI_MODE_AP],
g_setting.wifi.clientid,
g_setting.wifi.mac,
g_setting.wifi.ip_addr);
}

Expand Down Expand Up @@ -259,6 +261,50 @@ static void page_wifi_mask_password(lv_obj_t *obj, int size) {
lv_label_set_text(obj, buffer);
}

static bool page_wifi_is_valid_mac_address(const char mac_address[]) {
for (int i = 0; i < 17; i++) {
// first byte has to be even to be a valid MAC address for our usecase
if (i == 1 && (mac_address[i] != '0' && mac_address[i] != '2' && mac_address[i] != '4' && mac_address[i] != '6' && mac_address[i] != '8' && mac_address[i] != 'a' && mac_address[i] != 'A' && mac_address[i] != 'c' && mac_address[i] != 'C' && mac_address[i] != 'e' && mac_address[i] != 'E')) {
return false;
}
if (i % 3 == 2) {
if (mac_address[i] != ':') {
return false;
}
} else {
if (!(
mac_address[i] >= '0' && mac_address[i] <= '9' ||
mac_address[i] >= 'A' && mac_address[i] <= 'F' ||
mac_address[i] >= 'a' && mac_address[i] <= 'f')) {
return false;
}
}
}
return true;
}

static void page_wifi_generate_mac_address(char *mac_address) {
srandom(time(NULL));
sprintf(mac_address, "%02lx:%02lx:%02lx:%02lx:%02lx:%02lx",
random() & 254, // First byte must be even.
random() & 255,
random() & 255,
random() & 255,
random() & 255,
random() & 255);
}

static void page_wifi_read_mac_file(char *mac_address) {
FILE *file = fopen(MAC_OVERRIDE_FILE, "r");
char read_mac[18];
if (fgets(read_mac, 18, file) != NULL) {
if (page_wifi_is_valid_mac_address(read_mac)) {
strcpy(mac_address, read_mac);
}
}
fclose(file);
}

/**
* Update settings and apply them.
*/
Expand All @@ -278,9 +324,16 @@ static void page_wifi_update_settings() {

snprintf(g_setting.wifi.root_pw, WIFI_PASSWD_MAX, "%s", page_wifi.page_3.root_pw.text);

if (0 == strlen(g_setting.wifi.clientid)) {
page_wifi_generate_clientid(g_setting.wifi.clientid, WIFI_CLIENTID_MAX);
ini_puts("wifi", "clientid", g_setting.wifi.clientid, SETTING_INI);
// Generate one random MAC if none is set or if it is invalid.
if (0 == strlen(g_setting.wifi.mac) || !page_wifi_is_valid_mac_address(g_setting.wifi.mac)) {
page_wifi_generate_mac_address(g_setting.wifi.mac);
ini_puts("wifi", "mac", g_setting.wifi.mac, SETTING_INI);
}

// Check for override file and apply if it exists.
if (fs_file_exists(MAC_OVERRIDE_FILE)) {
page_wifi_read_mac_file(g_setting.wifi.mac);
ini_puts("wifi", "mac", g_setting.wifi.mac, SETTING_INI);
}

settings_put_bool("wifi", "enable", g_setting.wifi.enable);
Expand Down Expand Up @@ -314,7 +367,7 @@ static void page_wifi_update_settings() {
}

/**
* Acquire the actual address in use.
* Acquire the actual IP address in use.
*/
static const char *page_wifi_get_real_address() {
const char *address = NULL;
Expand All @@ -336,7 +389,37 @@ static const char *page_wifi_get_real_address() {
}

/**
* Updates the all notes on every page.
* Acquire the MAC address in use.
*/
static const char *page_wifi_get_real_mac_address() {
const char *address = NULL;
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

if (fd >= 0) {
struct ifreq ifr;
strcpy(ifr.ifr_name, "wlan0");

char mac[18];

if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) {
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)ifr.ifr_addr.sa_data[0],
(unsigned char)ifr.ifr_addr.sa_data[1],
(unsigned char)ifr.ifr_addr.sa_data[2],
(unsigned char)ifr.ifr_addr.sa_data[3],
(unsigned char)ifr.ifr_addr.sa_data[4],
(unsigned char)ifr.ifr_addr.sa_data[5]);
}
address = mac;

close(fd);
}

return address;
}

/**
* Updates the notes on page 1.
*/
static void page_wifi_update_page_1_notes() {
const char *address = page_wifi_get_real_address();
Expand All @@ -361,12 +444,23 @@ static void page_wifi_update_page_1_notes() {
lv_label_set_text(page_wifi.page_1.note, buffer);
}

/**
* Updates the notes on page 3.
*/
static void page_wifi_update_page_3_notes() {
const char *mac = page_wifi_get_real_mac_address();

static char buffer[1024];
snprintf(buffer,
sizeof(buffer),
"Password Requirements:\n"
" Minimum 8 characters, maximum 64 characters.\n\n");
" Minimum 8 characters, maximum 64 characters.\n\n"
"MAC-address:\n"
" %s\n\n"
"You can override the fixed MAC in client mode by creating the file macaddr.txt\n"
"with the new MAC inside on the SD card. Make sure there are no spaces!\n"
"Valid mac addresses start with an even byte.\n\n",
mac);

lv_label_set_text(page_wifi.page_3.note, buffer);
}
Expand Down Expand Up @@ -473,8 +567,8 @@ static void page_wifi_update_current_page(int which) {
lv_obj_clear_flag(page_wifi.page_2.gateway.input, LV_OBJ_FLAG_HIDDEN);

if (page_wifi.page_1.mode.button.current == WIFI_MODE_AP ||
(page_wifi.page_1.mode.button.current == WIFI_MODE_STA &&
page_wifi.page_2.dhcp.button.current == 1)) {
(page_wifi.page_1.mode.button.current == WIFI_MODE_STA &&
page_wifi.page_2.dhcp.button.current == 1)) {
lv_obj_clear_state(page_wifi.page_2.netmask.label, STATE_DISABLED);
lv_obj_clear_state(page_wifi.page_2.netmask.input, STATE_DISABLED);
lv_obj_clear_state(page_wifi.page_2.gateway.label, STATE_DISABLED);
Expand Down Expand Up @@ -1145,4 +1239,4 @@ void page_wifi_get_statusbar_text(char *buffer, int size) {
} else {
snprintf(buffer, size, "WiFi: Off");
}
}
}