mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-30 01:39:20 +00:00
LinphoneContent stored in database + few changes on Java API regarding file transfer
This commit is contained in:
parent
2d9de5a1bd
commit
e9a376a014
10 changed files with 162 additions and 32 deletions
|
|
@ -311,7 +311,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
|
||||
@Override
|
||||
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
|
||||
LinphoneContent content, String buffer, int size) {
|
||||
LinphoneContent content, byte[] buffer, int size) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
|
@ -322,6 +322,4 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa
|
|||
|
||||
@Override
|
||||
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
|
||||
LinphoneContent content, String buffer, int size) {
|
||||
LinphoneContent content, byte[] buffer, int size) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
|
||||
@Override
|
||||
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
|
||||
LinphoneContent content, String buffer, int size) {
|
||||
LinphoneContent content, byte[] buffer, int size) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
|
||||
@Override
|
||||
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
|
||||
LinphoneContent content, String buffer, int size) {
|
||||
LinphoneContent content, byte[] buffer, int size) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ public:
|
|||
|
||||
fileTransferProgressIndicationId = env->GetMethodID(listenerClass, "fileTransferProgressIndication", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;I)V");
|
||||
fileTransferSendId = env->GetMethodID(listenerClass, "fileTransferSend", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Ljava/nio/ByteBuffer;I)I");
|
||||
fileTransferRecvId = env->GetMethodID(listenerClass, "fileTransferRecv", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Ljava/lang/String;I)V");
|
||||
fileTransferRecvId = env->GetMethodID(listenerClass, "fileTransferRecv", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;[BI)V");
|
||||
}
|
||||
|
||||
~LinphoneCoreData() {
|
||||
|
|
@ -847,12 +847,16 @@ public:
|
|||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
|
||||
jbyteArray jbytes = env->NewByteArray(size);
|
||||
env->SetByteArrayRegion(jbytes, 0, size, (jbyte*)buff);
|
||||
|
||||
env->CallVoidMethod(lcData->listener,
|
||||
lcData->fileTransferRecvId,
|
||||
lcData->core,
|
||||
message ? env->NewObject(lcData->chatMessageClass, lcData->chatMessageCtrId, (jlong)message) : NULL,
|
||||
content ? create_java_linphone_content(env, content) : NULL,
|
||||
buff ? env->NewStringUTF(buff) : NULL,
|
||||
jbytes,
|
||||
size);
|
||||
}
|
||||
};
|
||||
|
|
@ -3926,21 +3930,23 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *
|
|||
jmethodID ctor;
|
||||
jstring jtype, jsubtype, jencoding, jname;
|
||||
jbyteArray jdata = NULL;
|
||||
jint jsize = 0;
|
||||
|
||||
contentClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneContentImpl"));
|
||||
ctor = env->GetMethodID(contentClass,"<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;)V");
|
||||
ctor = env->GetMethodID(contentClass,"<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;I)V");
|
||||
|
||||
jtype = env->NewStringUTF(content->type);
|
||||
jsubtype = env->NewStringUTF(content->subtype);
|
||||
jencoding = content->encoding ? env->NewStringUTF(content->encoding) : NULL;
|
||||
jname = content->name ? env->NewStringUTF(content->name) : NULL;
|
||||
jsize = (jint) content->size;
|
||||
|
||||
if (content->data){
|
||||
jdata = env->NewByteArray(content->size);
|
||||
env->SetByteArrayRegion(jdata, 0, content->size, (jbyte*)content->data);
|
||||
}
|
||||
|
||||
jobject jobj = env->NewObject(contentClass, ctor, jname, jtype, jsubtype, jdata, jencoding);
|
||||
jobject jobj = env->NewObject(contentClass, ctor, jname, jtype, jsubtype, jdata, jencoding, jsize);
|
||||
env->DeleteGlobalRef(contentClass);
|
||||
return jobj;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,49 @@ static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, u
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* DB layout:
|
||||
* | 0 | storage_id
|
||||
* | 1 | type
|
||||
* | 2 | subtype
|
||||
* | 3 | name
|
||||
* | 4 | encoding
|
||||
* | 5 | size
|
||||
* | 6 | data
|
||||
*/
|
||||
// Callback for sql request when getting linphone content
|
||||
static int callback_content(void *data, int argc, char **argv, char **colName) {
|
||||
LinphoneChatMessage *message = (LinphoneChatMessage *)data;
|
||||
|
||||
if (message->file_transfer_information) {
|
||||
linphone_content_uninit(message->file_transfer_information);
|
||||
ms_free(message->file_transfer_information);
|
||||
message->file_transfer_information = NULL;
|
||||
}
|
||||
message->file_transfer_information = (LinphoneContent *)malloc(sizeof(LinphoneContent));
|
||||
memset(message->file_transfer_information, 0, sizeof(*(message->file_transfer_information)));
|
||||
|
||||
message->file_transfer_information->type = argv[1] ? ms_strdup(argv[1]) : NULL;
|
||||
message->file_transfer_information->subtype = argv[2] ? ms_strdup(argv[2]) : NULL;
|
||||
message->file_transfer_information->name = argv[3] ? ms_strdup(argv[3]) : NULL;
|
||||
message->file_transfer_information->encoding = argv[4] ? ms_strdup(argv[4]) : NULL;
|
||||
message->file_transfer_information->size = (size_t) atoi(argv[5]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fetch_content_from_database(sqlite3 *db, LinphoneChatMessage *message, int content_id) {
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
char * buf;
|
||||
|
||||
buf = sqlite3_mprintf("SELECT * FROM content WHERE id = %i", content_id);
|
||||
ret = sqlite3_exec(db, buf, callback_content, message, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ms_error("Error in creation: %s.", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
sqlite3_free(buf);
|
||||
}
|
||||
|
||||
/* DB layout:
|
||||
* | 0 | storage_id
|
||||
|
|
@ -50,6 +93,7 @@ static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, u
|
|||
* | 8 | external body url
|
||||
* | 9 | utc timestamp
|
||||
* | 10 | app data text
|
||||
* | 11 | linphone content
|
||||
*/
|
||||
static void create_chat_message(char **argv, void *data){
|
||||
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
|
||||
|
|
@ -90,6 +134,13 @@ static void create_chat_message(char **argv, void *data){
|
|||
new_message->storage_id=storage_id;
|
||||
new_message->external_body_url= argv[8] ? ms_strdup(argv[8]) : NULL;
|
||||
new_message->appdata = argv[10]? ms_strdup(argv[10]) : NULL;
|
||||
|
||||
if (argv[11] != NULL) {
|
||||
int id = atoi(argv[11]);
|
||||
if (id >= 0) {
|
||||
fetch_content_from_database(cr->lc->db, new_message, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
cr->messages_hist=ms_list_prepend(cr->messages_hist,new_message);
|
||||
}
|
||||
|
|
@ -139,24 +190,51 @@ void linphone_sql_request_all(sqlite3* db,const char *stmt, LinphoneCore* lc){
|
|||
}
|
||||
}
|
||||
|
||||
static int linphone_chat_message_store_content(LinphoneChatMessage *msg) {
|
||||
LinphoneCore *lc = linphone_chat_room_get_lc(msg->chat_room);
|
||||
int id = -1;
|
||||
if (lc->db) {
|
||||
LinphoneContent *content = msg->file_transfer_information;
|
||||
char *buf = sqlite3_mprintf("INSERT INTO content VALUES(NULL,%Q,%Q,%Q,%Q,%i,%Q);",
|
||||
content->type,
|
||||
content->subtype,
|
||||
content->name,
|
||||
content->encoding,
|
||||
content->size,
|
||||
NULL
|
||||
);
|
||||
linphone_sql_request(lc->db, buf);
|
||||
sqlite3_free(buf);
|
||||
id = (unsigned int) sqlite3_last_insert_rowid (lc->db);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
|
||||
LinphoneCore *lc=linphone_chat_room_get_lc(msg->chat_room);
|
||||
int id=0;
|
||||
int id = 0;
|
||||
|
||||
if (lc->db){
|
||||
int content_id = -1;
|
||||
if (msg->file_transfer_information) {
|
||||
content_id = linphone_chat_message_store_content(msg);
|
||||
}
|
||||
|
||||
char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room));
|
||||
char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));
|
||||
char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%i,%Q);",
|
||||
char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%i,%Q,%i);",
|
||||
local_contact,
|
||||
peer,
|
||||
msg->dir,
|
||||
msg->message,
|
||||
"-1", /* use UTC field now */
|
||||
msg->is_read,
|
||||
msg->state,
|
||||
msg->external_body_url,
|
||||
msg->time,
|
||||
msg->appdata);
|
||||
peer,
|
||||
msg->dir,
|
||||
msg->message,
|
||||
"-1", /* use UTC field now */
|
||||
msg->is_read,
|
||||
msg->state,
|
||||
msg->external_body_url,
|
||||
msg->time,
|
||||
msg->appdata,
|
||||
content_id
|
||||
);
|
||||
linphone_sql_request(lc->db,buf);
|
||||
sqlite3_free(buf);
|
||||
ms_free(local_contact);
|
||||
|
|
@ -409,7 +487,7 @@ void linphone_update_table(sqlite3* db) {
|
|||
ms_message("Table already up to date: %s.", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
} else {
|
||||
ms_debug("Table updated successfully for URL.");
|
||||
ms_debug("Table history updated successfully for URL.");
|
||||
}
|
||||
|
||||
// for UTC timestamp storage
|
||||
|
|
@ -418,7 +496,7 @@ void linphone_update_table(sqlite3* db) {
|
|||
ms_message("Table already up to date: %s.", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
} else {
|
||||
ms_debug("Table updated successfully for UTC.");
|
||||
ms_debug("Table history updated successfully for UTC.");
|
||||
// migrate from old text-based timestamps to unix time-based timestamps
|
||||
linphone_migrate_timestamps(db);
|
||||
}
|
||||
|
|
@ -429,7 +507,32 @@ void linphone_update_table(sqlite3* db) {
|
|||
ms_message("Table already up to date: %s.", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
} else {
|
||||
ms_debug("Table updated successfully for app-specific data.");
|
||||
ms_debug("Table history updated successfully for app-specific data.");
|
||||
}
|
||||
|
||||
// new field for linphone content storage
|
||||
ret=sqlite3_exec(db,"ALTER TABLE history ADD COLUMN content INTEGER;",NULL,NULL,&errmsg);
|
||||
if(ret != SQLITE_OK) {
|
||||
ms_message("Table already up to date: %s.", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
} else {
|
||||
ms_debug("Table history updated successfully for content data.");
|
||||
ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS content ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
"type TEXT,"
|
||||
"subtype TEXT,"
|
||||
"name TEXT,"
|
||||
"encoding TEXT,"
|
||||
"size INTEGER,"
|
||||
"data BLOB"
|
||||
");",
|
||||
0,0,&errmsg);
|
||||
if(ret != SQLITE_OK) {
|
||||
ms_error("Error in creation: %s.\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
} else {
|
||||
ms_debug("Table content successfully created.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,10 +31,21 @@ public interface LinphoneContent {
|
|||
**/
|
||||
byte [] getData();
|
||||
/**
|
||||
* Get the data size.
|
||||
* @return the data size.
|
||||
* Get the expected data size.
|
||||
* @return the expected data size
|
||||
*/
|
||||
int getSize();
|
||||
int getExpectedSize();
|
||||
|
||||
/**
|
||||
* Sets the expected data size
|
||||
*/
|
||||
void setExpectedSize(int size);
|
||||
|
||||
/**
|
||||
* Return the size of the data field
|
||||
* @return the size of the data field
|
||||
*/
|
||||
int getRealSize();
|
||||
|
||||
/**
|
||||
* Set the content type, for example "application"
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ public interface LinphoneCoreListener {
|
|||
* @param buffer
|
||||
* @param size
|
||||
*/
|
||||
void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message, LinphoneContent content, String buffer, int size);
|
||||
void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message, LinphoneContent content, byte[] buffer, int size);
|
||||
|
||||
/**
|
||||
* Callback to be notified when new data needs to be sent
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
|
|||
@Override
|
||||
public LinphoneChatMessage createFileTransferMessage(LinphoneContent content) {
|
||||
synchronized(getCore()) {
|
||||
return new LinphoneChatMessageImpl(createFileTransferMessage(nativePtr, content.getName(), content.getType(), content.getSubtype(), content.getSize()));
|
||||
return new LinphoneChatMessageImpl(createFileTransferMessage(nativePtr, content.getName(), content.getType(), content.getSubtype(), content.getRealSize()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.linphone.core;
|
|||
public class LinphoneContentImpl implements LinphoneContent {
|
||||
private String mType, mSubtype, mEncoding, mName;
|
||||
private byte[] mData;
|
||||
private int mExpectedSize;
|
||||
|
||||
public LinphoneContentImpl(String type, String subtype, byte data[], String encoding){
|
||||
mType = type;
|
||||
|
|
@ -10,14 +11,16 @@ public class LinphoneContentImpl implements LinphoneContent {
|
|||
mData = data;
|
||||
mEncoding = encoding;
|
||||
mName = null;
|
||||
mExpectedSize = 0;
|
||||
}
|
||||
|
||||
public LinphoneContentImpl(String name, String type, String subtype, byte data[], String encoding){
|
||||
public LinphoneContentImpl(String name, String type, String subtype, byte data[], String encoding, int expectedSize){
|
||||
mType = type;
|
||||
mSubtype = subtype;
|
||||
mData = data;
|
||||
mEncoding = encoding;
|
||||
mName = name;
|
||||
mExpectedSize = expectedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -36,9 +39,19 @@ public class LinphoneContentImpl implements LinphoneContent {
|
|||
return new String(mData);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpectedSize(int size) {
|
||||
mExpectedSize = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
public int getExpectedSize() {
|
||||
return mExpectedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRealSize() {
|
||||
if (mData != null)
|
||||
return mData.length;
|
||||
return 0;
|
||||
|
|
@ -91,5 +104,4 @@ public class LinphoneContentImpl implements LinphoneContent {
|
|||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue