1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// Copyright (C) 2023 Vahab Jabrayilov
// Email: vjabrayilov@cs.columbia.edu
//
// This file is part of the Machnet project.
//
// This project is licensed under the MIT License - see the LICENSE file for details
pub use MachnetFlow;
use ;
unsafe
/// Initializes the Machnet library for interacting with the Machnet sidecar.
/// This function sets up the necessary components to allow communication and control
/// over the Machnet sidecar.
/// It should be called before making any other calls to the Machnet library.
///
/// /// # Examples
///
/// Basic usage:
///
/// ```
/// use machnet::machnet_init;
///
/// let result = machnet_init();
///
/// if result == 0 {
/// println!("Machnet initialized successfully.");
/// } else {
/// println!("Failed to initialize Machnet.");
/// }
/// ```
///
/// # Returns
///
/// Returns `0` on successful initialization of the Machnet library.
/// Returns `-1` if the initialization fails.
///
/// Creates a new channel to the Machnet controller and binds to it.
/// A channel is a logical entity between an application and the Machnet service.
///
/// # Examples
///
/// ```
/// use machnet::machnet_attach;
///
/// let channel= machnet_attach();
/// match channel{
/// Some(ch) => {
/// // Successfully attached to Machnet channel, use `ch` here
/// }
/// None => {
/// // Handle the case where attachment to Machnet channel fails
/// }
/// }
/// ```
/// # Returns
/// Returns an ```Option<MachnetChannel>```.
///
/// Establishes a Machnet connection using the provided chanenel.
///
/// This function attempts to create a connection between a local IP address and a remote IP address on a specified port.
///
/// # Arguments
///
/// * `channel` - A mutable reference to the `MachnetChannel`.
/// * `local_ip` - A string slice representing the local IP address to bind to.
/// * `remote_ip` - A string slice representing the remote IP address to connect to.
/// * `remote_port` - The remote port number to connect to.
///
/// # Returns
///
/// Returns an `Option<MachnetFlow>`
//
/// # Examples
///
/// ```
/// use machnet::{machnet_connect,machnet_attach};
///
/// let mut channel = machnet_attach().unwrap();
/// let local_ip = "192.168.1.2";
/// let remote_ip = "192.168.1.3";
/// let remote_port = 8080;
///
/// match machnet_connect(&mut channel, local_ip, remote_ip, remote_port) {
/// Some(flow) => {
/// // Connection was successful, use `flow` here
/// }
/// None => {
/// // Connection failed
/// }
/// }
/// ```
///
/// Listens for incoming messages on a specified local IP address and port.
///
/// This function establishes a listener on the given `local_ip` and `local_port`
/// using the provided `MachnetChannel`.
///
/// # Arguments
///
/// * `channel` - A reference to the `MachnetChannel` associated with the channel
/// that will be used for listening.
/// * `local_ip` - A string slice representing the local IP address to listen on.
/// This should be a valid IPv4 or IPv6 address.
/// * `local_port` - The local port number to listen on.
/// This should be a valid port that is not already in use.
///
/// # Returns
///
/// Returns `0` on successful setup, `-1` on failure.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use machnet::{machnet_attach, machnet_listen};
///
/// let mut channel = machnet_attach().unwrap();
/// let local_ip = "127.0.0.1";
/// let local_port = 8080;
///
/// let result = machnet_listen(&mut channel, local_ip, local_port);
/// if result == 0 {
/// println!("Listening on {}:{}", local_ip, local_port);
/// } else {
/// println!("Failed to set up listener on {}:{}", local_ip, local_port);
/// }
/// ```
///
/// Enqueues a message for transmission to a remote peer over the network.
///
/// This function sends data over a specified Machnet channel.
/// It uses the provided
/// Machnet channel context and a pre-created flow to the remote peer.
/// The data to be sent is specified by a buffer and its length in bytes.
///
/// # Arguments
///
/// * `channel` - A reference to the `MachnetChannel` representing the Machnet channel.
/// * `flow` - The `MachnetFlow` instance representing a pre-created flow to the remote peer.
/// * `buf` - A byte slice (`&[u8]`) reference representing the data buffer to be sent to the remote peer.
/// * `len` - The length of the data buffer in bytes (type `u64`).
///
/// # Returns
///
/// Returns `0` on successful transmission, `-1` on failure.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use machnet::{MachnetChannel, MachnetFlow, machnet_send, machnet_attach};
/// // Following is just for demonstration purposes, normally you do machnet_attach() to get the context and machnet_connect() to get the flow
/// let mut channel = machnet_attach().unwrap();
/// let flow = MachnetFlow::default();
/// let data = [1, 2, 3, 4]; // Example data to send
/// let len = data.len() as u64;
///
/// let result = machnet_send(&mut channel, flow, &data, len);
/// if result == 0 {
/// println!("Message enqueued for transmission");
/// } else {
/// println!("Failed to enqueue message");
/// }
/// ```
///
/// Receives a pending message from a remote peer over the network.
/// This function attempts to receive data from a specified Machnet channel. It uses the provided
/// Machnet channel (`channel`) and fills the given buffer (`buf`) with the received data.
/// The `flow` parameter will be populated with the flow information of the sender.
///
/// # Arguments
///
/// * `channel` - A reference to the `MachnetChannel` representing the Machnet channel.
/// * `buf` - A mutable byte slice (`&mut [u8]`) that will be filled with the received message.
/// The length of `buf` should be at least as large as the `len` parameter.
/// * `len` - The length of `buf` in bytes. This indicates the maximum amount of data
/// that can be written into `buf`.
/// * `flow` - A reference to `MachnetFlow` where the flow information of the sender will be stored.
///
/// # Returns
///
/// Returns a `i64` indicating the result of the receive operation:
/// * `0` if no message is currently available.
/// * `-1` on failure, such as if an error occurs during the receive operation.
/// * Otherwise, returns the number of bytes received and written into `buf`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use machnet::{ MachnetFlow, machnet_attach, machnet_recv};
/// // Following is just for demonstration purposes, normally you do machnet_attach() to get the context and flow is obtained from machnet_listen().
/// let mut channel = machnet_attach().unwrap();
/// let mut flow = MachnetFlow::default();
/// let mut buffer = [0; 1024]; // Example buffer
/// let len = buffer.len() as u64;
///
/// match machnet_recv(&channel, &mut buffer, len, &mut flow) {
/// 0 => println!("No message available"),
/// -1 => println!("Failed to receive message"),
/// bytes_received => println!("Received {} bytes", bytes_received),
/// }
/// ```
///