Skip to content

Commit

Permalink
Add support for changing the hostname.
Browse files Browse the repository at this point in the history
  • Loading branch information
floitsch committed Oct 23, 2024
1 parent f1915e4 commit 02819b6
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 1 deletion.
31 changes: 31 additions & 0 deletions lib/system/system.toit
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
// found in the lib/LICENSE file.
import system.trace show send-trace-message
import system.storage

// Use lazy initialization to delay opening the storage bucket
// until we need it the first time. From that point forward,
// we keep it around forever.
bucket_/storage.Bucket ::= storage.Bucket.open --flash "toitlang.org/system"

/** The number of bits per byte. */
BITS-PER-BYTE ::= 8
Expand Down Expand Up @@ -247,3 +253,28 @@ If the program is run as an executable, this is the fully resolved path to the
*/
program-path -> string?:
#primitive.core.program-path

/**
The hostname of the machine running the program.
*/
hostname -> string:
if platform == PLATFORM-FREERTOS:
config-name := bucket_.get "hostname"
if config-name: return config-name
return hostname_

/**
Sets the hostname of the machine running the program.
This operation is not supported on all platforms.
Only new network connections will use the new hostname. Also, some
routers may cache the old hostname for a while.
*/
hostname= hostname/string -> none:
if platform != PLATFORM-FREERTOS:
throw "Setting hostname is not supported on this platform"
bucket_["hostname"] = hostname

hostname_ -> string:
#primitive.core.hostname
2 changes: 2 additions & 0 deletions src/compiler/propagation/type_primitive_core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ TYPE_PRIMITIVE_ANY(firmware_mapping_at)
TYPE_PRIMITIVE_ANY(firmware_mapping_copy)
TYPE_PRIMITIVE_BYTE_ARRAY(rtc_user_bytes)

TYPE_PRIMITIVE_STRING(hostname)

bool TypePrimitive::uses_entry_task(unsigned module, unsigned index) {
return module == INDEX_core && index == CoreIndexes::task_new;
}
Expand Down
1 change: 1 addition & 0 deletions src/compiler/propagation/type_primitive_ethernet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ TYPE_PRIMITIVE_ANY(connect)
TYPE_PRIMITIVE_ANY(setup_ip)
TYPE_PRIMITIVE_ANY(disconnect)
TYPE_PRIMITIVE_ANY(get_ip)
TYPE_PRIMITIVE_ANY(set_hostname)

} // namespace toit::compiler
} // namespace toit
1 change: 1 addition & 0 deletions src/compiler/propagation/type_primitive_wifi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ TYPE_PRIMITIVE_ANY(get_ip)
TYPE_PRIMITIVE_ANY(init_scan)
TYPE_PRIMITIVE_ANY(start_scan)
TYPE_PRIMITIVE_ANY(read_scan)
TYPE_PRIMITIVE_ANY(set_hostname)
TYPE_PRIMITIVE_ARRAY(ap_info)

} // namespace toit::compiler
Expand Down
3 changes: 3 additions & 0 deletions src/primitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ namespace toit {
PRIMITIVE(firmware_mapping_at, 2) \
PRIMITIVE(firmware_mapping_copy, 5) \
PRIMITIVE(rtc_user_bytes, 0) \
PRIMITIVE(hostname, 0) \

#define MODULE_TIMER(PRIMITIVE) \
PRIMITIVE(init, 0) \
Expand Down Expand Up @@ -324,6 +325,7 @@ namespace toit {
PRIMITIVE(init_scan, 1) \
PRIMITIVE(start_scan, 4) \
PRIMITIVE(read_scan, 1) \
PRIMITIVE(set_hostname, 2) \
PRIMITIVE(ap_info, 1) \

#define MODULE_ETHERNET(PRIMITIVE) \
Expand All @@ -334,6 +336,7 @@ namespace toit {
PRIMITIVE(setup_ip, 1) \
PRIMITIVE(disconnect, 2) \
PRIMITIVE(get_ip, 1) \
PRIMITIVE(set_hostname, 2) \

#define MODULE_BLE(PRIMITIVE) \
PRIMITIVE(init, 0) \
Expand Down
15 changes: 15 additions & 0 deletions src/primitive_core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2571,4 +2571,19 @@ PRIMITIVE(rtc_user_bytes) {
}
#endif

PRIMITIVE(hostname) {
const char* name;
#ifdef TOIT_ESP32
name = CONFIG_LWIP_LOCAL_HOSTNAME;
#else
char buffer[HOST_NAME_MAX + 1];
int result = gethostname(buffer, sizeof(buffer));
if (result != 0) {
return Primitive::os_error(errno, process);
}
name = buffer;
#endif
return process->allocate_string_or_error(name);
}

} // namespace toit
14 changes: 14 additions & 0 deletions src/resources/ethernet_esp32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ class EthernetResourceGroup : public ResourceGroup {

uint32_t on_event(Resource* resource, word data, uint32_t state);

esp_err_t set_hostname(const char* hostname) {
return esp_netif_set_hostname(netif_, hostname);
}

private:
int id_;
esp_eth_mac_t* mac_;
Expand Down Expand Up @@ -449,6 +453,16 @@ PRIMITIVE(get_ip) {
return result;
}

PRIMITIVE(set_hostname) {
ARGS(EthernetResourceGroup, group, cstring, hostname);

if (strlen(hostname) > 32) FAIL(INVALID_ARGUMENT);

esp_err_t err = group->set_hostname(hostname);
if (err != ESP_OK) return Primitive::os_error(err, process);

return process->null_object();
}

} // namespace toit

Expand Down
16 changes: 15 additions & 1 deletion src/resources/wifi_esp32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ class WifiResourceGroup : public ResourceGroup {

esp_err_t start_scan(bool passive, int channel, uint32_t period_ms);

esp_err_t set_hostname(const char* hostname) {
return esp_netif_set_hostname(netif_, hostname);
}

~WifiResourceGroup() {
esp_err_t err = ESP_OK;
for (int i = 0; i < DEINIT_ATTEMPTS; i++) {
Expand Down Expand Up @@ -464,7 +468,6 @@ esp_err_t WifiResourceGroup::start_scan(bool passive, int channel, uint32_t peri
return esp_wifi_scan_start(&config, false);
}


MODULE_IMPLEMENTATION(wifi, MODULE_WIFI)

PRIMITIVE(init) {
Expand Down Expand Up @@ -763,6 +766,17 @@ PRIMITIVE(read_scan) {
return ap_array;
}

PRIMITIVE(set_hostname) {
ARGS(WifiResourceGroup, group, cstring, hostname);

if (strlen(hostname) > 32) FAIL(INVALID_ARGUMENT);

esp_err_t err = group->set_hostname(hostname);
if (err != ESP_OK) return Primitive::os_error(err, process);

return process->null_object();
}

PRIMITIVE(ap_info) {
ARGS(WifiResourceGroup, group);

Expand Down
5 changes: 5 additions & 0 deletions system/extensions/esp32/wifi.toit
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import net.udp
import net.wifi

import encoding.tison
import system
import system.assets
import system.firmware
import system.storage
Expand Down Expand Up @@ -226,6 +227,7 @@ class WifiModule implements NetworkModule:
return address_

connect -> none:
wifi-set-hostname_ resource-group_ system.hostname
with-timeout WIFI-CONNECT-TIMEOUT_: wait-for-connected_
if ap:
wait-for-static-ip-address_
Expand Down Expand Up @@ -357,6 +359,9 @@ class WifiModule implements NetworkModule:
wifi-init_ ap:
#primitive.wifi.init

wifi-set-hostname_ resource-group hostname:
#primitive.wifi.set-hostname

wifi-close_ resource-group:
#primitive.wifi.close

Expand Down
19 changes: 19 additions & 0 deletions tests/hostname-test.toit
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (C) 2024 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the tests/LICENSE file.
import expect show *
import host.pipe
import system

main:
expected-hostname/string := ?
if system.platform == system.PLATFORM-WINDOWS:
expected-hostname = pipe.backticks "hostname"
else if system.platform == system.PLATFORM-LINUX:
expected-hostname = pipe.backticks "hostnamectl" "hostname"
else:
expected-hostname = pipe.backticks "hostname" "-s"
expected-hostname = expected-hostname.trim

expect-equals expected-hostname system.hostname

0 comments on commit 02819b6

Please sign in to comment.