/* * Copyright (c) 2010-2019 Belledonne Communications SARL. * * This file is part of linphone-iphone * * 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 3 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, see . */ #import "HDLLinphoneProviderDelegate.h" #import "HDLLinphoneManager.h" //#import "PhoneMainView.h" #include "linphone/linphonecore.h" #import #import #define LC ([HDLLinphoneManager getLc]) @implementation HDLLinphoneProviderDelegate - (instancetype)init { NSLog(@"ProviderDelegate初始化了"); self = [super init]; self.calls = [[NSMutableDictionary alloc] init]; self.uuids = [[NSMutableDictionary alloc] init]; self.pendingCall = NULL; self.pendingAddr = NULL; self.pendingCallVideo = FALSE; // CXCallController *callController = [[CXCallController alloc] initWithQueue:dispatch_get_main_queue()]; // [callController.callObserver setDelegate:self queue:dispatch_get_main_queue()]; // self.controller = callController; self.callKCalls = 0; if (!self) { NSLog(@"ProviderDelegate not initialized..."); } return self; } - (void)config { // CXProviderConfiguration *config = [[CXProviderConfiguration alloc] // initWithLocalizedName:[NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"]]; // config.ringtoneSound = @"notes_of_the_optimistic.caf"; // config.supportsVideo = TRUE; // config.iconTemplateImageData = UIImagePNGRepresentation([UIImage imageNamed:@"callkit_logo"]); // // NSArray *ar = @[ [NSNumber numberWithInt:(int)CXHandleTypeGeneric] ]; // NSSet *handleTypes = [[NSSet alloc] initWithArray:ar]; // [config setSupportedHandleTypes:handleTypes]; // [config setMaximumCallGroups:2]; // [config setMaximumCallsPerCallGroup:1]; // //not show app's calls in tel's history // //config.includesCallsInRecents = NO; // self.provider = [[CXProvider alloc] initWithConfiguration:config]; // [self.provider setDelegate:self queue:dispatch_get_main_queue()]; } - (void)configAudioSession:(AVAudioSession *)audioSession { NSError *err = nil; [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeVoiceChat options:AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP error:&err]; if (err) { // LOGE(@"Unable to change audio session because: %@", err.localizedDescription); err = nil; } [audioSession setMode:AVAudioSessionModeVoiceChat error:&err]; if (err) { // LOGE(@"Unable to change audio mode because : %@", err.localizedDescription); err = nil; } double sampleRate = 48000.0; [audioSession setPreferredSampleRate:sampleRate error:&err]; if (err) { // LOGE(@"Unable to change preferred sample rate because : %@", err.localizedDescription); err = nil; } } //- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video; { // // Create update to describe the incoming call and caller // CXCallUpdate *update = [[CXCallUpdate alloc] init]; // update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle]; // update.supportsDTMF = TRUE; // update.supportsHolding = TRUE; // update.supportsGrouping = TRUE; // update.supportsUngrouping = TRUE; // update.hasVideo = _pendingCallVideo = video; // // // Report incoming call to system //// LOGD(@"CallKit: report new incoming call with call-id: [%@] and UUID: [%@]", [_calls objectForKey:uuid], uuid); // [self.provider reportNewIncomingCallWithUUID:uuid // update:update // completion:^(NSError *error) { // if (error) { //// LOGE(@"CallKit: cannot complete incoming call with call-id: [%@] and UUID: [%@] from [%@] caused by [%@]", //// [_calls objectForKey:uuid], uuid, handle, [error localizedDescription]); // if ([error code] == CXErrorCodeIncomingCallErrorFilteredByDoNotDisturb || // [error code] == CXErrorCodeIncomingCallErrorFilteredByBlockList) // linphone_call_decline(call,LinphoneReasonBusy); /*to give a chance for other devices to answer*/ // else // linphone_call_decline(call,LinphoneReasonUnknown); // } // }]; //} - (void)setPendingCall:(LinphoneCall *)pendingCall { if (pendingCall) { _pendingCall = pendingCall; if (_pendingCall) linphone_call_ref(_pendingCall); } else if (_pendingCall) { linphone_call_unref(_pendingCall); _pendingCall = NULL; } } #pragma mark - CXProviderDelegate Protocol //- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action { // NSUUID *uuid = action.callUUID; // NSString *callID = [self.calls objectForKey:uuid]; // first, make sure this callid is not already involved in a call //// LOGD(@"CallKit: Answering call with call-id: [%@] and UUID: [%@]", callID, uuid); // [self configAudioSession:[AVAudioSession sharedInstance]]; // [action fulfill]; // LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID]; // if (!call) // return; // // self.callKitCalls++; // self.pendingCall = call; //} //- (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action { // NSUUID *uuid = action.callUUID; // NSString *callID = [self.calls objectForKey:uuid]; // first, make sure this callid is not already involved in a call // NSLog(@"CallKit: Starting Call with call-id: [%@] and UUID: [%@]", callID, uuid); // // To restart Audio Unit // [self configAudioSession:[AVAudioSession sharedInstance]]; // [action fulfill]; // LinphoneCall *call; // if (![callID isEqualToString:@""]) { // call = linphone_core_get_current_call(LC); // } else { // call = [HDLLinphoneManager.instance callByCallId:callID]; // } // if (call != NULL) { // self.callKitCalls++; // self.pendingCall = call; // } //} //- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action { // self.callKitCalls--; // [action fulfill]; // if (linphone_core_is_in_conference(LC)) { // HDLLinphoneManager.instance.conf = TRUE; // linphone_core_terminate_conference(LC); //// LOGD(@"CallKit: Ending the conference"); // } else if (linphone_core_get_calls_nb(LC) > 1) { // HDLLinphoneManager.instance.conf = TRUE; // linphone_core_terminate_all_calls(LC); //// LOGD(@"CallKit: Ending all the ongoing calls"); // } else { // NSUUID *uuid = action.callUUID; // NSString *callID = [self.calls objectForKey:uuid]; // if (callID) { //// LOGD(@"CallKit: Ending the call with call-id: [%@] and UUID: [%@]", callID, uuid); // LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID]; // if (call) { // linphone_call_terminate((LinphoneCall *)call); // } // [self.uuids removeObjectForKey:callID]; // [self.calls removeObjectForKey:uuid]; // } // } //} //- (void)provider:(CXProvider *)provider performSetMutedCallAction:(nonnull CXSetMutedCallAction *)action { // [action fulfill]; //// if ([[PhoneMainView.instance currentView] equal:CallView.compositeViewDescription]) { //// CallView *view = (CallView *)[PhoneMainView.instance popToView:CallView.compositeViewDescription]; //// [view.microButton toggle]; //// } //} //- (void)provider:(CXProvider *)provider performSetHeldCallAction:(nonnull CXSetHeldCallAction *)action { // [action fulfill]; // if (linphone_core_is_in_conference(LC) && action.isOnHold) { // linphone_core_leave_conference(LC); //// LOGD(@"CallKit: Leaving conference"); // [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self]; // return; // } // // if (linphone_core_get_calls_nb(LC) > 1 && action.isOnHold) { // linphone_core_pause_all_calls(LC); //// LOGD(@"CallKit: Pausing all ongoing calls"); // return; // } // // NSUUID *uuid = action.callUUID; // NSString *callID = [self.calls objectForKey:uuid]; // if (!callID) { // return; // } // //// LOGD(@"CallKit: Call with call-id: [%@] and UUID: [%@] paused status changed to: []", callID, uuid, action.isOnHold ? @"Paused" : @"Resumed"); // LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID]; // if (!call) // return; // // if (action.isOnHold) { // HDLLinphoneManager.instance.speakerBeforePause = HDLLinphoneManager.instance.speakerEnabled; // linphone_call_pause((LinphoneCall *)call); // } else { // if (linphone_core_get_conference(LC)) { // linphone_core_enter_conference(LC); // [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self]; // } else { // [self configAudioSession:[AVAudioSession sharedInstance]]; // self.pendingCall = call; // } // } //} //- (void)provider:(CXProvider *)provider performPlayDTMFCallAction:(CXPlayDTMFCallAction *)action { // [action fulfill]; // NSUUID *uuid = action.callUUID; // NSString *callID = [self.calls objectForKey:uuid]; //// LOGD(@"CallKit: playing DTMF for call with call-id: [%@] and UUID: [%@]", callID, uuid); // LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID]; // char digit = action.digits.UTF8String[0]; // linphone_call_send_dtmf((LinphoneCall *)call, digit); //} //- (void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession { // NSLog(@"CallKit: Audio session activated"); // // Now we can (re)start the call // if (self.pendingCall) { // LinphoneCallState state = linphone_call_get_state(self.pendingCall); // switch (state) { // case LinphoneCallIncomingReceived: // [HDLLinphoneManager.instance acceptCall:(LinphoneCall *)self.pendingCall evenWithVideo:_pendingCallVideo]; // break; // case LinphoneCallPaused: // linphone_call_resume((LinphoneCall *)self.pendingCall); // break; // case LinphoneCallStreamsRunning: // // May happen when multiple calls // break; // default: // break; // } // } else { // if (_pendingAddr) { // [HDLLinphoneManager.instance doCall:_pendingAddr]; // } else { //// LOGE(@"CallKit: No pending call"); // } // } // // [self setPendingCall:NULL]; // if (_pendingAddr) // linphone_address_unref(_pendingAddr); // _pendingAddr = NULL; // _pendingCallVideo = FALSE; //} // //- (void)provider:(CXProvider *)provider didDeactivateAudioSession:(nonnull AVAudioSession *)audioSession { // NSLog(@"CallKit : Audio session deactivated"); // [self setPendingCall:NULL]; // if (_pendingAddr) // linphone_address_unref(_pendingAddr); // _pendingAddr = NULL; // _pendingCallVideo = FALSE; //} //- (void)providerDidReset:(CXProvider *)provider { //// LOGD(@"CallKit: Provider reset"); // HDLLinphoneManager.instance.conf = TRUE; // linphone_core_terminate_all_calls(LC); // [self.calls removeAllObjects]; // [self.uuids removeAllObjects]; //} // //#pragma mark - CXCallObserverDelegate Protocol // //- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call { // NSLog(@"CallKit: Call changed"); //} @end