-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #111 from team-telnyx/IS/Feature/CustomHeaders
Is/feature/custom headers
- Loading branch information
Showing
11 changed files
with
191 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
*.xcworkspace/ | ||
project.xcworkspace/ | ||
xcuserdata/ | ||
DerivedData/ | ||
|
||
# Podfiles | ||
Pods/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Params.swift | ||
// TelnyxRTC | ||
// | ||
// Created by Isaac Akakpo on 19/10/2023. | ||
// | ||
|
||
import Foundation | ||
|
||
|
||
struct CustomHeaderData:Codable{ | ||
let jsonrpc:String | ||
let method:String | ||
let params:Params | ||
} | ||
|
||
struct Params: Codable { | ||
let dialogParams: DialogParams | ||
} | ||
|
||
struct DialogParams: Codable { | ||
let custom_headers: [XHeader] | ||
} | ||
|
||
struct XHeader: Codable { | ||
let name: String | ||
let value: String | ||
} | ||
|
||
func appendCustomHeaders(customHeaders:[String:String]) -> [Any] { | ||
var xHeaders = [Any]() | ||
customHeaders.keys.forEach { key in | ||
var header = [String:String]() | ||
header["name"] = key | ||
header["value"] = customHeaders[key] | ||
xHeaders.append(header) | ||
} | ||
return xHeaders | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,6 +143,7 @@ public class TxClient { | |
private var gatewayState: GatewayStates = .NOREG | ||
private var isCallFromPush: Bool = false | ||
private var currentCallId:UUID = UUID() | ||
private var pendingAnswerHeaders = [String:String]() | ||
private var speakerOn:Bool = false | ||
|
||
func isSpeakerEnabled() -> Bool { | ||
|
@@ -165,7 +166,9 @@ public class TxClient { | |
RTCAudioSession.sharedInstance().isAudioEnabled = newValue | ||
} | ||
} | ||
|
||
|
||
let currentRoute = AVAudioSession.sharedInstance().currentRoute | ||
|
||
/// Client must be registered in order to receive or place calls. | ||
public var isRegistered: Bool { | ||
get { | ||
|
@@ -228,14 +231,21 @@ public class TxClient { | |
} | ||
|
||
/// To answer and control callKit active flow | ||
public func answerFromCallkit(answerAction:CXAnswerCallAction) { | ||
/// - Parameters: | ||
/// - answerAction : `CXAnswerCallAction` from callKit | ||
/// - customHeaders: (Optional) | ||
public func answerFromCallkit(answerAction:CXAnswerCallAction,customHeaders:[String:String] = [:]) { | ||
self.answerCallAction = answerAction | ||
///answer call if currentPushCall is not nil | ||
///This means the client has connected and we can safelyanswer | ||
if(self.calls[currentCallId] != nil){ | ||
self.calls[currentCallId]?.answer() | ||
self.calls[currentCallId]?.answer(customHeaders: customHeaders) | ||
answerCallAction?.fulfill() | ||
resetPushVariables() | ||
Logger.log.i(message: "answered from callkit") | ||
}else{ | ||
/// Let's Keep track od the `customHeaders` passed | ||
pendingAnswerHeaders = customHeaders | ||
} | ||
} | ||
|
||
|
@@ -378,16 +388,19 @@ extension TxClient { | |
/// - destinationNumber: The destination `SIP user address` (sip:[email protected]) or `phone number`. | ||
/// - callId: The current call UUID. | ||
/// - clientState: (optional) Custom state in string format encoded in base64 | ||
/// - customHeaders: (optional) Custom Headers to be passed over webRTC Messages, should be in the | ||
/// format `X-key:Value` `X` is required for headers to be passed. | ||
/// - Throws: | ||
/// - sessionId is required if user is not logged in | ||
/// - socket connection error if socket is not connected | ||
/// - destination number is required to start a call. | ||
/// - Returns: The call that has been created | ||
public func newCall(callerName: String, | ||
callerNumber: String, | ||
destinationNumber: String, | ||
callId: UUID, | ||
clientState: String? = nil) throws -> Call { | ||
callerNumber: String, | ||
destinationNumber: String, | ||
callId: UUID, | ||
clientState: String? = nil, | ||
customHeaders:[String:String] = [:]) throws -> Call { | ||
//User needs to be logged in to get a sessionId | ||
guard let sessionId = self.sessionId else { | ||
throw TxError.callFailed(reason: .sessionIdIsRequired) | ||
|
@@ -410,7 +423,7 @@ extension TxClient { | |
ringtone: self.txConfig?.ringtone, | ||
ringbackTone: self.txConfig?.ringBackTone, | ||
iceServers: self.serverConfiguration.webRTCIceServers) | ||
call.newCall(callerName: callerName, callerNumber: callerNumber, destinationNumber: destinationNumber, clientState: clientState) | ||
call.newCall(callerName: callerName, callerNumber: callerNumber, destinationNumber: destinationNumber, clientState: clientState,customHeaders: customHeaders) | ||
|
||
currentCallId = callId | ||
self.calls[callId] = call | ||
|
@@ -430,7 +443,8 @@ extension TxClient { | |
callId: UUID, | ||
remoteSdp: String, | ||
telnyxSessionId: String, | ||
telnyxLegId: String) { | ||
telnyxLegId: String, | ||
customHeaders:[String:String] = [:]) { | ||
|
||
guard let sessionId = self.sessionId, | ||
let socket = self.socket else { | ||
|
@@ -450,7 +464,7 @@ extension TxClient { | |
call.callInfo?.callerName = callerName | ||
call.callInfo?.callerNumber = callerNumber | ||
call.callOptions = TxCallOptions(audio: true) | ||
|
||
call.inviteCustomHeaders = customHeaders | ||
self.calls[callId] = call | ||
// propagate the incoming call to the App | ||
Logger.log.i(message: "TxClient:: push flow createIncomingCall \(call)") | ||
|
@@ -461,7 +475,7 @@ extension TxClient { | |
self.delegate?.onPushCall(call: call) | ||
//Answer is pending from push - Answer Call | ||
if(answerCallAction != nil){ | ||
call.answer() | ||
call.answer(customHeaders: pendingAnswerHeaders) | ||
answerCallAction?.fulfill() | ||
resetPushVariables() | ||
} | ||
|
@@ -663,7 +677,7 @@ extension TxClient : SocketDelegate { | |
let callUUIDString = params["callID"] as? String, | ||
let callUUID = UUID(uuidString: callUUIDString), | ||
let call = calls[callUUID] { | ||
call.handleVertoMessage(message: vertoMessage,txclient: self) | ||
call.handleVertoMessage(message: vertoMessage, dataMessage: message, txClient: self) | ||
} | ||
|
||
|
||
|
@@ -709,12 +723,26 @@ extension TxClient : SocketDelegate { | |
if telnyxLegId.isEmpty { | ||
Logger.log.w(message: "TxClient:: Telnyx Leg ID unavailable on INVITE message") | ||
} | ||
|
||
var customHeaders = [String:String]() | ||
if params["dialogParams"] is [String:Any] { | ||
do { | ||
let dataDecoded = try JSONDecoder().decode(CustomHeaderData.self, from: message.data(using: .utf8)!) | ||
dataDecoded.params.dialogParams.custom_headers.forEach { xHeader in | ||
customHeaders[xHeader.name] = xHeader.value | ||
} | ||
print("Data Decode : \(dataDecoded)") | ||
} catch { | ||
print("decoding error: \(error)") | ||
} | ||
} | ||
self.createIncomingCall(callerName: callerName, | ||
callerNumber: callerNumber, | ||
callId: uuid, | ||
remoteSdp: sdp, | ||
telnyxSessionId: telnyxSessionId, | ||
telnyxLegId: telnyxLegId) | ||
telnyxLegId: telnyxLegId, | ||
customHeaders: customHeaders) | ||
} | ||
break; | ||
//Mark: to send meassage to pong | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.