The esp8266 is compatible with most devices using this driver, with only a few modifications to the network device required:
-
TCP/SSL do not have the timeout field
-
it is not possible to configure the recv mode individually for each socket, the mode must be chosen in the function:
set_network_mode
const zig_serial = @import("serial");
const std = @import("std");
const Driver = @import("ESPAT");
const WiFi = Driver.WiFi;
const Network = Driver.ESP8266Network;
const Client = Network.Client;
const Runner = Driver.StandartRunner;
const wifi_ssid = "GUSTAVO";
const wifi_password = "anjos2018";
const html = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE html>\r\n<html lang=\"pt-BR\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<title>Hello World</title>\r\n<p>All Your Codebase Are Belong To Us</p>\r\n</head>\r\n<body>\r\n<h1>Hello World</h1>\r\n</body>\r\n</html>\r\n";
var rv_internal_buf: [2048]u8 = undefined;
fn rx_callback(free_size: usize, user_data: ?*anyopaque) []u8 {
if (user_data) |data| {
const serial: *std.fs.File = @ptrCast(@alignCast(data));
var size: usize = 0;
for (0..free_size) |_| {
const b = serial.reader().readByte() catch break;
rv_internal_buf[size] = b;
size += 1;
if (b == '\n' or b == '>') break;
}
return rv_internal_buf[0..size];
}
std.log.info("null args on RX", .{});
return rv_internal_buf[0..0];
}
fn TX_callback(data: []const u8, user_data: ?*anyopaque) void {
if (user_data) |userdata| {
const serial: *std.fs.File = @ptrCast(@alignCast(userdata));
serial.writer().writeAll(data) catch return;
}
}
fn WiFi_callback(event: WiFi.Event, _: ?*anyopaque) void {
switch (event) {
.AP_DISCONNECTED => {
std.log.info("WiFi disconnect from {s}", .{wifi_ssid});
},
.AP_CON_START => {
std.log.info("WiFi conn start", .{});
},
.AP_CONNECTED => {
std.log.info("WiFi connect waiting for IP", .{});
},
.AP_GOT_IP => |ip| {
std.log.info("WiFi got ip {s}", .{ip});
},
else => {
std.log.info("WiFi got event {any}", .{event});
},
}
}
fn server_callback(client: Client, user_data: ?*anyopaque) void {
_ = user_data;
switch (client.event) {
.Connected => {
std.log.info("Client {d} from {s}:{d} connected to the server!", .{
client.id,
client.remote_host.?,
client.remote_port.?,
});
},
.DataReport => |len| {
std.log.info("server: id {} have {} bytes in queue", .{ client.id, len });
client.accept() catch |err| {
std.log.info("SERVER: got error {}, on bind {}", .{ err, client.id });
};
},
.ReadData => |data| {
std.log.info("server got {s}", .{data});
client.send(@constCast(html)) catch |err| {
std.log.info("SERVER: got error {}, on bind {}", .{ err, client.id });
};
client.close() catch |err| {
std.log.info("SERVER: close got error {}", .{err});
};
},
else => {},
}
}
var req_buf_tcp: [200]u8 = undefined;
fn tcp_callback(client: Client, user_data: ?*anyopaque) void {
_ = user_data;
switch (client.event) {
.Connected => {
client.send("teste\r\n\r\n") catch unreachable;
std.log.info("TCP send data!", .{});
},
.DataReport => |len| {
std.log.info("client TCP: have {} bytes in queue", .{len});
client.accept() catch |err| {
std.log.info("tcp got error {}, on bind {}", .{ err, client.id });
};
},
.ReadData => |data| {
std.log.info("Client got {d}bytes: {s}", .{ data.len, data });
},
else => {
std.log.info("CLIENT TCP EVENT: {any}", .{client.event});
},
}
}
//all data passed to send or send_to needs to live until a Send event occurs
var req_buf_udp: [200]u8 = undefined;
var remote_host: [50]u8 = undefined;
fn udp_callback(client: Client, user_data: ?*anyopaque) void {
_ = user_data;
switch (client.event) {
.ReadData => |data| {
const host_len = client.remote_host.?.len;
std.mem.copyForwards(u8, &remote_host, client.remote_host.?);
const msg = std.fmt.bufPrint(&req_buf_udp, "{d}\r\n", .{data.len}) catch unreachable;
client.send_to(msg, remote_host[0..host_len], client.remote_port.?) catch |err| {
std.log.info("udp got error {any}", .{err});
};
},
else => {
std.log.info("CLIENT UDP EVENT: {any}", .{client.event});
},
}
}
const STA_config = WiFi.STAConfig{
.ssid = wifi_ssid,
.pwd = wifi_password,
.wifi_protocol = .{
.@"802.11b" = 1,
.@"802.11g" = 1,
.@"802.11n" = 1,
},
.wifi_ip = .{ .static = .{ .ip = "192.168.15.37" } },
};
const AP_config = WiFi.APConfig{
.ssid = "banana",
.channel = 5,
.ecn = .OPEN,
.wifi_protocol = .{
.@"802.11b" = 1,
.@"802.11g" = 1,
.@"802.11n" = 1,
},
.mac = "00:C0:DA:F0:F0:00",
.wifi_ip = .{ .DHCP = {} },
};
const config_tcp = Network.ConnectConfig{
.recv_mode = .passive,
.remote_host = "google.com",
.remote_port = 80,
.config = .{
.tcp = .{ .keep_alive = 100 },
},
};
const config_udp = Network.ConnectConfig{
.recv_mode = .active,
.remote_host = "0.0.0.0",
.remote_port = 1234,
.config = .{
.udp = .{
.local_port = 1234,
.mode = .Change_all,
},
},
};
const server_config = Network.ServerConfig{
.recv_mode = .passive,
.callback = server_callback,
.user_data = null,
.server_type = .TCP,
.port = 80,
.timeout = 2600,
};
pub fn main() !void {
const port_name = "/dev/ttyUSB0";
var net_dev = Network.Device(5).init();
var WiFi_dev = WiFi.Device.init();
var serial = std.fs.cwd().openFile(port_name, .{ .mode = .read_write }) catch |err| switch (err) {
error.FileNotFound => {
std.debug.print("Invalid config: the serial port '{s}' does not exist.\n", .{port_name});
return;
},
else => return err,
};
defer serial.close();
var my_drive = Runner.Runner(.{ .TX_event_pool = 30, .network_recv_size = 600 }).init(TX_callback, rx_callback, &serial);
defer my_drive.deinit_driver();
try zig_serial.configureSerialPort(serial, zig_serial.SerialConfig{
.baud_rate = 115200,
.word_size = .eight,
.parity = .none,
.stop_bits = .one,
.handshake = .none,
});
WiFi_dev.set_WiFi_event_handler(WiFi_callback, null);
try my_drive.init_driver();
net_dev.link_device(&my_drive);
WiFi_dev.link_device(&my_drive);
try WiFi_dev.set_WiFi_mode(.AP_STA);
try WiFi_dev.WiFi_config_AP(AP_config);
try WiFi_dev.WiFi_connect_AP(STA_config);
try net_dev.set_network_mode(.SERVER_CLIENT, .active);
const id_udp = try net_dev.bind(udp_callback, null);
const id_tcp = try net_dev.bind(tcp_callback, null);
try net_dev.connect(id_tcp, config_tcp);
try net_dev.connect(id_udp, config_udp);
try net_dev.create_server(server_config);
while (true) {
my_drive.process() catch |err| {
_ = std.log.err("Driver got error: {}", .{err});
};
}
}