Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: chat ffi find by message #6354

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions base_layer/chat_ffi/chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,26 @@ struct Message *create_chat_message(struct TariAddress *receiver,
*/
void destroy_chat_message(struct Message *ptr);

/**
* Get a ptr to a message from a message_id
*
* ## Arguments
* `client` - The ChatClient pointer
* `message_id` - A pointer to a byte vector representing a message id
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `*mut Message` - A pointer to a message
*
* # Safety
* The returned pointer to ```Message``` should be destroyed after use
* ```client``` should be destroyed after use
* ```message_id``` should be destroyed after use
*/
struct Message *get_chat_message(struct ChatClient *client,
struct ChatByteVector *message_id,
int *error_out);

/**
* Sends a message over a client
*
Expand Down
49 changes: 48 additions & 1 deletion base_layer/chat_ffi/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use tari_contacts::contacts_service::types::{Message, MessageBuilder, MessageMet
use tari_utilities::ByteArray;

use crate::{
byte_vector::{chat_byte_vector_create, ChatByteVector},
byte_vector::{chat_byte_vector_create, process_vector, ChatByteVector},
error::{InterfaceError, LibChatError},
ChatClient,
};
Expand Down Expand Up @@ -95,6 +95,53 @@ pub unsafe extern "C" fn destroy_chat_message(ptr: *mut Message) {
}
}

/// Get a ptr to a message from a message_id
///
/// ## Arguments
/// `client` - The ChatClient pointer
/// `message_id` - A pointer to a byte vector representing a message id
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `*mut Message` - A pointer to a message
///
/// # Safety
/// The returned pointer to ```Message``` should be destroyed after use
/// ```client``` should be destroyed after use
/// ```message_id``` should be destroyed after use
#[no_mangle]
pub unsafe extern "C" fn get_chat_message(
client: *mut ChatClient,
message_id: *mut ChatByteVector,
error_out: *mut c_int,
) -> *mut Message {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

if client.is_null() {
error = LibChatError::from(InterfaceError::NullError("client".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
}

if message_id.is_null() {
error = LibChatError::from(InterfaceError::NullError("message_id".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
}

let id = process_vector(message_id, error_out);

let result = (*client).runtime.block_on((*client).client.get_message(&id));

match result {
Ok(message) => Box::into_raw(Box::new(message)),
Err(e) => {
error = LibChatError::from(InterfaceError::ContactServiceError(e.to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
ptr::null_mut()
},
}
}

/// Sends a message over a client
///
/// ## Arguments
Expand Down
3 changes: 2 additions & 1 deletion base_layer/common_types/src/wallet_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[cfg(feature = "ledger")]
use std::convert::TryFrom;
use std::{
convert::TryFrom,
fmt,
fmt::{Display, Formatter},
};
Expand Down
66 changes: 38 additions & 28 deletions base_layer/contacts/src/chat_client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub trait ChatClient {
async fn check_online_status(&self, address: &TariAddress) -> Result<ContactOnlineStatus, Error>;
fn create_message(&self, receiver: &TariAddress, message: String) -> Message;
async fn get_messages(&self, sender: &TariAddress, limit: u64, page: u64) -> Result<Vec<Message>, Error>;
async fn get_message(&self, id: &[u8]) -> Result<Message, Error>;
async fn send_message(&self, message: Message) -> Result<(), Error>;
async fn send_read_receipt(&self, message: Message) -> Result<(), Error>;
async fn get_conversationalists(&self) -> Result<Vec<TariAddress>, Error>;
Expand Down Expand Up @@ -149,14 +150,6 @@ impl Client {

#[async_trait]
impl ChatClient for Client {
fn address(&self) -> TariAddress {
TariAddress::from_public_key(self.identity.public_key(), self.config.chat_client.network)
}

fn shutdown(&mut self) {
self.shutdown.trigger();
}

async fn add_contact(&self, address: &TariAddress) -> Result<(), Error> {
if let Some(mut contacts_service) = self.contacts.clone() {
contacts_service.upsert_contact(address.into()).await?;
Expand All @@ -165,6 +158,16 @@ impl ChatClient for Client {
Ok(())
}

fn add_metadata(&self, mut message: Message, key: String, data: String) -> Message {
let metadata = MessageMetadata {
key: key.into_bytes(),
data: data.into_bytes(),
};

message.push(metadata);
message
}

async fn check_online_status(&self, address: &TariAddress) -> Result<ContactOnlineStatus, Error> {
if let Some(mut contacts_service) = self.contacts.clone() {
let contact = contacts_service.get_contact(address.clone()).await?;
Expand All @@ -175,12 +178,8 @@ impl ChatClient for Client {
Ok(ContactOnlineStatus::Offline)
}

async fn send_message(&self, message: Message) -> Result<(), Error> {
if let Some(mut contacts_service) = self.contacts.clone() {
contacts_service.send_message(message).await?;
}

Ok(())
fn create_message(&self, receiver: &TariAddress, message: String) -> Message {
MessageBuilder::new().address(receiver.clone()).message(message).build()
}

async fn get_messages(&self, sender: &TariAddress, limit: u64, page: u64) -> Result<Vec<Message>, Error> {
Expand All @@ -192,6 +191,23 @@ impl ChatClient for Client {
Ok(messages)
}

async fn get_message(&self, message_id: &[u8]) -> Result<Message, Error> {
match self.contacts.clone() {
Some(mut contacts_service) => contacts_service.get_message(message_id).await.map_err(|e| e.into()),
None => Err(Error::InitializationError(
"ContactsServiceHandle unavailable".to_string(),
)),
}
}

async fn send_message(&self, message: Message) -> Result<(), Error> {
if let Some(mut contacts_service) = self.contacts.clone() {
contacts_service.send_message(message).await?;
}

Ok(())
}

async fn send_read_receipt(&self, message: Message) -> Result<(), Error> {
if let Some(mut contacts_service) = self.contacts.clone() {
contacts_service
Expand All @@ -202,20 +218,6 @@ impl ChatClient for Client {
Ok(())
}

fn create_message(&self, receiver: &TariAddress, message: String) -> Message {
MessageBuilder::new().address(receiver.clone()).message(message).build()
}

fn add_metadata(&self, mut message: Message, key: String, data: String) -> Message {
let metadata = MessageMetadata {
key: key.into_bytes(),
data: data.into_bytes(),
};

message.push(metadata);
message
}

async fn get_conversationalists(&self) -> Result<Vec<TariAddress>, Error> {
let mut addresses = vec![];
if let Some(mut contacts_service) = self.contacts.clone() {
Expand All @@ -224,6 +226,14 @@ impl ChatClient for Client {

Ok(addresses)
}

fn address(&self) -> TariAddress {
TariAddress::from_public_key(self.identity.public_key(), self.config.chat_client.network)
}

fn shutdown(&mut self) {
self.shutdown.trigger();
}
}

pub async fn wait_for_connectivity(comms: CommsNode) -> anyhow::Result<()> {
Expand Down
13 changes: 13 additions & 0 deletions base_layer/contacts/src/contacts_service/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ pub enum ContactsServiceRequest {
GetContactOnlineStatus(Contact),
SendMessage(TariAddress, Message),
GetMessages(TariAddress, i64, i64),
GetMessage(Vec<u8>),
SendReadConfirmation(TariAddress, Confirmation),
GetConversationalists,
}
Expand All @@ -150,6 +151,7 @@ pub enum ContactsServiceResponse {
Contacts(Vec<Contact>),
OnlineStatus(ContactOnlineStatus),
Messages(Vec<Message>),
Message(Message),
MessageSent,
ReadConfirmationSent,
Conversationalists(Vec<TariAddress>),
Expand Down Expand Up @@ -277,6 +279,17 @@ impl ContactsServiceHandle {
}
}

pub async fn get_message(&mut self, message_id: &[u8]) -> Result<Message, ContactsServiceError> {
match self
.request_response_service
.call(ContactsServiceRequest::GetMessage(message_id.to_vec()))
.await??
{
ContactsServiceResponse::Message(message) => Ok(message),
_ => Err(ContactsServiceError::UnexpectedApiResponse),
}
}

pub async fn send_message(&mut self, message: Message) -> Result<(), ContactsServiceError> {
match self
.request_response_service
Expand Down
8 changes: 6 additions & 2 deletions base_layer/contacts/src/contacts_service/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ where T: ContactsBackend + 'static
request: ContactsServiceRequest,
) -> Result<ContactsServiceResponse, ContactsServiceError> {
match request {
ContactsServiceRequest::GetContact(pk) => {
let result = self.db.get_contact(pk.clone());
ContactsServiceRequest::GetContact(address) => {
let result = self.db.get_contact(address.clone());
if let Ok(ref contact) = result {
self.liveness.check_add_monitored_peer(contact.node_id.clone()).await?;
};
Expand Down Expand Up @@ -350,6 +350,10 @@ where T: ContactsBackend + 'static
let result = self.db.get_conversationlists();
Ok(result.map(ContactsServiceResponse::Conversationalists)?)
},
ContactsServiceRequest::GetMessage(message_id) => {
let result = self.db.get_message(message_id);
Ok(result.map(ContactsServiceResponse::Message)?)
},
}
}

Expand Down
5 changes: 5 additions & 0 deletions base_layer/contacts/src/contacts_service/storage/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ where T: ContactsBackend + 'static
}
}

pub fn get_message(&self, message_id: Vec<u8>) -> Result<Message, ContactsServiceStorageError> {
let db_clone = self.db.clone();
fetch!(db_clone, message_id, Message)
}

pub fn save_message(&self, message: Message) -> Result<(), ContactsServiceStorageError> {
self.db
.write(WriteOperation::Insert(Box::new(DbValue::Message(Box::new(message)))))?;
Expand Down
Loading
Loading