Skip to content

Latest commit

 

History

History
237 lines (214 loc) · 7.28 KB

generic_port.md

File metadata and controls

237 lines (214 loc) · 7.28 KB

this is an example of generic impementation made using the ZEG serial library

code:

const zig_serial = @import("serial");
const std = @import("std");

const Driver = @import("ESPAT");
const WiFi = Driver.WiFi;
const Network = Driver.Network;
const Client = Network.Client;
const Runner = Driver.StandartRunner;

const wifi_ssid = "SSID";
const wifi_password = "password";
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,
    });
    var num: usize = 1234;
    WiFi_dev.set_WiFi_event_handler(WiFi_callback, &num);
    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);
    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});
        };
    }
}