mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
Working file transfer in Python.
- Add the LinphoneBuffer object so that file transfer callbacks do not pass out parameters - Use the LinphoneBuffer object in the file transfer callbacks - Implement the file_transfer_send callback in the Python file transfer test
This commit is contained in:
parent
1b61ea215e
commit
89565386ac
13 changed files with 381 additions and 48 deletions
|
|
@ -40,6 +40,7 @@ LOCAL_SRC_FILES := \
|
|||
bellesip_sal/sal_op_publish.c \
|
||||
bellesip_sal/sal_op_registration.c \
|
||||
bellesip_sal/sal_sdp.c \
|
||||
buffer.c \
|
||||
callbacks.c \
|
||||
call_log.c \
|
||||
call_params.c \
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@
|
|||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_publish.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_registration.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_sdp.c" />
|
||||
<ClCompile Include="..\..\coreapi\buffer.c" />
|
||||
<ClCompile Include="..\..\coreapi\call_log.c" />
|
||||
<ClCompile Include="..\..\coreapi\call_params.c" />
|
||||
<ClCompile Include="..\..\coreapi\callbacks.c" />
|
||||
|
|
@ -145,6 +146,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\coreapi\bellesip_sal\sal_impl.h" />
|
||||
<ClInclude Include="..\..\coreapi\buffer.h" />
|
||||
<ClInclude Include="..\..\coreapi\content.h" />
|
||||
<ClInclude Include="..\..\coreapi\enum.h" />
|
||||
<ClInclude Include="..\..\coreapi\event.h" />
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ set(SOURCE_FILES
|
|||
bellesip_sal/sal_op_publish.c
|
||||
bellesip_sal/sal_op_registration.c
|
||||
bellesip_sal/sal_sdp.c
|
||||
buffer.c
|
||||
callbacks.c
|
||||
call_log.c
|
||||
call_params.c
|
||||
|
|
@ -153,6 +154,7 @@ install(TARGETS linphone
|
|||
|
||||
|
||||
set(HEADER_FILES
|
||||
buffer.h
|
||||
call_log.h
|
||||
call_params.h
|
||||
content.h
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ CLEANFILES=$(GITVERSION_FILE)
|
|||
linphone_includedir=$(includedir)/linphone
|
||||
|
||||
linphone_include_HEADERS=\
|
||||
buffer.h \
|
||||
call_log.h \
|
||||
call_params.h \
|
||||
content.h \
|
||||
|
|
@ -44,6 +45,7 @@ lib_LTLIBRARIES=liblinphone.la
|
|||
liblinphone_la_SOURCES=\
|
||||
address.c \
|
||||
authentication.c \
|
||||
buffer.c \
|
||||
callbacks.c \
|
||||
call_log.c \
|
||||
call_params.c \
|
||||
|
|
|
|||
105
coreapi/buffer.c
Normal file
105
coreapi/buffer.c
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2010-2014 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
|
||||
|
||||
|
||||
static void linphone_buffer_destroy(LinphoneBuffer *buffer) {
|
||||
if (buffer->content) belle_sip_free(buffer->content);
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneBuffer);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneBuffer, belle_sip_object_t,
|
||||
(belle_sip_object_destroy_t)linphone_buffer_destroy,
|
||||
NULL, // clone
|
||||
NULL, // marshal
|
||||
TRUE
|
||||
);
|
||||
|
||||
|
||||
LinphoneBuffer * linphone_buffer_new(void) {
|
||||
LinphoneBuffer *buffer = belle_sip_object_new(LinphoneBuffer);
|
||||
belle_sip_object_ref(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
LinphoneBuffer * linphone_buffer_new_from_data(const uint8_t *data, size_t size) {
|
||||
LinphoneBuffer *buffer = linphone_buffer_new();
|
||||
linphone_buffer_set_content(buffer, data, size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
LinphoneBuffer * linphone_buffer_new_from_string(const char *data) {
|
||||
LinphoneBuffer *buffer = linphone_buffer_new();
|
||||
linphone_buffer_set_string_content(buffer, data);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
LinphoneBuffer * linphone_buffer_ref(LinphoneBuffer *buffer) {
|
||||
belle_sip_object_ref(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void linphone_buffer_unref(LinphoneBuffer *buffer) {
|
||||
belle_sip_object_unref(buffer);
|
||||
}
|
||||
|
||||
void *linphone_buffer_get_user_data(const LinphoneBuffer *buffer) {
|
||||
return buffer->user_data;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_user_data(LinphoneBuffer *buffer, void *ud) {
|
||||
buffer->user_data = ud;
|
||||
}
|
||||
|
||||
const uint8_t * linphone_buffer_get_content(const LinphoneBuffer *buffer) {
|
||||
return buffer->content;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_content(LinphoneBuffer *buffer, const uint8_t *content, size_t size) {
|
||||
buffer->size = size;
|
||||
if (buffer->content) belle_sip_free(buffer->content);
|
||||
buffer->content = belle_sip_malloc(size);
|
||||
memcpy(buffer->content, content, size);
|
||||
}
|
||||
|
||||
const char * linphone_buffer_get_string_content(const LinphoneBuffer *buffer) {
|
||||
return (const char *)buffer->content;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_string_content(LinphoneBuffer *buffer, const char *content) {
|
||||
buffer->size = strlen(content);
|
||||
if (buffer->content) belle_sip_free(buffer->content);
|
||||
buffer->content = (uint8_t *)belle_sip_strdup(content);
|
||||
}
|
||||
|
||||
size_t linphone_buffer_get_size(const LinphoneBuffer *buffer) {
|
||||
return buffer->size;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_size(LinphoneBuffer *buffer, size_t size) {
|
||||
buffer->size = size;
|
||||
}
|
||||
|
||||
bool_t linphone_buffer_is_empty(const LinphoneBuffer *buffer) {
|
||||
return (buffer->size == 0) ? TRUE : FALSE;
|
||||
}
|
||||
147
coreapi/buffer.h
Normal file
147
coreapi/buffer.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
buffer.h
|
||||
Copyright (C) 2010-2014 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LINPHONE_BUFFER_H_
|
||||
#define LINPHONE_BUFFER_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The LinphoneContent object representing a data buffer.
|
||||
**/
|
||||
typedef struct _LinphoneBuffer LinphoneBuffer;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new empty LinphoneBuffer object.
|
||||
* @return A new LinphoneBuffer object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new(void);
|
||||
|
||||
/**
|
||||
* Create a new LinphoneBuffer object from existing data.
|
||||
* @param[in] data The initial data to store in the LinphoneBuffer.
|
||||
* @param[in] size The size of the initial data to stroe in the LinphoneBuffer.
|
||||
* @return A new LinphoneBuffer object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new_from_data(const uint8_t *data, size_t size);
|
||||
|
||||
/**
|
||||
* Create a new LinphoneBuffer object from a string.
|
||||
* @param[in] data The initial string content of the LinphoneBuffer.
|
||||
* @return A new LinphoneBuffer object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new_from_string(const char *data);
|
||||
|
||||
/**
|
||||
* Acquire a reference to the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The same LinphoneBuffer object.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_ref(LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Release reference to the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_buffer_unref(LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Retrieve the user pointer associated with the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The user pointer associated with the buffer.
|
||||
**/
|
||||
LINPHONE_PUBLIC void *linphone_buffer_get_user_data(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Assign a user pointer to the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @param[in] ud The user pointer to associate with the buffer.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_user_data(LinphoneBuffer *buffer, void *ud);
|
||||
|
||||
/**
|
||||
* Get the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC const uint8_t * linphone_buffer_get_content(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Set the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @param[in] content The content of the data buffer.
|
||||
* @param[in] size The size of the content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_content(LinphoneBuffer *buffer, const uint8_t *content, size_t size);
|
||||
|
||||
/**
|
||||
* Get the string content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object
|
||||
* @return The string content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_buffer_get_string_content(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Set the string content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @param[in] content The string content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_string_content(LinphoneBuffer *buffer, const char *content);
|
||||
|
||||
/**
|
||||
* Get the size of the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The size of the content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC size_t linphone_buffer_get_size(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Set the size of the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object
|
||||
* @param[in] size The size of the content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_size(LinphoneBuffer *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Tell whether the LinphoneBuffer is empty.
|
||||
* @param[in] buffer LinphoneBuffer object
|
||||
* @return A boolean value telling whether the LinphoneBuffer is empty or not.
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_buffer_is_empty(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LINPHONE_CONTENT_H_ */
|
||||
|
|
@ -246,7 +246,13 @@ static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_
|
|||
if (offset<linphone_content_get_size(chatMsg->file_transfer_information)){
|
||||
/* get data from call back */
|
||||
if (linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
LinphoneBuffer *lb = linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, *size);
|
||||
if (lb == NULL) *size = 0;
|
||||
else {
|
||||
*size = linphone_buffer_get_size(lb);
|
||||
memcpy(buffer, linphone_buffer_get_content(lb), *size);
|
||||
linphone_buffer_unref(lb);
|
||||
}
|
||||
} else {
|
||||
/* Legacy */
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
|
|
@ -1205,7 +1211,9 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t
|
|||
return;
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
|
||||
LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size);
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb);
|
||||
linphone_buffer_unref(lb);
|
||||
} else {
|
||||
/* Legacy: call back given by application level */
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
|
||||
|
|
@ -1279,7 +1287,9 @@ static void linphone_chat_process_response_from_get_file(void *data, const belle
|
|||
LinphoneCore *lc = chatMsg->chat_room->lc;
|
||||
/* file downloaded succesfully, call again the callback with size at zero */
|
||||
if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, NULL, 0);
|
||||
LinphoneBuffer *lb = linphone_buffer_new();
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb);
|
||||
linphone_buffer_unref(lb);
|
||||
} else {
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -366,12 +366,14 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy);
|
|||
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "buffer.h"
|
||||
#include "call_log.h"
|
||||
#include "call_params.h"
|
||||
#include "content.h"
|
||||
#include "event.h"
|
||||
#include "linphonefriend.h"
|
||||
#else
|
||||
#include "linphone/buffer.h"
|
||||
#include "linphone/call_log.h"
|
||||
#include "linphone/call_params.h"
|
||||
#include "linphone/content.h"
|
||||
|
|
@ -1350,30 +1352,24 @@ typedef void (*LinphoneChatMessageCbsMsgStateChangedCb)(LinphoneChatMessage* msg
|
|||
|
||||
/**
|
||||
* File transfer receive callback prototype. This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file.
|
||||
*
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent incoming content information
|
||||
* @param buff pointer to the received data
|
||||
* @param size number of bytes to be read from buff. 0 means end of file.
|
||||
*
|
||||
* @param buffer #LinphoneBuffer holding the received data. Empty buffer means end of file.
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size);
|
||||
typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* File transfer send callback prototype. This function is called by the core upon an outgoing File transfer is started. This function is called until size is set to 0.
|
||||
* <br> a #LinphoneContent with a size equal zero
|
||||
*
|
||||
* File transfer send callback prototype. This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0.
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent outgoing content
|
||||
* @param buff pointer to the buffer where data chunk shall be written by the app
|
||||
* @param size as input value, it represents the number of bytes expected by the framework. As output value, it means the number of bytes wrote by the application in the buffer. 0 means end of file.
|
||||
*
|
||||
* @param offset the offset in the file from where to get the data to be sent
|
||||
* @param size the number of bytes expected by the framework
|
||||
* @return A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file.
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size);
|
||||
typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size);
|
||||
|
||||
/**
|
||||
* File transfer progress indication callback prototype.
|
||||
*
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent incoming content information
|
||||
* @param offset The number of bytes sent/received since the beginning of the transfer.
|
||||
|
|
|
|||
|
|
@ -936,6 +936,14 @@ struct _LinphoneContent {
|
|||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneContent);
|
||||
|
||||
struct _LinphoneBuffer {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
uint8_t *content; /**< A pointer to the buffer content */
|
||||
size_t size; /**< The size of the buffer content */
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneBuffer);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
@ -1012,6 +1020,7 @@ const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc);
|
|||
*/
|
||||
|
||||
BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000)
|
||||
BELLE_SIP_TYPE_ID(LinphoneBuffer),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
|
||||
BELLE_SIP_TYPE_ID(LinphoneCall),
|
||||
|
|
|
|||
|
|
@ -433,9 +433,16 @@ class Project:
|
|||
if pos == -1:
|
||||
return None
|
||||
returntype = definition[0:pos].strip()
|
||||
if returntype != "void":
|
||||
return None
|
||||
returnarg = CArgument(returntype, enums = self.enums, structs = self.__structs)
|
||||
returndesc = node.find("./detaileddescription/para/simplesect[@kind='return']")
|
||||
if returndesc is not None:
|
||||
if returnarg.ctype == 'MSList':
|
||||
n = returndesc.find('.//mslist')
|
||||
if n is not None:
|
||||
returnarg.containedType = n.text
|
||||
returnarg.description = self.__cleanDescription(returndesc)
|
||||
elif returnarg.completeType != 'void':
|
||||
missingDocWarning += "\tReturn value is not documented\n"
|
||||
definition = definition[pos + 2 :]
|
||||
pos = string.find(definition, "(")
|
||||
definition = definition[pos + 1 : -1]
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ blacklisted_events = [
|
|||
'LinphoneCoreFileTransferSendCb' # missing LinphoneContent
|
||||
]
|
||||
blacklisted_functions = [
|
||||
'linphone_buffer_new_from_data',
|
||||
'linphone_buffer_get_content',
|
||||
'linphone_buffer_set_content',
|
||||
'linphone_call_log_get_local_stats', # missing rtp_stats_t
|
||||
'linphone_call_log_get_remote_stats', # missing rtp_stats_t
|
||||
'linphone_call_params_get_privacy', # missing LinphonePrivacyMask
|
||||
|
|
|
|||
|
|
@ -238,24 +238,7 @@ class MethodDefinition:
|
|||
self.method_type = 'instancemethod'
|
||||
|
||||
def format_local_variables_definition(self):
|
||||
body = ''
|
||||
if self.xml_method_return is not None:
|
||||
self.return_type = self.xml_method_return.get('type')
|
||||
self.return_complete_type = self.xml_method_return.get('completetype')
|
||||
self.return_contained_type = self.xml_method_return.get('containedtype')
|
||||
if is_callback(self.return_complete_type):
|
||||
body += "\tPyObject * pyresult;\n"
|
||||
body += "\tPyObject * pyret;\n"
|
||||
argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
|
||||
self.build_value_format = argument_type.fmt_str
|
||||
elif self.return_complete_type != 'void':
|
||||
body += "\t" + self.return_complete_type + " cresult;\n"
|
||||
argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
|
||||
self.build_value_format = argument_type.fmt_str
|
||||
if self.build_value_format == 'O':
|
||||
body += "\tPyObject * pyresult;\n"
|
||||
body += "\tPyObject * pyret;\n"
|
||||
body += "\tconst char *pyret_fmt;\n"
|
||||
body = self.format_local_return_variables_definition()
|
||||
if self.self_arg is not None:
|
||||
body += "\t" + self.self_arg.get('completetype') + "native_ptr;\n"
|
||||
for xml_method_arg in self.xml_method_args:
|
||||
|
|
@ -473,6 +456,27 @@ class MethodDefinition:
|
|||
body = body[1:] # Remove leading '\t'
|
||||
return body
|
||||
|
||||
def format_local_return_variables_definition(self):
|
||||
body = ''
|
||||
if self.xml_method_return is not None:
|
||||
self.return_type = self.xml_method_return.get('type')
|
||||
self.return_complete_type = self.xml_method_return.get('completetype')
|
||||
self.return_contained_type = self.xml_method_return.get('containedtype')
|
||||
if is_callback(self.return_complete_type):
|
||||
body += "\tPyObject * pyresult;\n"
|
||||
body += "\tPyObject * pyret;\n"
|
||||
argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
|
||||
self.build_value_format = argument_type.fmt_str
|
||||
elif self.return_complete_type != 'void':
|
||||
body += "\t" + self.return_complete_type + " cresult;\n"
|
||||
argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
|
||||
self.build_value_format = argument_type.fmt_str
|
||||
if self.build_value_format == 'O':
|
||||
body += "\tPyObject * pyresult;\n"
|
||||
body += "\tPyObject * pyret;\n"
|
||||
body += "\tconst char *pyret_fmt;\n"
|
||||
return body
|
||||
|
||||
def parse_method_node(self):
|
||||
if self.method_node is not None:
|
||||
self.xml_method_return = self.method_node.find('./return')
|
||||
|
|
@ -778,6 +782,7 @@ class EventCallbackMethodDefinition(MethodDefinition):
|
|||
nocallbacks_class_name = class_name
|
||||
if class_name.endswith('Cbs'):
|
||||
nocallbacks_class_name = class_name[:-3]
|
||||
returnvars = self.format_local_return_variables_definition()
|
||||
common = \
|
||||
""" pylinphone_{class_name}Object *pyself = (pylinphone_{class_name}Object *){function_prefix}get_user_data(self);
|
||||
PyObject *func;
|
||||
|
|
@ -796,7 +801,7 @@ class EventCallbackMethodDefinition(MethodDefinition):
|
|||
argument_type = ArgumentType(arg_type, arg_complete_type, arg_contained_type, self.linphone_module)
|
||||
if argument_type.fmt_str == 'O':
|
||||
specific += "\tPyObject * py" + arg_name + " = NULL;\n"
|
||||
return "{common}\n{specific}".format(common=common, specific=specific)
|
||||
return "{returnvars}\n{common}\n{specific}".format(returnvars=returnvars, common=common, specific=specific)
|
||||
|
||||
def format_arguments_parsing(self):
|
||||
if self.class_['event_class'] == 'Core':
|
||||
|
|
@ -832,6 +837,7 @@ class EventCallbackMethodDefinition(MethodDefinition):
|
|||
|
||||
def format_c_function_call(self):
|
||||
create_python_objects_code = ''
|
||||
convert_python_result_code = ''
|
||||
fmt = 'O'
|
||||
args = ['pyself']
|
||||
for xml_method_arg in self.xml_method_args:
|
||||
|
|
@ -852,22 +858,52 @@ class EventCallbackMethodDefinition(MethodDefinition):
|
|||
type_class = self.find_class_definition(arg_type)
|
||||
create_python_objects_code += "\t\tpy{name} = pylinphone_{arg_type}_from_native_ptr(&pylinphone_{arg_type}Type, {name});\n".format(name=arg_name, arg_type=strip_leading_linphone(arg_type))
|
||||
args=', '.join(args)
|
||||
if self.return_complete_type != 'void':
|
||||
argument_type = ArgumentType(self.return_type, self.return_complete_type, self.return_contained_type, self.linphone_module)
|
||||
if argument_type.fmt_str == 'O':
|
||||
convert_python_result_code = \
|
||||
""" if ((pyresult != Py_None) && !PyObject_IsInstance(pyresult, (PyObject *)&pylinphone_{class_name}Type)) {{
|
||||
PyErr_SetString(PyExc_TypeError, "The return value must be a linphone.{class_name} instance.");
|
||||
return NULL;
|
||||
}}
|
||||
if ((cresult = pylinphone_{class_name}_get_native_ptr(pyresult)) == NULL) {{
|
||||
return NULL;
|
||||
}}
|
||||
""".format(class_name=strip_leading_linphone(self.return_type))
|
||||
|
||||
else:
|
||||
convert_python_result_code = "\t\tcresult = {convertfunc}(pyresult);\n".format(convertfunc=argument_type.convert_func)
|
||||
return \
|
||||
""" if ((func != NULL) && PyCallable_Check(func)) {{
|
||||
{create_python_objects_code}
|
||||
args = Py_BuildValue("{fmt}", {args});
|
||||
if (PyEval_CallObject(func, args) == NULL) {{
|
||||
pyresult = PyEval_CallObject(func, args);
|
||||
if (pyresult == NULL) {{
|
||||
PyErr_Print();
|
||||
}}
|
||||
Py_DECREF(args);
|
||||
{convert_python_result_code}
|
||||
}}
|
||||
""".format(fmt=fmt, args=args, create_python_objects_code=create_python_objects_code)
|
||||
""".format(fmt=fmt, args=args, create_python_objects_code=create_python_objects_code, convert_python_result_code=convert_python_result_code)
|
||||
|
||||
def format_return_trace(self):
|
||||
return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s\", __FUNCTION__);\n"
|
||||
|
||||
def format_return_result(self):
|
||||
return '\tPyGILState_Release(pygil_state);'
|
||||
s = '\tPyGILState_Release(pygil_state);'
|
||||
if self.return_complete_type != 'void':
|
||||
s += '\n\treturn cresult;'
|
||||
return s
|
||||
|
||||
def format_local_return_variables_definition(self):
|
||||
body = "\tPyObject * pyresult;"
|
||||
if self.xml_method_return is not None:
|
||||
self.return_type = self.xml_method_return.get('type')
|
||||
self.return_complete_type = self.xml_method_return.get('completetype')
|
||||
self.return_contained_type = self.xml_method_return.get('containedtype')
|
||||
if self.return_complete_type != 'void':
|
||||
body += "\n\t" + self.return_complete_type + " cresult;"
|
||||
return body
|
||||
|
||||
def format(self):
|
||||
body = MethodDefinition.format(self)
|
||||
|
|
@ -882,10 +918,10 @@ class EventCallbackMethodDefinition(MethodDefinition):
|
|||
arg_complete_type = xml_method_arg.get('completetype')
|
||||
arguments.append(arg_complete_type + ' ' + arg_name)
|
||||
definition = \
|
||||
"""static void pylinphone_{class_name}_callback_{event_name}({arguments}) {{
|
||||
"""static {returntype} pylinphone_{class_name}_callback_{event_name}({arguments}) {{
|
||||
{body}
|
||||
}}
|
||||
""".format(class_name=class_name, event_name=self.class_['event_name'], arguments=', '.join(arguments), body=body)
|
||||
""".format(returntype=self.return_complete_type, class_name=class_name, event_name=self.class_['event_name'], arguments=', '.join(arguments), body=body)
|
||||
return definition
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,17 @@ from copy import deepcopy
|
|||
import linphone
|
||||
from linphonetester import *
|
||||
import os
|
||||
import os.path
|
||||
import time
|
||||
|
||||
|
||||
class TestMessage:
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
if os.path.exists('receive_file.dump'):
|
||||
os.remove('receive_file.dump')
|
||||
|
||||
@classmethod
|
||||
def msg_state_changed(cls, msg, state):
|
||||
stats = msg.chat_room.core.user_data.stats
|
||||
|
|
@ -24,18 +30,23 @@ class TestMessage:
|
|||
linphonetester_logger.error("[TESTER] Unexpected state [{state}] for message [{msg}]".format(msg=msg, state=linphone.ChatMessageState.string(state)))
|
||||
|
||||
@classmethod
|
||||
def file_transfer_received(cls, msg, content, buf, size):
|
||||
print buf, size
|
||||
def file_transfer_send(cls, msg, content, offset, size):
|
||||
if offset >= len(msg.user_data):
|
||||
return linphone.Buffer.new() # end of file
|
||||
return linphone.Buffer.new_from_string(msg.user_data[offset:offset+size])
|
||||
|
||||
@classmethod
|
||||
def file_transfer_recv(cls, msg, content, buf):
|
||||
stats = msg.chat_room.core.user_data.stats
|
||||
if msg.user_data is None:
|
||||
msg.user_data = open('receive_file.dump', 'wb')
|
||||
msg.user_data.write(buf)
|
||||
msg.user_data.write(buf.string_content)
|
||||
else:
|
||||
if size == 0: # Transfer complete
|
||||
if buf.size == 0: # Transfer complete
|
||||
stats.number_of_LinphoneMessageExtBodyReceived += 1
|
||||
msg.user_data.close()
|
||||
else: # Store content
|
||||
msg.user_data.write(buf)
|
||||
msg.user_data.write(buf.string_content)
|
||||
|
||||
def wait_for_server_to_purge_messages(self, manager1, manager2):
|
||||
# Wait a little bit just to have time to purge message stored in the server
|
||||
|
|
@ -87,14 +98,16 @@ class TestMessage:
|
|||
content.size = len(big_file) # total size to be transfered
|
||||
content.name = 'bigfile.txt'
|
||||
message = chat_room.create_file_transfer_message(content)
|
||||
message.user_data = big_file # Store the file in the user data of the chat message
|
||||
self.wait_for_server_to_purge_messages(marie, pauline)
|
||||
message.callbacks.msg_state_changed = TestMessage.msg_state_changed
|
||||
message.callbacks.file_transfer_send = TestMessage.file_transfer_send
|
||||
chat_room.send_chat_message(message)
|
||||
assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageReceivedWithFile == 1), True)
|
||||
if marie.stats.last_received_chat_message is not None:
|
||||
cbs = marie.stats.last_received_chat_message.callbacks
|
||||
cbs.msg_state_changed = TestMessage.msg_state_changed
|
||||
cbs.file_transfer_recv = TestMessage.file_transfer_received
|
||||
cbs.file_transfer_recv = TestMessage.file_transfer_recv
|
||||
marie.stats.last_received_chat_message.download_file()
|
||||
assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageExtBodyReceived == 1), True)
|
||||
assert_equals(pauline.stats.number_of_LinphoneMessageInProgress, 1)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue