Skip to content

Commit

Permalink
feat: chat ffi (#5349)
Browse files Browse the repository at this point in the history
Description
---
Create an FFI wrapper for a simple chat client


Motivation and Context
---
So we can chat on mobile and other non rust platforms.

How Has This Been Tested?
---
Cucumber

What process can a PR reviewer use to test or verify this change?
---
Review the cucumber tests as well

<!-- Checklist -->
<!-- 1. Is the title of your PR in the form that would make nice release
notes? The title, excluding the conventional commit
tag, will be included exactly as is in the CHANGELOG, so please think
about it carefully. -->


Breaking Changes
---

- [x] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [ ] Other - Please specify

<!-- Does this include a breaking change? If so, include this line as a
footer -->
<!-- BREAKING CHANGE: Description what the user should do, e.g. delete a
database, resync the chain -->

---------

Co-authored-by: SW van Heerden <swvheerden@gmail.com>
  • Loading branch information
brianp and SWvheerden authored May 2, 2023
1 parent f5d36cf commit f7cece2
Show file tree
Hide file tree
Showing 26 changed files with 1,297 additions and 161 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
--all-features
--release
--package tari_integration_tests
-- -t "${{ env.CI_PROFILE }} and (not @wallet-ffi) and (not @broken)"
-- -t "${{ env.CI_PROFILE }} and (not @wallet-ffi) and (not @chat-ffi) and (not @broken)"
-c 5
--retry 2
Expand Down Expand Up @@ -167,6 +167,6 @@ jobs:
--all-features
--release
--package tari_integration_tests
-- -t "@wallet-ffi and ${{ env.CI_PROFILE }} and (not @broken)"
-- -t "(@wallet-ffi or @chat-ffi) and ${{ env.CI_PROFILE }} and (not @broken)"
-c 1
--retry 2
25 changes: 22 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]

members = [
"base_layer/chat_ffi",
"base_layer/core",
"base_layer/common_types",
"base_layer/contacts",
Expand Down
31 changes: 31 additions & 0 deletions base_layer/chat_ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "tari_chat_ffi"
authors = ["The Tari Development Community"]
description = "Tari cryptocurrency chat C FFI bindings"
license = "BSD-3-Clause"
version = "0.50.0-pre.0"
edition = "2018"

[dependencies]
tari_chat_client = { path = "../contacts/examples/chat_client" }
tari_common = { path = "../../common" }
tari_common_types = { path = "../common_types" }
tari_comms = { path = "../../comms/core" }
tari_contacts = { path = "../contacts" }
tari_p2p = { path = "../p2p" }

libc = "0.2.65"
log = "0.4.6"
serde_json = "1.0.64"
thiserror = "1.0.26"
tokio = "1.23"

[target.'cfg(target_os="android")'.dependencies]
openssl = { version = "0.10.48", features = ["vendored"] }

[lib]
crate-type = ["staticlib","cdylib"]

[build-dependencies]
cbindgen = "0.24.3"
tari_common = { path = "../../common", features = ["build", "static-application-info"] }
7 changes: 7 additions & 0 deletions base_layer/chat_ffi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Tari Chat FFI

Foreign Function interface for the Tari Android and Tari iOS Chat interface.

This crate is part of the [Tari Cryptocurrency](https://tari.com) project.

TODO
47 changes: 47 additions & 0 deletions base_layer/chat_ffi/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2023. The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

use std::{env, path::PathBuf};

use cbindgen::{Config, ExportConfig, Language, ParseConfig, Style};
use tari_common::build::StaticApplicationInfo;

fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

// generate version info
let gen = StaticApplicationInfo::initialize().unwrap();
gen.write_consts_to_outdir("consts.rs").unwrap();

// let package_name = env::var("CARGO_PKG_NAME").unwrap();
let output_file = PathBuf::from(&crate_dir).join("chat.h").display().to_string();

let config = Config {
language: Language::C,
header: Some("// Copyright 2023. The Tari Project\n// SPDX-License-Identifier: BSD-3-Clause".to_string()),
parse: ParseConfig {
parse_deps: true,
include: Some(vec![
"tari_core".to_string(),
"tari_common_types".to_string(),
"tari_crypto".to_string(),
"tari_p2p".to_string(),
"tari_wallet".to_string(),
"tari_contacts".to_string(),
]),
..Default::default()
},
autogen_warning: Some("// This file was generated by cargo-bindgen. Please do not edit manually.".to_string()),
style: Style::Tag,
cpp_compat: true,
export: ExportConfig {
include: vec!["TariUtxo".to_string()],
..Default::default()
},
..Default::default()
};

cbindgen::generate_with_config(&crate_dir, config)
.unwrap()
.write_to_file(output_file);
}
186 changes: 186 additions & 0 deletions base_layer/chat_ffi/chat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Copyright 2023. The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

// This file was generated by cargo-bindgen. Please do not edit manually.

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

struct ChatMessages;

struct ClientFFI;

struct ClientPeers;

/**
* Configuration for a comms node
*/
struct P2pConfig;

struct TariAddress;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/**
* Creates a Chat Client
* TODO: This function takes a ptr to a collection of seed peers and this works fine in cucumber, or native rust but
* isn't at all ideal for a real FFI. We need to work with the mobile teams and come up with a better interface
* for supplying seed peers.
*
* ## Arguments
* `config` - The P2PConfig pointer
* `identity_file_path` - The path to the node identity file
* `db_path` - The path to the db file
* `seed_peers` - A ptr to a collection of seed peers
* `network_str` - The network to connect to
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `*mut ChatClient` - Returns a pointer to a ChatClient, note that it returns ptr::null_mut()
* if any error was encountered or if the runtime could not be created.
*
* # Safety
* The ```destroy_client``` method must be called when finished with a ClientFFI to prevent a memory leak
*/
struct ClientFFI *create_chat_client(struct P2pConfig *config,
const char *identity_file_path,
const char *db_path,
struct ClientPeers *seed_peers,
const char *network_str,
int *error_out);

/**
* Frees memory for a ClientFFI
*
* ## Arguments
* `client` - The pointer of a ClientFFI
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* None
*/
void destroy_client_ffi(struct ClientFFI *client);

/**
* Sends a message over a client
*
* ## Arguments
* `client` - The Client pointer
* `receiver` - A string containing a tari address
* `message` - The peer seeds config for the node
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* The ```receiver``` should be destroyed after use
*/
void send_message(struct ClientFFI *client,
struct TariAddress *receiver,
const char *message_c_char,
int *error_out);

/**
* Add a contact
*
* ## Arguments
* `client` - The Client pointer
* `address` - A TariAddress ptr
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* The ```address``` should be destroyed after use
*/
void add_contact(struct ClientFFI *client, struct TariAddress *receiver, int *error_out);

/**
* Check the online status of a contact
*
* ## Arguments
* `client` - The Client pointer
* `address` - A TariAddress ptr
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* The ```address``` should be destroyed after use
*/
int check_online_status(struct ClientFFI *client, struct TariAddress *receiver, int *error_out);

/**
* Get a ptr to all messages from or to address
*
* ## Arguments
* `client` - The Client pointer
* `address` - A TariAddress ptr
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* The ```address``` should be destroyed after use
* The returned pointer to ```*mut ChatMessages``` should be destroyed after use
*/
struct ChatMessages *get_all_messages(struct ClientFFI *client,
struct TariAddress *address,
int *error_out);

/**
* Frees memory for messages
*
* ## Arguments
* `messages_ptr` - The pointer of a Vec<Message>
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* None
*/
void destroy_messages(struct ChatMessages *messages_ptr);

/**
* Creates a TariAddress and returns a ptr
*
* ## Arguments
* `receiver_c_char` - A string containing a tari address hex value
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `*mut TariAddress` - A ptr to a TariAddress
*
* # Safety
* The ```destroy_tari_address``` function should be called when finished with the TariAddress
*/
struct TariAddress *create_tari_address(const char *receiver_c_char, int *error_out);

/**
* Frees memory for a TariAddress
*
* ## Arguments
* `address` - The pointer of a TariAddress
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* None
*/
void destroy_tari_address(struct TariAddress *address);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
Loading

0 comments on commit f7cece2

Please sign in to comment.