From 18754293b8455fb820246fc536e38036c7a134ca Mon Sep 17 00:00:00 2001 From: Redmer Loen Date: Wed, 25 Apr 2018 09:31:05 +0200 Subject: [PATCH 1/5] Add configurable codecs (#133) --- Example/VialerSIPLib/AppDelegate.swift | 11 ++- .../VialerSIPLib_Example-Bridging-Header.h | 2 + Pod/Classes/Codecs/VSLAudioCodecs.h | 78 +++++++++++++++ Pod/Classes/Codecs/VSLAudioCodecs.m | 30 ++++++ Pod/Classes/Codecs/VSLVideoCodecs.h | 59 +++++++++++ Pod/Classes/Codecs/VSLVideoCodecs.m | 31 ++++++ .../Configurations/VSLCodecConfiguration.h | 23 +++++ .../Configurations/VSLCodecConfiguration.m | 42 ++++++++ .../Configurations/VSLEndpointConfiguration.h | 12 +++ .../Configurations/VSLEndpointConfiguration.m | 2 +- Pod/Classes/VSLEndpoint.h | 2 +- Pod/Classes/VSLEndpoint.m | 99 ++++++++++++++++++- Pod/Classes/VialerSIPLib.h | 2 +- 13 files changed, 388 insertions(+), 5 deletions(-) create mode 100644 Pod/Classes/Codecs/VSLAudioCodecs.h create mode 100644 Pod/Classes/Codecs/VSLAudioCodecs.m create mode 100644 Pod/Classes/Codecs/VSLVideoCodecs.h create mode 100644 Pod/Classes/Codecs/VSLVideoCodecs.m create mode 100644 Pod/Classes/Configurations/VSLCodecConfiguration.h create mode 100644 Pod/Classes/Configurations/VSLCodecConfiguration.m diff --git a/Example/VialerSIPLib/AppDelegate.swift b/Example/VialerSIPLib/AppDelegate.swift index 66d2ff4f..3e190955 100644 --- a/Example/VialerSIPLib/AppDelegate.swift +++ b/Example/VialerSIPLib/AppDelegate.swift @@ -73,11 +73,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate { endpointConfiguration.ipChangeConfiguration = ipChangeConfiguration; + let codecConfiguration = VSLCodecConfiguration() + codecConfiguration.audioCodecs = [ + VSLAudioCodecs(audioCodec: .ILBC, andPriority: 210), + VSLAudioCodecs(audioCodec: .g711a, andPriority: 209) + ] +// codecConfiguration.videoCodecs = [ +// VSLVideoCodecs(videoCodec: .H264, andPriority: 210) +// ] + endpointConfiguration.codecConfiguration = codecConfiguration; + do { try VialerSIPLib.sharedInstance().configureLibrary(withEndPointConfiguration: endpointConfiguration) // Set your incoming call block here. setupIncomingCallBlock() - VialerSIPLib.sharedInstance().onlyUseIlbc(true) } catch let error { DDLogWrapper.logError("Error setting up VialerSIPLib: \(error)") } diff --git a/Example/VialerSIPLib/VialerSIPLib_Example-Bridging-Header.h b/Example/VialerSIPLib/VialerSIPLib_Example-Bridging-Header.h index 3efeef6d..6859d61b 100644 --- a/Example/VialerSIPLib/VialerSIPLib_Example-Bridging-Header.h +++ b/Example/VialerSIPLib/VialerSIPLib_Example-Bridging-Header.h @@ -7,3 +7,5 @@ #import #import #import +#import +#import diff --git a/Pod/Classes/Codecs/VSLAudioCodecs.h b/Pod/Classes/Codecs/VSLAudioCodecs.h new file mode 100644 index 00000000..6ae60d77 --- /dev/null +++ b/Pod/Classes/Codecs/VSLAudioCodecs.h @@ -0,0 +1,78 @@ +// +// VSLCodecs.h +// Copyright © 2018 Devhouse Spindle. All rights reserved. +// + + +#import + +#import "VSLCodecConfiguration.h" + +/** + * Enum of possible Audio Codecs. + */ +typedef NS_ENUM(NSInteger, VSLAudioCodec) { + // G711a + VSLAudioCodecG711a, + // G722 + VSLAudioCodecG722, + // iLBC + VSLAudioCodecILBC, + // G711 + VSLAudioCodecG711, + // Speex 8 kHz + VSLAudioCodecSpeex8000, + // Speex 16 kHz + VSLAudioCodecSpeex16000, + // Speex 32 kHz + VSLAudioCodecSpeex32000, + // GSM 8 kHZ + VSLAudioCodecGSM, + // Opus + VSLAudioCodecOpus, +}; +#define VSLAudioCodecString(VSLAudioCodec) [VSLAudioCodecArray objectAtIndex:VSLAudioCodec] +#define VSLAudioCodecStringWithIndex(NSInteger) [VSLAudioCodecArray objectAtIndex:NSInteger] +#define VSLAudioCodecArray @[@"PCMA/8000/1", @"G722/16000/1", @"iLBC/8000/1", @"PCMU/8000/1", @"speex/8000/1", @"speex/16000/1", @"speex/32000/1", @"GSM/8000/1", @"opus/48000/2"] + + +@interface VSLAudioCodecs : NSObject + +/** + * The prioritiy of the codec + */ +@property (readonly, nonatomic) NSUInteger priority; + +/** + * The used codec. + */ +@property (readonly, nonatomic) VSLAudioCodec codec; + +/** + * Make the default init unavaibale. + */ +- (instancetype _Nonnull) init __attribute__((unavailable("init not available. Use initWithAudioCodec instead."))); + +/** + * The init to setup the audio codecs. + * + * @param codec Audio codec codec to set the prioritiy for. + * @param priority NSUInteger the priority the codec will have. + */ +- (instancetype _Nonnull)initWithAudioCodec:(VSLAudioCodec)codec andPriority:(NSUInteger)priority; + +/** + * Get the codec from the #define VSLCodecConfigurationAudioString with a VSLCodecConfigurationAudio type. + * + * @param codec VSLCodecConfigurationAudio the codec to get the string representation of. + * + * @return NSString the string representation of the VSLCodecConfigurationAudio type. + */ ++ (NSString * _Nonnull)codecString:(VSLAudioCodec)codec; + +/** + * Get the codec from the defined VSLCodecConfigurationAudioString with an index. + */ ++ (NSString * _Nonnull)codecStringWithIndex:(NSInteger)index; + +@end diff --git a/Pod/Classes/Codecs/VSLAudioCodecs.m b/Pod/Classes/Codecs/VSLAudioCodecs.m new file mode 100644 index 00000000..7fe727ea --- /dev/null +++ b/Pod/Classes/Codecs/VSLAudioCodecs.m @@ -0,0 +1,30 @@ +// +// VSLCodecs.m +// Copyright © 2018 Devhouse Spindle. All rights reserved. +// + +#import "VSLAudioCodecs.h" + +@interface VSLAudioCodecs() +@property (readwrite, nonatomic) NSUInteger priority; +@property (readwrite, nonatomic) VSLAudioCodec codec; +@end + +@implementation VSLAudioCodecs +- (instancetype)initWithAudioCodec:(VSLAudioCodec)codec andPriority:(NSUInteger)priority { + if (self = [super init]) { + self.codec = codec; + self.priority = priority; + } + + return self; +} + ++ (NSString *)codecString:(VSLAudioCodec)codec { + return VSLAudioCodecString(codec); +} + ++ (NSString *)codecStringWithIndex:(NSInteger)index { + return VSLAudioCodecStringWithIndex(index); +} +@end diff --git a/Pod/Classes/Codecs/VSLVideoCodecs.h b/Pod/Classes/Codecs/VSLVideoCodecs.h new file mode 100644 index 00000000..65d03932 --- /dev/null +++ b/Pod/Classes/Codecs/VSLVideoCodecs.h @@ -0,0 +1,59 @@ +// +// VSLVideoCodecs.h +// VialerSIPLib +// +// Created by Redmer Loen on 4/5/18. +// + +#import + + +typedef NS_ENUM(NSInteger, VSLVideoCodec) { + // H264 + VSLVideoCodecH264 +}; +#define VSLVideoCodecString(VSLVideoCodec) [VSLVideoCodecArray objectAtIndex:VSLVideoCodec] +#define VSLVideoCodecStringWithIndex(NSInteger) [VSLVideoCodecArray objectAtIndex:NSInteger] +#define VSLVideoCodecArray @[@"H264/97"] + + +@interface VSLVideoCodecs : NSObject + +/** + * The prioritiy of the codec + */ +@property (readonly, nonatomic) NSUInteger priority; + +/** + * The used codec. + */ +@property (readonly, nonatomic) VSLVideoCodec codec; + +/** + * Make the default init unavaibale. + */ +- (instancetype _Nonnull) init __attribute__((unavailable("init not available. Use initWithVideoCodec instead."))); + +/** + * The init to setup the video codecs. + * + * @param codec Audio codec codec to set the prioritiy for. + * @param priority NSUInteger the priority the codec will have. + */ +- (instancetype _Nonnull)initWithVideoCodec:(VSLVideoCodec)codec andPriority:(NSUInteger)priority; + +/** + * Get the codec from the #define VSLVideoCodecString with a VSLVideoCodec type. + * + * @param codec VSLVideoCodec the codec to get the string representation of. + * + * @return NSString the string representation of the VSLVideoCodec type. + */ ++ (NSString * _Nonnull)codecString:(VSLVideoCodec)codec; + +/** + * Get the codec from the defined VSLVideoCodecString with an index. + */ ++ (NSString * _Nonnull)codecStringWithIndex:(NSInteger)index; + +@end diff --git a/Pod/Classes/Codecs/VSLVideoCodecs.m b/Pod/Classes/Codecs/VSLVideoCodecs.m new file mode 100644 index 00000000..b7b9d2b1 --- /dev/null +++ b/Pod/Classes/Codecs/VSLVideoCodecs.m @@ -0,0 +1,31 @@ +// +// VSLVideoCodecs.m +// VialerSIPLib +// +// Created by Redmer Loen on 4/5/18. +// + +#import "VSLVideoCodecs.h" + +@interface VSLVideoCodecs() +@property (readwrite, nonatomic) NSUInteger priority; +@property (readwrite, nonatomic) VSLVideoCodec codec; +@end + +@implementation VSLVideoCodecs +-(instancetype)initWithVideoCodec:(VSLVideoCodec)codec andPriority:(NSUInteger)priority { + if (self = [super init]) { + self.codec = codec; + self.priority = priority; + } + return self; +} + ++ (NSString *)codecString:(VSLVideoCodec)codec { + return VSLVideoCodecString(codec); +} + ++ (NSString *)codecStringWithIndex:(NSInteger)index { + return VSLVideoCodecStringWithIndex(index); +} +@end diff --git a/Pod/Classes/Configurations/VSLCodecConfiguration.h b/Pod/Classes/Configurations/VSLCodecConfiguration.h new file mode 100644 index 00000000..d561eb1d --- /dev/null +++ b/Pod/Classes/Configurations/VSLCodecConfiguration.h @@ -0,0 +1,23 @@ +// +// VSLCodecConfiguration.h +// Copyright © 2018 Devhouse Spindle. All rights reserved. +// + +#import + +@class VSLAudioCodecs; +@class VSLVideoCodecs; + +@interface VSLCodecConfiguration : NSObject + +/** + * An array of available audio codecs. + */ +@property (strong, nonatomic) NSArray* audioCodecs; + +/** + * An array of available video codecs. + */ +@property (strong, nonatomic) NSArray* videoCodecs; + +@end diff --git a/Pod/Classes/Configurations/VSLCodecConfiguration.m b/Pod/Classes/Configurations/VSLCodecConfiguration.m new file mode 100644 index 00000000..456530af --- /dev/null +++ b/Pod/Classes/Configurations/VSLCodecConfiguration.m @@ -0,0 +1,42 @@ +// +// VSLCodecConfiguration.m +// Copyright © 2018 Devhouse Spindle. All rights reserved. + + +#import "VSLCodecConfiguration.h" + +#import "VSLAudioCodecs.h" +#import "VSLVideoCodecs.h" +#import "NSString+PJString.h" + +@implementation VSLCodecConfiguration + +- (instancetype)init { + if (self = [super init]) { + self.audioCodecs = [self defaultAudioCodecs]; + self.videoCodecs = [self defaultVideoCodecs]; + } + return self; +} + +- (NSArray *) defaultAudioCodecs { + return @[ + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecG711a andPriority:210], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecG722 andPriority:209], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecILBC andPriority:208], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecG711 andPriority:0], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecSpeex8000 andPriority:0], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecSpeex16000 andPriority:0], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecSpeex32000 andPriority:0], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecGSM andPriority:0], + [[VSLAudioCodecs alloc] initWithAudioCodec:VSLAudioCodecOpus andPriority:0] + ]; +} + +- (NSArray *) defaultVideoCodecs { + return @[ + [[VSLVideoCodecs alloc] initWithVideoCodec:VSLVideoCodecH264 andPriority:210] + ]; +} + +@end diff --git a/Pod/Classes/Configurations/VSLEndpointConfiguration.h b/Pod/Classes/Configurations/VSLEndpointConfiguration.h index cbf9947e..2e3fff63 100644 --- a/Pod/Classes/Configurations/VSLEndpointConfiguration.h +++ b/Pod/Classes/Configurations/VSLEndpointConfiguration.h @@ -6,6 +6,7 @@ #import #import "VSLIpChangeConfiguration.h" #import "VSLStunConfiguration.h" +#import "VSLCodecConfiguration.h" @interface VSLEndpointConfiguration : NSObject @@ -81,10 +82,21 @@ */ @property (nonatomic) BOOL disableVideoSupport; +/** + * The available STUN configuration + */ @property (nonatomic) VSLStunConfiguration * _Nullable stunConfiguration; +/** + * The IP change configuration, what happens when an ip address changes. + */ @property (nonatomic) VSLIpChangeConfiguration * _Nullable ipChangeConfiguration; +/** + * The codecs that are going to be used by the endpoint + */ +@property (nonatomic) VSLCodecConfiguration * _Nullable codecConfiguration; + /** * Whether the account needs to be unregistered after a call has been made * diff --git a/Pod/Classes/Configurations/VSLEndpointConfiguration.m b/Pod/Classes/Configurations/VSLEndpointConfiguration.m index 08593af7..f90ed2ee 100644 --- a/Pod/Classes/Configurations/VSLEndpointConfiguration.m +++ b/Pod/Classes/Configurations/VSLEndpointConfiguration.m @@ -10,7 +10,7 @@ static NSUInteger const VSLEndpointConfigurationMaxCalls = 4; static NSUInteger const VSLEndpointConfigurationLogLevel = 5; -static NSUInteger const VSLEndpointConfigurationLogConsoleLevel = 4; +static NSUInteger const VSLEndpointConfigurationLogConsoleLevel = 4; static NSString * const VSLEndpointConfigurationLogFileName = nil; static NSUInteger const VSLEndpointConfigurationClockRate = PJSUA_DEFAULT_CLOCK_RATE; static NSUInteger const VSLEndpointConfigurationSndClockRate = 0; diff --git a/Pod/Classes/VSLEndpoint.h b/Pod/Classes/VSLEndpoint.h index 932698b2..68f6fe8e 100644 --- a/Pod/Classes/VSLEndpoint.h +++ b/Pod/Classes/VSLEndpoint.h @@ -158,6 +158,6 @@ typedef NS_ENUM(NSInteger, VSLEndpointState) { * * @param activate BOOL, if YES, only iLBC will be used. */ -- (void)onlyUseILBC:(BOOL)activate; +- (void)onlyUseILBC:(BOOL)activate __attribute__((deprecated("Deprecated, use VSLCodecConfigurarion to add codecs to the endpoint instead"))); @end diff --git a/Pod/Classes/VSLEndpoint.m b/Pod/Classes/VSLEndpoint.m index 8624a79c..ba5a9631 100644 --- a/Pod/Classes/VSLEndpoint.m +++ b/Pod/Classes/VSLEndpoint.m @@ -11,10 +11,12 @@ #import "VialerSIPLib.h" #import "VSLCall.h" #import "VSLCallManager.h" +#import "VSLAudioCodecs.h" #import "VSLLogging.h" #import "VSLNetworkMonitor.h" #import "VSLIpChangeConfiguration.h" #import "VSLTransportConfiguration.h" +#import "VSLVideoCodecs.h" static NSString * const VSLEndpointErrorDomain = @"VialerSIPLib.VSLEndpoint.error"; @@ -255,7 +257,12 @@ - (BOOL)startEndpointWithEndpointConfiguration:(VSLEndpointConfiguration * _Non self.endpointConfiguration = endpointConfiguration; self.state = VSLEndpointStarted; - [self updateCodecs]; + if (self.endpointConfiguration.codecConfiguration != NULL) { + [self updateAudioCodecs]; + [self updateVideoCodecs]; + } else { + [self updateCodecs]; + } return YES; } @@ -446,6 +453,96 @@ - (pj_uint8_t)priorityForCodec:(NSString *)identifier { return (pj_uint8_t)[priorities[identifier] unsignedIntegerValue]; } +-(BOOL)updateAudioCodecs { + if (self.state != VSLEndpointStarted) { + return NO; + } + + const unsigned audioCodecInfoSize = 64; + pjsua_codec_info audioCodecInfo[audioCodecInfoSize]; + unsigned audioCodecCount = audioCodecInfoSize; + pj_status_t status = pjsua_enum_codecs(audioCodecInfo, &audioCodecCount); + if (status != PJ_SUCCESS) { + VSLLogError(@"Error getting list of audio codecs"); + return NO; + } + + for (NSUInteger i = 0; i < audioCodecCount; i++) { + NSString *codecIdentifier = [NSString stringWithPJString:audioCodecInfo[i].codec_id]; + pj_uint8_t priority = [self priorityForAudioCodec:codecIdentifier]; + status = pjsua_codec_set_priority(&audioCodecInfo[i].codec_id, priority); + if (status != PJ_SUCCESS) { + VSLLogError(@"Error setting codec priority to the correct value"); + return NO; + } + } + return YES; +} + +-(pj_uint8_t)priorityForAudioCodec:(NSString *)identifier { + NSUInteger priority = 0; + for (VSLAudioCodecs* audioCodec in self.endpointConfiguration.codecConfiguration.audioCodecs) { + if ([VSLAudioCodecString(audioCodec.codec) isEqualToString:identifier]) { + priority = audioCodec.priority; + return (pj_uint8_t)priority; + } + } + return (pj_uint8_t)priority; +} + +-(BOOL)updateVideoCodecs { + if (self.state != VSLEndpointStarted) { + return NO; + } + + const unsigned videoCodecInfoSize = 64; + pjsua_codec_info videoCodecInfo[videoCodecInfoSize]; + unsigned videoCodecCount = videoCodecInfoSize; + pj_status_t videoStatus = pjsua_vid_enum_codecs(videoCodecInfo, &videoCodecCount); + if (videoStatus != PJ_SUCCESS) { + VSLLogError(@"Error getting list of video codecs"); + return NO; + } else { + for (NSUInteger i = 0; i < videoCodecCount; i++) { + NSString *codecIdentifier = [NSString stringWithPJString:videoCodecInfo[i].codec_id]; + pj_uint8_t priority = [self priorityForVideoCodec:codecIdentifier]; + + videoStatus = pjsua_vid_codec_set_priority(&videoCodecInfo[i].codec_id, priority); + + if (priority > 0) { + pjmedia_vid_codec_param param; + pjsua_vid_codec_get_param(&videoCodecInfo[i].codec_id, ¶m); + param.ignore_fmtp = PJ_TRUE; + param.enc_fmt.det.vid.size.w = 288; + param.enc_fmt.det.vid.size.h = 352; + param.enc_fmt.det.vid.fps.num = 20; + param.enc_fmt.det.vid.fps.denum = 1; + param.dec_fmt.det.vid.size.w = 1920; + param.dec_fmt.det.vid.size.h = 1920; + pjsua_vid_codec_set_param(&videoCodecInfo[i].codec_id, ¶m); + + if (videoStatus != PJ_SUCCESS) { + DDLogError(@"Error setting video codec priority to the correct value"); + return NO; + } + } + } + } + + return YES; +} + +-(pj_uint8_t)priorityForVideoCodec:(NSString *)identifier { + NSUInteger priority = 0; + for (VSLVideoCodecs* videoCodec in self.endpointConfiguration.codecConfiguration.videoCodecs) { + if ([VSLVideoCodecString(videoCodec.codec) isEqualToString:identifier] && !self.endpointConfiguration.disableVideoSupport) { + priority = videoCodec.priority; + return (pj_uint8_t)priority; + } + } + return (pj_uint8_t)priority; +} + #pragma mark - PJSUA callbacks static void logCallBack(int logLevel, const char *data, int len) { diff --git a/Pod/Classes/VialerSIPLib.h b/Pod/Classes/VialerSIPLib.h index dd70d932..fd356900 100644 --- a/Pod/Classes/VialerSIPLib.h +++ b/Pod/Classes/VialerSIPLib.h @@ -286,6 +286,6 @@ typedef NS_ENUM(NSUInteger, VialerSIPLibErrors) { * * @param activate BOOL, if YES, only iLBC will be used. */ -- (void)onlyUseIlbc:(BOOL)activate; +- (void)onlyUseIlbc:(BOOL)activate __attribute__((deprecated("Deprecated, use VSLCodecConfigurarion to add codecs to the endpoint instead"))); @end From 3fc4eac539a855a54d09ffcb02770c8a33b17e1c Mon Sep 17 00:00:00 2001 From: Redmer Loen Date: Fri, 4 May 2018 08:43:05 +0200 Subject: [PATCH 2/5] Added Blind transfer possibility to a call (#137) --- Example/Podfile.lock | 16 ++--- .../VialerSIPLib/Base.lproj/Main.storyboard | 58 ++++++++++++------- .../VSLTransferCallViewController.swift | 18 ++++++ .../VSLTransferInProgressViewController.swift | 10 ++++ Pod/Classes/VSLCall.h | 9 +++ Pod/Classes/VSLCall.m | 18 ++++++ 6 files changed, 99 insertions(+), 30 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index d1812fdf..c5bf3f1a 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,15 +1,15 @@ PODS: - - CocoaLumberjack (3.4.1): - - CocoaLumberjack/Default (= 3.4.1) - - CocoaLumberjack/Extensions (= 3.4.1) - - CocoaLumberjack/Default (3.4.1) - - CocoaLumberjack/Extensions (3.4.1): + - CocoaLumberjack (3.4.2): + - CocoaLumberjack/Default (= 3.4.2) + - CocoaLumberjack/Extensions (= 3.4.2) + - CocoaLumberjack/Default (3.4.2) + - CocoaLumberjack/Extensions (3.4.2): - CocoaLumberjack/Default - OCMock (3.4.1) - Reachability (3.2) - SPLumberjackLogFormatter (0.0.1): - CocoaLumberjack - - Vialer-pjsip-iOS (3.3.5) + - Vialer-pjsip-iOS (3.3.6) - VialerSIPLib (3.1.3): - CocoaLumberjack - Reachability @@ -39,11 +39,11 @@ CHECKOUT OPTIONS: :git: https://github.com/VoIPGRID/SPLumberjackLogFormatter.git SPEC CHECKSUMS: - CocoaLumberjack: 2e258a064cacc8eb9a2aca318e24d02a0a7fd56d + CocoaLumberjack: db7cc9e464771f12054c22ff6947c5a58d43a0fd OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 SPLumberjackLogFormatter: a2290c9b880f3166b2d1bace45dc1fc1302b28ab - Vialer-pjsip-iOS: 73572fa0f9cf8791c318580c606d1b95163a4ca4 + Vialer-pjsip-iOS: 34ba5d7f2a756be28f5a2c8d72e5f68b08003844 VialerSIPLib: dfcf0f28bc9e77f9f763a7562bc8db7b6b82477d PODFILE CHECKSUM: d5d9deca56ac68b69c70ab9a6d89a30c6d4fef32 diff --git a/Example/VialerSIPLib/Base.lproj/Main.storyboard b/Example/VialerSIPLib/Base.lproj/Main.storyboard index 1c61a85b..81f4bd9b 100644 --- a/Example/VialerSIPLib/Base.lproj/Main.storyboard +++ b/Example/VialerSIPLib/Base.lproj/Main.storyboard @@ -714,7 +714,7 @@ @@ -860,18 +860,30 @@ + + + + + @@ -880,6 +892,7 @@ + @@ -914,7 +927,6 @@ - @@ -925,6 +937,7 @@ + @@ -935,7 +948,6 @@ - @@ -943,12 +955,13 @@ + - + @@ -1331,7 +1344,7 @@ - + @@ -1393,7 +1406,7 @@ - + @@ -1415,8 +1428,9 @@ - - + + + diff --git a/Example/VialerSIPLib/VSLTransferCallViewController.swift b/Example/VialerSIPLib/VSLTransferCallViewController.swift index 70adc0e5..76f00083 100644 --- a/Example/VialerSIPLib/VSLTransferCallViewController.swift +++ b/Example/VialerSIPLib/VSLTransferCallViewController.swift @@ -17,6 +17,7 @@ private var myContext = 0 static let UnwindToMainView = "UnwindToMainViewSegue" static let ShowKeypad = "ShowKeypadSegue" static let UnwindToFirstCallInProgress = "UnwindToFirstCallInProgressSegue" + static let TransferInProgress = "TransferInProgressSegue" } } @@ -58,6 +59,19 @@ private var myContext = 0 } } + @IBAction func blindButtonPressed(_ sender: UIButton) { + guard let number = numberToDialLabel.text, number != "" else { return } + guard let call = currentCall else { return } + + if call.blindTransferCall(withNumber: number) { + callManager.end(call) { (error) in + if error != nil { + self.performSegue(withIdentifier: Configuration.Segues.TransferInProgress, sender: nil) + } + } + } + } + @IBAction override func callButtonPressed(_ sender: UIButton) { guard let number = numberToDialLabel.text, number != "" else { return } @@ -98,6 +112,10 @@ private var myContext = 0 } else if let call = currentCall, call.callState != .null && call.callState != .disconnected { callVC.activeCall = call } + } else if let transferInProgressVC = segue.destination as? VSLTransferInProgressViewController { + guard let call = currentCall else { return } + transferInProgressVC.firstCall = call + transferInProgressVC.secondCallBlindNumber = numberToDialLabel.text } } diff --git a/Example/VialerSIPLib/VSLTransferInProgressViewController.swift b/Example/VialerSIPLib/VSLTransferInProgressViewController.swift index 210bd5bf..d2a54658 100644 --- a/Example/VialerSIPLib/VSLTransferInProgressViewController.swift +++ b/Example/VialerSIPLib/VSLTransferInProgressViewController.swift @@ -34,6 +34,12 @@ class VSLTransferInProgressViewController: UIViewController { } } + var secondCallBlindNumber: String? { + didSet { + updateUI() + } + } + // MARK: - Lifecycle override func viewWillAppear(_ animated: Bool) { @@ -79,6 +85,10 @@ class VSLTransferInProgressViewController: UIViewController { if let call = secondCall, let label = secondCallNumberLabel { label.text = call.callerNumber! } + + if let phoneNumber = secondCallBlindNumber, let label = secondCallNumberLabel { + label.text = phoneNumber + } } fileprivate func prepareForDismissing() { diff --git a/Pod/Classes/VSLCall.h b/Pod/Classes/VSLCall.h index f57448ec..bb1a6c63 100644 --- a/Pod/Classes/VSLCall.h +++ b/Pod/Classes/VSLCall.h @@ -416,6 +416,15 @@ typedef NS_ENUM(NSInteger, VSLCallTerminateReason) { */ - (BOOL)sendDTMF:(NSString * _Nonnull)character error:(NSError * _Nullable * _Nullable)error; +/** + * Blind transfer a call with a given number. + * + * @param number NSString the number that should be transfered to. + * + * @return BOOL success if the transfer has been sent. + */ +- (BOOL)blindTransferCallWithNumber:(NSString * _Nonnull)number; + /** * Transfer the call to the given VSLCall. * diff --git a/Pod/Classes/VSLCall.m b/Pod/Classes/VSLCall.m index 01fcd044..6ca39966 100644 --- a/Pod/Classes/VSLCall.m +++ b/Pod/Classes/VSLCall.m @@ -257,6 +257,24 @@ - (AVAudioPlayer *)disconnectedSoundPlayer { return _disconnectedSoundPlayer; } +- (BOOL)blindTransferCallWithNumber:(NSString *)number { + NSString *cleanedNumber = [VialerUtils cleanPhoneNumber:number]; + + if ([cleanedNumber isEqualToString:@""]) { + return NO; + } + + pj_str_t sipUri = [cleanedNumber sipUriWithDomain:self.account.accountConfiguration.sipDomain]; + + pj_status_t status = pjsua_call_xfer((pjsua_call_id)self.callId, &sipUri, nil); + + if (status == PJ_SUCCESS) { + self.transferStatus = VSLCallTransferStateInitialized; + return YES; + } + return NO; +} + - (BOOL)transferToCall:(VSLCall *)secondCall { NSError *error; if (!self.onHold && ![self toggleHold:&error]) { From 00dfdbc6704ee0c0987e063ba9fbe6a11f4f8ba9 Mon Sep 17 00:00:00 2001 From: Redmer Loen Date: Mon, 7 May 2018 08:13:22 +0200 Subject: [PATCH 3/5] Add a check to see if there is currently audio for a call. (#138) --- .../VialerSIPLib/Base.lproj/Main.storyboard | 2 +- .../VialerSIPLib/VSLCallViewController.swift | 8 ++++ .../VialerSIPLib_Example-Bridging-Header.h | 1 + Pod/Classes/VSLCall.h | 9 ++++- Pod/Classes/VSLCall.m | 38 ++++++++++++++++++- Pod/Classes/VSLEndpoint.m | 1 + 6 files changed, 56 insertions(+), 3 deletions(-) diff --git a/Example/VialerSIPLib/Base.lproj/Main.storyboard b/Example/VialerSIPLib/Base.lproj/Main.storyboard index 81f4bd9b..04d67334 100644 --- a/Example/VialerSIPLib/Base.lproj/Main.storyboard +++ b/Example/VialerSIPLib/Base.lproj/Main.storyboard @@ -66,7 +66,7 @@ -