Commit 3e754fb4 authored by jehan's avatar jehan

add a third cb dedicated to progress

parent d5a88652
......@@ -60,47 +60,6 @@
<resource resourceType="PROJECT" workspacePath="/linphone"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="test" path="mediastreamer2/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>CFLAGS="-g"</buildArguments>
<buildTarget>install</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>CFLAGS="-g"</buildArguments>
<buildTarget>install</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="doc" path="coreapi/help" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="doc" path="mediastreamer2/help" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
......@@ -209,4 +168,40 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="test" path="mediastreamer2/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j4 CFLAGS="-g -Wall -Werror -Qunused-arguments" CXXFLAGS="-g"</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j4 CFLAGS="-g -Wall -Werror -Qunused-arguments" CXXFLAGS="-g"</buildArguments>
<buildTarget/>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="doc" path="coreapi/help" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j4 CFLAGS="-g -Wall -Werror -Qunused-arguments" CXXFLAGS="-g"</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="doc" path="mediastreamer2/help" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j4 CFLAGS="-g -Wall -Werror -Qunused-arguments" CXXFLAGS="-g"</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>
......@@ -46,7 +46,7 @@ clean-local:
if ENABLE_TUTORIALS
noinst_PROGRAMS=helloworld registration buddy_status chatroom notify
noinst_PROGRAMS=helloworld registration buddy_status chatroom notify filetransfer
helloworld_SOURCES=helloworld.c
LINPHONE_TUTOS=$(helloworld_SOURCES)
......@@ -76,6 +76,9 @@ LINPHONE_TUTOS+=$(notify_SOURCES)
notify_LDADD=$(helloworld_LDADD)
filetransfer_SOURCES=filetransfer.c
LINPHONE_TUTOS+=$(filetransfer_SOURCES)
AM_CFLAGS=\
-I$(top_srcdir)/coreapi \
$(STRICT_OPTIONS) \
......
/*
linphone
Copyright (C) 2010 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.
*/
/**
* @defgroup chatroom_tuto Chat room and messaging
* @ingroup tutorials
*This program is a _very_ simple usage example of liblinphone,
*desmonstrating how to send/receive SIP MESSAGE from a sip uri identity passed from the command line.
*<br>Argument must be like sip:jehan@sip.linphone.org .
*<br>
*ex chatroom sip:jehan@sip.linphone.org
*<br>
*@include chatroom.c
*
*/
#ifdef IN_LINPHONE
#include "linphonecore.h"
#else
#include "linphone/linphonecore.h"
#endif
#include <signal.h>
static bool_t running=TRUE;
static void stop(int signum){
running=FALSE;
}
/**
* function invoked to report file transfer progress.
* */
static void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress) {
const LinphoneAddress* from_address = linphone_chat_message_get_from(message);
const LinphoneAddress* to_address = linphone_chat_message_get_to(message);
char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address);
printf(" File transfer [%i&] %s of type [%s/%s] %s [%s] \n", (int)(content->size/progress)*100
,(linphone_chat_message_is_outgoing(message)?"sent":"received")
, content->type
, content->subtype
,(linphone_chat_message_is_outgoing(message)?"to":"from")
, address);
free(address);
}
/**
* function invoked when a file transfer is received.
* */
static void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size){
const LinphoneAddress* from_address = linphone_chat_message_get_from(message);
char *from = linphone_address_as_string(from_address);
int file=-1;
printf(" File transfer receive [%i] bytes of type [%s/%s] from [%s] \n" , (int)size
, content->type
, content->subtype
, from);
if (!linphone_chat_message_get_user_data(message)) {
/*first chunk, creating file*/
file = open("receive_file.dump",O_WRONLY);
linphone_chat_message_set_user_data(message,(void*)(long)(0x00000000FFFFFFFF&file)); /*store fd for next chunks*/
} else {
/*next chunk*/
file = (int)linphone_chat_message_get_user_data(message);
}
/*store content on a file*/
write(file,buff,size);
if (size==0) {
printf("File transfert completed");
close(file);
} /*else wait for next chunk*/
free(from);
}
char big_file [128000];
/*
* function call when is file transfer is initiated. file content should be feed into object LinphoneContent
* */
static void file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size){
const LinphoneAddress* to_address = linphone_chat_message_get_to(message);
char *to = linphone_address_as_string(to_address);
int offset=-1;
/*content->size can be feed*/
if (!linphone_chat_message_get_user_data(message)) {
/*first chunk*/
offset=0;
} else {
/*subsequent chunk*/
offset = (int)linphone_chat_message_get_user_data(message);
}
*size = MIN(*size,sizeof(big_file)-offset); /*updating content->size with minimun between remaining data and requested size*/
if (*size==0) {
/*end of file*/
return;
}
memcpy(buff,big_file+offset,*size);
printf(" File transfer sending [%i] bytes of type [%s/%s] from [%s] \n" , (int)*size
, content->type
, content->subtype
, to);
/*store offset for next chunk*/
linphone_chat_message_set_user_data(message,(void*)(offset+*size));
free(to);
}
/*
* Call back to get delivery status of a message
* */
static void linphone_file_transfer_state_changed(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
const LinphoneAddress* to_address = linphone_chat_message_get_to(msg);
char *to = linphone_address_as_string(to_address);
printf("File transfer sent to [%s] delivery status is [%s] \n" , to
, linphone_chat_message_state_to_string(state));
free(to);
}
LinphoneCore *lc;
int main(int argc, char *argv[]){
LinphoneCoreVTable vtable={0};
char* dest_friend=NULL;
int i;
const char* big_file_content="big file";
/*seting dummy file content to something*/
for (i=0;i<sizeof(big_file)/strlen(big_file_content);i++)
sprintf(big_file+i,"%s",big_file_content);
/* takes sip uri identity from the command line arguments */
if (argc>1){
dest_friend=argv[1];
}
signal(SIGINT,stop);
//#define DEBUG
#ifdef DEBUG
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*
Fill the LinphoneCoreVTable with application callbacks.
All are optional. Here we only use the file_transfer_received callback
in order to get notifications about incoming file receive, file_transfer_send to feed file to be transfered
and file_transfer_progress_indication to print progress.
*/
vtable.file_transfer_received=file_transfer_received;
vtable.file_transfer_send=file_transfer_send;
vtable.file_transfer_progress_indication=file_transfer_progress_indication;
/*
Instantiate a LinphoneCore object given the LinphoneCoreVTable
*/
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
/**
* Globally configure an http file transfer server.
*/
linphone_core_set_file_transfer_server(lc,"http://sharing.linphone.org/upload.php");
/*Next step is to create a chat root*/
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,dest_friend);
LinphoneContent content;
memset(&content,0,sizeof(content));
content.type="text";
content.subtype="plain";
content.size=sizeof(big_file); /*total size to be transfered*/
/*now create a chat message with custom content*/
LinphoneChatMessage* chat_message = linphone_chat_room_create_file_transfer_message(chat_room,&content);
/*initiating file transfer*/
/**/
linphone_chat_room_send_message2(chat_room, chat_message,linphone_file_transfer_state_changed,NULL);
/* main loop for receiving incoming messages and doing background linphone core work: */
while(running){
linphone_core_iterate(lc);
ms_usleep(50000);
}
printf("Shutting down...\n");
linphone_chat_room_destroy(chat_room);
linphone_core_destroy(lc);
printf("Exited\n");
return 0;
}
......@@ -133,8 +133,9 @@ typedef struct belle_sip_dict LinphoneDictionary;
struct _LinphoneContent{
char *type; /**<mime type for the data, for example "application"*/
char *subtype; /**<mime subtype for the data, for example "html"*/
void *data; /**<the actual data buffer, usually a string */
size_t size; /**<the size of the data buffer, excluding null character despite null character is always set for convenience.*/
void *data; /**<the actual data buffer, usually a string. Null when provided by callbacks #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferReceiveCb*/
size_t size; /**<the size of the data buffer, excluding null character despite null character is always set for convenience.
When provided by callback #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferReceiveCb, it states the total number of bytes of the transfered file*/
char *encoding; /**<The encoding of the data buffer, for example "gzip"*/
};
......@@ -928,6 +929,18 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_privacy(LinphoneProxyConfig *para
* @return Privacy mode
* */
LINPHONE_PUBLIC LinphonePrivacyMask linphone_proxy_config_get_privacy(const LinphoneProxyConfig *params);
/**
* Set the http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml
* @param #LinphoneProxyConfig to be modified
* @param const char* url of the file server like https://file.linphone.org/upload.php
* */
LINPHONE_PUBLIC void linphone_proxy_config_set_file_transfert_server(LinphoneProxyConfig *params, const char * server_url);
/**
* Get the http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml
* @param params object
* @return const char* url of the file server like https://file.linphone.org/upload.php
* */
LINPHONE_PUBLIC const char* linphone_proxy_config_get_file_transfer_server(const LinphoneProxyConfig *params);
/**
* @}
......@@ -1061,6 +1074,15 @@ LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_chat_room_destroy(LinphoneChatRoom *cr);
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr,const char* message);
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming);
/**
* Create a message attached to a dedicated chat room with a particular content. Use #linphone_chat_room_file_transfer_send to initiate the transfer
* @param cr the chat room.
* @param a #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContentSourceType.src_type is set to LINPHONE_CONTENT_SOURCE_CHUNKED_BUFFER.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent* initial_content);
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr);
LINPHONE_PUBLIC void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg);
LINPHONE_PUBLIC void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb,void* ud);
......@@ -1241,6 +1263,43 @@ typedef void (*LinphoneCoreTextMessageReceivedCb)(LinphoneCore *lc, LinphoneChat
*/
typedef void (*LinphoneCoreMessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
/**
* 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 lc #LinphoneCore object
* @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.
*
*/
typedef void (*LinphoneCoreFileTransferRecvCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size);
/**
* 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
*
* @param lc #LinphoneCore object
* @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.
*
*/
typedef void (*LinphoneCoreFileTransferSendCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size);
/**
* File transfer progress indication callback prototype.
*
* @param lc #LinphoneCore object
* @param message #LinphoneChatMessage message from which the body is received.
* @param content #LinphoneContent incoming content information
* @param progress number of bytes sent/received from the begening of the transfer.
*
*/
typedef void (*LinphoneCoreFileTransferProgressIndicationCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress);
/**
* Is composing notification callback prototype.
*
......@@ -1333,6 +1392,9 @@ typedef struct _LinphoneCoreVTable{
DisplayUrlCb display_url; /**< @deprecated */
ShowInterfaceCb show; /**< @deprecated Notifies the application that it should show up*/
LinphoneCoreTextMessageReceivedCb text_received; /** @deprecated, use #message_received instead <br> A text message has been received */
LinphoneCoreFileTransferRecvCb file_transfer_received; /** Callback to store file received attached to a #LinphoneChatMessage */
LinphoneCoreFileTransferSendCb file_transfer_send; /** Callback to collect file chunk to be sent for a #LinphoneChatMessage */
LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**Callback to indicate file transfer progress*/
} LinphoneCoreVTable;
/**
......@@ -2452,6 +2514,14 @@ typedef enum _LinphoneToneID LinphoneToneID;
LINPHONE_PUBLIC void linphone_core_set_call_error_tone(LinphoneCore *lc, LinphoneReason reason, const char *audiofile);
LINPHONE_PUBLIC void linphone_core_set_tone(LinphoneCore *lc, LinphoneToneID id, const char *audiofile);
/**
* Globaly set an http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml. This value can also be set for a dedicated account using #linphone_proxy_config_set_file_transfer_server
* @param #LinphoneCore to be modified
* @param const char* url of the file server like https://file.linphone.org/upload.php
* */
LINPHONE_PUBLIC void linphone_core_set_file_transfer_server(LinphoneCore *core, const char * server_url);
#ifdef __cplusplus
}
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment