//
|
// LinphoneManager.m
|
// VoipTest
|
//
|
// Created by StevStark on 2020/11/11.
|
//
|
|
#import "HDLLinphoneManager.h"
|
#import "HDLLinPhoneSDK-Swift.h"
|
#import "HDLAudioHelper.h"
|
#import "HDLLinPhoneCommon.h"
|
//#include "linphone/linphonecore.h"
|
NSString *const kLinphoneBluetoothAvailabilityUpdate = @"LinphoneBluetoothAvailabilityUpdate";
|
NSString *const kLinphoneGlobalStateUpdate = @"LinphoneGlobalStateUpdate";
|
NSString *const kLinphoneConfiguringStateUpdate = @"LinphoneConfiguringStateUpdate";
|
NSString *const kLinphoneCoreUpdate = @"LinphoneCoreUpdate";
|
NSString *const kLinphoneRegistrationUpdate = @"LinphoneRegistrationUpdate";
|
NSString *const kLinphoneNotifyPresenceReceivedForUriOrTel = @"LinphoneNotifyPresenceReceivedForUriOrTel";
|
NSString *const kLinphoneNotifyReceived = @"LinphoneNotifyReceived";
|
NSString *const kLinphoneCallEncryptionChanged = @"LinphoneCallEncryptionChanged";
|
NSString *const kLinphoneMessageReceived = @"LinphoneMessageReceived";
|
NSString *const kLinphoneTextComposeEvent = @"LinphoneTextComposeStarted";
|
|
NSString *const kLinphoneOldChatDBFilename = @"chat_database.sqlite";
|
NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db";
|
NSString *const LINPHONERC_APPLICATION_KEY = @"app";
|
|
extern void libmsamr_init(MSFactory *factory);
|
extern void libmsx264_init(MSFactory *factory);
|
extern void libmsopenh264_init(MSFactory *factory);
|
extern void libmssilk_init(MSFactory *factory);
|
extern void libmswebrtc_init(MSFactory *factory);
|
extern void libmscodec2_init(MSFactory *factory);
|
|
@interface HDLLinphoneManager (){
|
LinphoneAccountCreator *account_creator;
|
|
}
|
@property(strong, nonatomic) AVAudioPlayer* messagePlayer;
|
@end
|
|
@implementation HDLLinphoneManager
|
- (id)init {
|
if ((self = [super init])) {
|
[NSNotificationCenter.defaultCenter addObserver:self
|
selector:@selector(audioRouteChangeListenerCallback:)
|
name:AVAudioSessionRouteChangeNotification
|
object:nil];
|
|
NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
|
self.messagePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil];
|
|
|
_sounds.vibrate = kSystemSoundID_Vibrate;
|
[self migrateImportantFiles];
|
[self renameDefaultSettings];
|
[self copyDefaultSettings];
|
[self overrideDefaultSettings];
|
|
[HDLConfigManager.instance lpConfigSetStringWithValue:[HDLLinphoneManager dataFile:@"linphone.db"] key:@"uri" section:@"storage"];
|
[HDLConfigManager.instance lpConfigSetStringWithValue:[HDLLinphoneManager dataFile:@"x3dh.c25519.sqlite3"] key:@"x3dh_db_path" section:@"lime"];
|
// set default values for first boot
|
|
|
if ([HDLConfigManager.instance lpConfigStringForKeyWithKey:@"debugenable_preference"] == nil) {
|
#ifdef DEBUG
|
[HDLConfigManager.instance lpConfigSetIntWithValue:1 key:@"debugenable_preference"];
|
|
#else
|
[HDLConfigManager.instance lpConfigSetIntWithValue:0 key:@"debugenable_preference"];
|
|
#endif
|
}
|
|
|
// by default if handle_content_encoding is not set, we use plain text for debug purposes only
|
if ( [HDLConfigManager.instance lpConfigStringForKeyWithKey:@"handle_content_encoding" section:@"misc"] == nil) {
|
#ifdef DEBUG
|
[HDLConfigManager.instance lpConfigSetStringWithValue:@"none" key:@"handle_content_encoding" section:@"misc"];
|
|
#else
|
[HDLConfigManager.instance lpConfigSetStringWithValue:@"conflate" key:@"handle_content_encoding" section:@"misc"];
|
#endif
|
}
|
[self migrateFromUserPrefs];
|
|
}
|
return self;
|
}
|
|
+ (HDLLinphoneManager *)instance {
|
@synchronized(self) {
|
if (theLinphoneManager == nil) {
|
theLinphoneManager = [[HDLLinphoneManager alloc] init];
|
}
|
}
|
return theLinphoneManager;
|
}
|
|
+ (LinphoneCore *)getLc {
|
if (theLinphoneCore == nil) {
|
@throw([NSException exceptionWithName:@"LinphoneCoreException"
|
reason:@"Linphone core not initialized yet"
|
userInfo:nil]);
|
}
|
return theLinphoneCore;
|
}
|
- (void)migrateImportantFiles {
|
if ([HDLLinphoneManager copyFile:[HDLLinphoneManager oldPreferenceFile:@"linphonerc"] destination:[HDLLinphoneManager preferenceFile:@"linphonerc"] override:TRUE ignore:TRUE]) {
|
[NSFileManager.defaultManager
|
removeItemAtPath:[HDLLinphoneManager oldPreferenceFile:@"linphonerc"]
|
error:nil];
|
} else if ([HDLLinphoneManager copyFile:[HDLLinphoneManager documentFile:@"linphonerc"] destination:[HDLLinphoneManager preferenceFile:@"linphonerc"] override:TRUE ignore:TRUE]) {
|
[NSFileManager.defaultManager
|
removeItemAtPath:[HDLLinphoneManager documentFile:@"linphonerc"]
|
error:nil];
|
}
|
|
if ([HDLLinphoneManager copyFile:[HDLLinphoneManager oldDataFile:@"linphone.db"] destination:[HDLLinphoneManager dataFile:@"linphone.db"] override:TRUE ignore:TRUE]) {
|
[NSFileManager.defaultManager
|
removeItemAtPath:[HDLLinphoneManager oldDataFile:@"linphone.db"]
|
error:nil];
|
}
|
|
if ([HDLLinphoneManager copyFile:[HDLLinphoneManager oldDataFile:@"x3dh.c25519.sqlite3"] destination:[HDLLinphoneManager dataFile:@"x3dh.c25519.sqlite3"] override:TRUE ignore:TRUE]) {
|
[NSFileManager.defaultManager
|
removeItemAtPath:[HDLLinphoneManager oldDataFile:@"x3dh.c25519.sqlite3"]
|
error:nil];
|
}
|
|
// call history
|
if ([HDLLinphoneManager copyFile:[HDLLinphoneManager oldDataFile:kLinphoneInternalChatDBFilename] destination:[HDLLinphoneManager dataFile:kLinphoneInternalChatDBFilename] override:TRUE ignore:TRUE]) {
|
[NSFileManager.defaultManager
|
removeItemAtPath:[HDLLinphoneManager oldDataFile:kLinphoneInternalChatDBFilename]
|
error:nil];
|
}
|
|
if ([HDLLinphoneManager copyFile:[HDLLinphoneManager oldDataFile:@"zrtp_secrets"] destination:[HDLLinphoneManager dataFile:@"zrtp_secrets"] override:TRUE ignore:TRUE]) {
|
[NSFileManager.defaultManager
|
removeItemAtPath:[HDLLinphoneManager oldDataFile:@"zrtp_secrets"]
|
error:nil];
|
}
|
}
|
|
- (void)renameDefaultSettings {
|
// rename .linphonerc to linphonerc to ease debugging: when downloading
|
// containers from MacOSX, Finder do not display hidden files leading
|
// to useless painful operations to display the .linphonerc file
|
NSString *src = [HDLLinphoneManager documentFile:@".linphonerc"];
|
NSString *dst = [HDLLinphoneManager preferenceFile:@"linphonerc"];
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
NSError *fileError = nil;
|
if ([fileManager fileExistsAtPath:src]) {
|
if ([fileManager fileExistsAtPath:dst]) {
|
[fileManager removeItemAtPath:src error:&fileError];
|
|
} else {
|
[fileManager moveItemAtPath:src toPath:dst error:&fileError];
|
|
}
|
}
|
}
|
|
- (void)copyDefaultSettings {
|
NSString *src = [HDLLinphoneManager bundleFile:@"linphonerc"];
|
NSString *dst = [HDLLinphoneManager preferenceFile:@"linphonerc"];
|
[HDLLinphoneManager copyFile:src destination:dst override:FALSE ignore:FALSE];
|
}
|
|
- (void)overrideDefaultSettings {
|
NSString *linphonecfg = [HDLLinphoneManager bundleFile:@"linphonerc"];
|
NSString *fileStr = [NSString stringWithContentsOfFile:linphonecfg encoding:NSUTF8StringEncoding error:nil];
|
_configDb = linphone_config_new_from_buffer(fileStr.UTF8String);
|
//linphone_config_new_with_factory(linphonecfg.UTF8String, factory.UTF8String);
|
lp_config_clean_entry(_configDb, "misc", "max_calls");
|
}
|
|
|
|
+ (NSString *)dataFile:(NSString *)file {
|
LinphoneFactory *factory = linphone_factory_get();
|
|
NSString *fullPath = [NSString stringWithUTF8String:linphone_factory_get_data_dir(factory,nil)];
|
|
return [fullPath stringByAppendingPathComponent:file];
|
}
|
|
- (void)migrateFromUserPrefs {
|
static NSString *migration_flag = @"userpref_migration_done";
|
|
if (_configDb == nil)
|
return;
|
|
|
if ([HDLConfigManager.instance lpConfigIntForKeyWithKey:migration_flag defaultValue:0]) {
|
return;
|
}
|
|
NSDictionary *defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
|
NSArray *defaults_keys = [defaults allKeys];
|
NSDictionary *values =
|
@{ @"backgroundmode_preference" : @NO,
|
@"debugenable_preference" : @NO,
|
@"start_at_boot_preference" : @YES };
|
BOOL shouldSync = FALSE;
|
|
for (NSString *userpref in values) {
|
if ([defaults_keys containsObject:userpref]) {
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:[[defaults objectForKey:userpref] boolValue] key:userpref];
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:userpref];
|
shouldSync = TRUE;
|
|
} else if ( [HDLConfigManager.instance lpConfigStringForKeyWithKey:userpref] == nil) {
|
// no default value found in our linphonerc, we need to add them
|
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:[[values objectForKey:userpref] boolValue] key:userpref];
|
}
|
}
|
if (shouldSync) {
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
}
|
// don't get back here in the future
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:YES key:migration_flag];
|
}
|
|
|
- (void)audioRouteChangeListenerCallback:(NSNotification *)notif {
|
|
// there is at least one bug when you disconnect an audio bluetooth headset
|
// since we only get notification of route having changed, we cannot tell if that is due to:
|
// -bluetooth headset disconnected or
|
// -user wanted to use earpiece
|
// the only thing we can assume is that when we lost a device, it must be a bluetooth one (strong hypothesis though)
|
if ([[notif.userInfo valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue] == AVAudioSessionRouteChangeReasonOldDeviceUnavailable)
|
_bluetoothAvailable = NO;
|
|
AVAudioSessionRouteDescription *newRoute = [AVAudioSession sharedInstance].currentRoute;
|
|
if (newRoute && newRoute.outputs.count > 0) {
|
NSString *route = newRoute.outputs[0].portType;
|
|
|
HDLCallManager.instance.speakerEnabled = [route isEqualToString:AVAudioSessionPortBuiltInSpeaker];
|
if (([[HDLAudioHelper bluetoothRoutes] containsObject:route]) && !HDLCallManager.instance.speakerEnabled) {
|
_bluetoothAvailable = TRUE;
|
HDLCallManager.instance.bluetoothEnabled = TRUE;
|
} else
|
HDLCallManager.instance.bluetoothEnabled = FALSE;
|
|
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:_bluetoothAvailable], @"available", nil];
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneBluetoothAvailabilityUpdate
|
object:self
|
userInfo:dict];
|
}
|
}
|
|
+ (BOOL)copyFile:(NSString *)src destination:(NSString *)dst override:(BOOL)override ignore:(BOOL)ignore {
|
NSFileManager *fileManager = NSFileManager.defaultManager;
|
NSError *error = nil;
|
if ([fileManager fileExistsAtPath:src] == NO) {
|
if (!ignore)
|
|
return FALSE;
|
}
|
if ([fileManager fileExistsAtPath:dst] == YES) {
|
if (override) {
|
[fileManager removeItemAtPath:dst error:&error];
|
if (error != nil) {
|
|
return FALSE;
|
}
|
} else {
|
|
return FALSE;
|
}
|
}
|
[fileManager copyItemAtPath:src toPath:dst error:&error];
|
if (error != nil) {
|
|
return FALSE;
|
}
|
return TRUE;
|
}
|
|
+ (NSString *)oldPreferenceFile:(NSString *)file {
|
// migration
|
LinphoneFactory *factory = linphone_factory_get();
|
NSString *fullPath = [NSString stringWithUTF8String:linphone_factory_get_config_dir(factory, nil)];
|
return [fullPath stringByAppendingPathComponent:file];
|
}
|
|
+ (NSString *)preferenceFile:(NSString *)file {
|
LinphoneFactory *factory = linphone_factory_get();
|
NSString *fullPath = [NSString stringWithUTF8String:linphone_factory_get_config_dir(factory, nil)];
|
return [fullPath stringByAppendingPathComponent:file];
|
}
|
|
+ (NSString *)documentFile:(NSString *)file {
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
NSString *documentsPath = [paths objectAtIndex:0];
|
return [documentsPath stringByAppendingPathComponent:file];
|
}
|
|
|
+ (NSString *)oldDataFile:(NSString *)file {
|
// migration
|
LinphoneFactory *factory = linphone_factory_get();
|
NSString *fullPath = [NSString stringWithUTF8String:linphone_factory_get_data_dir(factory, nil)];
|
return [fullPath stringByAppendingPathComponent:file];
|
}
|
|
+ (NSString *)bundleFile:(NSString *)file {
|
return [[NSBundle mainBundle] pathForResource:[file stringByDeletingPathExtension] ofType:[file pathExtension]];
|
}
|
|
static BOOL libStarted = FALSE;
|
|
- (void)launchLinphoneCore {
|
|
if (libStarted) {
|
return;
|
}
|
|
libStarted = TRUE;
|
|
signal(SIGPIPE, SIG_IGN);
|
|
// create linphone core
|
[self createLinphoneCore];
|
|
|
|
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
BOOL bAudioInputAvailable = audioSession.inputAvailable;
|
NSError *err = nil;
|
|
if (![audioSession setActive:NO error:&err] && err) {
|
|
err = nil;
|
}
|
if (!bAudioInputAvailable) {
|
|
}
|
}
|
|
- (void)createLinphoneCore {
|
[self migrationAllPre];
|
if (theLinphoneCore != nil) {
|
return;
|
}
|
|
|
// Set audio assets
|
NSString *ring =
|
([HDLLinphoneManager bundleFile:@"notes_of_the_optimistic.caf"])
|
.lastPathComponent;
|
NSString *ringback =
|
([HDLLinphoneManager bundleFile:@"ringback.wav"])
|
.lastPathComponent;
|
NSString *hold =
|
([HDLLinphoneManager bundleFile:@"hold.mkv"])
|
.lastPathComponent;
|
|
[HDLConfigManager.instance lpConfigSetStringWithValue:[HDLLinphoneManager bundleFile:ring] key:@"local_ring" section:@"sound"];
|
[HDLConfigManager.instance lpConfigSetStringWithValue:[HDLLinphoneManager bundleFile:ringback] key:@"remote_ring" section:@"sound"];
|
[HDLConfigManager.instance lpConfigSetStringWithValue:[HDLLinphoneManager bundleFile:hold] key:@"hold_music" section:@"sound"];
|
|
|
LinphoneFactory *factory = linphone_factory_get();
|
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(factory);
|
linphone_core_cbs_set_registration_state_changed(cbs,linphone_iphone_registration_state);
|
linphone_core_cbs_set_notify_presence_received_for_uri_or_tel(cbs, linphone_iphone_notify_presence_received_for_uri_or_tel);
|
linphone_core_cbs_set_authentication_requested(cbs, linphone_iphone_popup_password_request);
|
linphone_core_cbs_set_message_received(cbs, linphone_iphone_message_received);
|
linphone_core_cbs_set_message_received_unable_decrypt(cbs, linphone_iphone_message_received_unable_decrypt);
|
linphone_core_cbs_set_transfer_state_changed(cbs, linphone_iphone_transfer_state_changed);
|
linphone_core_cbs_set_is_composing_received(cbs, linphone_iphone_is_composing_received);
|
linphone_core_cbs_set_configuring_status(cbs, linphone_iphone_configuring_status_changed);
|
linphone_core_cbs_set_global_state_changed(cbs, linphone_iphone_global_state_changed);
|
linphone_core_cbs_set_notify_received(cbs, linphone_iphone_notify_received);
|
linphone_core_cbs_set_call_encryption_changed(cbs, linphone_iphone_call_encryption_changed);
|
linphone_core_cbs_set_chat_room_state_changed(cbs, linphone_iphone_chatroom_state_changed);
|
|
linphone_core_cbs_set_call_log_updated(cbs, linphone_iphone_call_log_updated);
|
linphone_core_cbs_set_user_data(cbs, (__bridge void *)(self));
|
theLinphoneCore = linphone_factory_create_core_with_config_3(factory, _configDb, NULL);
|
linphone_core_add_callbacks(theLinphoneCore, cbs);
|
|
[HDLCallManager.instance setCoreWithCore:theLinphoneCore];
|
[HDLCoreManager.instance setCoreWithCore:theLinphoneCore];
|
[HDLConfigManager.instance setDbWithDb:_configDb];
|
|
linphone_core_start(theLinphoneCore);
|
|
NSLog(@"创建成功");
|
// Let the core handle cbs
|
linphone_core_cbs_unref(cbs);
|
|
|
// Load plugins if available in the linphone SDK - otherwise these calls will do nothing
|
MSFactory *f = linphone_core_get_ms_factory(theLinphoneCore);
|
libmssilk_init(f);
|
libmsamr_init(f);
|
libmsx264_init(f);
|
libmsopenh264_init(f);
|
libmswebrtc_init(f);
|
libmscodec2_init(f);
|
|
linphone_core_reload_ms_plugins(theLinphoneCore, NULL);
|
[self migrationAllPost];
|
|
/* Use the rootca from framework, which is already set*/
|
//linphone_core_set_root_ca(theLinphoneCore, [LinphoneManager bundleFile:@"rootca.pem"].UTF8String);
|
linphone_core_set_user_certificates_path(theLinphoneCore, [HDLLinphoneManager cacheDirectory].UTF8String);
|
|
/* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded
|
(or skipped).
|
Wait for this to finish the code configuration */
|
|
[NSNotificationCenter.defaultCenter addObserver:self
|
selector:@selector(globalStateChangedNotificationHandler:)
|
name:kLinphoneGlobalStateUpdate
|
object:nil];
|
[NSNotificationCenter.defaultCenter addObserver:self
|
selector:@selector(configuringStateChangedNotificationHandler:)
|
name:kLinphoneConfiguringStateUpdate
|
object:nil];
|
|
|
/*call iterate once immediately in order to initiate background connections with sip server or remote provisioning
|
* grab, if any */
|
// [self iterate];
|
// start scheduler
|
[HDLCoreManager.instance startIterateTimer];
|
}
|
|
|
|
- (void)migrationAllPre {
|
// migrate xmlrpc URL if needed
|
if ([HDLConfigManager.instance lpConfigBoolForKeyWithKey:@"migration_xmlrpc"] == NO) {
|
[HDLConfigManager.instance lpConfigSetStringWithValue:@"https://subscribe.linphone.org:444/wizard.php" key:@"xmlrpc_url" section:@"assistant"];
|
[HDLConfigManager.instance lpConfigSetStringWithValue:@"sip:rls@sip.linphone.org" key:@"rls_uri" section:@"sip"];
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:YES key:@"migration_xmlrpc"];
|
}
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:NO key:@"store_friends" section:@"misc"];
|
//so far, storing friends in files is not needed. may change in the future.
|
|
}
|
|
- (void)migrationAllPost {
|
[self migrationLinphoneSettings];
|
[self migrationPerAccount];
|
}
|
|
+ (NSString *)cacheDirectory {
|
LinphoneFactory *factory = linphone_factory_get();
|
|
NSString *cachePath = [NSString stringWithUTF8String:linphone_factory_get_download_dir(factory, NULL)];
|
BOOL isDir = NO;
|
NSError *error;
|
// cache directory must be created if not existing
|
if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) {
|
[[NSFileManager defaultManager] createDirectoryAtPath:cachePath
|
withIntermediateDirectories:NO
|
attributes:nil
|
error:&error];
|
}
|
return cachePath;
|
}
|
|
- (void)globalStateChangedNotificationHandler:(NSNotification *)notif {
|
if ((LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn) {
|
[self finishCoreConfiguration];
|
}
|
}
|
|
- (void)iterate {
|
linphone_core_iterate(theLinphoneCore);
|
}
|
|
- (void)configuringStateChangedNotificationHandler:(NSNotification *)notif {
|
|
|
}
|
|
|
- (void)migrationPerAccount {
|
const bctbx_list_t * proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
|
|
|
NSString *appDomain = [HDLConfigManager.instance lpConfigStringForKeyWithKey:@"domain_name" section:@"app" defaultValue:@"sip.linphone.org"];
|
while (proxies) {
|
LinphoneProxyConfig *config = proxies->data;
|
// can not create group chat without conference factory
|
if (!linphone_proxy_config_get_conference_factory_uri(config)) {
|
if (strcmp(appDomain.UTF8String, linphone_proxy_config_get_domain(config)) == 0) {
|
linphone_proxy_config_set_conference_factory_uri(config, "sip:conference-factory@sip.linphone.org");
|
}
|
}
|
proxies = proxies->next;
|
}
|
|
NSString *s = [HDLConfigManager.instance lpConfigStringForKeyWithKey:@"pushnotification_preference"];
|
if (s && s.boolValue) {
|
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:NO key:@"pushnotification_preference"];
|
const MSList *proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
|
while (proxies) {
|
linphone_proxy_config_set_push_notification_allowed(proxies->data, true);
|
// [self configurePushTokenForProxyConfig:proxies->data];
|
proxies = proxies->next;
|
}
|
}
|
}
|
- (void)migrationLinphoneSettings {
|
/* AVPF migration */
|
|
|
if ( [HDLConfigManager.instance lpConfigBoolForKeyWithKey:@"avpf_migration_done"] == FALSE) {
|
const MSList *proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
|
while (proxies) {
|
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)proxies->data;
|
const char *addr = linphone_proxy_config_get_addr(proxy);
|
// we want to enable AVPF for the proxies
|
|
if (addr &&
|
strstr(addr, [HDLConfigManager.instance lpConfigStringForKeyWithKey:@"domain_name" section:@"app" defaultValue:@"sip.linphone.org"]
|
.UTF8String) != 0) {
|
linphone_proxy_config_enable_avpf(proxy, TRUE);
|
}
|
proxies = proxies->next;
|
}
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:TRUE key:@"avpf_migration_done"];
|
|
}
|
/* Quality Reporting migration */
|
if ([HDLConfigManager.instance lpConfigBoolForKeyWithKey:@"quality_report_migration_done"] == FALSE) {
|
const MSList *proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
|
while (proxies) {
|
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)proxies->data;
|
const char *addr = linphone_proxy_config_get_addr(proxy);
|
// we want to enable quality reporting for the proxies that are on linphone.org
|
|
if (addr &&
|
strstr(addr, [HDLConfigManager.instance lpConfigStringForKeyWithKey: @"domain_name" section:@"app" defaultValue:@"sip.linphone.org"]
|
.UTF8String) != 0) {
|
|
linphone_proxy_config_set_quality_reporting_collector(
|
proxy, "sip:voip-metrics@sip.linphone.org;transport=tcp");
|
linphone_proxy_config_set_quality_reporting_interval(proxy, 180);
|
linphone_proxy_config_enable_quality_reporting(proxy, TRUE);
|
}
|
proxies = proxies->next;
|
}
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:TRUE key:@"quality_report_migration_done"];
|
}
|
/* File transfer migration */
|
if ([HDLConfigManager.instance lpConfigBoolForKeyWithKey:@"file_transfer_migration_done"] == FALSE) {
|
const char *newURL = "https://www.linphone.org:444/lft.php";
|
|
linphone_core_set_file_transfer_server(theLinphoneCore, newURL);
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:TRUE key:@"file_transfer_migration_done"];
|
}
|
|
if ([HDLConfigManager.instance lpConfigBoolForKeyWithKey:@"lime_migration_done"] == FALSE) {
|
const MSList *proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
|
while (proxies) {
|
if (!strcmp(linphone_proxy_config_get_domain((LinphoneProxyConfig *)proxies->data),"sip.linphone.org")) {
|
linphone_core_set_lime_x3dh_server_url(theLinphoneCore, "https://lime.linphone.org/lime-server/lime-server.php");
|
break;
|
}
|
proxies = proxies->next;
|
}
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:TRUE key:@"lime_migration_done"];
|
}
|
|
if ([HDLConfigManager.instance lpConfigBoolForKeyWithKey:@"push_notification_migration_done"] == FALSE) {
|
const MSList *proxies = linphone_core_get_proxy_config_list(theLinphoneCore);
|
bool_t pushEnabled;
|
while (proxies) {
|
const char *refkey = linphone_proxy_config_get_ref_key(proxies->data);
|
if (refkey) {
|
pushEnabled = (strcmp(refkey, "push_notification") == 0);
|
} else {
|
pushEnabled = true;
|
}
|
linphone_proxy_config_set_push_notification_allowed(proxies->data, pushEnabled);
|
proxies = proxies->next;
|
}
|
[HDLConfigManager.instance lpConfigSetBoolWithValue:TRUE key:@"push_notification_migration_done"];
|
}
|
}
|
|
- (void)finishCoreConfiguration {
|
//Force keep alive to workaround push notif on chat message
|
linphone_core_enable_keep_alive(theLinphoneCore, true);
|
|
// get default config from bundle
|
NSString *zrtpSecretsFileName = [HDLLinphoneManager dataFile:@"zrtp_secrets"];
|
NSString *chatDBFileName = [HDLLinphoneManager dataFile:kLinphoneInternalChatDBFilename];
|
NSString *device = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"%@iOS/%@ (%@) LinphoneSDK",
|
[NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"],
|
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"],
|
[[UIDevice currentDevice] name]]];
|
|
|
linphone_core_set_user_agent(theLinphoneCore, device.UTF8String,LINPHONE_SDK_VERSION);
|
|
|
_contactSipField = [HDLConfigManager.instance lpConfigStringForKeyWithKey:@"contact_im_type_value" section:@"sip" defaultValue:@"SIP"];
|
|
|
|
linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName UTF8String]);
|
//linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName UTF8String]);
|
linphone_core_set_call_logs_database_path(theLinphoneCore, [chatDBFileName UTF8String]);
|
|
NSString *path = [HDLLinphoneManager bundleFile:@"nowebcamCIF.jpg"];
|
if (path) {
|
const char *imagePath = [path UTF8String];
|
linphone_core_set_static_picture(theLinphoneCore, imagePath);
|
}
|
|
/*DETECT cameras*/
|
_frontCamId = _backCamId = nil;
|
char **camlist = (char **)linphone_core_get_video_devices(theLinphoneCore);
|
if (camlist) {
|
for (char *cam = *camlist; *camlist != NULL; cam = *++camlist) {
|
if (strcmp(FRONT_CAM_NAME, cam) == 0) {
|
_frontCamId = cam;
|
// great set default cam to front
|
|
linphone_core_set_video_device(theLinphoneCore, _frontCamId);
|
}
|
if (strcmp(BACK_CAM_NAME, cam) == 0) {
|
_backCamId = cam;
|
}
|
}
|
} else {
|
|
}
|
|
// [self enableProxyPublish:([UIApplication sharedApplication].applicationState == UIApplicationStateActive)];
|
|
|
// Post event
|
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"];
|
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCoreUpdate
|
object:HDLLinphoneManager.instance
|
userInfo:dict];
|
}
|
|
- (void)onRegister:(LinphoneCore *)lc
|
cfg:(LinphoneProxyConfig *)cfg
|
state:(LinphoneRegistrationState)state
|
message:(const char *)cmessage {
|
|
LinphoneReason reason = linphone_proxy_config_get_error(cfg);
|
NSString *message = nil;
|
switch (reason) {
|
case LinphoneReasonBadCredentials:
|
message = NSLocalizedString(@"Bad credentials, check your account settings", nil);
|
break;
|
case LinphoneReasonNoResponse:
|
message = NSLocalizedString(@"No response received from remote", nil);
|
break;
|
case LinphoneReasonUnsupportedContent:
|
message = NSLocalizedString(@"Unsupported content", nil);
|
break;
|
case LinphoneReasonIOError:
|
message = NSLocalizedString(
|
@"Cannot reach the server: either it is an invalid address or it may be temporary down.", nil);
|
break;
|
|
case LinphoneReasonUnauthorized:
|
message = NSLocalizedString(@"Operation is unauthorized because missing credential", nil);
|
break;
|
case LinphoneReasonNoMatch:
|
message = NSLocalizedString(@"Operation could not be executed by server or remote client because it "
|
@"didn't have any context for it",
|
nil);
|
break;
|
case LinphoneReasonMovedPermanently:
|
message = NSLocalizedString(@"Resource moved permanently", nil);
|
break;
|
case LinphoneReasonGone:
|
message = NSLocalizedString(@"Resource no longer exists", nil);
|
break;
|
case LinphoneReasonTemporarilyUnavailable:
|
message = NSLocalizedString(@"Temporarily unavailable", nil);
|
break;
|
case LinphoneReasonAddressIncomplete:
|
message = NSLocalizedString(@"Address incomplete", nil);
|
break;
|
case LinphoneReasonNotImplemented:
|
message = NSLocalizedString(@"Not implemented", nil);
|
break;
|
case LinphoneReasonBadGateway:
|
message = NSLocalizedString(@"Bad gateway", nil);
|
break;
|
case LinphoneReasonServerTimeout:
|
message = NSLocalizedString(@"Server timeout", nil);
|
break;
|
case LinphoneReasonNotAcceptable:
|
case LinphoneReasonDoNotDisturb:
|
case LinphoneReasonDeclined:
|
case LinphoneReasonNotFound:
|
case LinphoneReasonNotAnswered:
|
case LinphoneReasonBusy:
|
case LinphoneReasonNone:
|
case LinphoneReasonUnknown:
|
message = NSLocalizedString(@"Unknown error", nil);
|
break;
|
}
|
|
// Post event
|
NSDictionary *dict =
|
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:state], @"state",
|
[NSValue valueWithPointer:cfg], @"cfg", message, @"message", nil];
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneRegistrationUpdate object:nil userInfo:dict];
|
}
|
|
- (void)onNotifyPresenceReceivedForUriOrTel:(LinphoneCore *)lc
|
friend:(LinphoneFriend *)lf
|
uri:(const char *)uri
|
presenceModel:(const LinphonePresenceModel *)model {
|
// Post event
|
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
[dict setObject:[NSValue valueWithPointer:lf] forKey:@"friend"];
|
[dict setObject:[NSValue valueWithPointer:uri] forKey:@"uri"];
|
[dict setObject:[NSValue valueWithPointer:model] forKey:@"presence_model"];
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneNotifyPresenceReceivedForUriOrTel
|
object:self
|
userInfo:dict];
|
}
|
|
- (void)onMessageReceived:(LinphoneCore *)lc room:(LinphoneChatRoom *)room message:(LinphoneChatMessage *)msg {
|
|
}
|
|
- (void)onMessageComposeReceived:(LinphoneCore *)core forRoom:(LinphoneChatRoom *)room {
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneTextComposeEvent
|
object:self
|
userInfo:@{
|
@"room" : [NSValue valueWithPointer:room]
|
}];
|
}
|
|
-(void)login:(NSString*)username password:(NSString*)pwd domain:(NSString*) domain {
|
LinphoneProxyConfig *config = linphone_core_create_proxy_config(theLinphoneCore);
|
LinphoneAddress *addr = linphone_address_new(NULL);
|
LinphoneAddress *tmpAddr = linphone_address_new([NSString stringWithFormat:@"sip:%@",domain].UTF8String);
|
if (tmpAddr == nil) {
|
return;
|
}
|
|
linphone_address_set_username(addr, username.UTF8String);
|
linphone_address_set_port(addr, linphone_address_get_port(tmpAddr));
|
linphone_address_set_domain(addr, linphone_address_get_domain(tmpAddr));
|
// if (displayName && ![displayName isEqualToString:@""]) {
|
// linphone_address_set_display_name(addr, displayName.UTF8String);
|
// }
|
linphone_proxy_config_set_identity_address(config, addr);
|
// set transport
|
NSString *type = @"UDP";
|
linphone_proxy_config_set_route(
|
config,
|
[NSString stringWithFormat:@"%s;transport=%s", domain.UTF8String, type.lowercaseString.UTF8String]
|
.UTF8String);
|
linphone_proxy_config_set_server_addr(
|
config,
|
[NSString stringWithFormat:@"%s;transport=%s", domain.UTF8String, type.lowercaseString.UTF8String]
|
.UTF8String);
|
linphone_proxy_config_enable_publish(config, FALSE);
|
linphone_proxy_config_enable_register(config, TRUE);
|
|
LinphoneAuthInfo *info =
|
linphone_auth_info_new(linphone_address_get_username(addr), // username
|
NULL, // user id
|
pwd.UTF8String, // passwd
|
NULL, // ha1
|
linphone_address_get_domain(addr), // realm - assumed to be domain
|
linphone_address_get_domain(addr) // domain
|
);
|
linphone_core_add_auth_info(theLinphoneCore, info);
|
linphone_address_unref(addr);
|
linphone_address_unref(tmpAddr);
|
if (config) {
|
// [[LinphoneManager instance] configurePushTokenForProxyConfig:config];
|
if (linphone_core_add_proxy_config(theLinphoneCore, config) != -1) {
|
linphone_core_set_default_proxy_config(theLinphoneCore, config);
|
// reload address book to prepend proxy config domain to contacts' phone number
|
// todo: STOP doing that!
|
// [[LinphoneManager.instance fastAddressBook] fetchContactsInBackGroundThread];
|
NSLog(@"登录成功");
|
}
|
}
|
}
|
|
|
-(void)startCall:(NSString*)phoneNum {
|
LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(theLinphoneCore);
|
const char *normvalue;
|
normvalue = linphone_proxy_config_is_phone_number(cfg, phoneNum.UTF8String)
|
? linphone_proxy_config_normalize_phone_number(cfg, phoneNum.UTF8String)
|
: phoneNum.UTF8String;
|
|
LinphoneAddress *addr = linphone_proxy_config_normalize_sip_uri(cfg, normvalue);
|
|
// numbers by default
|
if (addr && cfg) {
|
const char *username = linphone_proxy_config_get_dial_escape_plus(cfg) ? normvalue : phoneNum.UTF8String;
|
if (linphone_proxy_config_is_phone_number(cfg, username))
|
linphone_address_set_username(addr, linphone_proxy_config_normalize_phone_number(cfg, username));
|
}
|
[self call:addr];
|
if (addr)
|
linphone_address_destroy(addr);
|
}
|
|
-(void)endCall{
|
LinphoneCall * call = linphone_core_get_current_call(theLinphoneCore);
|
[HDLCallManager.instance terminateCallWithCall:call];
|
}
|
-(void)acceptCall{
|
LinphoneCall * call = linphone_core_get_current_call(theLinphoneCore);
|
[HDLCallManager.instance acceptCallWithCall:call hasVideo:YES];
|
}
|
|
-(void)fetchVideo{
|
|
if (!linphone_core_video_display_enabled(theLinphoneCore))
|
return;
|
LinphoneCall *call = linphone_core_get_current_call(theLinphoneCore);
|
if (call) {
|
CallAppData *data = [HDLCallManager getAppDataWithCall:call];
|
data.videoRequested = TRUE;/* will be used later to notify user if video was not activated because of the linphone core*/
|
[HDLCallManager setAppDataWithCall:call appData:data];
|
LinphoneCallParams *call_params = linphone_core_create_call_params(theLinphoneCore,call);
|
linphone_call_params_enable_video(call_params, TRUE);
|
linphone_call_update(call, call_params);
|
linphone_call_params_unref(call_params);
|
} else {
|
|
}
|
|
}
|
|
-(void)closeCamera {
|
if (!linphone_core_video_display_enabled(theLinphoneCore))
|
return;
|
// [LinphoneManager.instance setSpeakerEnabled:FALSE];
|
|
LinphoneCall *call = linphone_core_get_current_call(theLinphoneCore);
|
if (call) {
|
LinphoneCallParams *call_params = linphone_core_create_call_params(theLinphoneCore,call);
|
linphone_call_params_enable_video(call_params, FALSE);
|
linphone_core_update_call(theLinphoneCore, call, call_params);
|
linphone_call_params_destroy(call_params);
|
} else {
|
NSLog(@"Cannot toggle video button, because no current call");
|
}
|
}
|
|
- (void)call:(const LinphoneAddress *)iaddr {
|
// First verify that network is available, abort otherwise.
|
if (!linphone_core_is_network_reachable(theLinphoneCore)) {
|
|
return;
|
}
|
|
// Then check that no GSM calls are in progress, abort otherwise.
|
CTCallCenter *callCenter = [[CTCallCenter alloc] init];
|
if ([callCenter currentCalls] != nil && floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
|
|
return;
|
}
|
|
if (!iaddr) {
|
|
return;
|
}
|
// For OutgoingCall, show CallOutgoingView
|
[HDLCallManager.instance startCallWithAddr:iaddr isSas:FALSE];
|
}
|
|
|
- (void)onConfiguringStatusChanged:(LinphoneConfiguringState)status withMessage:(const char *)message {
|
NSDictionary *dict = [NSDictionary
|
dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:status], @"state",
|
[NSString stringWithUTF8String:message ? message : ""], @"message", nil];
|
|
// dispatch the notification asynchronously
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneConfiguringStateUpdate
|
object:self
|
userInfo:dict];
|
});
|
}
|
|
|
- (void)onGlobalStateChanged:(LinphoneGlobalState)state withMessage:(const char *)message {
|
|
|
NSDictionary *dict = [NSDictionary
|
dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:state], @"state",
|
[NSString stringWithUTF8String:message ? message : ""], @"message", nil];
|
|
// dispatch the notification asynchronously
|
dispatch_async(dispatch_get_main_queue(), ^(void) {
|
if (theLinphoneCore && linphone_core_get_global_state(theLinphoneCore) != LinphoneGlobalOff)
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneGlobalStateUpdate object:self userInfo:dict];
|
});
|
}
|
|
- (void)onNotifyReceived:(LinphoneCore *)lc
|
event:(LinphoneEvent *)lev
|
notifyEvent:(const char *)notified_event
|
content:(const LinphoneContent *)body {
|
// Post event
|
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
[dict setObject:[NSValue valueWithPointer:lev] forKey:@"event"];
|
[dict setObject:[NSString stringWithUTF8String:notified_event] forKey:@"notified_event"];
|
if (body != NULL) {
|
[dict setObject:[NSValue valueWithPointer:body] forKey:@"content"];
|
}
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneNotifyReceived object:self userInfo:dict];
|
}
|
|
- (void)onCallEncryptionChanged:(LinphoneCore *)lc
|
call:(LinphoneCall *)call
|
on:(BOOL)on
|
token:(const char *)authentication_token {
|
// Post event
|
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
[dict setObject:[NSValue valueWithPointer:call] forKey:@"call"];
|
[dict setObject:[NSNumber numberWithBool:on] forKey:@"on"];
|
if (authentication_token) {
|
[dict setObject:[NSString stringWithUTF8String:authentication_token] forKey:@"token"];
|
}
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallEncryptionChanged object:self userInfo:dict];
|
}
|
|
-(void)initalLinPhonal{
|
[HDLLinphoneManager.instance launchLinphoneCore];
|
// Override point for customization after application launch.
|
// UIApplication *app = [UIApplication sharedApplication];
|
if (!account_creator) {
|
account_creator = linphone_account_creator_new(
|
[HDLLinphoneManager getLc],
|
[HDLConfigManager.instance lpConfigStringForKeyWithKey:@"xmlrpc_url" section:@"assistant" defaultValue:@""]
|
.UTF8String);
|
}
|
[self loadAssistantConfig:@"assistant_external_sip.rc"];
|
|
}
|
- (void)loadAssistantConfig:(NSString *)rcFilename {
|
linphone_core_load_config_from_xml( [HDLLinphoneManager getLc],
|
[HDLLinphoneManager bundleFile:rcFilename].UTF8String);
|
|
if (account_creator) {
|
linphone_account_creator_set_domain(account_creator, [ [HDLConfigManager.instance lpConfigStringForKeyWithKey:@"domain" section:@"assistant" defaultValue:@""] UTF8String]);
|
|
|
linphone_account_creator_set_algorithm(account_creator, [[HDLConfigManager.instance lpConfigStringForKeyWithKey:@"algorithm" section:@"assistant" defaultValue:@""] UTF8String]);
|
}
|
// linphone_core_set_preferred_video_size_by_name([HDLLinphoneManager getLc], [@"vga" UTF8String]);
|
MSVideoSize vsize;
|
MS_VIDEO_SIZE_ASSIGN(vsize, QVGA);
|
linphone_core_set_preferred_video_size([HDLLinphoneManager getLc], vsize);
|
linphone_core_set_video_preset([HDLLinphoneManager getLc], [@"custom" UTF8String]);
|
linphone_core_set_preferred_framerate([HDLLinphoneManager getLc], 5);
|
|
// LinphoneVideoPolicy policy;
|
// policy.automatically_initiate = YES;
|
// policy.automatically_accept = YES;
|
// linphone_core_set_video_policy([HDLLinphoneManager getLc], &policy);
|
// linphone_core_set_audio_payload_types([HDLLinphoneManager getLc], <#const bctbx_list_t *payload_types#>)
|
|
// PayloadType *pt;
|
// int bitrate = linphone_config_get_int(
|
// _configDb, "audio", "codec_bitrate_limit",
|
// 36); /*default value is in linphonerc or linphonerc-factory*/
|
// const MSList *audio_codecs = linphone_core_get_audio_payload_types(theLinphoneCore);
|
// const MSList *codec = audio_codecs;
|
// while (codec) {
|
// pt = codec->data;
|
// if (linphone_core_payload_type_is_vbr([HDLLinphoneManager getLc], pt)) {
|
// linphone_core_set_payload_type_bitrate([HDLLinphoneManager getLc], pt, bitrate);
|
// }
|
// codec = codec->next;
|
// }
|
}
|
|
-(void)snapShot{
|
NSString *path=[HDLLinPhoneCommon temporarySaveImagePath];
|
LinphoneCall * call = linphone_core_get_current_call(theLinphoneCore);
|
[HDLCallManager.instance snaphotWithFilePath:path call:call];
|
NSLog(@"path:%@",path);
|
UIImage *image=[UIImage imageWithContentsOfFile:path];
|
|
NSLog(@"获取到的图片:%@",image);
|
[HDLLinPhoneCommon saveImageToPhotosAlbum:image];
|
|
|
}
|
-(void)snapShotWithView:(UIView *)view{
|
UIImage *image= [HDLLinPhoneCommon captureImageFromView:view];
|
[HDLLinPhoneCommon saveImageToPhotosAlbum:image];
|
}
|
// C Function
|
static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyConfig *cfg,
|
LinphoneRegistrationState state, const char *message) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onRegister:lc cfg:cfg state:state message:message];
|
}
|
|
static void linphone_iphone_notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *lf,
|
const char *uri_or_tel,
|
const LinphonePresenceModel *presence_model) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onNotifyPresenceReceivedForUriOrTel:lc
|
friend:lf
|
uri:uri_or_tel
|
presenceModel:presence_model];
|
|
}
|
|
static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAuthInfo *auth_info, LinphoneAuthMethod method) {
|
// let the wizard handle its own errors
|
printf("账号认证错误");
|
}
|
|
static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onMessageReceived:lc room:room message:message];
|
}
|
|
static void linphone_iphone_message_received_unable_decrypt(LinphoneCore *lc, LinphoneChatRoom *room,
|
LinphoneChatMessage *message) {
|
NSString *callId = [NSString stringWithUTF8String:linphone_chat_message_get_custom_header(message, "Call-ID")];
|
}
|
|
static void linphone_iphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState state) {
|
|
|
}
|
|
static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onMessageComposeReceived:lc forRoom:room];
|
}
|
|
static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, LinphoneConfiguringState status,
|
const char *message) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onConfiguringStatusChanged:status withMessage:message];
|
}
|
|
static void linphone_iphone_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onGlobalStateChanged:gstate withMessage:message];
|
}
|
|
static void linphone_iphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event,
|
const LinphoneContent *body) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onNotifyReceived:lc
|
event:lev
|
notifyEvent:notified_event
|
content:body];
|
}
|
|
static void linphone_iphone_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on,
|
const char *authentication_token) {
|
[(__bridge HDLLinphoneManager *)linphone_core_cbs_get_user_data(linphone_core_get_current_callbacks(lc)) onCallEncryptionChanged:lc
|
call:call
|
on:on
|
token:authentication_token];
|
}
|
|
void linphone_iphone_chatroom_state_changed(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatRoomState state) {
|
if (state == LinphoneChatRoomStateCreated) {
|
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:nil];
|
}
|
}
|
|
static void linphone_iphone_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl) {
|
if (linphone_call_log_get_status(newcl) == LinphoneCallEarlyAborted) {
|
const char *cid = linphone_call_log_get_call_id(newcl);
|
if (cid) {
|
[HDLCallManager.instance markCallAsDeclinedWithCallId:[NSString stringWithUTF8String:cid]];
|
}
|
}
|
}
|
|
|
|
@end
|