refactor(stdio): replace console/terminal command system with buffer-based stdio - Introduced stdio.pas as the unified command I/O layer. - All 31 command procedures across 15 files now receive stdin_buf, stdout_buf, and stderr_buf (POutBuf) instead of a single outbuf. - vterminal.pas creates all three buffers per command invocation and displays both stdout and stderr. - Deleted console.pas, terminal.pas, and 9 obsolete windowing programs (shell, splash, edit, memview, themer, netlog, vmlog, vmstate, udpcat). - Migrated all registerCommand calls to stdio, rewrote vterminal processCommand to use stdio.findCommand, and added proper error routing to stderr for invalid params, bad paths, and system errors. refactor(syslog): replace console logging with serial-backed syslog - Introduced syslog.pas for kernel-level logging over serial/dev. - Migrated all boot logging in kernel.pas from console.outputln/ writestringln to syslog.logln/writestringln. - Converted 19 fault handlers, hashmap, lists, scheduler, tracer, net, udp, and all driver init paths to use syslog. - Rewrote BSOD in util.pas (50+ calls) from console to syslog. - Removed CONSOLE_SLOW_REDRAW, TRGB565, TRGB565Pair, and HWND from system.pas. fix(keyboard): add ring buffer and proper press/release cycling for LVGL input - Replaced the single last_key/key_pressed slot in lvgl.pas with a 16-entry ring buffer (kb_buf, kb_head, kb_tail) to prevent ISR overwrites when typing fast. - Added a kb_pending_release flag so each keystroke gets a full PRESSED->RELEASED cycle before the next key is consumed — LVGL requires this pairing and was silently dropping intermediate keys when receiving consecutive PRESSED events without intervening releases. feat(vterminal): use Hack monospace font for terminal output - Added Hack Regular 14px (hack_14.c) as a custom LVGL font. - Removed the .static_bitmap field from the generated font file (not present in LVGL 9.2 lv_font_t struct). - Declared the hack_14 external symbol in lvgl.pas and switched vterminal's text label from lv_font_montserrat_14 to hack_14 for proper monospace terminal rendering.
221 lines
7.0 KiB
ObjectPascal
221 lines
7.0 KiB
ObjectPascal
// Copyright 2021 Kieron Morris
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
{
|
|
Driver->Net->L3->IPv4 - Internet Protocol Version 4 Driver.
|
|
|
|
@author(Kieron Morris <[email protected]>)
|
|
}
|
|
unit ipv4;
|
|
|
|
interface
|
|
|
|
uses
|
|
tracer, lmemorymanager,
|
|
util, strings,
|
|
net, nettypes, netutils,
|
|
lists,
|
|
eth2;
|
|
|
|
procedure send(p_data : void; p_len : uint16; p_context : PPacketContext);
|
|
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
|
|
function getIPv4Config : PIPv4Configuration;
|
|
procedure register;
|
|
|
|
implementation
|
|
|
|
uses
|
|
arp, stdio;
|
|
|
|
var
|
|
Registered : Boolean = false;
|
|
Protocols : Array[0..255] of TRecvCallback;
|
|
Config : TIPv4Configuration;
|
|
CurrentID : uint16 = 0;
|
|
|
|
function getIPv4Config : PIPv4Configuration;
|
|
begin
|
|
getIPv4Config:= @Config;
|
|
end;
|
|
|
|
procedure send(p_data : void; p_len : uint16; p_context : PPacketContext);
|
|
var
|
|
Header : TIPV4Header;
|
|
Len : uint16;
|
|
CHK : uint16;
|
|
buffer : void;
|
|
|
|
begin
|
|
inc(CurrentID);
|
|
Header.version:= 4;
|
|
Header.header_len:= 5;
|
|
Header.ToS:= 0;
|
|
Len:= 20 + p_len;
|
|
Header.total_len_Hi:= Len SHR 8;
|
|
Header.total_len_Lo:= Len AND $FF;
|
|
Header.identifier_Hi:= CurrentID SHR 8;
|
|
Header.identifier_Lo:= CurrentID AND $FF;
|
|
Header.Flags:= 0;
|
|
Header.Fragment_Off:= 0;
|
|
Header.TTL:= p_context^.TTL;
|
|
Header.Protocol:= p_context^.Protocol.L4 AND $FF;
|
|
Header.HDR_CHK_Hi:= 0;
|
|
Header.HDR_CHK_Lo:= 0;
|
|
CopyIPv4(@getIPv4Config^.Address[0], @Header.Src[0]);
|
|
CopyIPv4(@p_context^.IP.Destination[0], @Header.Dst[0]);
|
|
Header.Options:= 0;
|
|
Header.Padding:= 0;
|
|
CHK:= calculateChecksum(puint16(@Header), sizeof(TIPV4Header));
|
|
Header.HDR_CHK_Hi:= CHK AND $FF;//CHK SHR 8;
|
|
Header.HDR_CHK_Lo:= CHK SHR 8;//CHK AND $FF;
|
|
Buffer:= kalloc(Len);
|
|
memcpy(uint32(@Header), uint32(Buffer), Header.header_len * 4);
|
|
memcpy(uint32(p_data), uint32(Buffer) + (Header.header_len * 4), p_len);
|
|
eth2.send(Buffer, (Header.header_len * 4) + p_len, $0800, p_context);
|
|
kfree(Buffer);
|
|
end;
|
|
|
|
procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext);
|
|
var
|
|
Header : PIPV4Header;
|
|
AHeader : TIPV4AbstractHeader;
|
|
i : Integer;
|
|
buf : puint8;
|
|
len : uint16;
|
|
|
|
begin
|
|
Header:= PIPV4Header(p_data);
|
|
AHeader.version:= Header^.version;
|
|
AHeader.header_len:= Header^.header_len;
|
|
AHeader.ToS:= Header^.ToS;
|
|
AHeader.total_len:= (Header^.total_len_Hi SHL 8) + Header^.total_len_Lo;
|
|
AHeader.identifier:= (Header^.identifier_Hi SHL 8) + Header^.identifier_Lo;
|
|
AHeader.Flags.RS:= false;
|
|
AHeader.Flags.DF:= (Header^.Flags AND $2) > 0;
|
|
AHeader.Flags.MF:= (Header^.Flags AND $1) > 0;
|
|
AHeader.Fragment_Off:= Header^.Fragment_Off;
|
|
AHeader.TTL:= Header^.TTL;
|
|
AHeader.Protocol:= Header^.Protocol;
|
|
AHeader.HDR_CHK:= (Header^.HDR_CHK_Hi SHL 8) + Header^.HDR_CHK_Lo;
|
|
for i:=0 to 3 do begin
|
|
AHeader.Src[i]:= Header^.Src[i];
|
|
AHeader.Dst[i]:= Header^.Dst[i];
|
|
end;
|
|
AHeader.Options:= Header^.Options;
|
|
|
|
buf:= puint8(p_data);
|
|
buf:= buf + (AHeader.header_len * 4);
|
|
len:= p_len - (AHeader.header_len * 4);
|
|
|
|
copyIPv4(@AHeader.Src[0], @p_context^.IP.Source[0]);
|
|
copyIPv4(@AHeader.Dst[0], @p_context^.IP.Destination[0]);
|
|
|
|
if Config.UP then begin
|
|
if (IPEqual(@Config.Address[0], @AHeader.Dst[0])) OR (AHeader.Dst[3] = 255) OR (IPEqual(@Config.Address[0], @NULL_IP[0])) then begin
|
|
if Protocols[AHeader.Protocol] <> nil then begin
|
|
Protocols[AHeader.Protocol](void(buf), len, p_context);
|
|
end;
|
|
end;
|
|
end;
|
|
pop_trace;
|
|
end;
|
|
|
|
procedure terminal_command_ifconfig(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
|
var
|
|
Command, Sub, Address, Gateway, Netmask : pchar;
|
|
_Address, _Gateway, _Netmask : puint8;
|
|
Target : TIPv4Address;
|
|
context : PPacketContext;
|
|
i : uint32;
|
|
|
|
begin
|
|
if paramCount(params) > 1 then begin
|
|
Command:= GetParam(0, Params);
|
|
if StringEquals(Command, 'set') then begin
|
|
if paramCount(params) > 3 then begin
|
|
Address:= GetParam(1, Params);
|
|
Gateway:= GetParam(2, Params);
|
|
Netmask:= GetParam(3, Params);
|
|
_Address:= stringToIPv4(Address);
|
|
_Gateway:= stringToIPv4(Gateway);
|
|
_Netmask:= stringToIPv4(Netmask);
|
|
copyIPv4(_Address, @Config.Address[0]);
|
|
copyIPv4(_Gateway, @Config.Gateway[0]);
|
|
copyIPv4(_Netmask, @Config.Netmask[0]);
|
|
kfree(void(_Address));
|
|
kfree(void(_Gateway));
|
|
kfree(void(_Netmask));
|
|
end else begin
|
|
stdio.bufWriteStrLn(stderr_buf, 'Invalid number of params to call ''set''.');
|
|
end;
|
|
end;
|
|
if StringEquals(Command, 'net') then begin
|
|
Sub:= GetParam(1, Params);
|
|
if StringEquals(Sub, 'up') then begin
|
|
Config.UP:= true;
|
|
end;
|
|
if StringEquals(Sub, 'down') then begin
|
|
Config.UP:= false;
|
|
end;
|
|
end;
|
|
arp.sendGratuitous;
|
|
CopyIPv4(@Config.Gateway[0], @Target[0]);
|
|
arp.sendRequest(@Target[0]);
|
|
end else begin
|
|
stdio.bufWriteStr(stdout_buf, ' MAC: ');
|
|
writeMACAddress(net.GetMAC, stdout_buf);
|
|
stdio.bufWriteStr(stdout_buf, ' IPv4: ');
|
|
writeIPv4Address(@Config.Address[0], stdout_buf);
|
|
stdio.bufWriteStr(stdout_buf, ' Gateway: ');
|
|
writeIPv4Address(@Config.Gateway[0], stdout_buf);
|
|
stdio.bufWriteStr(stdout_buf, ' Netmask: ');
|
|
writeIPv4Address(@Config.Netmask[0], stdout_buf);
|
|
if Config.UP then
|
|
stdio.bufWriteStrLn(stdout_buf, ' NetUP: true')
|
|
else
|
|
stdio.bufWriteStrLn(stdout_buf, ' NetUP: false');
|
|
end;
|
|
end;
|
|
|
|
procedure register;
|
|
var
|
|
i : uint8;
|
|
|
|
begin
|
|
push_trace('ipv4.register');
|
|
if not Registered then begin
|
|
for i:=0 to 255 do begin
|
|
Protocols[i]:= nil;
|
|
end;
|
|
for i:=0 to 3 do begin
|
|
Config.Address[i]:= 0;
|
|
Config.Gateway[i]:= 0;
|
|
Config.Netmask[i]:= 0;
|
|
end;
|
|
Config.UP:= false;
|
|
eth2.registerType($0800, @recv);
|
|
stdio.registerCommand('IFCONFIG', @terminal_command_ifconfig, 'Configure Network Settings.');
|
|
Registered:= true;
|
|
end;
|
|
pop_trace;
|
|
end;
|
|
|
|
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
|
|
begin
|
|
register;
|
|
if Protocols[Protocol_ID] = nil then Protocols[Protocol_ID]:= recv_callback;
|
|
pop_trace;
|
|
end;
|
|
|
|
end. |