Skip to content

A pure-Rust gateway for Fjåge with C API compatibility #316

@brodiealexander

Description

@brodiealexander

A few weeks ago, I was reading about a framework for Rust serialization/deserialization framework called Serde, which has the ability to derive serialization/deserialization methods using a macro like so:

#[derive(Serialize, Deserialize)]
pub struct ParameterReq {
    pub msgID: String,
    pub perf: Performative,
    pub recipient: String,
    pub inReplyTo: Option<String>,
    pub sender: String,
    pub sentAt: i64,
    pub index: i64,
    pub param: Option<String>,
    pub value: Value,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub requests: Option<HashMap<String, Value>>,
}

I sat down to start playing with it, and now I have a (mostly) working Fjage gateway written in Rust.

While providing the ability to interface with Fjage from Rust programs is my eventual goal, so far, I have been focused on making this package binary-compatible with the C gateway API. As of right now, you can download the Rust gateway, build it, link the resulting library against the UnetSocket C API, and successfully send and receive a datagram. Further, it passes all of the C gateway's tests when linked with test_fjage.c

In addition to implementing the base C API, it also provides the following extensions:

#include "fjage.h"

// New to fjage-rs
// double param extension
int fjage_param_set_double(fjage_gw_t gw, fjage_aid_t aid, const char *param, double value, int ndx);
double fjage_param_get_double(fjage_gw_t gw, fjage_aid_t aid, const char *param, int ndx, double defval);

// array params extension
// setters
int fjage_param_set_int_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, int *value, int len, int ndx);
int fjage_param_set_long_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, long *value, int len, int ndx);
int fjage_param_set_float_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, float *value, int len, int ndx);
int fjage_param_set_double_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, double *value, int len, int ndx);
int fjage_param_set_string_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, const char **value, int len, int ndx);

// getters
int fjage_param_get_int_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, int *value, int maxlen, int ndx);
int fjage_param_get_long_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, long *value, int maxlen, int ndx);
int fjage_param_get_float_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, float *value, int maxlen, int ndx);
int fjage_param_get_double_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, double *value, int maxlen, int ndx);
int fjage_param_get_string_array(fjage_gw_t gw, fjage_aid_t aid, const char *param, char **value, int maxlen, int ndx);

In addition, I think it should be relatively easy to add support for generic messages using something similar to:

fjage_obj_t fjage_obj_create();
fjage_obj_add_int(fjage_obt_t obj, *const char key, int value);
...
fjage_msg_add_obj(fjage_msg_t msg, *const char key, fjage_obj_t value);

For fjage_param_set...() methods, it will also return an error if the ParameterRsp values do not match those that were sent (as in the case of trying to write to a read-only parameter)

It also implements base64 decoding and encoding, though encoding is only enabled for array parameters at the moment.

What I have so far is available for viewing at https://github.com/brodiealexander/fjage-rs

There are a few demos, including an implementation of datagram reception and transmission, a GetFileReq/PutFileReq utility, and an interactive remote shell.

The implementation is not ready for use, as I still have a lot of testing and cleaning up to do, and it doesn't yet support RS-232, but I did want to reach out and ask for feedback on where the project is at so far, as well as if there is any interest in adding it as a proper gateway in the future.

Thanks,
Brodie

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions