Commit e350d2ca authored by Ghislain MARY's avatar Ghislain MARY

Handle check for update.

parent beb062bd
......@@ -54,6 +54,7 @@ option(ENABLE_TOOLS "Turn on or off compilation of tools." YES)
option(ENABLE_TUNNEL "Turn on compilation of tunnel support." NO)
option(ENABLE_TUTORIALS "Enable compilation of tutorials." YES)
option(ENABLE_UNIT_TESTS "Enable compilation of unit tests." YES)
option(ENABLE_UPDATE_CHECK "Enable update check." NO)
option(ENABLE_VIDEO "Build with video support." YES)
cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO)
option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO)
......
......@@ -47,3 +47,4 @@
#cmakedefine HAVE_LIBUDEV_H 0
#cmakedefine HAVE_LIME
#cmakedefine ENABLE_NLS 1
#cmakedefine ENABLE_UPDATE_CHECK 1
......@@ -401,6 +401,15 @@ void linphone_core_cbs_set_call_created(LinphoneCoreCbs *cbs, LinphoneCoreCbsCal
cbs->vtable->call_created = cb;
}
LinphoneCoreCbsVersionUpdateCheckResultReceivedCb linphone_core_cbs_get_version_update_check_result_received(LinphoneCoreCbs *cbs) {
return cbs->vtable->version_update_check_result_received;
}
void linphone_core_cbs_set_version_update_check_result_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsVersionUpdateCheckResultReceivedCb cb) {
cbs->vtable->version_update_check_result_received = cb;
}
typedef belle_sip_object_t_vptr_t LinphoneCore_vptr_t;
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCore);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneCore, belle_sip_object_t,
......@@ -7245,3 +7254,143 @@ bool_t linphone_core_is_content_type_supported(const LinphoneCore *lc, const cha
void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type) {
sal_add_content_type_support(lc->sal, content_type);
}
#ifdef ENABLE_UPDATE_CHECK
static void update_check_process_terminated(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url) {
linphone_core_notify_version_update_check_result_received(lc, result, version, url);
if (lc->update_check_http_listener) {
belle_sip_object_unref(lc->update_check_http_listener);
lc->update_check_http_listener = NULL;
}
bctbx_free(lc->update_check_current_version);
lc->update_check_current_version = NULL;
}
typedef struct _parsed_version_st {
int major;
int minor;
int patch;
} parsed_version_t;
static int compare_parsed_versions(parsed_version_t current_version, parsed_version_t last_version) {
if (last_version.major > current_version.major) return 1;
if (last_version.minor > current_version.minor) return 1;
if (last_version.patch > current_version.patch) return 1;
return -1;
}
static void parse_version(const char *version, parsed_version_t *parsed_version) {
char *copy = bctbx_strdup(version);
char *ptr = copy;
char *next;
memset(parsed_version, 0, sizeof(parsed_version_t));
next = strchr(ptr, '.');
parsed_version->major = atoi(ptr);
ptr = next + 1;
next = strchr(ptr, '.');
parsed_version->minor = atoi(ptr);
if (next != NULL) {
ptr = next + 1;
parsed_version->patch = atoi(ptr);
}
bctbx_free(copy);
}
static bool_t update_is_available(const char *current_version, const char *last_version) {
parsed_version_t current_parsed_version;
parsed_version_t last_parsed_version;
parse_version(current_version, &current_parsed_version);
parse_version(last_version, &last_parsed_version);
return (compare_parsed_versions(current_parsed_version, last_parsed_version) > 0) ? TRUE : FALSE;
}
static void update_check_process_response_event(void *ctx, const belle_http_response_event_t *event) {
LinphoneCore *lc = (LinphoneCore *)ctx;
if (belle_http_response_get_status_code(event->response) == 200) {
belle_sip_message_t *message = BELLE_SIP_MESSAGE(event->response);
char *body = bctbx_strdup(belle_sip_message_get_body(message));
char *last_version = body;
char *url = strchr(body, '\t');
char *ptr;
if (url == NULL) {
update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
bctbx_free(body);
return;
}
*url = '\0';
url++;
ptr = strrchr(url, '\r');
if (ptr != NULL) *ptr = '\0';
ptr = strrchr(url, '\n');
if (ptr != NULL) *ptr = '\0';
if (update_is_available(lc->update_check_current_version, last_version)) {
update_check_process_terminated(lc, LinphoneVersionUpdateCheckNewVersionAvailable, last_version, url);
} else {
update_check_process_terminated(lc, LinphoneVersionUpdateCheckUpToDate, NULL, NULL);
}
bctbx_free(body);
} else {
update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
}
}
static void update_check_process_io_error(void *ctx, const belle_sip_io_error_event_t *event) {
LinphoneCore *lc = (LinphoneCore *)ctx;
update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
}
static void update_check_process_timeout(void *ctx, const belle_sip_timeout_event_t *event) {
LinphoneCore *lc = (LinphoneCore *)ctx;
update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
}
static void update_check_process_auth_requested(void *ctx, belle_sip_auth_event_t *event) {
LinphoneCore *lc = (LinphoneCore *)ctx;
update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
}
#endif /* ENABLE_UPDATE_CHECK */
void linphone_core_check_for_update(LinphoneCore *lc, const char *current_version) {
#ifdef ENABLE_UPDATE_CHECK
int err;
bool_t is_desktop = FALSE;
const char *platform = NULL;
const char *version_check_url_root = lp_config_get_string(lc->config, "misc", "version_check_url_root", NULL);
if (version_check_url_root != NULL) {
belle_http_request_listener_callbacks_t belle_request_listener = { 0 };
belle_http_request_t *request;
belle_generic_uri_t *uri;
char *version_check_url;
MSList *item;
MSList *platform_tags = ms_factory_get_platform_tags(linphone_core_get_ms_factory(lc));
for (item = platform_tags; item != NULL; item = ms_list_next(item)) {
const char *tag = (const char *)item->data;
if (strcmp(tag, "win32") == 0) platform = "windows";
else if (strcmp(tag, "apple") == 0) platform = "macosx";
else if (strcmp(tag, "linux") == 0) platform = "linux";
else if (strcmp(tag, "desktop") == 0) is_desktop = TRUE;
}
if ((is_desktop == FALSE) || (platform == NULL)) {
ms_warning("Update checking is not supported on this platform");
return;
}
version_check_url = bctbx_strdup_printf("%s/%s/RELEASE", version_check_url_root, platform);
uri = belle_generic_uri_parse(version_check_url);
ms_message("Checking for new version at: %s", version_check_url);
bctbx_free(version_check_url);
belle_request_listener.process_response = update_check_process_response_event;
belle_request_listener.process_auth_requested = update_check_process_auth_requested;
belle_request_listener.process_io_error = update_check_process_io_error;
belle_request_listener.process_timeout = update_check_process_timeout;
lc->update_check_current_version = bctbx_strdup(current_version);
lc->update_check_http_listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc);
request = belle_http_request_create("GET", uri, belle_sip_header_create("User-Agent", linphone_core_get_user_agent(lc)), NULL);
err = belle_http_provider_send_request(lc->http_provider, request, lc->update_check_http_listener);
}
#endif
}
......@@ -1110,6 +1110,10 @@ struct _LinphoneCore
belle_http_provider_t *http_provider;
belle_tls_crypto_config_t *http_crypto_config;
belle_http_request_listener_t *provisioning_http_listener;
#ifdef ENABLE_UPDATE_CHECK
belle_http_request_listener_t *update_check_http_listener;
char *update_check_current_version;
#endif
MSList *tones;
LinphoneReason chat_deny_code;
char *file_transfer_server;
......@@ -1922,6 +1926,7 @@ void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore
void linphone_core_notify_friend_list_created(LinphoneCore *lc, LinphoneFriendList *list);
void linphone_core_notify_friend_list_removed(LinphoneCore *lc, LinphoneFriendList *list);
void linphone_core_notify_call_created(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_notify_version_update_check_result_received(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url);
void set_mic_gain_db(AudioStream *st, float gain);
void set_playback_gain_db(AudioStream *st, float gain);
......
......@@ -316,6 +316,11 @@ void linphone_core_notify_call_created(LinphoneCore *lc, LinphoneCall *call) {
cleanup_dead_vtable_refs(lc);
}
void linphone_core_notify_version_update_check_result_received(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url) {
NOTIFY_IF_EXIST(version_update_check_result_received, lc, result, version, url);
cleanup_dead_vtable_refs(lc);
}
static VTableReference * v_table_reference_new(LinphoneCoreCbs *cbs, bool_t internal){
VTableReference *ref=ms_new0(VTableReference,1);
ref->valid=TRUE;
......
......@@ -486,6 +486,14 @@ typedef void (*LinphoneCoreCbsFriendListRemovedCb) (LinphoneCore *lc, LinphoneFr
*/
typedef LinphoneCoreCbsFriendListRemovedCb LinphoneCoreFriendListRemovedCb;
/**
* Callback prototype for reporting the result of a version update check.
* @param[in] lc LinphoneCore object
* @param[in] result The result of the version update check
* @param[in] url The url where to download the new version if the result is LinphoneVersionUpdateCheckNewVersionAvailable
*/
typedef void (*LinphoneCoreCbsVersionUpdateCheckResultReceivedCb) (LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url);
/**
* @}
**/
......
......@@ -113,6 +113,13 @@ LINPHONE_PUBLIC LinphonePlayer *linphone_core_create_local_player(LinphoneCore *
**/
LINPHONE_PUBLIC LinphoneInfoMessage *linphone_core_create_info_message(LinphoneCore*lc);
/**
* Checks if a new version of the application is available.
* @param lc LinphoneCore object
* @param current_version The current version of the application
*/
LINPHONE_PUBLIC void linphone_core_check_for_update(LinphoneCore *lc, const char *current_version);
/**
* @}
*/
......@@ -208,6 +215,7 @@ typedef struct _LinphoneCoreVTable{
LinphoneCoreFriendListCreatedCb friend_list_created;
LinphoneCoreFriendListRemovedCb friend_list_removed;
LinphoneCoreCbsCallCreatedCb call_created;
LinphoneCoreCbsVersionUpdateCheckResultReceivedCb version_update_check_result_received;
void *user_data; /**<User data associated with the above callbacks */
} LinphoneCoreVTable;
......@@ -652,6 +660,20 @@ LINPHONE_PUBLIC void linphone_core_cbs_set_call_created(LinphoneCoreCbs *cbs, Li
*/
LINPHONE_PUBLIC LinphoneCoreCbsCallCreatedCb linphone_core_cbs_get_call_created(LinphoneCoreCbs *cbs);
/**
* Set the version update check result callback.
* @param[in] cbs LinphoneCoreCbs object
* @param[in] cb The callback to use
*/
LINPHONE_PUBLIC void linphone_core_cbs_set_version_update_check_result_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsVersionUpdateCheckResultReceivedCb cb);
/**
* Get the version update check result callback.
* @param[in] cbs LinphoneCoreCbs object
* @return The current callback
*/
LINPHONE_PUBLIC LinphoneCoreCbsVersionUpdateCheckResultReceivedCb linphone_core_cbs_get_version_update_check_result_received(LinphoneCoreCbs *cbs);
/**
* @}
**/
......
......@@ -1148,6 +1148,16 @@ typedef enum _LinphoneUpnpState {
*/
typedef struct _LinphoneVcard LinphoneVcard;
/**
* Enum describing the result of a version update check.
* @ingroup misc
*/
typedef enum _LinphoneVersionUpdateCheckResult {
LinphoneVersionUpdateCheckUpToDate,
LinphoneVersionUpdateCheckNewVersionAvailable,
LinphoneVersionUpdateCheckError
} LinphoneVersionUpdateCheckResult;
/**
* The LinphoneVideoDefinition object represents a video definition, eg. its width and its height.
* @ingroup media_parameters
......
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