master
1const std = @import("std");
2const uefi = std.os.uefi;
3const Guid = uefi.Guid;
4const Event = uefi.Event;
5const Status = uefi.Status;
6const Time = uefi.Time;
7const Ip6 = uefi.protocol.Ip6;
8const ManagedNetworkConfigData = uefi.protocol.ManagedNetwork.Config;
9const SimpleNetwork = uefi.protocol.SimpleNetwork;
10const cc = uefi.cc;
11const Error = Status.Error;
12
13pub const Udp6 = extern struct {
14 _get_mode_data: *const fn (*const Udp6, ?*Config, ?*Ip6.Mode, ?*ManagedNetworkConfigData, ?*SimpleNetwork) callconv(cc) Status,
15 _configure: *const fn (*const Udp6, ?*const Config) callconv(cc) Status,
16 _groups: *const fn (*const Udp6, bool, ?*const Ip6.Address) callconv(cc) Status,
17 _transmit: *const fn (*const Udp6, *CompletionToken) callconv(cc) Status,
18 _receive: *const fn (*const Udp6, *CompletionToken) callconv(cc) Status,
19 _cancel: *const fn (*const Udp6, ?*CompletionToken) callconv(cc) Status,
20 _poll: *const fn (*const Udp6) callconv(cc) Status,
21
22 pub const GetModeDataError = uefi.UnexpectedError || error{
23 NotStarted,
24 InvalidParameter,
25 };
26 pub const ConfigureError = uefi.UnexpectedError || error{
27 NoMapping,
28 InvalidParameter,
29 AlreadyStarted,
30 AccessDenied,
31 OutOfResources,
32 DeviceError,
33 };
34 pub const GroupsError = uefi.UnexpectedError || error{
35 NotStarted,
36 OutOfResources,
37 InvalidParameter,
38 AlreadyStarted,
39 NotFound,
40 DeviceError,
41 };
42 pub const TransmitError = uefi.UnexpectedError || error{
43 NotStarted,
44 NoMapping,
45 InvalidParameter,
46 AccessDenied,
47 NotReady,
48 OutOfResources,
49 NotFound,
50 BadBufferSize,
51 NoMedia,
52 };
53 pub const ReceiveError = uefi.UnexpectedError || error{
54 NotStarted,
55 NoMapping,
56 InvalidParameter,
57 OutOfResources,
58 DeviceError,
59 AccessDenied,
60 NotReady,
61 NoMedia,
62 };
63 pub const CancelError = uefi.UnexpectedError || error{
64 InvalidParameter,
65 NotStarted,
66 NotFound,
67 };
68 pub const PollError = uefi.UnexpectedError || error{
69 InvalidParameter,
70 DeviceError,
71 Timeout,
72 };
73
74 pub fn getModeData(self: *const Udp6) GetModeDataError!ModeData {
75 var data: ModeData = undefined;
76 switch (self._get_mode_data(
77 self,
78 &data.udp6_config_data,
79 &data.ip6_mode_data,
80 &data.mnp_config_data,
81 &data.snp_mode_data,
82 )) {
83 .success => return data,
84 .not_started => return Error.NotStarted,
85 .invalid_parameter => return Error.InvalidParameter,
86 else => |status| return uefi.unexpectedStatus(status),
87 }
88 }
89
90 pub fn configure(self: *Udp6, udp6_config_data: ?*const Config) ConfigureError!void {
91 switch (self._configure(self, udp6_config_data)) {
92 .success => {},
93 .no_mapping => return Error.NoMapping,
94 .invalid_parameter => return Error.InvalidParameter,
95 .already_started => return Error.AlreadyStarted,
96 .access_denied => return Error.AccessDenied,
97 .out_of_resources => return Error.OutOfResources,
98 .device_error => return Error.DeviceError,
99 else => |status| return uefi.unexpectedStatus(status),
100 }
101 }
102
103 pub fn groups(
104 self: *Udp6,
105 join_flag: JoinFlag,
106 multicast_address: ?*const Ip6.Address,
107 ) GroupsError!void {
108 switch (self._groups(
109 self,
110 // set to TRUE to join a multicast group
111 join_flag == .join,
112 multicast_address,
113 )) {
114 .success => {},
115 .not_started => return Error.NotStarted,
116 .out_of_resources => return Error.OutOfResources,
117 .invalid_parameter => return Error.InvalidParameter,
118 .already_started => return Error.AlreadyStarted,
119 .not_found => return Error.NotFound,
120 .device_error => return Error.DeviceError,
121 else => |status| return uefi.unexpectedStatus(status),
122 }
123 }
124
125 pub fn transmit(self: *Udp6, token: *CompletionToken) TransmitError!void {
126 switch (self._transmit(self, token)) {
127 .success => {},
128 .not_started => return Error.NotStarted,
129 .no_mapping => return Error.NoMapping,
130 .invalid_parameter => return Error.InvalidParameter,
131 .access_denied => return Error.AccessDenied,
132 .not_ready => return Error.NotReady,
133 .out_of_resources => return Error.OutOfResources,
134 .not_found => return Error.NotFound,
135 .bad_buffer_size => return Error.BadBufferSize,
136 .no_media => return Error.NoMedia,
137 else => |status| return uefi.unexpectedStatus(status),
138 }
139 }
140
141 pub fn receive(self: *Udp6, token: *CompletionToken) ReceiveError!void {
142 switch (self._receive(self, token)) {
143 .success => {},
144 .not_started => return Error.NotStarted,
145 .no_mapping => return Error.NoMapping,
146 .invalid_parameter => return Error.InvalidParameter,
147 .out_of_resources => return Error.OutOfResources,
148 .device_error => return Error.DeviceError,
149 .access_denied => return Error.AccessDenied,
150 .not_ready => return Error.NotReady,
151 .no_media => return Error.NoMedia,
152 else => |status| return uefi.unexpectedStatus(status),
153 }
154 }
155
156 pub fn cancel(self: *Udp6, token: ?*CompletionToken) CancelError!void {
157 switch (self._cancel(self, token)) {
158 .success => {},
159 .invalid_parameter => return Error.InvalidParameter,
160 .not_started => return Error.NotStarted,
161 .not_found => return Error.NotFound,
162 else => |status| return uefi.unexpectedStatus(status),
163 }
164 }
165
166 pub fn poll(self: *Udp6) PollError!void {
167 switch (self._poll(self)) {
168 .success => {},
169 .invalid_parameter => return Error.InvalidParameter,
170 .device_error => return Error.DeviceError,
171 .timeout => return Error.Timeout,
172 else => |status| return uefi.unexpectedStatus(status),
173 }
174 }
175
176 pub const guid align(8) = uefi.Guid{
177 .time_low = 0x4f948815,
178 .time_mid = 0xb4b9,
179 .time_high_and_version = 0x43cb,
180 .clock_seq_high_and_reserved = 0x8a,
181 .clock_seq_low = 0x33,
182 .node = [_]u8{ 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55 },
183 };
184
185 pub const JoinFlag = enum {
186 join,
187 leave,
188 };
189
190 pub const ModeData = struct {
191 udp6_config_data: Config,
192 ip6_mode_data: Ip6.Mode,
193 mnp_config_data: ManagedNetworkConfigData,
194 snp_mode_data: SimpleNetwork,
195 };
196
197 pub const Config = extern struct {
198 accept_promiscuous: bool,
199 accept_any_port: bool,
200 allow_duplicate_port: bool,
201 traffic_class: u8,
202 hop_limit: u8,
203 receive_timeout: u32,
204 transmit_timeout: u32,
205 station_address: Ip6.Address,
206 station_port: u16,
207 remote_address: Ip6.Address,
208 remote_port: u16,
209 };
210
211 pub const CompletionToken = extern struct {
212 event: Event,
213 status: usize,
214 packet: extern union {
215 rx_data: *ReceiveData,
216 tx_data: *TransmitData,
217 },
218 };
219
220 pub const ReceiveData = extern struct {
221 timestamp: Time,
222 recycle_signal: Event,
223 udp6_session: SessionData,
224 data_length: u32,
225 fragment_count: u32,
226
227 pub fn getFragments(self: *ReceiveData) []Fragment {
228 return @as([*]Fragment, @ptrCast(@alignCast(@as([*]u8, @ptrCast(self)) + @sizeOf(ReceiveData))))[0..self.fragment_count];
229 }
230 };
231
232 pub const TransmitData = extern struct {
233 udp6_session_data: ?*SessionData,
234 data_length: u32,
235 fragment_count: u32,
236
237 pub fn getFragments(self: *TransmitData) []Fragment {
238 return @as([*]Fragment, @ptrCast(@alignCast(@as([*]u8, @ptrCast(self)) + @sizeOf(TransmitData))))[0..self.fragment_count];
239 }
240 };
241
242 pub const SessionData = extern struct {
243 source_address: Ip6.Address,
244 source_port: u16,
245 destination_address: Ip6.Address,
246 destination_port: u16,
247 };
248
249 pub const Fragment = extern struct {
250 fragment_length: u32,
251 fragment_buffer: [*]u8,
252 };
253};