Networking
Endpoint provides full networking through .NET's standard System.Net
stack (sockets, HTTP/HTTPS, WebSockets, TLS). The Endpoint-specific
GHIElectronics.Endpoint.Devices.Network package is only for bringing the
network interface up and configuring it. The same package is shipped for
Python and C/C++, with the same class and method names.
Two interface types are supported:
- Ethernet: the board's built-in Ethernet, or any USB Ethernet adapter.
- Wi-Fi: a built-in Wi-Fi module, or a USB Wi-Fi dongle.
Settings persist in /config/network.json. Nothing starts automatically at
boot; the application calls Enable() on the interfaces it wants up.
Wi-Fi
- .NET
- Python
- C/C++
using GHIElectronics.Endpoint.Devices.Network;
var wifi = NetworkController.FromType(NetworkType.Wifi);
var settings = new WiFiNetworkInterfaceSettings {
Ssid = "MyNetwork",
Password = "secret123",
Security = WiFiSecurityType.Wpa2,
IsDhcpEnabled = true,
};
wifi.SetInterfaceSettings(settings); // saves to /config/network.json
wifi.Enable(); // brings the interface up, runs DHCP
Console.WriteLine($"Connected: {wifi.IsConnected}");
Console.WriteLine($"Interface: {wifi.Name}");
// Standard .NET info is also available
var nic = wifi.NetworkInterface;
if (nic != null) {
foreach (var ip in nic.GetIPProperties().UnicastAddresses)
Console.WriteLine(ip.Address);
}
import socket
from GHIElectronics.Endpoint.Devices.Network import (
NetworkController, NetworkType,
WiFiNetworkInterfaceSettings, WiFiSecurityType,
)
wifi = NetworkController.FromType(NetworkType.Wifi)
settings = WiFiNetworkInterfaceSettings()
settings.Ssid = "MyNetwork"
settings.Password = "secret123"
settings.Security = WiFiSecurityType.Wpa2
settings.IsDhcpEnabled = True
wifi.SetInterfaceSettings(settings) # saves to /config/network.json
wifi.Enable() # brings the interface up, runs DHCP
print(f"Connected: {wifi.IsConnected}")
print(f"Interface: {wifi.Name}")
# Standard Python info is also available via the socket module
if wifi.Name:
print(socket.gethostbyname(socket.gethostname()))
#include <cstdio>
#include <endpoint/Network.h>
using namespace GHIElectronics::Endpoint::Devices::Network;
auto wifi = NetworkController::FromType(NetworkType::Wifi);
WiFiNetworkInterfaceSettings settings;
settings.Ssid = "MyNetwork";
settings.Password = "secret123";
settings.Security = WiFiSecurityType::Wpa2;
settings.IsDhcpEnabled = true;
wifi->SetInterfaceSettings(settings); // saves to /config/network.json
wifi->Enable(); // brings the interface up, runs DHCP
std::printf("Connected: %d\n", wifi->IsConnected() ? 1 : 0);
std::printf("Interface: %s\n", wifi->Name().c_str());
Ethernet
Static IP:
- .NET
- Python
- C/C++
using System.Net;
using GHIElectronics.Endpoint.Devices.Network;
var eth = NetworkController.FromType(NetworkType.Ethernet);
var settings = new NetworkInterfaceSettings {
IsDhcpEnabled = false,
Address = IPAddress.Parse("192.168.1.50"),
SubnetMask = IPAddress.Parse("255.255.255.0"),
GatewayAddress = IPAddress.Parse("192.168.1.1"),
DnsAddresses = new[] { IPAddress.Parse("8.8.8.8") },
};
eth.SetInterfaceSettings(settings);
eth.Enable();
from GHIElectronics.Endpoint.Devices.Network import (
NetworkController, NetworkType, NetworkInterfaceSettings,
)
eth = NetworkController.FromType(NetworkType.Ethernet)
settings = NetworkInterfaceSettings()
settings.IsDhcpEnabled = False
settings.Address = "192.168.1.50"
settings.SubnetMask = "255.255.255.0"
settings.GatewayAddress = "192.168.1.1"
settings.DnsAddresses = ["8.8.8.8"]
eth.SetInterfaceSettings(settings)
eth.Enable()
#include <endpoint/Network.h>
using namespace GHIElectronics::Endpoint::Devices::Network;
auto eth = NetworkController::FromType(NetworkType::Ethernet);
NetworkInterfaceSettings settings;
settings.IsDhcpEnabled = false;
settings.Address = "192.168.1.50";
settings.SubnetMask = "255.255.255.0";
settings.GatewayAddress = "192.168.1.1";
settings.DnsAddresses = {"8.8.8.8"};
eth->SetInterfaceSettings(settings);
eth->Enable();
DHCP (the common case):
- .NET
- Python
- C/C++
var eth = NetworkController.FromType(NetworkType.Ethernet);
eth.SetInterfaceSettings(new NetworkInterfaceSettings { IsDhcpEnabled = true });
eth.Enable();
from GHIElectronics.Endpoint.Devices.Network import (
NetworkController, NetworkType, NetworkInterfaceSettings,
)
eth = NetworkController.FromType(NetworkType.Ethernet)
settings = NetworkInterfaceSettings()
settings.IsDhcpEnabled = True
eth.SetInterfaceSettings(settings)
eth.Enable()
#include <endpoint/Network.h>
using namespace GHIElectronics::Endpoint::Devices::Network;
auto eth = NetworkController::FromType(NetworkType::Ethernet);
NetworkInterfaceSettings settings;
settings.IsDhcpEnabled = true;
eth->SetInterfaceSettings(settings);
eth->Enable();
Using the network
Once an interface is enabled, use the standard networking surface of your language (HTTP, sockets, WebSockets, TLS) exactly as you would on a PC:
- .NET
- Python
- C/C++
using var http = new HttpClient();
var json = await http.GetStringAsync("https://api.example.com/status");
Console.WriteLine(json);
import urllib.request
with urllib.request.urlopen("https://api.example.com/status") as resp:
print(resp.read().decode())
// The Endpoint firmware ships libcurl. Link with -lcurl.
#include <cstdio>
#include <curl/curl.h>
static size_t WriteCallback(void* data, size_t size, size_t count, void*) {
std::fwrite(data, size, count, stdout);
return size * count;
}
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com/status");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
TLS certificates
HTTPS clients on Endpoint trust the public CA bundle out of the box, same as any desktop. If your server uses a self-signed certificate or a private CA, ship the CA certificate (PEM file) with your app and tell the HTTP client to trust it.
- .NET (C#)
- Python
- C/C++
using System.IO;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
var ca = new X509Certificate2(Path.Combine(AppContext.BaseDirectory, "ca.crt"));
var handler = new HttpClientHandler {
ServerCertificateCustomValidationCallback = (msg, chain, errors) => {
chain.ChainPolicy.CustomTrustStore.Add(ca);
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
return chain.Build(chain.ChainElements[0].Certificate);
},
};
using var http = new HttpClient(handler);
var body = await http.GetStringAsync("https://my-server.local/");
For mutual TLS (client certificate too), add handler.ClientCertificates.Add(new X509Certificate2("client.pfx", password));.
import requests
from pathlib import Path
cert = str(Path(__file__).parent / "ca.crt")
r = requests.get("https://my-server.local/", verify=cert)
print(r.text)
For mutual TLS, pass the client cert + key: requests.get(url, verify=ca, cert=(client_cert, client_key)).
Install requests the usual way: pip install requests.
The firmware ships with libcurl + its OpenSSL backend. Drop the curl headers into your project (download from curl.se or copy from a Linux libcurl4-openssl-dev package), then:
#include <curl/curl.h>
#include <filesystem>
auto cert = std::filesystem::canonical("/proc/self/exe").parent_path() / "ca.crt";
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "https://my-server.local/");
curl_easy_setopt(curl, CURLOPT_CAINFO, cert.c_str());
curl_easy_perform(curl);
curl_easy_cleanup(curl);
For mutual TLS, add curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.crt") and CURLOPT_SSLKEY for the private key.
Higher-level protocols
For pub/sub messaging and edge-gateway patterns see MQTT and Endpoint as gateway under Cloud, IoT and Industrial.