зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 10 changesets (bug 1091242) for Android/b2g non-unified build bustage
CLOSED TREE Backed out changeset 7f72b55c5de7 (bug 1091242) Backed out changeset f1501aa24397 (bug 1091242) Backed out changeset 7fde5994aee5 (bug 1091242) Backed out changeset 59b415714087 (bug 1091242) Backed out changeset dadb65fedc08 (bug 1091242) Backed out changeset 21be81424e4e (bug 1091242) Backed out changeset 498fb1dafba5 (bug 1091242) Backed out changeset 8d0653eb85ab (bug 1091242) Backed out changeset c82d484e135a (bug 1091242) Backed out changeset 3e0c8932f1b1 (bug 1091242)
This commit is contained in:
Родитель
91fcbf833d
Коммит
5fe54ea0fd
|
@ -507,7 +507,7 @@ class Automation(object):
|
|||
env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
|
||||
|
||||
# Set WebRTC logging in case it is not set yet
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')
|
||||
env.setdefault('R_LOG_LEVEL', '6')
|
||||
env.setdefault('R_LOG_DESTINATION', 'stderr')
|
||||
env.setdefault('R_LOG_VERBOSE', '1')
|
||||
|
|
|
@ -410,7 +410,7 @@ def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=N
|
|||
env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
|
||||
|
||||
# Set WebRTC logging in case it is not set yet
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')
|
||||
env.setdefault('R_LOG_LEVEL', '6')
|
||||
env.setdefault('R_LOG_DESTINATION', 'stderr')
|
||||
env.setdefault('R_LOG_VERBOSE', '1')
|
||||
|
|
|
@ -862,7 +862,7 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'PeerConnectionImpl': {
|
||||
'nativeType': 'mozilla::PeerConnectionImpl',
|
||||
'nativeType': 'sipcc::PeerConnectionImpl',
|
||||
'headerFile': 'PeerConnectionImpl.h',
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
|
|
@ -64,7 +64,6 @@ LOCAL_INCLUDES += [
|
|||
'/layout/style',
|
||||
'/layout/xul/tree',
|
||||
'/media/mtransport',
|
||||
'/media/webrtc/',
|
||||
'/media/webrtc/signaling/src/common/time_profiling',
|
||||
'/media/webrtc/signaling/src/peerconnection',
|
||||
]
|
||||
|
|
|
@ -25,7 +25,7 @@ const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
|
|||
const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
|
||||
const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
|
||||
|
||||
const PC_CID = Components.ID("{bdc2e533-b308-4708-ac8e-a8bfade6d851}");
|
||||
const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
|
||||
const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
|
||||
const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
|
||||
const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
|
||||
|
@ -849,7 +849,7 @@ RTCPeerConnection.prototype = {
|
|||
|
||||
this._impl.addIceCandidate(cand.candidate, cand.sdpMid || "",
|
||||
(cand.sdpMLineIndex === null) ? 0 :
|
||||
cand.sdpMLineIndex);
|
||||
cand.sdpMLineIndex + 1);
|
||||
},
|
||||
|
||||
addStream: function(stream) {
|
||||
|
@ -1122,7 +1122,7 @@ PeerConnectionObserver.prototype = {
|
|||
const reasonName = [
|
||||
"",
|
||||
"InternalError",
|
||||
"InvalidCandidateError",
|
||||
"InternalError",
|
||||
"InvalidParameter",
|
||||
"InvalidStateError",
|
||||
"InvalidSessionDescriptionError",
|
||||
|
@ -1221,7 +1221,7 @@ PeerConnectionObserver.prototype = {
|
|||
{
|
||||
candidate: candidate,
|
||||
sdpMid: mid,
|
||||
sdpMLineIndex: level
|
||||
sdpMLineIndex: level - 1
|
||||
}
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
component {bdc2e533-b308-4708-ac8e-a8bfade6d851} PeerConnection.js
|
||||
component {00e0e20d-1494-4776-8e0e-0f0acbea3c79} PeerConnection.js
|
||||
component {d1748d4c-7f6a-4dc5-add6-d55b7678537e} PeerConnection.js
|
||||
component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
|
||||
component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
|
||||
|
@ -9,7 +9,7 @@ component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
|
|||
component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
|
||||
component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
|
||||
|
||||
contract @mozilla.org/dom/peerconnection;1 {bdc2e533-b308-4708-ac8e-a8bfade6d851}
|
||||
contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
|
||||
contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
|
||||
contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
|
||||
contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
|
||||
|
|
|
@ -59,7 +59,6 @@ interface IPeerConnection : nsISupports
|
|||
|
||||
/* Constants for 'name' in error callbacks */
|
||||
const unsigned long kNoError = 0; // Test driver only
|
||||
const unsigned long kInvalidCandidate = 2;
|
||||
const unsigned long kInvalidMediastreamTrack = 3;
|
||||
const unsigned long kInvalidState = 4;
|
||||
const unsigned long kInvalidSessionDescription = 5;
|
||||
|
|
|
@ -21,9 +21,9 @@ NS_DEFINE_NAMED_CID(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CID)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStunUDPSocketFilterHandler)
|
||||
|
||||
|
||||
namespace mozilla
|
||||
namespace sipcc
|
||||
{
|
||||
// Factory defined in mozilla::, defines mozilla::PeerConnectionImplConstructor
|
||||
// Factory defined in sipcc::, defines sipcc::PeerConnectionImplConstructor
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PeerConnectionImpl)
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(PeerConnectionImpl)
|
|||
NS_DEFINE_NAMED_CID(PEERCONNECTION_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kCIDs[] = {
|
||||
{ &kPEERCONNECTION_CID, false, nullptr, mozilla::PeerConnectionImplConstructor },
|
||||
{ &kPEERCONNECTION_CID, false, nullptr, sipcc::PeerConnectionImplConstructor },
|
||||
{ &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID, false, nullptr, nsStunUDPSocketFilterHandlerConstructor },
|
||||
{ nullptr }
|
||||
};
|
||||
|
|
|
@ -17,12 +17,12 @@ SOURCES += [
|
|||
LOCAL_INCLUDES += [
|
||||
'/ipc/chromium/src',
|
||||
'/media/mtransport',
|
||||
'/media/mtransport',
|
||||
'/media/webrtc/',
|
||||
'/media/webrtc/signaling/include',
|
||||
'/media/webrtc/signaling/src/common/time_profiling',
|
||||
'/media/webrtc/signaling/src/media-conduit',
|
||||
'/media/webrtc/signaling/src/mediapipeline',
|
||||
'/media/webrtc/signaling/src/peerconnection',
|
||||
'/media/webrtc/signaling/src/sipcc/include',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
@ -53,7 +53,7 @@ var fingerprintRegex = /^a=fingerprint:(\S+) (\S+)/m;
|
|||
var identityRegex = /^a=identity:(\S+)/m;
|
||||
|
||||
function fingerprintSdp(fingerprints) {
|
||||
return fingerprints.map(fp => "a=fInGeRpRiNt:" + fp.algorithm +
|
||||
return fingerprints.map(fp => "a=fInGeRpRiNt=" + fp.algorithm +
|
||||
" " + fp.digest + "\n").join("");
|
||||
}
|
||||
|
||||
|
@ -78,20 +78,20 @@ function testMultipleFingerprints() {
|
|||
|
||||
pcDouble.createOffer(function(offer) {
|
||||
ok(offer, "Got offer");
|
||||
var fp = offer.sdp.match(fingerprintRegex);
|
||||
if (!fp) {
|
||||
var m = offer.sdp.match(fingerprintRegex);
|
||||
if (!m) {
|
||||
finished(false, "No fingerprint in offer SDP");
|
||||
return;
|
||||
}
|
||||
|
||||
var fingerprints = makeFingerprints(fp[1], fp[2]);
|
||||
var fingerprints = makeFingerprints(m[1], m[2]);
|
||||
getIdentityAssertion(fingerprints, function(assertion) {
|
||||
ok(assertion, "Should have assertion");
|
||||
|
||||
var sdp = offer.sdp.slice(0, fp.index) +
|
||||
var sdp = offer.sdp.slice(0, m.index) +
|
||||
"a=identity:" + assertion + "\n" +
|
||||
fingerprintSdp(fingerprints.slice(1)) +
|
||||
offer.sdp.slice(fp.index);
|
||||
offer.sdp.slice(m.index);
|
||||
|
||||
var desc = new mozRTCSessionDescription({ type: "offer", sdp: sdp });
|
||||
pcStrict.setRemoteDescription(desc, function() {
|
||||
|
|
|
@ -128,12 +128,5 @@ skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabl
|
|||
[test_peerConnection_toJSON.html]
|
||||
skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
|
||||
|
||||
# multistream is not ready quite yet (bug 1056650)
|
||||
# [test_peerConnection_twoAudioStreams.html]
|
||||
# [test_peerConnection_twoAudioVideoStreams.html]
|
||||
# [test_peerConnection_twoAudioVideoStreamsCombined.html]
|
||||
# [test_peerConnection_twoVideoStreams.html]
|
||||
# [test_peerConnection_addSecondAudioStream.html]
|
||||
|
||||
# Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
|
||||
[test_zmedia_cleanup.html]
|
||||
|
|
|
@ -1755,13 +1755,11 @@ PeerConnectionWrapper.prototype = {
|
|||
*
|
||||
* @param {function} onSuccess
|
||||
* Callback to execute if all media has been requested successfully
|
||||
* @param {array} constraintsList
|
||||
* Array of constraints for GUM calls
|
||||
*/
|
||||
getAllUserMedia : function PCW_GetAllUserMedia(constraintsList, onSuccess) {
|
||||
getAllUserMedia : function PCW_GetAllUserMedia(onSuccess) {
|
||||
var self = this;
|
||||
|
||||
function _getAllUserMedia(index) {
|
||||
function _getAllUserMedia(constraintsList, index) {
|
||||
if (index < constraintsList.length) {
|
||||
var constraints = constraintsList[index];
|
||||
|
||||
|
@ -1778,20 +1776,20 @@ PeerConnectionWrapper.prototype = {
|
|||
|
||||
self.attachMedia(stream, type, 'local');
|
||||
|
||||
_getAllUserMedia(index + 1);
|
||||
_getAllUserMedia(constraintsList, index + 1);
|
||||
}, generateErrorCallback());
|
||||
} else {
|
||||
onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
if (constraintsList.length === 0) {
|
||||
if (this.constraints.length === 0) {
|
||||
info("Skipping GUM: no UserMedia requested");
|
||||
onSuccess();
|
||||
}
|
||||
else {
|
||||
info("Get " + constraintsList.length + " local streams");
|
||||
_getAllUserMedia(0);
|
||||
info("Get " + this.constraints.length + " local streams");
|
||||
_getAllUserMedia(this.constraints, 0);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -2176,13 +2174,13 @@ PeerConnectionWrapper.prototype = {
|
|||
if ((!constraints) || (constraints.length === 0)) {
|
||||
return 0;
|
||||
}
|
||||
var numAudioTracks = 0;
|
||||
var audioTracks = 0;
|
||||
for (var i = 0; i < constraints.length; i++) {
|
||||
if (constraints[i].audio) {
|
||||
numAudioTracks++;
|
||||
audioTracks++;
|
||||
}
|
||||
}
|
||||
return numAudioTracks;
|
||||
return audioTracks;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2225,13 +2223,13 @@ PeerConnectionWrapper.prototype = {
|
|||
if ((!constraints) || (constraints.length === 0)) {
|
||||
return 0;
|
||||
}
|
||||
var numVideoTracks = 0;
|
||||
var videoTracks = 0;
|
||||
for (var i = 0; i < constraints.length; i++) {
|
||||
if (constraints[i].video) {
|
||||
numVideoTracks++;
|
||||
videoTracks++;
|
||||
}
|
||||
}
|
||||
return numVideoTracks;
|
||||
return videoTracks;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2274,11 +2272,11 @@ PeerConnectionWrapper.prototype = {
|
|||
if (!streams || (streams.length === 0)) {
|
||||
return 0;
|
||||
}
|
||||
var numAudioTracks = 0;
|
||||
var audioTracks = 0;
|
||||
streams.forEach(function(st) {
|
||||
numAudioTracks += st.getAudioTracks().length;
|
||||
audioTracks += st.getAudioTracks().length;
|
||||
});
|
||||
return numAudioTracks;
|
||||
return audioTracks;
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -2292,11 +2290,11 @@ PeerConnectionWrapper.prototype = {
|
|||
if (!streams || (streams.length === 0)) {
|
||||
return 0;
|
||||
}
|
||||
var numVideoTracks = 0;
|
||||
var videoTracks = 0;
|
||||
streams.forEach(function(st) {
|
||||
numVideoTracks += st.getVideoTracks().length;
|
||||
videoTracks += st.getVideoTracks().length;
|
||||
});
|
||||
return numVideoTracks;
|
||||
return videoTracks;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2369,9 +2367,10 @@ PeerConnectionWrapper.prototype = {
|
|||
},
|
||||
|
||||
verifySdp : function PCW_verifySdp(desc, expectedType, offerConstraintsList,
|
||||
offerOptions, trickleIceCallback) {
|
||||
answerConstraintsList, offerOptions, trickleIceCallback) {
|
||||
info("Examining this SessionDescription: " + JSON.stringify(desc));
|
||||
info("offerConstraintsList: " + JSON.stringify(offerConstraintsList));
|
||||
info("answerConstraintsList: " + JSON.stringify(answerConstraintsList));
|
||||
info("offerOptions: " + JSON.stringify(offerOptions));
|
||||
ok(desc, "SessionDescription is not null");
|
||||
is(desc.type, expectedType, "SessionDescription type is " + expectedType);
|
||||
|
@ -2391,7 +2390,8 @@ PeerConnectionWrapper.prototype = {
|
|||
//TODO: how can we check for absence/presence of m=application?
|
||||
|
||||
var audioTracks =
|
||||
this.countAudioTracksInMediaConstraint(offerConstraintsList) ||
|
||||
Math.max(this.countAudioTracksInMediaConstraint(offerConstraintsList),
|
||||
this.countAudioTracksInMediaConstraint(answerConstraintsList)) ||
|
||||
this.audioInOfferOptions(offerOptions);
|
||||
|
||||
info("expected audio tracks: " + audioTracks);
|
||||
|
@ -2407,7 +2407,8 @@ PeerConnectionWrapper.prototype = {
|
|||
}
|
||||
|
||||
var videoTracks =
|
||||
this.countVideoTracksInMediaConstraint(offerConstraintsList) ||
|
||||
Math.max(this.countVideoTracksInMediaConstraint(offerConstraintsList),
|
||||
this.countVideoTracksInMediaConstraint(answerConstraintsList)) ||
|
||||
this.videoInOfferOptions(offerOptions);
|
||||
|
||||
info("expected video tracks: " + videoTracks);
|
||||
|
@ -2635,46 +2636,6 @@ PeerConnectionWrapper.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Compares amount of established ICE connection according to ICE candidate
|
||||
* pairs in the stats reporting with the expected amount of connection based
|
||||
* on the constraints.
|
||||
*
|
||||
* @param {object} stats
|
||||
* The stats to check for ICE candidate pairs
|
||||
* @param {object} counters
|
||||
* The counters for media and data tracks based on constraints
|
||||
* @param {object} answer
|
||||
* The SDP answer to check for SDP bundle support
|
||||
*/
|
||||
checkStatsIceConnections : function PCW_checkStatsIceConnections(stats,
|
||||
offerConstraintsList, offerOptions, numDataTracks, answer) {
|
||||
var numIceConnections = 0;
|
||||
Object.keys(stats).forEach(function(key) {
|
||||
if ((stats[key].type === "candidatepair") && stats[key].selected) {
|
||||
numIceConnections += 1;
|
||||
}
|
||||
});
|
||||
info("ICE connections according to stats: " + numIceConnections);
|
||||
if (answer.sdp.contains('a=group:BUNDLE')) {
|
||||
is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
|
||||
} else {
|
||||
// This code assumes that no media sections have been rejected due to
|
||||
// codec mismatch or other unrecoverable negotiation failures.
|
||||
var numAudioTracks =
|
||||
this.countAudioTracksInMediaConstraint(offerConstraintsList) ||
|
||||
this.audioInOfferOptions(offerOptions);
|
||||
|
||||
var numVideoTracks =
|
||||
this.countVideoTracksInMediaConstraint(offerConstraintsList) ||
|
||||
this.videoInOfferOptions(offerOptions);
|
||||
|
||||
var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks;
|
||||
info("expected audio + video + data tracks: " + numAudioVideoDataTracks);
|
||||
is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Property-matching function for finding a certain stat in passed-in stats
|
||||
*
|
||||
|
|
|
@ -111,7 +111,7 @@ var commandsPeerConnection = [
|
|||
[
|
||||
'PC_LOCAL_GUM',
|
||||
function (test) {
|
||||
test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () {
|
||||
test.pcLocal.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ var commandsPeerConnection = [
|
|||
[
|
||||
'PC_REMOTE_GUM',
|
||||
function (test) {
|
||||
test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () {
|
||||
test.pcRemote.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ var commandsPeerConnection = [
|
|||
'PC_LOCAL_SANE_LOCAL_SDP',
|
||||
function (test) {
|
||||
test.pcLocal.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function(trickle) {
|
||||
test.pcLocal.localRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -243,7 +243,7 @@ var commandsPeerConnection = [
|
|||
'PC_REMOTE_SANE_REMOTE_SDP',
|
||||
function (test) {
|
||||
test.pcRemote.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcRemote.remoteRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -356,7 +356,7 @@ var commandsPeerConnection = [
|
|||
'PC_REMOTE_SANE_LOCAL_SDP',
|
||||
function (test) {
|
||||
test.pcRemote.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcRemote.localRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -367,7 +367,7 @@ var commandsPeerConnection = [
|
|||
'PC_LOCAL_SANE_REMOTE_SDP',
|
||||
function (test) {
|
||||
test.pcLocal.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcLocal.remoteRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -522,32 +522,6 @@ var commandsPeerConnection = [
|
|||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_ICE_CONNECTIONS',
|
||||
function (test) {
|
||||
test.pcLocal.getStats(null, function(stats) {
|
||||
test.pcLocal.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
0,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_ICE_CONNECTIONS',
|
||||
function (test) {
|
||||
test.pcRemote.getStats(null, function(stats) {
|
||||
test.pcRemote.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
0,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_GETSTATS_AUDIOTRACK_OUTBOUND',
|
||||
function (test) {
|
||||
|
@ -754,7 +728,7 @@ var commandsDataChannel = [
|
|||
[
|
||||
'PC_LOCAL_GUM',
|
||||
function (test) {
|
||||
test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () {
|
||||
test.pcLocal.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
|
@ -778,7 +752,7 @@ var commandsDataChannel = [
|
|||
[
|
||||
'PC_REMOTE_GUM',
|
||||
function (test) {
|
||||
test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () {
|
||||
test.pcRemote.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
|
@ -893,7 +867,7 @@ var commandsDataChannel = [
|
|||
'PC_LOCAL_SANE_LOCAL_SDP',
|
||||
function (test) {
|
||||
test.pcLocal.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function(trickle) {
|
||||
test.pcLocal.localRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -904,7 +878,7 @@ var commandsDataChannel = [
|
|||
'PC_REMOTE_SANE_REMOTE_SDP',
|
||||
function (test) {
|
||||
test.pcRemote.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcRemote.remoteRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -997,7 +971,7 @@ var commandsDataChannel = [
|
|||
'PC_REMOTE_SANE_LOCAL_SDP',
|
||||
function (test) {
|
||||
test.pcRemote.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcRemote.localRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -1008,7 +982,7 @@ var commandsDataChannel = [
|
|||
'PC_LOCAL_SANE_REMOTE_SDP',
|
||||
function (test) {
|
||||
test.pcLocal.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test._offer_constraints, test._answer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcLocal.remoteRequiresTrickleIce = trickle;
|
||||
});
|
||||
|
@ -1155,32 +1129,6 @@ var commandsDataChannel = [
|
|||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_ICE_CONNECTIONS',
|
||||
function (test) {
|
||||
test.pcLocal.getStats(null, function(stats) {
|
||||
test.pcLocal.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
1,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_ICE_CONNECTIONS',
|
||||
function (test) {
|
||||
test.pcRemote.getStats(null, function(stats) {
|
||||
test.pcRemote.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
1,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE',
|
||||
function (test) {
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
<script type="application/javascript" src="turnConfig.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "1091242",
|
||||
title: "Renegotiation: add second audio stream"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
test.chain.append([
|
||||
[
|
||||
'PC_LOCAL_SETUP_NEGOTIATION_CALLBACK',
|
||||
function (test) {
|
||||
test.pcLocal.onNegotiationneededFired = false;
|
||||
test.pcLocal._pc.onnegotiationneeded = function (anEvent) {
|
||||
info("pcLocal.onnegotiationneeded fired");
|
||||
test.pcLocal.onNegotiationneededFired = true;
|
||||
};
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_ADD_SECOND_STREAM',
|
||||
function (test) {
|
||||
test.pcLocal.getAllUserMedia([{audio: true}], function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_NEW_OFFER',
|
||||
function (test) {
|
||||
ok(test.pcLocal.onNegotiationneededFired, "onnegotiationneeded");
|
||||
test.createOffer(test.pcLocal, function (offer) {
|
||||
test._new_offer = offer;
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_NEW_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcLocal, test._new_offer, HAVE_LOCAL_OFFER, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_NEW_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcRemote, test._new_offer, HAVE_REMOTE_OFFER, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CREATE_NEW_ANSWER',
|
||||
function (test) {
|
||||
test.createAnswer(test.pcRemote, function (answer) {
|
||||
test._new_answer = answer;
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_NEW_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcRemote, test._new_answer, STABLE, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_NEW_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcLocal, test._new_answer, STABLE, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
]
|
||||
// TODO(bug 1093835): figure out how to verify if media flows through the new stream
|
||||
]);
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
runNetworkTest(function() {
|
||||
var test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([], [{audio: true}]);
|
||||
|
||||
// TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223).
|
||||
// Watch out for case-difference when fixing: { offerToReceiveAudio: true }
|
||||
test.setOfferOptions({ mandatory: { OfferToReceiveAudio: true } });
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
runNetworkTest(function() {
|
||||
var test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([], [{video: true}]);
|
||||
// TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223).
|
||||
// Watch out for case-difference when fixing: { offerToReceiveVideo: true }
|
||||
test.setOfferOptions({ optional: [{ OfferToReceiveVideo: true }] });
|
||||
|
|
|
@ -18,8 +18,10 @@
|
|||
|
||||
runNetworkTest(function() {
|
||||
var test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([], [{audio: true, video: true}]);
|
||||
test.setOfferOptions({ offerToReceiveVideo: true, offerToReceiveAudio: true });
|
||||
test.setOfferOptions({
|
||||
offerToReceiveVideo: true,
|
||||
offerToReceiveAudio: true
|
||||
});
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
<script type="application/javascript" src="turnConfig.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "1091242",
|
||||
title: "Multistream: Two audio streams"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
test.setMediaConstraints([{audio: true}, {audio: true}],
|
||||
[{audio: true}, {audio: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,33 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
<script type="application/javascript" src="turnConfig.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
createHTML({
|
||||
bug: "1091242",
|
||||
title: "Multistream: Two audio streams, two video streams"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
test.setMediaConstraints([{audio: true}, {video: true}, {audio: true},
|
||||
{video: true}],
|
||||
[{audio: true}, {video: true}, {audio: true},
|
||||
{video: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,33 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
<script type="application/javascript" src="turnConfig.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
createHTML({
|
||||
bug: "1091242",
|
||||
title: "Multistream: Two audio/video streams"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
test.setMediaConstraints([{audio: true, video: true},
|
||||
{audio: true, video: true}],
|
||||
[{audio: true, video: true},
|
||||
{audio: true, video: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,30 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
<script type="application/javascript" src="turnConfig.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "1091242",
|
||||
title: "Multistream: Two video streams"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
test.setMediaConstraints([{video: true}, {video: true}],
|
||||
[{video: true}, {video: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -67,7 +67,6 @@ interface PeerConnectionImpl {
|
|||
boolean pluginCrash(unsigned long long pluginId, DOMString name, DOMString pluginDumpID);
|
||||
|
||||
/* Attributes */
|
||||
[Constant]
|
||||
readonly attribute DOMString fingerprint;
|
||||
readonly attribute DOMString localDescription;
|
||||
readonly attribute DOMString remoteDescription;
|
||||
|
@ -75,6 +74,7 @@ interface PeerConnectionImpl {
|
|||
readonly attribute PCImplIceConnectionState iceConnectionState;
|
||||
readonly attribute PCImplIceGatheringState iceGatheringState;
|
||||
readonly attribute PCImplSignalingState signalingState;
|
||||
readonly attribute PCImplSipccState sipccState;
|
||||
attribute DOMString id;
|
||||
|
||||
attribute DOMString peerIdentity;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
DtlsIdentity::~DtlsIdentity() {
|
||||
// XXX: make cert_ a smart pointer to avoid this, after we figure
|
||||
// out the linking problem.
|
||||
|
@ -25,6 +27,7 @@ DtlsIdentity::~DtlsIdentity() {
|
|||
}
|
||||
|
||||
const std::string DtlsIdentity::DEFAULT_HASH_ALGORITHM = "sha-256";
|
||||
const size_t DtlsIdentity::HASH_ALGORITHM_MAX_LENGTH = 64;
|
||||
|
||||
TemporaryRef<DtlsIdentity> DtlsIdentity::Generate() {
|
||||
|
||||
|
@ -207,4 +210,89 @@ nsresult DtlsIdentity::ComputeFingerprint(const CERTCertificate *cert,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Format the fingerprint in RFC 4572 Section 5 attribute format, including both
|
||||
// the hash name and the fingerprint, colons and all.
|
||||
// returns an empty string if there is a problem
|
||||
std::string DtlsIdentity::GetFormattedFingerprint(const std::string &algorithm) {
|
||||
unsigned char digest[HASH_ALGORITHM_MAX_LENGTH];
|
||||
size_t digest_length;
|
||||
|
||||
nsresult res = this->ComputeFingerprint(algorithm,
|
||||
digest,
|
||||
sizeof(digest),
|
||||
&digest_length);
|
||||
if (NS_FAILED(res)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Unable to compute " << algorithm
|
||||
<< " hash for identity: nsresult = 0x"
|
||||
<< std::hex << std::uppercase
|
||||
<< static_cast<uint32_t>(res)
|
||||
<< std::nouppercase << std::dec);
|
||||
return "";
|
||||
}
|
||||
|
||||
return algorithm + " " + this->FormatFingerprint(digest, digest_length);
|
||||
}
|
||||
|
||||
std::string DtlsIdentity::FormatFingerprint(const unsigned char *digest,
|
||||
std::size_t size) {
|
||||
std::string str("");
|
||||
char group[3];
|
||||
|
||||
for (std::size_t i=0; i < size; i++) {
|
||||
PR_snprintf(group, sizeof(group), "%.2X", digest[i]);
|
||||
if (i != 0) {
|
||||
str += ":";
|
||||
}
|
||||
str += group;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(str.size() == (size * 3 - 1)); // Check result length
|
||||
return str;
|
||||
}
|
||||
|
||||
// Parse a fingerprint in RFC 4572 format.
|
||||
// Note that this tolerates some badly formatted data, in particular:
|
||||
// (a) arbitrary runs of colons
|
||||
// (b) colons at the beginning or end.
|
||||
nsresult DtlsIdentity::ParseFingerprint(const std::string fp,
|
||||
unsigned char *digest,
|
||||
size_t size,
|
||||
size_t *length) {
|
||||
size_t offset = 0;
|
||||
bool top_half = true;
|
||||
uint8_t val = 0;
|
||||
|
||||
for (size_t i=0; i<fp.length(); i++) {
|
||||
if (offset >= size) {
|
||||
// Note: no known way for offset to get > size
|
||||
MOZ_MTLOG(ML_ERROR, "Fingerprint too long for buffer");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (top_half && (fp[i] == ':')) {
|
||||
continue;
|
||||
} else if ((fp[i] >= '0') && (fp[i] <= '9')) {
|
||||
val |= fp[i] - '0';
|
||||
} else if ((fp[i] >= 'A') && (fp[i] <= 'F')) {
|
||||
val |= fp[i] - 'A' + 10;
|
||||
} else {
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid fingerprint value " << fp[i]);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if (top_half) {
|
||||
val <<= 4;
|
||||
top_half = false;
|
||||
} else {
|
||||
digest[offset++] = val;
|
||||
top_half = true;
|
||||
val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*length = offset;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // close namespace
|
||||
|
|
|
@ -33,6 +33,8 @@ class DtlsIdentity {
|
|||
CERTCertificate *cert() { return cert_; }
|
||||
SECKEYPrivateKey *privkey() { return privkey_; }
|
||||
|
||||
std::string GetFormattedFingerprint(const std::string &algorithm = DEFAULT_HASH_ALGORITHM);
|
||||
|
||||
nsresult ComputeFingerprint(const std::string algorithm,
|
||||
unsigned char *digest,
|
||||
std::size_t size,
|
||||
|
@ -43,18 +45,24 @@ class DtlsIdentity {
|
|||
unsigned char *digest,
|
||||
std::size_t size,
|
||||
std::size_t *digest_length);
|
||||
static const std::string DEFAULT_HASH_ALGORITHM;
|
||||
enum {
|
||||
HASH_ALGORITHM_MAX_LENGTH = 64
|
||||
};
|
||||
|
||||
static nsresult ParseFingerprint(const std::string fp,
|
||||
unsigned char *digest,
|
||||
size_t size, size_t *length);
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DtlsIdentity)
|
||||
|
||||
private:
|
||||
private:
|
||||
DtlsIdentity(SECKEYPrivateKey *privkey, CERTCertificate *cert)
|
||||
: privkey_(privkey), cert_(cert) {}
|
||||
DISALLOW_COPY_ASSIGN(DtlsIdentity);
|
||||
|
||||
static const std::string DEFAULT_HASH_ALGORITHM;
|
||||
static const size_t HASH_ALGORITHM_MAX_LENGTH;
|
||||
|
||||
std::string FormatFingerprint(const unsigned char *digest,
|
||||
std::size_t size);
|
||||
|
||||
ScopedSECKEYPrivateKey privkey_;
|
||||
CERTCertificate *cert_; // TODO: Using a smart pointer here causes link
|
||||
// errors.
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
// PR_LOGGING is off --> make no-op MTLOG macros
|
||||
#define MOZ_MTLOG_MODULE(n)
|
||||
#define MOZ_MTLOG(level, b)
|
||||
|
||||
#endif // defined(PR_LOGGING)
|
||||
|
||||
#endif // logging_h__
|
||||
|
|
|
@ -533,21 +533,11 @@ NrIceCtx::CreateStream(const std::string& name, int components) {
|
|||
RefPtr<NrIceMediaStream> stream =
|
||||
NrIceMediaStream::Create(this, name, components);
|
||||
|
||||
if (stream) {
|
||||
streams_.push_back(stream);
|
||||
}
|
||||
streams_.push_back(stream);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
std::string NrIceCtx::ufrag() const {
|
||||
return ctx_->ufrag;
|
||||
}
|
||||
|
||||
std::string NrIceCtx::pwd() const {
|
||||
return ctx_->pwd;
|
||||
}
|
||||
|
||||
void NrIceCtx::destroy_peer_ctx() {
|
||||
nr_ice_peer_ctx_destroy(&peer_);
|
||||
}
|
||||
|
|
|
@ -207,20 +207,9 @@ class NrIceCtx {
|
|||
RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
|
||||
int components);
|
||||
|
||||
RefPtr<NrIceMediaStream> GetStream(size_t index) {
|
||||
if (index < streams_.size()) {
|
||||
return streams_[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The name of the ctx
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
// Get ufrag and password.
|
||||
std::string ufrag() const;
|
||||
std::string pwd() const;
|
||||
|
||||
// Current state
|
||||
ConnectionState connection_state() const {
|
||||
return connection_state_;
|
||||
|
|
|
@ -338,27 +338,6 @@ nsresult NrIceMediaStream::GetCandidatePairs(std::vector<NrIceCandidatePair>*
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::GetDefaultCandidate(
|
||||
NrIceCandidate* candidate) const {
|
||||
|
||||
nr_ice_candidate *cand;
|
||||
|
||||
int r = nr_ice_media_stream_get_default_candidate(stream_, 1, &cand);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't get default ICE candidate for '"
|
||||
<< name_ << "'");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!ToNrIceCandidate(*cand, candidate)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to convert default ICE candidate for '"
|
||||
<< name_ << "'");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::string> NrIceMediaStream::GetCandidates() const {
|
||||
char **attrs = 0;
|
||||
int attrct;
|
||||
|
|
|
@ -136,10 +136,6 @@ class NrIceMediaStream {
|
|||
// queue, in priority order. |out_pairs| is cleared before being filled.
|
||||
nsresult GetCandidatePairs(std::vector<NrIceCandidatePair>* out_pairs) const;
|
||||
|
||||
// TODO(bug 1096795): This needs to take a component number, so we can get
|
||||
// default candidates for rtcp.
|
||||
nsresult GetDefaultCandidate(NrIceCandidate* candidate) const;
|
||||
|
||||
// Parse remote attributes
|
||||
nsresult ParseAttributes(std::vector<std::string>& candidates);
|
||||
|
||||
|
@ -155,7 +151,7 @@ class NrIceMediaStream {
|
|||
NrIceCandidate** local, NrIceCandidate** remote);
|
||||
|
||||
// The number of components
|
||||
size_t components() const { return components_; }
|
||||
int components() const { return components_; }
|
||||
|
||||
// The underlying nICEr stream
|
||||
nr_ice_media_stream *stream() { return stream_; }
|
||||
|
@ -192,7 +188,7 @@ class NrIceMediaStream {
|
|||
|
||||
private:
|
||||
NrIceMediaStream(NrIceCtx *ctx, const std::string& name,
|
||||
size_t components) :
|
||||
int components) :
|
||||
state_(ICE_CONNECTING),
|
||||
ctx_(ctx),
|
||||
name_(name),
|
||||
|
@ -207,7 +203,7 @@ class NrIceMediaStream {
|
|||
State state_;
|
||||
NrIceCtx *ctx_;
|
||||
const std::string name_;
|
||||
const size_t components_;
|
||||
const int components_;
|
||||
nr_ice_media_stream *stream_;
|
||||
uint16_t level_;
|
||||
};
|
||||
|
|
|
@ -282,10 +282,6 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
void SetStunServer(const std::string addr, uint16_t port) {
|
||||
if (addr.empty()) {
|
||||
// Happens when MOZ_DISABLE_NONLOCAL_CONNECTIONS is set
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<NrIceStunServer> stun_servers;
|
||||
ScopedDeletePtr<NrIceStunServer> server(NrIceStunServer::Create(addr,
|
||||
|
@ -320,14 +316,12 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
void SetFakeResolver() {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(dns_resolver_->Init()));
|
||||
if (!g_stun_server_address.empty() && !g_stun_server_hostname.empty()) {
|
||||
PRNetAddr addr;
|
||||
PRStatus status = PR_StringToNetAddr(g_stun_server_address.c_str(),
|
||||
&addr);
|
||||
addr.inet.port = kDefaultStunServerPort;
|
||||
ASSERT_EQ(PR_SUCCESS, status);
|
||||
fake_resolver_.SetAddr(g_stun_server_hostname, addr);
|
||||
}
|
||||
PRNetAddr addr;
|
||||
PRStatus status = PR_StringToNetAddr(g_stun_server_address.c_str(),
|
||||
&addr);
|
||||
addr.inet.port = kDefaultStunServerPort;
|
||||
ASSERT_EQ(PR_SUCCESS, status);
|
||||
fake_resolver_.SetAddr(g_stun_server_hostname, addr);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver(
|
||||
fake_resolver_.AllocateResolver())));
|
||||
}
|
||||
|
@ -551,7 +545,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
void DumpAndCheckActiveCandidates_s() {
|
||||
std::cerr << "Active candidates:" << std::endl;
|
||||
for (size_t i=0; i < streams_.size(); ++i) {
|
||||
for (size_t j=0; j < streams_[i]->components(); ++j) {
|
||||
for (int j=0; j < streams_[i]->components(); ++j) {
|
||||
std::cerr << "Stream " << i << " component " << j+1 << std::endl;
|
||||
|
||||
NrIceCandidate *local;
|
||||
|
@ -1281,20 +1275,12 @@ class PacketFilterTest : public ::testing::Test {
|
|||
} // end namespace
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
|
||||
if (g_stun_server_hostname.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerIpAddress) {
|
||||
if (g_stun_server_address.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(g_stun_server_address, kDefaultStunServerPort);
|
||||
peer_->SetFakeResolver();
|
||||
|
@ -1302,10 +1288,6 @@ TEST_F(IceGatherTest, TestGatherFakeStunServerIpAddress) {
|
|||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerHostname) {
|
||||
if (g_stun_server_hostname.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
|
||||
peer_->SetFakeResolver();
|
||||
|
@ -1320,10 +1302,6 @@ TEST_F(IceGatherTest, TestGatherFakeStunBogusHostname) {
|
|||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddress) {
|
||||
if (g_stun_server_address.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(g_stun_server_address, kDefaultStunServerPort);
|
||||
peer_->SetDNSResolver();
|
||||
|
@ -1332,10 +1310,6 @@ TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddress) {
|
|||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerHostname) {
|
||||
if (g_stun_server_hostname.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
|
||||
peer_->SetDNSResolver();
|
||||
|
@ -1368,12 +1342,8 @@ TEST_F(IceGatherTest, TestGatherTurnTcp) {
|
|||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDisableComponent) {
|
||||
if (g_stun_server_hostname.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
|
||||
peer_->SetStunServer(kDefaultStunServerHostname, kDefaultStunServerPort);
|
||||
peer_->AddStream(2);
|
||||
peer_->DisableComponent(1, 2);
|
||||
Gather();
|
||||
|
@ -2122,17 +2092,6 @@ int main(int argc, char **argv)
|
|||
if (tmp != "")
|
||||
g_stun_server_hostname = tmp;
|
||||
|
||||
tmp = get_environment("MOZ_DISABLE_NONLOCAL_CONNECTIONS");
|
||||
|
||||
if ((tmp != "" && tmp != "0") || getenv("MOZ_UPLOAD_DIR")) {
|
||||
// We're assuming that MOZ_UPLOAD_DIR is only set on tbpl;
|
||||
// MOZ_DISABLE_NONLOCAL_CONNECTIONS probably should be set when running the
|
||||
// cpp unit-tests, but is not presently.
|
||||
g_stun_server_address = "";
|
||||
g_stun_server_hostname = "";
|
||||
g_turn_server = "";
|
||||
}
|
||||
|
||||
test_utils = new MtransportTestUtils();
|
||||
NSS_NoDB_Init(nullptr);
|
||||
NSS_SetDomesticPolicy();
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
||||
GeckoCppUnitTests([
|
||||
'buffered_stun_socket_unittest',
|
||||
'ice_unittest',
|
||||
'nrappkit_unittest',
|
||||
'rlogringbuffer_unittest',
|
||||
'runnable_utils_unittest',
|
||||
|
@ -18,6 +17,12 @@ if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
|||
'turn_unittest',
|
||||
])
|
||||
|
||||
# Bug 1037618 - Cross-tree (network related?) failures on OSX
|
||||
if CONFIG['OS_TARGET'] != 'Darwin':
|
||||
GeckoCppUnitTests([
|
||||
'ice_unittest',
|
||||
])
|
||||
|
||||
if CONFIG['MOZ_SCTP']:
|
||||
GeckoCppUnitTests([
|
||||
'sctp_unittest',
|
||||
|
|
|
@ -607,8 +607,7 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
connect(this, &TransportTestPeer::GotCandidate);
|
||||
|
||||
// Create the transport layer
|
||||
ice_ = new TransportLayerIce(name);
|
||||
ice_->SetParameters(ice_ctx_, stream, 1);
|
||||
ice_ = new TransportLayerIce(name, ice_ctx_, stream, 1);
|
||||
|
||||
// Assemble the stack
|
||||
nsAutoPtr<std::queue<mozilla::TransportLayer *> > layers(
|
||||
|
|
|
@ -463,9 +463,7 @@ int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, vo
|
|||
if(r=nr_socket_getaddr(cand->isock->sock,&cand->addr))
|
||||
ABORT(r);
|
||||
cand->osock=cand->isock->sock;
|
||||
// This is actually ready, but we set this anyway to prevent it from
|
||||
// being paired twice.
|
||||
cand->state=NR_ICE_CAND_STATE_INITIALIZING;
|
||||
cand->state=NR_ICE_CAND_STATE_INITIALIZED;
|
||||
// Post this so that it doesn't happen in-line
|
||||
cand->ready_cb = ready_cb;
|
||||
cand->ready_cb_arg = cb_arg;
|
||||
|
|
|
@ -793,11 +793,10 @@ int nr_ice_component_pair_candidate(nr_ice_peer_ctx *pctx, nr_ice_component *pco
|
|||
trickle candidates).
|
||||
*/
|
||||
if (pair_all_remote || (pcand->state == NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED)) {
|
||||
if (pair_all_remote) {
|
||||
/* When a remote candidate arrives after the start of checking, but
|
||||
* before the gathering of local candidates, it can be in UNPAIRED */
|
||||
pcand->state = NR_ICE_CAND_PEER_CANDIDATE_PAIRED;
|
||||
}
|
||||
/* If we are pairing our own trickle candidates, the remote candidate should
|
||||
all be paired */
|
||||
if (pair_all_remote)
|
||||
assert (pcand->state == NR_ICE_CAND_PEER_CANDIDATE_PAIRED);
|
||||
|
||||
nr_ice_compute_codeword(pcand->label,strlen(pcand->label),codeword);
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/CAND(%s): Pairing with peer candidate %s", pctx->label, codeword, pcand->label);
|
||||
|
@ -1102,12 +1101,10 @@ int nr_ice_component_insert_pair(nr_ice_component *pcomp, nr_ice_cand_pair *pair
|
|||
ABORT(r);
|
||||
|
||||
/* Make sure the check timer is running, if the stream was previously
|
||||
* started. We will not start streams just because a pair was created,
|
||||
* unless it is the first pair to be created across all streams. */
|
||||
* started. We will not start streams just because a pair was created. */
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/CAND-PAIR(%s): Ensure that check timer is running for new pair %s.",pair->remote->stream->pctx->label, pair->codeword, pair->as_string);
|
||||
|
||||
if(pair->remote->stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE ||
|
||||
!pair->remote->stream->pctx->checks_started){
|
||||
if(pair->remote->stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE){
|
||||
if(nr_ice_media_stream_start_checks(pair->remote->stream->pctx, pair->remote->stream)) {
|
||||
r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s)/CAND-PAIR(%s): Could not restart checks for new pair %s.",pair->remote->stream->pctx->label, pair->codeword, pair->as_string);
|
||||
ABORT(R_INTERNAL);
|
||||
|
|
|
@ -455,10 +455,6 @@ void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
|
|||
|
||||
ctx->uninitialized_candidates--;
|
||||
|
||||
// Avoid the need for yet another initialization function
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZING && cand->type == HOST)
|
||||
cand->state = NR_ICE_CAND_STATE_INITIALIZED;
|
||||
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZED) {
|
||||
int was_pruned = 0;
|
||||
|
||||
|
@ -472,7 +468,7 @@ void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
|
|||
if (ctx->trickle_cb && !was_pruned) {
|
||||
ctx->trickle_cb(ctx->trickle_cb_arg, ctx, cand->stream, cand->component_id, cand);
|
||||
|
||||
if (nr_ice_ctx_pair_new_trickle_candidates(ctx, cand)) {
|
||||
if (r=nr_ice_ctx_pair_new_trickle_candidates(ctx, cand)) {
|
||||
r_log(LOG_ICE,LOG_ERR, "ICE(%s): All could not pair new trickle candidate",ctx->label);
|
||||
/* But continue */
|
||||
}
|
||||
|
|
|
@ -137,10 +137,6 @@ nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_str
|
|||
cand->stream=stream;
|
||||
skip_whitespace(&str);
|
||||
|
||||
/* Skip a= if present */
|
||||
if (!strncmp(str, "a=", 2))
|
||||
str += 2;
|
||||
|
||||
/* Candidate attr */
|
||||
if (strncasecmp(str, "candidate:", 10))
|
||||
ABORT(R_BAD_DATA);
|
||||
|
|
|
@ -171,7 +171,7 @@ static int nr_ice_peer_ctx_parse_stream_attributes_int(nr_ice_peer_ctx *pctx, nr
|
|||
}
|
||||
}
|
||||
else {
|
||||
r_log(LOG_ICE,LOG_WARNING,"ICE(%s): peer (%s) specified bogus attribute: %s",pctx->ctx->label,pctx->label,attrs[i]);
|
||||
r_log(LOG_ICE,LOG_WARNING,"ICE(%s): peer (%s) specified bogus attribute",pctx->ctx->label,pctx->label);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,9 +220,6 @@ static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream
|
|||
|
||||
TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp);
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/CAND(%s): creating peer candidate",
|
||||
pctx->label,cand->label);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status) {
|
||||
|
@ -294,25 +291,25 @@ int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_
|
|||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) failed to pair trickle ICE candidates",pctx->ctx->label,pctx->label,stream->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start checks if this stream is not checking yet or if it has checked
|
||||
all the available candidates but not had a completed check for all
|
||||
components.
|
||||
/* Start checks if this stream is not checking yet or if it has checked
|
||||
all the available candidates but not had a completed check for all
|
||||
components.
|
||||
|
||||
Note that this is not compliant with RFC 5245, but consistent with
|
||||
the libjingle trickle ICE behavior. Note that we will not restart
|
||||
checks if either (a) the stream has failed or (b) all components
|
||||
have a successful pair because the switch statement above jumps
|
||||
will in both states.
|
||||
Note that this is not compliant with RFC 5245, but consistent with
|
||||
the libjingle trickle ICE behavior. Note that we will not restart
|
||||
checks if either (a) the stream has failed or (b) all components
|
||||
have a successful pair because the switch statement above jumps
|
||||
will in both states.
|
||||
|
||||
TODO(ekr@rtfm.com): restart checks.
|
||||
TODO(ekr@rtfm.com): update when the trickle ICE RFC is published
|
||||
*/
|
||||
if (!pstream->timer) {
|
||||
if(r=nr_ice_media_stream_start_checks(pctx, pstream)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) failed to start checks",pctx->ctx->label,pctx->label,stream->label);
|
||||
ABORT(r);
|
||||
}
|
||||
TODO(ekr@rtfm.com): restart checks.
|
||||
TODO(ekr@rtfm.com): update when the trickle ICE RFC is published
|
||||
*/
|
||||
if (!pstream->timer) {
|
||||
if(r=nr_ice_media_stream_start_checks(pctx, pstream)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) failed to start checks",pctx->ctx->label,pctx->label,stream->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,25 +84,11 @@ namespace mozilla {
|
|||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
TransportLayerIce::TransportLayerIce(const std::string& name)
|
||||
: name_(name), ctx_(nullptr), stream_(nullptr), component_(0) {}
|
||||
|
||||
TransportLayerIce::~TransportLayerIce() {
|
||||
// No need to do anything here, since we use smart pointers
|
||||
}
|
||||
|
||||
void TransportLayerIce::SetParameters(RefPtr<NrIceCtx> ctx,
|
||||
RefPtr<NrIceMediaStream> stream,
|
||||
int component) {
|
||||
ctx_ = ctx;
|
||||
stream_ = stream;
|
||||
component_ = component;
|
||||
|
||||
PostSetup();
|
||||
}
|
||||
|
||||
void TransportLayerIce::PostSetup() {
|
||||
target_ = ctx_->thread();
|
||||
TransportLayerIce::TransportLayerIce(const std::string& name,
|
||||
RefPtr<NrIceCtx> ctx, RefPtr<NrIceMediaStream> stream,
|
||||
int component)
|
||||
: name_(name), ctx_(ctx), stream_(stream), component_(component) {
|
||||
target_ = ctx->thread();
|
||||
|
||||
stream_->SignalReady.connect(this, &TransportLayerIce::IceReady);
|
||||
stream_->SignalFailed.connect(this, &TransportLayerIce::IceFailed);
|
||||
|
@ -113,6 +99,10 @@ void TransportLayerIce::PostSetup() {
|
|||
}
|
||||
}
|
||||
|
||||
TransportLayerIce::~TransportLayerIce() {
|
||||
// No need to do anything here, since we use smart pointers
|
||||
}
|
||||
|
||||
TransportResult TransportLayerIce::SendPacket(const unsigned char *data,
|
||||
size_t len) {
|
||||
CheckThread();
|
||||
|
|
|
@ -31,14 +31,12 @@ namespace mozilla {
|
|||
|
||||
class TransportLayerIce : public TransportLayer {
|
||||
public:
|
||||
explicit TransportLayerIce(const std::string& name);
|
||||
|
||||
TransportLayerIce(const std::string& name,
|
||||
RefPtr<NrIceCtx> ctx,
|
||||
RefPtr<NrIceMediaStream> stream,
|
||||
int component);
|
||||
virtual ~TransportLayerIce();
|
||||
|
||||
void SetParameters(RefPtr<NrIceCtx> ctx,
|
||||
RefPtr<NrIceMediaStream> stream,
|
||||
int component);
|
||||
|
||||
// Transport layer overrides.
|
||||
virtual TransportResult SendPacket(const unsigned char *data, size_t len);
|
||||
|
||||
|
@ -53,7 +51,6 @@ class TransportLayerIce : public TransportLayer {
|
|||
|
||||
private:
|
||||
DISALLOW_COPY_ASSIGN(TransportLayerIce);
|
||||
void PostSetup();
|
||||
|
||||
const std::string name_;
|
||||
RefPtr<NrIceCtx> ctx_;
|
||||
|
|
|
@ -51,36 +51,56 @@ if CONFIG['MOZ_WEBRTC_SIGNALING']:
|
|||
build_for_test=0
|
||||
)
|
||||
GYP_DIRS['signaling'].sandbox_vars['FINAL_LIBRARY'] = 'xul'
|
||||
# Excluded for various symbol conflicts
|
||||
# Excluded because of name clash in the logTag variable
|
||||
signaling_non_unified_sources = [
|
||||
'signaling/src/common/browser_logging/CSFLog.cpp',
|
||||
'signaling/src/jsep/JsepSessionImpl.cpp',
|
||||
'signaling/src/media-conduit/AudioConduit.cpp',
|
||||
'signaling/src/media-conduit/CodecStatistics.cpp',
|
||||
'signaling/src/media-conduit/VideoConduit.cpp',
|
||||
'signaling/src/mediapipeline/MediaPipeline.cpp',
|
||||
'signaling/src/mediapipeline/MediaPipelineFilter.cpp',
|
||||
'signaling/src/mediapipeline/SrtpFlow.cpp',
|
||||
'signaling/src/peerconnection/MediaPipelineFactory.cpp',
|
||||
'signaling/src/peerconnection/MediaStreamList.cpp',
|
||||
'signaling/src/media/CSFAudioControlWrapper.cpp',
|
||||
'signaling/src/media/CSFVideoControlWrapper.cpp',
|
||||
'signaling/src/media/VcmSIPCCBinding.cpp',
|
||||
'signaling/src/peerconnection/PeerConnectionCtx.cpp',
|
||||
'signaling/src/peerconnection/PeerConnectionImpl.cpp',
|
||||
'signaling/src/peerconnection/PeerConnectionMedia.cpp',
|
||||
'signaling/src/peerconnection/WebrtcGlobalInformation.cpp',
|
||||
'signaling/src/sdp/sipcc/ccsdp.c',
|
||||
'signaling/src/sdp/sipcc/cpr_string.c',
|
||||
'signaling/src/sdp/sipcc/sdp_access.c',
|
||||
'signaling/src/sdp/sipcc/sdp_attr.c',
|
||||
'signaling/src/sdp/sipcc/sdp_attr_access.c',
|
||||
'signaling/src/sdp/sipcc/sdp_base64.c',
|
||||
'signaling/src/sdp/sipcc/sdp_config.c',
|
||||
'signaling/src/sdp/sipcc/sdp_main.c',
|
||||
'signaling/src/sdp/sipcc/sdp_services_unix.c',
|
||||
'signaling/src/sdp/sipcc/sdp_token.c',
|
||||
'signaling/src/sdp/sipcc/sdp_utils.c',
|
||||
'signaling/src/sipcc/core/ccapp/ccapi_device_info.c',
|
||||
'signaling/src/sipcc/core/gsm/fim.c',
|
||||
'signaling/src/sipcc/core/gsm/gsm_sdp.c',
|
||||
'signaling/src/sipcc/core/gsm/lsm.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_access.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_attr.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_attr_access.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_config.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_main.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_token.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_utils.c',
|
||||
'signaling/src/softphonewrapper/CC_SIPCCCall.cpp',
|
||||
'signaling/src/softphonewrapper/CC_SIPCCCallInfo.cpp',
|
||||
'signaling/src/softphonewrapper/CC_SIPCCService.cpp',
|
||||
'signaling/src/softphonewrapper/ccapi_plat_api_impl.cpp',
|
||||
]
|
||||
|
||||
# Excluded for various symbol conflicts
|
||||
signaling_non_unified_sources_2 = [
|
||||
'signaling/src/mediapipeline/MediaPipelineFilter.cpp',
|
||||
'signaling/src/mediapipeline/SrtpFlow.cpp',
|
||||
'signaling/src/sipcc/core/ccapp/ccapi_call_info.c',
|
||||
'signaling/src/sipcc/core/ccapp/ccprovider.c',
|
||||
'signaling/src/sipcc/core/common/platform_api.c',
|
||||
'signaling/src/sipcc/core/common/ui.c',
|
||||
'signaling/src/sipcc/core/gsm/ccapi_strings.c',
|
||||
'signaling/src/sipcc/core/gsm/fsm.c',
|
||||
'signaling/src/sipcc/core/gsm/fsmcac.c',
|
||||
'signaling/src/sipcc/core/gsm/fsmdef.c',
|
||||
'signaling/src/sipcc/core/sdp/sdp_base64.c', # Because of name clash with the macro PADDING
|
||||
'signaling/src/sipcc/core/sipstack/ccsip_cc.c',
|
||||
'signaling/src/sipcc/core/sipstack/sip_common_transport.c',
|
||||
'signaling/src/sipcc/core/sipstack/sip_platform_task.c',
|
||||
'signaling/src/sipcc/core/src-common/string_lib.c',
|
||||
]
|
||||
|
||||
GYP_DIRS['signaling'].non_unified_sources += signaling_non_unified_sources
|
||||
GYP_DIRS['signaling'].non_unified_sources += signaling_non_unified_sources_2
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
||||
GYP_DIRS += ['trunk/testing']
|
||||
|
@ -96,4 +116,5 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
|||
build_for_test=1
|
||||
)
|
||||
GYP_DIRS['signalingtest'].non_unified_sources += signaling_non_unified_sources
|
||||
GYP_DIRS['signalingtest'].non_unified_sources += signaling_non_unified_sources_2
|
||||
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
#include "fsmdef_states.h"
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
typedef struct Timecard Timecard;
|
||||
#else
|
||||
#include "timecard.h"
|
||||
#endif
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_Call
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Call)
|
||||
|
||||
protected:
|
||||
CC_Call () { }
|
||||
|
||||
virtual ~CC_Call () {}
|
||||
|
||||
public:
|
||||
virtual void setRemoteWindow (VideoWindowHandle window) = 0;
|
||||
|
||||
virtual int setExternalRenderer(VideoFormat videoFormat, ExternalRendererHandle renderer) = 0;
|
||||
|
||||
virtual void sendIFrame () = 0;
|
||||
|
||||
virtual void getLocalSdp(std::string *sdp) const = 0;
|
||||
virtual void getRemoteSdp(std::string *sdp) const = 0;
|
||||
virtual fsmdef_states_t getFsmState () const = 0;
|
||||
virtual std::string fsmStateToString (fsmdef_states_t state) const = 0;
|
||||
|
||||
virtual void getErrorString(std::string *error) const = 0;
|
||||
virtual pc_error getError() const = 0;
|
||||
|
||||
virtual CC_CallInfoPtr getCallInfo () = 0;
|
||||
|
||||
virtual std::string toString() = 0;
|
||||
|
||||
/**
|
||||
Originate call - API to go offhook and dial specified digits on a given call
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@param [in] digits - digits to be dialed. can be empty then this API simply goes offhook
|
||||
|
||||
@return true or false.
|
||||
*/
|
||||
virtual bool originateCall (cc_sdp_direction_t video_pref, const std::string & digits) = 0;
|
||||
|
||||
/**
|
||||
Use this function to answer an incoming call.
|
||||
|
||||
@param[in] video_pref - video direction desired on call
|
||||
|
||||
@return true or false.
|
||||
*/
|
||||
virtual bool answerCall (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
Use this function to put an active call on hold.
|
||||
|
||||
@param[in] reason - If the user chooses to put the call on hold then
|
||||
CC_HOLD_REASON_NONE should be the value passed in here.
|
||||
|
||||
@return true or false. If it's not appropriate to put this call on
|
||||
hold at the moment then this function will return false.
|
||||
*/
|
||||
virtual bool hold (cc_hold_reason_t reason) = 0;
|
||||
|
||||
/**
|
||||
Use this function to resume a call that is currently on hold.
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool resume (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
Use this function to end an active call.
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool endCall() = 0;
|
||||
|
||||
/**
|
||||
Send digits on the call - can be invoked either to dial additional digits or send DTMF
|
||||
|
||||
@param [in] digit - digit to be dialed
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool sendDigit (cc_digit_t digit) = 0;
|
||||
|
||||
/**
|
||||
Send Backspace - Delete last digit dialed.
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool backspace() = 0;
|
||||
|
||||
/**
|
||||
Redial
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool redial (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
Initiate Call Forward All
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool initiateCallForwardAll() = 0;
|
||||
|
||||
/**
|
||||
end Consult leg - used to end consult leg when the user picks active calls list for xfer/conf
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool endConsultativeCall() = 0;
|
||||
|
||||
/**
|
||||
Initiate a conference
|
||||
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool conferenceStart (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
complete conference
|
||||
|
||||
@param [in] otherCall - CC_CallPtr of the other leg
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool conferenceComplete (CC_CallPtr otherLog, cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
start transfer
|
||||
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool transferStart (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
complete transfer
|
||||
|
||||
@param [in] otherLeg - CC_CallPtr of the other leg
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool transferComplete (CC_CallPtr otherLeg,
|
||||
cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
cancel conference or transfer
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool cancelTransferOrConferenceFeature() = 0;
|
||||
|
||||
/**
|
||||
direct Transfer
|
||||
|
||||
@param [in] target - call handle for transfer target call
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool directTransfer (CC_CallPtr target) = 0;
|
||||
|
||||
/**
|
||||
Join Across line
|
||||
|
||||
@param [in] target - join target
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool joinAcrossLine (CC_CallPtr target) = 0;
|
||||
|
||||
/**
|
||||
BLF Call Pickup
|
||||
|
||||
@param [in] video_pref - video direction preference
|
||||
@param [in] speed - speedDial Number
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool blfCallPickup (cc_sdp_direction_t video_pref, const std::string & speed) = 0;
|
||||
|
||||
/**
|
||||
Select a call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool select() = 0;
|
||||
|
||||
/**
|
||||
Update Video Media Cap for the call
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool updateVideoMediaCap (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
send INFO method for the call
|
||||
@param [in] handle - call handle
|
||||
@param [in] infopackage - Info-Package header value
|
||||
@param [in] infotype - Content-Type header val
|
||||
@param [in] infobody - Body of the INFO message
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool sendInfo (const std::string & infopackage, const std::string & infotype, const std::string & infobody) = 0;
|
||||
|
||||
/**
|
||||
API to mute audio
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool muteAudio(void) = 0;
|
||||
|
||||
|
||||
/**
|
||||
API to unmute audio
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool unmuteAudio(void) = 0;
|
||||
/**
|
||||
API to mute video
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool muteVideo(void) = 0;
|
||||
|
||||
|
||||
/**
|
||||
API to unmute video
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool unmuteVideo(void) = 0;
|
||||
|
||||
|
||||
/**
|
||||
API to set the call volume, acceptable values are 0 - 100
|
||||
@return true if volume set successfully, false if value out of range or change failed
|
||||
*/
|
||||
virtual bool setVolume(int volume) = 0;
|
||||
|
||||
|
||||
/**
|
||||
Originate P2P call - API to go offhook and dial specified digits\user on a given call
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@param [in] digits - digits to be dialed. can be empty then this API simply goes offhook
|
||||
@param [in] ip address - the ip address of the peer to call
|
||||
|
||||
@return void
|
||||
*/
|
||||
virtual void originateP2PCall (cc_sdp_direction_t video_pref, const std::string & digits, const std::string & ip) = 0;
|
||||
|
||||
virtual pc_error createOffer (cc_media_options_t* options, Timecard *) = 0;
|
||||
|
||||
virtual pc_error createAnswer(Timecard *) = 0;
|
||||
|
||||
virtual pc_error setLocalDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *) = 0;
|
||||
|
||||
virtual pc_error setRemoteDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *) = 0;
|
||||
|
||||
virtual pc_error setPeerConnection(const std::string& handle) = 0;
|
||||
|
||||
virtual pc_error addStream(cc_media_stream_id_t stream_id,
|
||||
cc_media_track_id_t track_id,
|
||||
cc_media_type_t media_type) = 0;
|
||||
|
||||
virtual pc_error removeStream(cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) = 0;
|
||||
|
||||
virtual const std::string& getPeerConnection() const = 0;
|
||||
|
||||
virtual pc_error addICECandidate(const std::string & candidate, const std::string & mid, unsigned short level, Timecard *) = 0;
|
||||
|
||||
virtual pc_error foundICECandidate(const std::string & candidate, const std::string & mid, unsigned short level, Timecard *) = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,339 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
#include "fsmdef_states.h"
|
||||
}
|
||||
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "CC_CallTypes.h"
|
||||
#include "peer_connection_types.h"
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
typedef struct Timecard Timecard;
|
||||
#else
|
||||
#include "timecard.h"
|
||||
#endif
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
|
||||
class ECC_API CC_CallInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_CallInfo)
|
||||
protected:
|
||||
CC_CallInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_CallInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the line object associated with this call.
|
||||
|
||||
@return CC_LinePtr - line ID
|
||||
*/
|
||||
virtual CC_LinePtr getline () = 0;
|
||||
|
||||
/**
|
||||
get Call state
|
||||
@param [in] handle - call info handle
|
||||
@return call state
|
||||
*/
|
||||
virtual cc_call_state_t getCallState () = 0;
|
||||
|
||||
/**
|
||||
get FSM state
|
||||
@param [in] handle - call info handle
|
||||
@return FSM state
|
||||
*/
|
||||
virtual fsmdef_states_t getFsmState () const = 0;
|
||||
|
||||
/**
|
||||
print Call state
|
||||
@param [in] handle - call info handle
|
||||
@return call state as string
|
||||
*/
|
||||
virtual std::string callStateToString (cc_call_state_t state) = 0;
|
||||
|
||||
/**
|
||||
print FSM state
|
||||
@param [in] handle - call info handle
|
||||
@return call state as string
|
||||
*/
|
||||
virtual std::string fsmStateToString (fsmdef_states_t state) const = 0;
|
||||
|
||||
/**
|
||||
print Call event
|
||||
@param [in] call event
|
||||
@return call event as string
|
||||
*/
|
||||
virtual std::string callEventToString (ccapi_call_event_e callEvent) = 0;
|
||||
|
||||
/**
|
||||
Get ringer state.
|
||||
|
||||
@return bool ringer state.
|
||||
*/
|
||||
virtual bool getRingerState() = 0;
|
||||
|
||||
/**
|
||||
Get call attributes
|
||||
|
||||
@return cc_call_attr_t.
|
||||
*/
|
||||
virtual cc_call_attr_t getCallAttr() = 0;
|
||||
|
||||
/**
|
||||
Get the call type
|
||||
|
||||
@return cc_call_type_t for this call. Supported values inlude:
|
||||
CC_CALL_TYPE_INCOMING, CC_CALL_TYPE_OUTGOING and CC_CALL_TYPE_FORWARDED.
|
||||
*/
|
||||
virtual cc_call_type_t getCallType() = 0;
|
||||
|
||||
/**
|
||||
Get called party name
|
||||
|
||||
@return called party name
|
||||
*/
|
||||
virtual std::string getCalledPartyName() = 0;
|
||||
|
||||
/**
|
||||
Get called party number
|
||||
|
||||
@return called party number as a string.
|
||||
*/
|
||||
virtual std::string getCalledPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
Get calling party name
|
||||
|
||||
@return calling party name
|
||||
*/
|
||||
virtual std::string getCallingPartyName() = 0;
|
||||
|
||||
/**
|
||||
Get calling party number
|
||||
@return calling party number as a string
|
||||
Note: this is a const reference to a string that's owned by the
|
||||
*/
|
||||
virtual std::string getCallingPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
Get alternate number
|
||||
|
||||
@return calling party number as a string.
|
||||
*/
|
||||
virtual std::string getAlternateNumber() = 0;
|
||||
|
||||
/**
|
||||
This function is used to check if a given capability is supported
|
||||
based on the information in this CC_CallInfo object.
|
||||
|
||||
@param [in] capability - the capability that is to be checked for availability.
|
||||
@return boolean - returns true if the given capability is available, false otherwise.
|
||||
*/
|
||||
virtual bool hasCapability (CC_CallCapabilityEnum::CC_CallCapability capability) = 0;
|
||||
|
||||
/**
|
||||
If you need the complete set of capabilities
|
||||
|
||||
@return cc_return_t - set of Call Capabilities.
|
||||
*/
|
||||
virtual std::set<CC_CallCapabilityEnum::CC_CallCapability> getCapabilitySet() = 0;
|
||||
|
||||
/**
|
||||
get Original Called party name
|
||||
@param [in] handle - call info handle
|
||||
@return original called party name
|
||||
*/
|
||||
virtual std::string getOriginalCalledPartyName() = 0;
|
||||
|
||||
/**
|
||||
get Original Called party number
|
||||
@param [in] handle - call info handle
|
||||
@return original called party number
|
||||
*/
|
||||
virtual std::string getOriginalCalledPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
get last redirecting party name
|
||||
@param [in] handle - call info handle
|
||||
@return last redirecting party name
|
||||
*/
|
||||
virtual std::string getLastRedirectingPartyName() = 0;
|
||||
|
||||
/**
|
||||
get past redirecting party number
|
||||
@param [in] handle - call info handle
|
||||
@return last redirecting party number
|
||||
*/
|
||||
virtual std::string getLastRedirectingPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
get placed call party name
|
||||
@param [in] handle - call info handle
|
||||
@return placed party name
|
||||
*/
|
||||
virtual std::string getPlacedCallPartyName() = 0;
|
||||
|
||||
/**
|
||||
get placed call party number
|
||||
@param [in] handle - call info handle
|
||||
@return placed party number
|
||||
*/
|
||||
virtual std::string getPlacedCallPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
get call instance number
|
||||
@param [in] handle - call info handle
|
||||
@return
|
||||
*/
|
||||
virtual cc_int32_t getCallInstance() = 0;
|
||||
|
||||
/**
|
||||
get call status prompt
|
||||
@param [in] handle - call info handle
|
||||
@return call status
|
||||
*/
|
||||
virtual std::string getStatus() = 0;
|
||||
|
||||
/**
|
||||
get call security // TODO XLS has callagent security and endtoend security on call?
|
||||
@param [in] handle - call info handle
|
||||
@return call security status
|
||||
*/
|
||||
virtual cc_call_security_t getSecurity() = 0;
|
||||
|
||||
/**
|
||||
get Call Selection Status
|
||||
@param [in] handle - call info handle
|
||||
@return bool - TRUE => selected
|
||||
*/
|
||||
virtual cc_int32_t getSelectionStatus() = 0;
|
||||
|
||||
/**
|
||||
get GCID
|
||||
@param [in] handle - call info handle
|
||||
@return GCID
|
||||
*/
|
||||
virtual std::string getGCID() = 0;
|
||||
|
||||
/**
|
||||
get ringer loop count
|
||||
@param handle - call handle
|
||||
@return once Vs continuous
|
||||
*/
|
||||
virtual bool getIsRingOnce() = 0;
|
||||
|
||||
/**
|
||||
get ringer mode
|
||||
@param handle - call handle
|
||||
@return ringer mode
|
||||
*/
|
||||
virtual int getRingerMode() = 0;
|
||||
|
||||
/**
|
||||
get onhook reason
|
||||
@param [in] handle - call info handle
|
||||
@return onhook reason
|
||||
*/
|
||||
virtual cc_int32_t getOnhookReason() = 0;
|
||||
|
||||
/**
|
||||
is Conference Call?
|
||||
@param [in] handle - call info handle
|
||||
@return boolean - is Conference
|
||||
*/
|
||||
virtual bool getIsConference() = 0;
|
||||
|
||||
/**
|
||||
getStream Statistics
|
||||
@param [in] handle - call info handle
|
||||
@param [in,out] stats - Array to get the stats
|
||||
@param [in,out] count - in len of stats arraysize of stats / out stats copied
|
||||
@return cc_return_t - CC_SUCCESS or CC_FAILURE
|
||||
*/
|
||||
virtual std::set<cc_int32_t> getStreamStatistics() = 0;
|
||||
|
||||
/**
|
||||
Call selection status
|
||||
@param [in] handle - call info handle
|
||||
@return bool - selection status
|
||||
*/
|
||||
virtual bool isCallSelected() = 0;
|
||||
|
||||
/**
|
||||
INFO Package for RECEIVED_INFO event
|
||||
@param [in] handle - call info handle
|
||||
@return string - Info package header
|
||||
*/
|
||||
virtual std::string getINFOPack() = 0;
|
||||
|
||||
/**
|
||||
INFO type for RECEIVED_INFO event
|
||||
|
||||
@return string - content-type header
|
||||
*/
|
||||
virtual std::string getINFOType() = 0;
|
||||
|
||||
/**
|
||||
INFO body for RECEIVED_INFO event
|
||||
|
||||
@return string - INFO body
|
||||
*/
|
||||
virtual std::string getINFOBody() = 0;
|
||||
|
||||
/**
|
||||
Get the call log reference
|
||||
|
||||
//TODO NEED TO DO SOMETHING WRAP CALL LOG REF.
|
||||
@return string - INFO body
|
||||
NOTE: Memory associated with the call log is tied to the
|
||||
this would be freed when the callinfo ref is freed.
|
||||
*/
|
||||
virtual cc_calllog_ref_t getCallLogRef() = 0;
|
||||
|
||||
/**
|
||||
returns the negotiated video direction for this call
|
||||
|
||||
@return cc_sdp_direction_t - video direction
|
||||
*/
|
||||
virtual cc_sdp_direction_t getVideoDirection() = 0;
|
||||
|
||||
/**
|
||||
Find out if this call is capable of querying the media state, which includes mute state and video direction
|
||||
@return bool
|
||||
*/
|
||||
virtual bool isMediaStateAvailable() = 0;
|
||||
|
||||
/**
|
||||
Get the audio mute state if available (check availability with isMediaStateAvailable())
|
||||
@return bool - the current audio state of the call
|
||||
*/
|
||||
virtual bool isAudioMuted(void) = 0;
|
||||
|
||||
/**
|
||||
Get the video mute state if available (check availability with isMediaStateAvailable())
|
||||
@return bool - the current video state of the call
|
||||
*/
|
||||
virtual bool isVideoMuted(void) = 0;
|
||||
|
||||
/**
|
||||
Get the current call volume level
|
||||
@return int - the current call volume level, or -1 if it cannot be determined
|
||||
*/
|
||||
virtual int getVolume() = 0;
|
||||
|
||||
};
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_CallServerInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_CallServerInfo)
|
||||
|
||||
protected:
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_CallServerInfo() { }
|
||||
CC_CallServerInfo() { }
|
||||
|
||||
public:
|
||||
/**
|
||||
gets call server name
|
||||
|
||||
@returns name of the call server
|
||||
*/
|
||||
virtual std::string getCallServerName() = 0;
|
||||
|
||||
/**
|
||||
gets call server mode
|
||||
|
||||
@returns - mode of the call server
|
||||
*/
|
||||
virtual cc_cucm_mode_t getCallServerMode() = 0;
|
||||
|
||||
/**
|
||||
gets calls erver name
|
||||
|
||||
@returns status of the call server
|
||||
*/
|
||||
virtual cc_ccm_status_t getCallServerStatus() = 0;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
namespace CC_CallCapabilityEnum
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
canSetRemoteWindow,
|
||||
canSetLocalWindow,
|
||||
canSendIFrame,
|
||||
canOriginateCall,
|
||||
canAnswerCall,
|
||||
canHold,
|
||||
canResume,
|
||||
canEndCall,
|
||||
canSendDigit,
|
||||
canBackspace,
|
||||
canRedial,
|
||||
canInitiateCallForwardAll,
|
||||
canEndConsultativeCall,
|
||||
canConferenceStart,
|
||||
canConferenceComplete,
|
||||
canTransferStart,
|
||||
canTransferComplete,
|
||||
canCancelTransferOrConferenceFeature,
|
||||
canDirectTransfer,
|
||||
canJoinAcrossLine,
|
||||
canBlfCallPickup,
|
||||
canSelect,
|
||||
canUpdateVideoMediaCap,
|
||||
canSendInfo,
|
||||
canMuteAudio,
|
||||
canUnmuteAudio,
|
||||
canMuteVideo,
|
||||
canUnmuteVideo,
|
||||
canSetVolume
|
||||
} CC_CallCapability;
|
||||
std::string ECC_API toString(CC_CallCapability cap);
|
||||
std::string ECC_API toString(std::set<CC_CallCapability>& caps);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SharedPtr.h"
|
||||
|
||||
#ifndef ECC_API
|
||||
#ifdef ECC_EXPORT
|
||||
#define ECC_API _declspec(dllexport)
|
||||
#elif ECC_IMPORT
|
||||
#define ECC_API _declspec(dllimport)
|
||||
#else
|
||||
#define ECC_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(CallControlManager)
|
||||
DECLARE_NS_PTR_VECTOR(PhoneDetails)
|
||||
DECLARE_NS_PTR(CC_Service)
|
||||
DECLARE_NS_PTR(VideoControl)
|
||||
DECLARE_NS_PTR(AudioControl)
|
||||
DECLARE_NS_PTR_VECTOR(CC_Device)
|
||||
DECLARE_NS_PTR(CC_DeviceInfo)
|
||||
DECLARE_NS_PTR(CC_CallServerInfo)
|
||||
DECLARE_NS_PTR(CC_FeatureInfo)
|
||||
DECLARE_NS_PTR_VECTOR(CC_Line)
|
||||
DECLARE_NS_PTR(CC_LineInfo)
|
||||
DECLARE_NS_PTR_VECTOR(CC_Call)
|
||||
DECLARE_NS_PTR(CC_CallInfo)
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
|
||||
class ECC_API CC_Device
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Device)
|
||||
protected:
|
||||
CC_Device() {}
|
||||
|
||||
virtual ~CC_Device() {}
|
||||
|
||||
public:
|
||||
virtual std::string toString() = 0;
|
||||
|
||||
virtual CC_DeviceInfoPtr getDeviceInfo () = 0;
|
||||
|
||||
/**
|
||||
Create a call on the device. Line selection is on the first available line.
|
||||
Lines that have their MNC reached will be skipped. If you have a specific line
|
||||
you want to make a call on (assuming the device has more than available) then
|
||||
you should use CC_Line::createCall() to do that.
|
||||
|
||||
@return CC_CallPtr - the created call object wrapped in a smart_ptr.
|
||||
*/
|
||||
virtual CC_CallPtr createCall() = 0;
|
||||
|
||||
virtual void enableVideo(bool enable) = 0;
|
||||
virtual void enableCamera(bool enable) = 0;
|
||||
virtual void setDigestNamePasswd (char *name, char *pw) = 0;
|
||||
|
||||
private:
|
||||
// Cannot copy - clients should be passing the pointer not the object.
|
||||
CC_Device& operator=(const CC_Device& rhs);
|
||||
CC_Device(const CC_Device&);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_DeviceInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_DeviceInfo)
|
||||
protected:
|
||||
CC_DeviceInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_DeviceInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
gets the device name
|
||||
@returns - the device name as an std::string
|
||||
*/
|
||||
virtual std::string getDeviceName() = 0;
|
||||
|
||||
/**
|
||||
gets the service state
|
||||
@param [in] handle - reference to device info
|
||||
@returns cc_service_state_t - INS/OOS
|
||||
*/
|
||||
virtual cc_service_state_t getServiceState() = 0;
|
||||
|
||||
/**
|
||||
gets the service cause
|
||||
@param [in] handle - reference to device info
|
||||
@returns cc_service_cause_t - reason for service state
|
||||
*/
|
||||
virtual cc_service_cause_t getServiceCause() = 0;
|
||||
|
||||
/**
|
||||
gets vector of CC_CallPtr from this CC_DeviceInfo
|
||||
|
||||
@returns vector<CC_CallPtr> containing the CC_CallPtrs
|
||||
*/
|
||||
virtual std::vector<CC_CallPtr> getCalls () = 0;
|
||||
|
||||
/**
|
||||
gets list of handles to calls on the device by state
|
||||
@param [in] handle - reference to device info
|
||||
@param [in] state - call state for which the calls are requested
|
||||
@param [out] handles - array of call handle to be returned
|
||||
@param [in,out] count number allocated in array/elements returned
|
||||
@returns
|
||||
*/
|
||||
// void getCallsByState (cc_call_state_t state,
|
||||
// cc_call_handle_t handles[], cc_uint16_t *count);
|
||||
|
||||
/**
|
||||
gets vector of CC_LinePtr from this CC_DeviceInfo
|
||||
|
||||
@returns vector<CC_LinePtr> containing the CC_LinePtrs
|
||||
*/
|
||||
virtual std::vector<CC_LinePtr> getLines () = 0;
|
||||
|
||||
/**
|
||||
gets vector of features on the device
|
||||
|
||||
@returns
|
||||
*/
|
||||
virtual std::vector<CC_FeatureInfoPtr> getFeatures () = 0;
|
||||
|
||||
/**
|
||||
gets handles of call agent servers
|
||||
|
||||
@returns
|
||||
*/
|
||||
virtual std::vector<CC_CallServerInfoPtr> getCallServers () = 0;
|
||||
|
||||
/**
|
||||
gets call server name
|
||||
@param [in] handle - handle of call server
|
||||
@returns name of the call server
|
||||
NOTE: The memory for return string doesn't need to be freed it will be freed when the info reference is freed
|
||||
*/
|
||||
// cc_string_t getCallServerName (cc_callserver_ref_t handle);
|
||||
|
||||
/**
|
||||
gets call server mode
|
||||
@param [in] handle - handle of call server
|
||||
@returns - mode of the call server
|
||||
*/
|
||||
// cc_cucm_mode_t getCallServerMode (cc_callserver_ref_t handle);
|
||||
|
||||
/**
|
||||
gets calls erver name
|
||||
@param [in] handle - handle of call server
|
||||
@returns status of the call server
|
||||
*/
|
||||
// cc_ccm_status_t getCallServerStatus (cc_callserver_ref_t handle);
|
||||
|
||||
/**
|
||||
get the NOTIFICATION PROMPT
|
||||
@param [in] handle - reference to device info
|
||||
@returns
|
||||
*/
|
||||
// cc_string_t getNotifyPrompt ();
|
||||
|
||||
/**
|
||||
get the NOTIFICATION PROMPT PRIORITY
|
||||
@param [in] handle - reference to device info
|
||||
@returns
|
||||
*/
|
||||
// cc_uint32_t getNotifyPromptPriority ();
|
||||
|
||||
/**
|
||||
get the NOTIFICATION PROMPT Progress
|
||||
@param [in] handle - reference to device info
|
||||
@returns
|
||||
*/
|
||||
// cc_uint32_t getNotifyPromptProgress ();
|
||||
|
||||
private:
|
||||
// Cannot copy - clients should be passing the pointer not the object.
|
||||
CC_DeviceInfo& operator=(const CC_DeviceInfo& rhs);
|
||||
CC_DeviceInfo(const CC_DeviceInfo&);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_FeatureInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_FeatureInfo)
|
||||
protected:
|
||||
CC_FeatureInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_FeatureInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the physical button number on which this feature is configured
|
||||
|
||||
@return cc_int32_t - button assgn to the feature
|
||||
*/
|
||||
virtual cc_int32_t getButton() = 0;
|
||||
|
||||
/**
|
||||
Get the featureID
|
||||
|
||||
@return cc_int32_t - button assgn to the feature
|
||||
*/
|
||||
virtual cc_int32_t getFeatureID() = 0;
|
||||
|
||||
/**
|
||||
Get the feature Name
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getDisplayName() = 0;
|
||||
|
||||
/**
|
||||
Get the speeddial Number
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getSpeedDialNumber() = 0;
|
||||
|
||||
/**
|
||||
Get the contact
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getContact() = 0;
|
||||
|
||||
/**
|
||||
Get the retrieval prefix
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getRetrievalPrefix() = 0;
|
||||
|
||||
/**
|
||||
Get the feature option mask
|
||||
|
||||
@return cc_int32_t - button assgn to the feature
|
||||
*/
|
||||
virtual cc_int32_t getFeatureOptionMask() = 0;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_Line
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Line)
|
||||
protected:
|
||||
CC_Line () { }
|
||||
|
||||
virtual ~CC_Line () {};
|
||||
|
||||
public:
|
||||
virtual std::string toString() = 0;
|
||||
|
||||
virtual cc_lineid_t getID() = 0;
|
||||
virtual CC_LineInfoPtr getLineInfo () = 0;
|
||||
virtual CC_CallPtr createCall () = 0;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,152 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include <bitset>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_LineInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_LineInfo)
|
||||
protected:
|
||||
CC_LineInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_LineInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the line Name
|
||||
|
||||
@return string - line Name
|
||||
*/
|
||||
virtual std::string getName() = 0;
|
||||
|
||||
/**
|
||||
Get the line DN Number
|
||||
@return string - line DN
|
||||
*/
|
||||
virtual std::string getNumber() = 0;
|
||||
|
||||
/**
|
||||
Get the physical button number on which this line is configured
|
||||
|
||||
@return cc_uint32_t - button number
|
||||
*/
|
||||
virtual cc_uint32_t getButton() = 0;
|
||||
|
||||
/**
|
||||
Get the Line Type
|
||||
|
||||
@return cc_line_feature_t - line featureID ( Line )
|
||||
*/
|
||||
virtual cc_line_feature_t getLineType() = 0;
|
||||
|
||||
/**
|
||||
|
||||
@return bool - true if phone is currently registered with CM.
|
||||
*/
|
||||
virtual bool getRegState() = 0;
|
||||
|
||||
/**
|
||||
Get the CFWDAll status for the line
|
||||
|
||||
@return bool - isForwarded
|
||||
*/
|
||||
virtual bool isCFWDActive() = 0;
|
||||
|
||||
/**
|
||||
Get the CFWDAll destination
|
||||
|
||||
@return string - cfwd target
|
||||
*/
|
||||
virtual std::string getCFWDName() = 0;
|
||||
|
||||
/**
|
||||
Get calls on line
|
||||
|
||||
@param [in] line - line
|
||||
@return vector<CC_CallPtr>
|
||||
*/
|
||||
virtual std::vector<CC_CallPtr> getCalls (CC_LinePtr linePtr) = 0;
|
||||
|
||||
/**
|
||||
Get calls on line by state
|
||||
|
||||
@param [in] line - line
|
||||
@param [in] state - state
|
||||
|
||||
@return vector<CC_CallPtr>
|
||||
*/
|
||||
virtual std::vector<CC_CallPtr> getCallsByState (CC_LinePtr linePtr, cc_call_state_t state) = 0;
|
||||
|
||||
/**
|
||||
Get the MWI Status
|
||||
|
||||
@return cc_uint32_t - MWI status (boolean 0 => no MWI)
|
||||
*/
|
||||
virtual bool getMWIStatus() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI Type
|
||||
|
||||
@return cc_uint32_t - MWI Type
|
||||
*/
|
||||
virtual cc_uint32_t getMWIType() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI new msg count
|
||||
|
||||
@return cc_uint32_t - MWI new msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWINewMsgCount() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI old msg count
|
||||
|
||||
@return cc_uint32_t - MWI old msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWIOldMsgCount() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI high priority new msg count
|
||||
|
||||
@return cc_uint32_t - MWI new msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWIPrioNewMsgCount() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI high priority old msg count
|
||||
|
||||
@return cc_uint32_t - MWI old msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWIPrioOldMsgCount() = 0;
|
||||
|
||||
/**
|
||||
has capability - is the feature allowed
|
||||
|
||||
@param [in] capability - capability being queried to see if it's available
|
||||
@return bool - is Allowed
|
||||
*/
|
||||
virtual bool hasCapability(ccapi_call_capability_e capability) = 0;
|
||||
|
||||
/**
|
||||
get Allowed Feature set
|
||||
|
||||
@return cc_return_t - bitset of Line Capabilities.
|
||||
*/
|
||||
virtual std::bitset<CCAPI_CALL_CAP_MAX> getCapabilitySet() = 0;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
/**
|
||||
* These callbacks relate to the "core" Call Control API objects CC_Device, CC_Line and CC_Call.
|
||||
*/
|
||||
class ECC_API CC_Observer
|
||||
{
|
||||
public:
|
||||
virtual void onDeviceEvent ( ccapi_device_event_e deviceEvent, CC_DevicePtr device, CC_DeviceInfoPtr info ) = 0;
|
||||
virtual void onFeatureEvent ( ccapi_device_event_e deviceEvent, CC_DevicePtr device, CC_FeatureInfoPtr feature_info) = 0;
|
||||
virtual void onLineEvent ( ccapi_line_event_e lineEvent, CC_LinePtr line, CC_LineInfoPtr info ) = 0;
|
||||
virtual void onCallEvent ( ccapi_call_event_e callEvent, CC_CallPtr call, CC_CallInfoPtr infog ) = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "CC_Observer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
#include "ccapi_service.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_Service
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Service)
|
||||
protected:
|
||||
CC_Service() {}
|
||||
virtual ~CC_Service() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Clients use CC_Observer to receive CCAPI events (Device, Line, Call) from the service.
|
||||
*/
|
||||
virtual void addCCObserver ( CC_Observer * observer ) = 0;
|
||||
virtual void removeCCObserver ( CC_Observer * observer ) = 0;
|
||||
|
||||
/**
|
||||
* Use init() immediately on creating the service, and destroy() when finished with it.
|
||||
* password is required for Asterisk not CUCM.
|
||||
* deviceName is required for CUCM not Asterisk.
|
||||
*/
|
||||
virtual bool init(const std::string& user, const std::string& password, const std::string& domain, const std::string& deviceName) = 0;
|
||||
virtual void destroy() = 0;
|
||||
|
||||
/**
|
||||
* TODO: Set config parameters prior to starting the service.
|
||||
* Need to design a nice abstraction for this accommodating SIPCC and CTI.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Use start() to attempt to register for a device and stop() to cancel a current
|
||||
* registration (or registration attempt).
|
||||
*/
|
||||
virtual bool startService() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Check on the current status/health of the service.
|
||||
*/
|
||||
virtual bool isStarted() = 0;
|
||||
|
||||
/**
|
||||
* Obtain the currently selected Device.
|
||||
* If multiple devices are discoverable (i.e. in CTI), all known devices will appear
|
||||
* in getDevices(), but only the ActiveDevice will be controllable at any given time.
|
||||
*/
|
||||
virtual CC_DevicePtr getActiveDevice() = 0;
|
||||
virtual std::vector<CC_DevicePtr> getDevices() = 0;
|
||||
|
||||
/**
|
||||
* Global settings for audio and video control. Return nullptr if Media control is not
|
||||
* available in this implementation. Return nullptr in any case if media is not yet
|
||||
* initialized.
|
||||
* TODO: Assuming for now that media init aligns with init/destroy.
|
||||
*/
|
||||
virtual AudioControlPtr getAudioControl() = 0;
|
||||
virtual VideoControlPtr getVideoControl() = 0;
|
||||
|
||||
virtual bool setLocalVoipPort(int port) = 0;
|
||||
virtual bool setRemoteVoipPort(int port) = 0;
|
||||
virtual bool setP2PMode(bool mode) = 0;
|
||||
virtual bool setSDPMode(bool mode) = 0;
|
||||
|
||||
private:
|
||||
CC_Service(const CC_Service& rhs);
|
||||
CC_Service& operator=(const CC_Service& rhs);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(AudioControl)
|
||||
class ECC_API AudioControl
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioControl)
|
||||
// device names are in UTF-8 encoding
|
||||
|
||||
virtual std::vector<std::string> getRecordingDevices() = 0;
|
||||
virtual std::vector<std::string> getPlayoutDevices() = 0;
|
||||
|
||||
virtual std::string getRecordingDevice() = 0;
|
||||
virtual std::string getPlayoutDevice() = 0;
|
||||
|
||||
virtual bool setRecordingDevice( const std::string& name ) = 0;
|
||||
virtual bool setPlayoutDevice( const std::string& name ) = 0;
|
||||
|
||||
virtual bool setDefaultVolume( int ) = 0;
|
||||
virtual int getDefaultVolume() = 0;
|
||||
|
||||
virtual bool setRingerVolume( int ) = 0;
|
||||
virtual int getRingerVolume() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~AudioControl(){};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(VideoControl)
|
||||
class ECC_API VideoControl
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoControl)
|
||||
|
||||
virtual void setVideoMode( bool enable ) = 0;
|
||||
|
||||
// window type is platform-specific
|
||||
virtual void setPreviewWindow( VideoWindowHandle window, int top, int left, int bottom, int right, RenderScaling style ) = 0;
|
||||
virtual void showPreviewWindow( bool show ) = 0;
|
||||
|
||||
// device names are in UTF-8 encoding
|
||||
virtual std::vector<std::string> getCaptureDevices() = 0;
|
||||
|
||||
virtual std::string getCaptureDevice() = 0;
|
||||
virtual bool setCaptureDevice( const std::string& name ) = 0;
|
||||
protected:
|
||||
virtual ~VideoControl() {};
|
||||
};
|
||||
|
||||
}; // namespace
|
|
@ -0,0 +1,130 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
#include "CC_Observer.h"
|
||||
#include "ECC_Observer.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @mainpage Enhanced Call Control
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
* This wraps and aggregates the SIPCC and CTI call control stacks, media stacks, and various additional
|
||||
* components and glue necessary to start, configure and run them, and presents a high-level C++ API
|
||||
* for connection, device selection and status, and call control.
|
||||
*
|
||||
* @section main_outline Outline
|
||||
* @li The main entry point is CSF::CallControlManager, which is used to configure and start a
|
||||
* call control stack.
|
||||
* @li Configuration and events are raised to the CSF::ECC_Observer interface.
|
||||
* @li Call Control is performed via CSF::CC_Device, CSF::CC_Line and CSF::CC_Call.
|
||||
* @li Call Control events are raised to the CSF::CC_Observer interface.
|
||||
* @li Audio/Video device selection and global media configuration is performed via CSF::AudioControl
|
||||
* and CSF::VideoControl. Per-call media operations (mute, volume, etc) are integrated onto
|
||||
* the CSF::CC_Call and CSF::CC_CallInfo interfaces.
|
||||
*/
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(CallControlManager)
|
||||
/**
|
||||
* CallControlManager
|
||||
*
|
||||
* The class is partitioned into several blocks of functionality:
|
||||
* - Create/Destroy - Initialisation and clean shutdown.
|
||||
* Destroy is optional if the destructor is used properly.
|
||||
* - Observer - Register for events when any state changes. Optional but strongly advised.
|
||||
*
|
||||
* Methods are generally synchronous (at present).
|
||||
*/
|
||||
class ECC_API CallControlManager
|
||||
{
|
||||
protected:
|
||||
virtual ~CallControlManager();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CallControlManager)
|
||||
/**
|
||||
* Use create() to create a CallControlManager instance.
|
||||
*
|
||||
* CallControlManager cleans up its resources in its destructor, implicitly disconnect()in if required.
|
||||
* Use the destroy() method if you need to force a cleanup earlier. It is a bad idea to continue using
|
||||
* CallControlManager or any of its related objects after destroy().
|
||||
*/
|
||||
static CallControlManagerPtr create();
|
||||
virtual bool destroy() = 0;
|
||||
|
||||
/**
|
||||
CC_Observer is for core call control events (on CC_Device, CC_Line and CC_Call).
|
||||
ECC_Observer is for "value add" features of CallControlManager.
|
||||
|
||||
Client can add multiple observers if they have different Observer objects that handle
|
||||
different event scenarios, but generally it's probably sufficient to only register one observer.
|
||||
|
||||
@param[in] observer - This is a pointer to a CC_Observer-derived class that the client
|
||||
must instantiate to receive notifications on this client object.
|
||||
*/
|
||||
virtual void addCCObserver ( CC_Observer * observer ) = 0;
|
||||
virtual void removeCCObserver ( CC_Observer * observer ) = 0;
|
||||
|
||||
virtual void addECCObserver ( ECC_Observer * observer ) = 0;
|
||||
virtual void removeECCObserver ( ECC_Observer * observer ) = 0;
|
||||
|
||||
virtual void setMultiClusterMode(bool allowMultipleClusters) = 0;
|
||||
virtual void setSIPCCLoggingMask(const cc_int32_t mask) = 0;
|
||||
virtual void setAuthenticationString(const std::string &authString) = 0;
|
||||
virtual void setSecureCachePath(const std::string &secureCachePath) = 0;
|
||||
|
||||
// Add local codecs
|
||||
virtual void setAudioCodecs(int codecMask) = 0;
|
||||
virtual void setVideoCodecs(int codecMask) = 0;
|
||||
|
||||
virtual bool registerUser(const std::string& deviceName, const std::string& user, const std::string& password, const std::string& domain) = 0;
|
||||
virtual bool disconnect() = 0;
|
||||
virtual std::string getPreferredDeviceName() = 0;
|
||||
virtual std::string getPreferredLineDN() = 0;
|
||||
virtual ConnectionStatusEnum::ConnectionStatus getConnectionStatus() = 0;
|
||||
virtual std::string getCurrentServer() = 0;
|
||||
|
||||
/* P2P MODE */
|
||||
virtual bool startP2PMode(const std::string& user) = 0;
|
||||
|
||||
/* SDP MODE */
|
||||
virtual bool startSDPMode() = 0;
|
||||
|
||||
/**
|
||||
* Obtain the device object, from which call control can be done.
|
||||
* getAvailablePhoneDetails lists all known devices which the user is likely to be able to control.
|
||||
*/
|
||||
virtual CC_DevicePtr getActiveDevice() = 0;
|
||||
virtual PhoneDetailsVtrPtr getAvailablePhoneDetails() = 0;
|
||||
virtual PhoneDetailsPtr getAvailablePhoneDetails(const std::string& deviceName) = 0;
|
||||
|
||||
/**
|
||||
* Obtain the audio/video object, from which video setup can be done.
|
||||
* This relates to global tuning, device selection, preview window positioning, etc, not to
|
||||
* per-call settings or control.
|
||||
*
|
||||
* These objects are unavailable except while in softphone mode.
|
||||
*/
|
||||
virtual VideoControlPtr getVideoControl() = 0;
|
||||
virtual AudioControlPtr getAudioControl() = 0;
|
||||
|
||||
virtual bool setProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key, std::string& value) = 0;
|
||||
virtual std::string getProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key) = 0;
|
||||
|
||||
protected:
|
||||
CallControlManager() {}
|
||||
private:
|
||||
CallControlManager(const CallControlManager&);
|
||||
CallControlManager& operator=(const CallControlManager&);
|
||||
};
|
||||
} //end namespace CSF
|
|
@ -0,0 +1,27 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
/**
|
||||
* These callbacks relate to CallControlManager's "value add" features relating to authentication,
|
||||
* configuration, setup, service health and management of SIP.
|
||||
*
|
||||
* They do not relate to call control - see also CC_Observer.
|
||||
*/
|
||||
class ECC_API ECC_Observer
|
||||
{
|
||||
public:
|
||||
virtual void onAvailablePhoneEvent (AvailablePhoneEventType::AvailablePhoneEvent event,
|
||||
const PhoneDetailsPtr availablePhoneDetails) = 0;
|
||||
|
||||
virtual void onAuthenticationStatusChange (AuthenticationStatusEnum::AuthenticationStatus) = 0;
|
||||
virtual void onConnectionStatusChange(ConnectionStatusEnum::ConnectionStatus status) = 0;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
/*
|
||||
These #defines are for use with CallControlManager::createSoftphone(..., const cc_int32_t mask) parameter as follows:
|
||||
|
||||
CallControlManager::createSoftphone(..., GSM_DEBUG_BIT | FIM_DEBUG_BIT | LSM_DEBUG_BIT );
|
||||
|
||||
This turns on debugging for the three areas (and disables logging in all other areas) of pSIPCC logging specified.
|
||||
|
||||
*/
|
||||
|
||||
#define SIP_DEBUG_MSG_BIT (1 << 0) // Bit 0
|
||||
#define SIP_DEBUG_STATE_BIT (1 << 1) // Bit 1
|
||||
#define SIP_DEBUG_TASK_BIT (1 << 2) // Bit 2
|
||||
#define SIP_DEBUG_REG_STATE_BIT (1 << 3) // Bit 3
|
||||
#define GSM_DEBUG_BIT (1 << 4) // Bit 4
|
||||
#define FIM_DEBUG_BIT (1 << 5) // Bit 5
|
||||
#define LSM_DEBUG_BIT (1 << 6) // Bit 6
|
||||
#define FSM_DEBUG_SM_BIT (1 << 7) // Bit 7
|
||||
#define CSM_DEBUG_SM_BIT (1 << 8) // Bit 8
|
||||
#define CC_DEBUG_BIT (1 << 9) // Bit 9
|
||||
#define CC_DEBUG_MSG_BIT (1 << 10) // Bit 10
|
||||
#define AUTH_DEBUG_BIT (1 << 11) // Bit 11
|
||||
#define CONFIG_DEBUG_BIT (1 << 12) // Bit 12
|
||||
#define DPINT_DEBUG_BIT (1 << 13) // Bit 13
|
||||
#define KPML_DEBUG_BIT (1 << 15) // Bit 15
|
||||
#define VCM_DEBUG_BIT (1 << 17) // Bit 17
|
||||
#define CC_APP_DEBUG_BIT (1 << 18) // Bit 18
|
||||
#define CC_LOG_DEBUG_BIT (1 << 19) // Bit 19
|
||||
#define TNP_DEBUG_BIT (1 << 20) // Bit 20
|
||||
|
||||
namespace CSFUnified
|
||||
{
|
||||
DECLARE_PTR(DeviceInfo)
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
namespace AuthenticationFailureCodeType
|
||||
{
|
||||
typedef enum {
|
||||
eNoError,
|
||||
eNoServersConfigured,
|
||||
eNoCredentialsConfigured,
|
||||
eCouldNotConnect,
|
||||
eServerCertificateRejected,
|
||||
eCredentialsRejected,
|
||||
eResponseEmpty,
|
||||
eResponseInvalid
|
||||
} AuthenticationFailureCode;
|
||||
std::string ECC_API toString(AuthenticationFailureCode value);
|
||||
}
|
||||
|
||||
namespace AuthenticationStatusEnum
|
||||
{
|
||||
typedef enum {
|
||||
eNotAuthenticated,
|
||||
eInProgress,
|
||||
eAuthenticated,
|
||||
eFailed
|
||||
} AuthenticationStatus;
|
||||
std::string ECC_API toString(AuthenticationStatus value);
|
||||
}
|
||||
|
||||
namespace DeviceRetrievalFailureCodeType
|
||||
{
|
||||
typedef enum {
|
||||
eNoError,
|
||||
eNoServersConfigured,
|
||||
eNoDeviceNameConfigured,
|
||||
eCouldNotConnect,
|
||||
eFileNotFound,
|
||||
eFileEmpty,
|
||||
eFileInvalid
|
||||
} DeviceRetrievalFailureCode;
|
||||
std::string ECC_API toString(DeviceRetrievalFailureCode value);
|
||||
}
|
||||
|
||||
namespace ConnectionStatusEnum
|
||||
{
|
||||
typedef enum {
|
||||
eIdle,
|
||||
eNone,
|
||||
eFetchingDeviceConfig,
|
||||
eRegistering,
|
||||
eReady,
|
||||
eConnectedButNoDeviceReady,
|
||||
eRetrying,
|
||||
eFailed
|
||||
} ConnectionStatus;
|
||||
std::string ECC_API toString(ConnectionStatus value);
|
||||
}
|
||||
|
||||
namespace ServiceStateType {
|
||||
typedef enum
|
||||
{
|
||||
eUnknown,
|
||||
eInService,
|
||||
eOutOfService
|
||||
} ServiceState;
|
||||
std::string ECC_API toString(ServiceState value);
|
||||
}
|
||||
|
||||
namespace AvailablePhoneEventType
|
||||
{
|
||||
typedef enum {
|
||||
eFound, // New Phone device discovered and added to the Available list.
|
||||
eUpdated, // Change to an existing Phone details record in the Available list.
|
||||
eLost // Phone device removed from the Available list.
|
||||
} AvailablePhoneEvent;
|
||||
std::string ECC_API toString(AvailablePhoneEvent value);
|
||||
}
|
||||
|
||||
namespace ConfigPropertyKeysEnum
|
||||
{
|
||||
typedef enum {
|
||||
eLocalVoipPort,
|
||||
eRemoteVoipPort,
|
||||
eVersion,
|
||||
eTransport
|
||||
} ConfigPropertyKeys;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VideoEnableMode_DISABLED,
|
||||
VideoEnableMode_SENDONLY,
|
||||
VideoEnableMode_RECVONLY,
|
||||
VideoEnableMode_SENDRECV
|
||||
|
||||
} VideoEnableMode;
|
||||
|
||||
typedef enum // scaling from codec size to render window size
|
||||
{
|
||||
RenderScaling_NONE, // 1:1 actual pixels, crop and/or fill
|
||||
RenderScaling_TO_FIT, // scale to fit, without preserving aspect ratio
|
||||
RenderScaling_BORDER, // scale to fit, fill without cropping
|
||||
RenderScaling_CROP // scale to fit, crop without filling
|
||||
|
||||
} RenderScaling;
|
||||
|
||||
typedef void *VideoWindowHandle;
|
||||
typedef void* ExternalRendererHandle;
|
||||
typedef unsigned int VideoFormat;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR_VECTOR(PhoneDetails);
|
||||
class ECC_API PhoneDetails
|
||||
{
|
||||
protected:
|
||||
virtual ~PhoneDetails() {}
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PhoneDetails)
|
||||
/**
|
||||
* Get the device name (the CUCM device name) and the free text description.
|
||||
*/
|
||||
virtual std::string getName() const = 0;
|
||||
virtual std::string getDescription() const = 0;
|
||||
|
||||
/**
|
||||
* Get the model number (the internal CUCM number, not the number printed on the phone)
|
||||
* and the corresponding description (which normally does include the number printed on the phone).
|
||||
* Returns -1, "" if unknown
|
||||
*/
|
||||
virtual int getModel() const = 0;
|
||||
virtual std::string getModelDescription() const = 0;
|
||||
|
||||
virtual bool isSoftPhone() = 0;
|
||||
|
||||
/**
|
||||
* List the known directory numbers of lines associated with the device.
|
||||
* Empty list if unknown.
|
||||
*/
|
||||
virtual std::vector<std::string> getLineDNs() const = 0;
|
||||
|
||||
/**
|
||||
* Current status of the device, if known.
|
||||
*/
|
||||
virtual ServiceStateType::ServiceState getServiceState() const = 0;
|
||||
|
||||
/**
|
||||
* TFTP config of device, and freshness of the config.
|
||||
*/
|
||||
virtual std::string getConfig() const = 0;
|
||||
|
||||
protected:
|
||||
PhoneDetails() {}
|
||||
|
||||
private:
|
||||
PhoneDetails(const PhoneDetails&);
|
||||
PhoneDetails& operator=(const PhoneDetails&);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "base/linked_ptr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#ifndef DECLARE_PTR
|
||||
#define DECLARE_PTR(className)\
|
||||
class className;\
|
||||
typedef linked_ptr<className> className##Ptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DECLARE_PTR_VECTOR
|
||||
#define DECLARE_PTR_VECTOR(className)\
|
||||
DECLARE_PTR(className)\
|
||||
typedef std::vector<className##Ptr> className##Vtr;\
|
||||
typedef linked_ptr<className##Vtr> className##Vtr##Ptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NULL_PTR
|
||||
#define NULL_PTR(className) linked_ptr<className>()
|
||||
#endif
|
||||
|
||||
// NSPR Variations of the above, to help with migration
|
||||
// from linked_ptr to nsRefPtr
|
||||
#ifndef DECLARE_NS_PTR
|
||||
#define DECLARE_NS_PTR(className)\
|
||||
class className;\
|
||||
typedef nsRefPtr<className> className##Ptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DECLARE_NS_PTR_VECTOR
|
||||
#define DECLARE_NS_PTR_VECTOR(className)\
|
||||
DECLARE_NS_PTR(className)\
|
||||
typedef std::vector<className##Ptr> className##Vtr;\
|
||||
typedef linked_ptr<className##Vtr> className##Vtr##Ptr;
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef T1_DEBUG_H
|
||||
#define T1_DEBUG_H
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <ccapi_service.h>
|
||||
#include "ccapi_types.h"
|
||||
|
||||
ECC_API cc_string_t device_event_getname(ccapi_device_event_e);
|
||||
ECC_API cc_string_t call_event_getname(ccapi_call_event_e);
|
||||
ECC_API cc_string_t line_event_getname(ccapi_line_event_e);
|
||||
|
||||
ECC_API cc_string_t digit_getname(cc_digit_t);
|
||||
ECC_API cc_string_t cucm_mode_getname(cc_cucm_mode_t);
|
||||
ECC_API cc_string_t line_feature_getname(cc_line_feature_t);
|
||||
ECC_API cc_string_t feature_option_mask_getname(cc_feature_option_mask_t);
|
||||
ECC_API cc_string_t service_cause_getname(cc_service_cause_t);
|
||||
ECC_API cc_string_t service_state_getname(cc_service_state_t);
|
||||
ECC_API cc_string_t ccm_status_getname(cc_ccm_status_t);
|
||||
ECC_API cc_string_t line_reg_state_getname(cc_line_reg_state_t);
|
||||
ECC_API cc_string_t shutdown_reason_getname(cc_shutdown_reason_t);
|
||||
ECC_API cc_string_t kpml_config_getname(cc_kpml_config_t);
|
||||
ECC_API cc_string_t upgrade_getname(cc_upgrade_t);
|
||||
ECC_API cc_string_t sdp_direction_getname(cc_sdp_direction_t);
|
||||
ECC_API cc_string_t blf_state_getname(cc_blf_state_t);
|
||||
ECC_API cc_string_t blf_feature_mask_getname(cc_blf_feature_mask_t);
|
||||
ECC_API cc_string_t call_state_getname(cc_call_state_t);
|
||||
ECC_API cc_string_t call_attr_getname(cc_call_attr_t);
|
||||
ECC_API cc_string_t hold_reason_getname(cc_hold_reason_t);
|
||||
ECC_API cc_string_t call_type_getname(cc_call_type_t);
|
||||
ECC_API cc_string_t call_security_getname(cc_call_security_t);
|
||||
ECC_API cc_string_t call_policy_getname(cc_call_policy_t);
|
||||
ECC_API cc_string_t log_disposition_getname(cc_log_disposition_t);
|
||||
ECC_API cc_string_t call_priority_getname(cc_call_priority_t);
|
||||
ECC_API cc_string_t call_selection_getname(cc_call_selection_t);
|
||||
ECC_API cc_string_t call_capability_getname(ccapi_call_capability_e);
|
||||
ECC_API cc_string_t srv_ctrl_req_getname(cc_srv_ctrl_req_t);
|
||||
ECC_API cc_string_t srv_ctrl_cmd_getname(cc_srv_ctrl_cmd_t);
|
||||
ECC_API cc_string_t message_type_getname(cc_message_type_t);
|
||||
ECC_API cc_string_t lamp_state_getname(cc_lamp_state_t);
|
||||
ECC_API cc_string_t cause_getname(cc_cause_t);
|
||||
ECC_API cc_string_t subscriptions_ext_getname(cc_subscriptions_ext_t);
|
||||
ECC_API cc_string_t apply_config_result_getname(cc_apply_config_result_t);
|
||||
|
||||
}
|
||||
|
||||
#endif /* T1_DEBUG_H */
|
|
@ -38,14 +38,23 @@
|
|||
'include_dirs': [
|
||||
'..',
|
||||
'./src',
|
||||
'./src/callcontrol',
|
||||
'./src/common',
|
||||
'./src/common/browser_logging',
|
||||
'./src/common/time_profiling',
|
||||
'./src/media',
|
||||
'./src/media-conduit',
|
||||
'./src/mediapipeline',
|
||||
'./src/softphonewrapper',
|
||||
'./src/peerconnection',
|
||||
'./src/sdp/sipcc',
|
||||
'./include',
|
||||
'./src/sipcc/include',
|
||||
'./src/sipcc/cpr/include',
|
||||
'./src/sipcc/core/includes',
|
||||
'./src/sipcc/core/gsm/h',
|
||||
'./src/sipcc/core/common',
|
||||
'./src/sipcc/core/sipstack/h',
|
||||
'./src/sipcc/core/sdp',
|
||||
'../../../xpcom/base',
|
||||
'../../../dom/base',
|
||||
'../../../dom/media',
|
||||
|
@ -98,9 +107,51 @@
|
|||
# Browser Logging
|
||||
'./src/common/time_profiling/timecard.c',
|
||||
'./src/common/time_profiling/timecard.h',
|
||||
# Call Control
|
||||
'./src/callcontrol/CC_CallTypes.cpp',
|
||||
'./src/callcontrol/CallControlManager.cpp',
|
||||
'./src/callcontrol/CallControlManagerImpl.cpp',
|
||||
'./src/callcontrol/ECC_Types.cpp',
|
||||
'./src/callcontrol/PhoneDetailsImpl.cpp',
|
||||
'./src/callcontrol/debug-psipcc-types.cpp',
|
||||
'./src/callcontrol/CallControlManagerImpl.h',
|
||||
'./src/callcontrol/PhoneDetailsImpl.h',
|
||||
# Media
|
||||
'./src/media/CSFAudioControlWrapper.cpp',
|
||||
'./src/media/CSFVideoControlWrapper.cpp',
|
||||
'./src/media/VcmSIPCCBinding.cpp',
|
||||
'./src/media/cip_mmgr_mediadefinitions.h',
|
||||
'./src/media/cip_Sipcc_CodecMask.h',
|
||||
'./src/media/CSFAudioControlWrapper.h',
|
||||
'./src/media/CSFAudioTermination.h',
|
||||
'./src/media/CSFMediaProvider.h',
|
||||
'./src/media/CSFMediaTermination.h',
|
||||
'./src/media/CSFToneDefinitions.h',
|
||||
'./src/media/CSFVideoCallMediaControl.h',
|
||||
'./src/media/CSFVideoControlWrapper.h',
|
||||
'./src/media/CSFVideoTermination.h',
|
||||
'./src/media/VcmSIPCCBinding.h',
|
||||
# SoftPhoneWrapper
|
||||
'./src/softphonewrapper/CC_SIPCCCall.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCCallInfo.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCCallServerInfo.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCDevice.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCDeviceInfo.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCFeatureInfo.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCLine.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCLineInfo.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCService.cpp',
|
||||
'./src/softphonewrapper/ccapi_plat_api_impl.cpp',
|
||||
'./src/softphonewrapper/CC_SIPCCCall.h',
|
||||
'./src/softphonewrapper/CC_SIPCCCallInfo.h',
|
||||
'./src/softphonewrapper/CC_SIPCCCallServerInfo.h',
|
||||
'./src/softphonewrapper/CC_SIPCCDevice.h',
|
||||
'./src/softphonewrapper/CC_SIPCCDeviceInfo.h',
|
||||
'./src/softphonewrapper/CC_SIPCCFeatureInfo.h',
|
||||
'./src/softphonewrapper/CC_SIPCCLine.h',
|
||||
'./src/softphonewrapper/CC_SIPCCLineInfo.h',
|
||||
'./src/softphonewrapper/CC_SIPCCService.h',
|
||||
# PeerConnection
|
||||
'./src/peerconnection/MediaPipelineFactory.cpp',
|
||||
'./src/peerconnection/MediaPipelineFactory.h',
|
||||
'./src/peerconnection/MediaStreamList.cpp',
|
||||
'./src/peerconnection/MediaStreamList.h',
|
||||
'./src/peerconnection/PeerConnectionCtx.cpp',
|
||||
|
@ -109,51 +160,12 @@
|
|||
'./src/peerconnection/PeerConnectionImpl.h',
|
||||
'./src/peerconnection/PeerConnectionMedia.cpp',
|
||||
'./src/peerconnection/PeerConnectionMedia.h',
|
||||
|
||||
# Media pipeline
|
||||
'./src/mediapipeline/MediaPipeline.h',
|
||||
'./src/mediapipeline/MediaPipeline.cpp',
|
||||
'./src/mediapipeline/MediaPipelineFilter.h',
|
||||
'./src/mediapipeline/MediaPipelineFilter.cpp',
|
||||
# SDP
|
||||
'./src/sdp/sipcc/ccsdp.h',
|
||||
'./src/sdp/sipcc/cpr_string.c',
|
||||
'./src/sdp/sipcc/sdp_access.c',
|
||||
'./src/sdp/sipcc/sdp_attr.c',
|
||||
'./src/sdp/sipcc/sdp_attr_access.c',
|
||||
'./src/sdp/sipcc/sdp_base64.c',
|
||||
'./src/sdp/sipcc/sdp_config.c',
|
||||
'./src/sdp/sipcc/sdp_main.c',
|
||||
'./src/sdp/sipcc/sdp_token.c',
|
||||
'./src/sdp/sipcc/sdp.h',
|
||||
'./src/sdp/sipcc/sdp_base64.h',
|
||||
'./src/sdp/sipcc/sdp_os_defs.h',
|
||||
'./src/sdp/sipcc/sdp_private.h',
|
||||
'./src/sdp/sipcc/sdp_utils.c',
|
||||
'./src/sdp/sipcc/sdp_services_unix.c',
|
||||
|
||||
# SDP Wrapper
|
||||
'./src/sdp/Sdp.h',
|
||||
'./src/sdp/SdpAttribute.h',
|
||||
'./src/sdp/SdpAttribute.cpp',
|
||||
'./src/sdp/SdpAttributeList.h',
|
||||
'./src/sdp/SdpErrorHolder.h',
|
||||
'./src/sdp/SdpMediaSection.h',
|
||||
'./src/sdp/SipccSdp.h',
|
||||
'./src/sdp/SipccSdpAttributeList.h',
|
||||
'./src/sdp/SipccSdpAttributeList.cpp',
|
||||
'./src/sdp/SipccSdpMediaSection.h',
|
||||
'./src/sdp/SipccSdpParser.h',
|
||||
'./src/sdp/SipccSdp.cpp',
|
||||
'./src/sdp/SipccSdpMediaSection.cpp',
|
||||
'./src/sdp/SipccSdpParser.cpp',
|
||||
|
||||
# JSEP
|
||||
'./src/jsep/JsepCodecDescription.h',
|
||||
'./src/jsep/JsepSession.h',
|
||||
'./src/jsep/JsepSessionImpl.cpp',
|
||||
'./src/jsep/JsepSessionImpl.h',
|
||||
'./src/jsep/JsepTrack.h',
|
||||
'./src/jsep/JsepTransport.h'
|
||||
],
|
||||
|
||||
#
|
||||
|
@ -166,7 +178,7 @@
|
|||
'USE_SSLEAY',
|
||||
'_CPR_USE_EXTERNAL_LOGGER',
|
||||
'WEBRTC_RELATIVE_PATH',
|
||||
'HAVE_WEBRTC_VIDEO',
|
||||
'HAVE_WEBRTC_VIDEO',
|
||||
'HAVE_WEBRTC_VOICE',
|
||||
'HAVE_STDINT_H=1',
|
||||
'HAVE_STDLIB_H=1',
|
||||
|
@ -180,10 +192,8 @@
|
|||
'$(NSPR_CFLAGS)',
|
||||
'$(NSS_CFLAGS)',
|
||||
'$(MOZ_PIXMAN_CFLAGS)',
|
||||
'$(WARNINGS_AS_ERRORS)',
|
||||
],
|
||||
|
||||
|
||||
#
|
||||
# Conditionals
|
||||
#
|
||||
|
@ -302,6 +312,588 @@
|
|||
}],
|
||||
],
|
||||
},
|
||||
|
||||
#
|
||||
# SIPCC
|
||||
#
|
||||
{
|
||||
'target_name': 'sipcc',
|
||||
'type': 'static_library',
|
||||
|
||||
#
|
||||
# INCLUDES
|
||||
#
|
||||
'include_dirs': [
|
||||
'./src/common/browser_logging',
|
||||
'./src/common/time_profiling',
|
||||
'./src/sipcc/include',
|
||||
'./src/sipcc/core/includes',
|
||||
'./src/sipcc/cpr/include',
|
||||
'./src/sipcc/core/common',
|
||||
'./src/sipcc/core/sipstack/h',
|
||||
'./src/sipcc/core/ccapp',
|
||||
'./src/sipcc/core/sdp',
|
||||
'./src/sipcc/core/gsm/h',
|
||||
'./src/sipcc/plat/common',
|
||||
'../../../media/mtransport',
|
||||
'../../../dom/base',
|
||||
'../../../netwerk/sctp/datachannel',
|
||||
],
|
||||
|
||||
#
|
||||
# DEPENDENCIES
|
||||
#
|
||||
'dependencies': [
|
||||
],
|
||||
|
||||
|
||||
'export_dependent_settings': [
|
||||
],
|
||||
|
||||
|
||||
#
|
||||
# SOURCES
|
||||
#
|
||||
'sources': [
|
||||
# CCAPP
|
||||
'./src/sipcc/core/ccapp/call_logger.c',
|
||||
'./src/sipcc/core/ccapp/call_logger.h',
|
||||
'./src/sipcc/core/ccapp/capability_set.c',
|
||||
'./src/sipcc/core/ccapp/capability_set.h',
|
||||
'./src/sipcc/core/ccapp/cc_blf.c',
|
||||
'./src/sipcc/core/ccapp/cc_call_feature.c',
|
||||
'./src/sipcc/core/ccapp/cc_config.c',
|
||||
'./src/sipcc/core/ccapp/cc_device_feature.c',
|
||||
'./src/sipcc/core/ccapp/cc_device_manager.c',
|
||||
'./src/sipcc/core/ccapp/cc_device_manager.h',
|
||||
'./src/sipcc/core/ccapp/cc_info.c',
|
||||
'./src/sipcc/core/ccapp/cc_service.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_call.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_call_info.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_config.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_device.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_device_info.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_feature_info.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_line.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_line_info.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_service.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_snapshot.c',
|
||||
'./src/sipcc/core/ccapp/ccapi_snapshot.h',
|
||||
'./src/sipcc/core/ccapp/ccapp_task.c',
|
||||
'./src/sipcc/core/ccapp/ccapp_task.h',
|
||||
'./src/sipcc/core/ccapp/ccprovider.c',
|
||||
'./src/sipcc/core/ccapp/CCProvider.h',
|
||||
'./src/sipcc/core/ccapp/conf_roster.c',
|
||||
'./src/sipcc/core/ccapp/conf_roster.h',
|
||||
'./src/sipcc/core/ccapp/sessionHash.c',
|
||||
'./src/sipcc/core/ccapp/sessionHash.h',
|
||||
# COMMON
|
||||
'./src/sipcc/core/common/cfgfile_utils.c',
|
||||
'./src/sipcc/core/common/cfgfile_utils.h',
|
||||
'./src/sipcc/core/common/config_api.c',
|
||||
'./src/sipcc/core/common/config_parser.c',
|
||||
'./src/sipcc/core/common/config_parser.h',
|
||||
'./src/sipcc/core/common/init.c',
|
||||
'./src/sipcc/core/common/logger.c',
|
||||
'./src/sipcc/core/common/logger.h',
|
||||
'./src/sipcc/core/common/logmsg.h',
|
||||
'./src/sipcc/core/common/misc.c',
|
||||
'./src/sipcc/core/common/plat.c',
|
||||
'./src/sipcc/core/common/platform_api.c',
|
||||
'./src/sipcc/core/common/prot_cfgmgr_private.h',
|
||||
'./src/sipcc/core/common/prot_configmgr.c',
|
||||
'./src/sipcc/core/common/prot_configmgr.h',
|
||||
'./src/sipcc/core/common/resource_manager.c',
|
||||
'./src/sipcc/core/common/resource_manager.h',
|
||||
'./src/sipcc/core/common/sip_socket_api.c',
|
||||
'./src/sipcc/core/common/subscription_handler.c',
|
||||
'./src/sipcc/core/common/subscription_handler.h',
|
||||
'./src/sipcc/core/common/text_strings.c',
|
||||
'./src/sipcc/core/common/text_strings.h',
|
||||
'./src/sipcc/core/common/ui.c',
|
||||
# GSM
|
||||
'./src/sipcc/core/gsm/ccapi.c',
|
||||
'./src/sipcc/core/gsm/ccapi_strings.c',
|
||||
'./src/sipcc/core/gsm/dcsm.c',
|
||||
'./src/sipcc/core/gsm/fim.c',
|
||||
'./src/sipcc/core/gsm/fsm.c',
|
||||
'./src/sipcc/core/gsm/fsmb2bcnf.c',
|
||||
'./src/sipcc/core/gsm/fsmcac.c',
|
||||
'./src/sipcc/core/gsm/fsmcnf.c',
|
||||
'./src/sipcc/core/gsm/fsmdef.c',
|
||||
'./src/sipcc/core/gsm/fsmxfr.c',
|
||||
'./src/sipcc/core/gsm/gsm.c',
|
||||
'./src/sipcc/core/gsm/gsm_sdp.c',
|
||||
'./src/sipcc/core/gsm/gsm_sdp_crypto.c',
|
||||
'./src/sipcc/core/gsm/lsm.c',
|
||||
'./src/sipcc/core/gsm/media_cap_tbl.c',
|
||||
'./src/sipcc/core/gsm/sm.c',
|
||||
'./src/sipcc/core/gsm/subapi.c',
|
||||
'./src/sipcc/core/gsm/h/fim.h',
|
||||
'./src/sipcc/core/gsm/h/fsm.h',
|
||||
'./src/sipcc/core/gsm/h/gsm.h',
|
||||
'./src/sipcc/core/gsm/h/gsm_sdp.h',
|
||||
'./src/sipcc/core/gsm/h/lsm.h',
|
||||
'./src/sipcc/core/gsm/h/lsm_private.h',
|
||||
'./src/sipcc/core/gsm/h/sm.h',
|
||||
# CORE INCLUDES
|
||||
'./src/sipcc/core/includes/ccSesion.h',
|
||||
'./src/sipcc/core/includes/ccapi.h',
|
||||
'./src/sipcc/core/includes/check_sync.h',
|
||||
'./src/sipcc/core/includes/ci.h',
|
||||
'./src/sipcc/core/includes/codec_mask.h',
|
||||
'./src/sipcc/core/includes/config.h',
|
||||
'./src/sipcc/core/includes/configapp.h',
|
||||
'./src/sipcc/core/includes/configmgr.h',
|
||||
'./src/sipcc/core/includes/debug.h',
|
||||
'./src/sipcc/core/includes/dialplan.h',
|
||||
'./src/sipcc/core/includes/dialplanint.h',
|
||||
'./src/sipcc/core/includes/digcalc.h',
|
||||
'./src/sipcc/core/includes/dns_utils.h',
|
||||
'./src/sipcc/core/includes/dtmf.h',
|
||||
'./src/sipcc/core/includes/embedded.h',
|
||||
'./src/sipcc/core/includes/fsmdef_states.h',
|
||||
'./src/sipcc/core/includes/intelpentiumtypes.h',
|
||||
'./src/sipcc/core/includes/kpml_common_util.h',
|
||||
'./src/sipcc/core/includes/kpmlmap.h',
|
||||
'./src/sipcc/core/includes/md5.h',
|
||||
'./src/sipcc/core/includes/memory.h',
|
||||
'./src/sipcc/core/includes/misc_apps_task.h',
|
||||
'./src/sipcc/core/includes/misc_util.h',
|
||||
'./src/sipcc/core/includes/phntask.h',
|
||||
'./src/sipcc/core/includes/phone.h',
|
||||
'./src/sipcc/core/includes/phone_debug.h',
|
||||
'./src/sipcc/core/includes/phone_platform_constants.h',
|
||||
'./src/sipcc/core/includes/phone_types.h',
|
||||
'./src/sipcc/core/includes/platform_api.h',
|
||||
'./src/sipcc/core/includes/pres_sub_not_handler.h',
|
||||
'./src/sipcc/core/includes/publish_int.h',
|
||||
'./src/sipcc/core/includes/regexp.h',
|
||||
'./src/sipcc/core/includes/ringlist.h',
|
||||
'./src/sipcc/core/includes/rtp_defs.h',
|
||||
'./src/sipcc/core/includes/session.h',
|
||||
'./src/sipcc/core/includes/sessionConstants.h',
|
||||
'./src/sipcc/core/includes/sessionTypes.h',
|
||||
'./src/sipcc/core/includes/sessuri.h',
|
||||
'./src/sipcc/core/includes/singly_link_list.h',
|
||||
'./src/sipcc/core/includes/sip_socket_api.h',
|
||||
'./src/sipcc/core/includes/sntp.h',
|
||||
'./src/sipcc/core/includes/string_lib.h',
|
||||
'./src/sipcc/core/includes/subapi.h',
|
||||
'./src/sipcc/core/includes/task.h',
|
||||
'./src/sipcc/core/includes/time2.h',
|
||||
'./src/sipcc/core/includes/timer.h',
|
||||
'./src/sipcc/core/includes/tnpphone.h',
|
||||
'./src/sipcc/core/includes/uart.h',
|
||||
'./src/sipcc/core/includes/uiapi.h',
|
||||
'./src/sipcc/core/includes/upgrade.h',
|
||||
'./src/sipcc/core/includes/util_ios_queue.h',
|
||||
'./src/sipcc/core/includes/util_parse.h',
|
||||
'./src/sipcc/core/includes/util_string.h',
|
||||
'./src/sipcc/core/includes/www.h',
|
||||
'./src/sipcc/core/includes/xml_defs.h',
|
||||
# SDP
|
||||
'./src/sipcc/core/sdp/ccsdp.c',
|
||||
'./src/sipcc/core/sdp/sdp_access.c',
|
||||
'./src/sipcc/core/sdp/sdp_attr.c',
|
||||
'./src/sipcc/core/sdp/sdp_attr_access.c',
|
||||
'./src/sipcc/core/sdp/sdp_base64.c',
|
||||
'./src/sipcc/core/sdp/sdp_config.c',
|
||||
'./src/sipcc/core/sdp/sdp_main.c',
|
||||
'./src/sipcc/core/sdp/sdp_token.c',
|
||||
'./src/sipcc/core/sdp/sdp.h',
|
||||
'./src/sipcc/core/sdp/sdp_base64.h',
|
||||
'./src/sipcc/core/sdp/sdp_os_defs.h',
|
||||
'./src/sipcc/core/sdp/sdp_private.h',
|
||||
'./src/sipcc/core/sdp/sdp_utils.c',
|
||||
'./src/sipcc/core/sdp/sdp_services_unix.c',
|
||||
# SIPSTACK
|
||||
'./src/sipcc/core/sipstack/ccsip_callinfo.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_cc.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_common_util.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_core.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_debug.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_info.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_messaging.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_platform.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_platform_tcp.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_platform_timers.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_platform_tls.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_platform_udp.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_pmh.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_publish.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_register.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_reldev.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_sdp.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_spi_utils.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_subsmanager.c',
|
||||
'./src/sipcc/core/sipstack/ccsip_task.c',
|
||||
'./src/sipcc/core/sipstack/httpish.c',
|
||||
'./src/sipcc/core/sipstack/pmhutils.c',
|
||||
'./src/sipcc/core/sipstack/sip_common_regmgr.c',
|
||||
'./src/sipcc/core/sipstack/sip_common_transport.c',
|
||||
'./src/sipcc/core/sipstack/sip_csps_transport.c',
|
||||
'./src/sipcc/core/sipstack/sip_interface_regmgr.c',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_callinfo.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_cc.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_common_cb.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_core.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_credentials.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_macros.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_messaging.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_platform.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_platform_tcp.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_platform_timers.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_platform_tls.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_platform_udp.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_pmh.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_protocol.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_publish.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_register.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_reldev.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_sdp.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_sim.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_spi_utils.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_subsmanager.h',
|
||||
'./src/sipcc/core/sipstack/h/ccsip_task.h',
|
||||
'./src/sipcc/core/sipstack/h/httpish.h',
|
||||
'./src/sipcc/core/sipstack/h/httpish_protocol.h',
|
||||
'./src/sipcc/core/sipstack/h/pmhdefs.h',
|
||||
'./src/sipcc/core/sipstack/h/pmhutils.h',
|
||||
'./src/sipcc/core/sipstack/h/regmgrapi.h',
|
||||
'./src/sipcc/core/sipstack/h/sip_ccm_transport.h',
|
||||
'./src/sipcc/core/sipstack/h/sip_common_regmgr.h',
|
||||
'./src/sipcc/core/sipstack/h/sip_common_transport.h',
|
||||
'./src/sipcc/core/sipstack/h/sip_csps_transport.h',
|
||||
'./src/sipcc/core/sipstack/h/sip_interface_regmgr.h',
|
||||
'./src/sipcc/core/sipstack/h/sip_platform_task.h',
|
||||
# SRC-COMMON
|
||||
'./src/sipcc/core/src-common/configapp.c',
|
||||
'./src/sipcc/core/src-common/dialplan.c',
|
||||
'./src/sipcc/core/src-common/dialplanint.c',
|
||||
'./src/sipcc/core/src-common/digcalc.c',
|
||||
'./src/sipcc/core/src-common/kpml_common_util.c',
|
||||
'./src/sipcc/core/src-common/kpmlmap.c',
|
||||
'./src/sipcc/core/src-common/md5.c',
|
||||
'./src/sipcc/core/src-common/misc_apps_task.c',
|
||||
'./src/sipcc/core/src-common/pres_sub_not_handler.c',
|
||||
'./src/sipcc/core/src-common/publish_int.c',
|
||||
'./src/sipcc/core/src-common/singly_link_list.c',
|
||||
'./src/sipcc/core/src-common/sll_lite.c',
|
||||
'./src/sipcc/core/src-common/string_lib.c',
|
||||
'./src/sipcc/core/src-common/util_ios_queue.c',
|
||||
'./src/sipcc/core/src-common/util_parse.c',
|
||||
'./src/sipcc/core/src-common/util_string.c',
|
||||
# CPR
|
||||
'./src/sipcc/cpr/include/cpr.h',
|
||||
'./src/sipcc/cpr/include/cpr_assert.h',
|
||||
'./src/sipcc/cpr/include/cpr_debug.h',
|
||||
'./src/sipcc/cpr/include/cpr_errno.h',
|
||||
'./src/sipcc/cpr/include/cpr_in.h',
|
||||
'./src/sipcc/cpr/include/cpr_ipc.h',
|
||||
'./src/sipcc/cpr/include/cpr_locks.h',
|
||||
'./src/sipcc/cpr/include/cpr_memory.h',
|
||||
'./src/sipcc/cpr/include/cpr_rand.h',
|
||||
'./src/sipcc/cpr/include/cpr_socket.h',
|
||||
'./src/sipcc/cpr/include/cpr_stddef.h',
|
||||
'./src/sipcc/cpr/include/cpr_stdio.h',
|
||||
'./src/sipcc/cpr/include/cpr_stdlib.h',
|
||||
'./src/sipcc/cpr/include/cpr_string.h',
|
||||
'./src/sipcc/cpr/include/cpr_strings.h',
|
||||
'./src/sipcc/cpr/include/cpr_threads.h',
|
||||
'./src/sipcc/cpr/include/cpr_time.h',
|
||||
'./src/sipcc/cpr/include/cpr_timers.h',
|
||||
'./src/sipcc/cpr/include/cpr_types.h',
|
||||
'./src/sipcc/cpr/common/cpr_ipc.c',
|
||||
'./src/sipcc/cpr/common/cpr_string.c',
|
||||
# INCLUDE
|
||||
'./src/sipcc/include/cc_blf.h',
|
||||
'./src/sipcc/include/cc_blf_listener.h',
|
||||
'./src/sipcc/include/cc_call_feature.h',
|
||||
'./src/sipcc/include/cc_call_listener.h',
|
||||
'./src/sipcc/include/cc_config.h',
|
||||
'./src/sipcc/include/cc_constants.h',
|
||||
'./src/sipcc/include/cc_debug.h',
|
||||
'./src/sipcc/include/cc_device_feature.h',
|
||||
'./src/sipcc/include/cc_device_listener.h',
|
||||
'./src/sipcc/include/cc_info.h',
|
||||
'./src/sipcc/include/cc_info_listener.h',
|
||||
'./src/sipcc/include/cc_service.h',
|
||||
'./src/sipcc/include/cc_service_listener.h',
|
||||
'./src/sipcc/include/cc_types.h',
|
||||
'./src/sipcc/include/ccapi_call.h',
|
||||
'./src/sipcc/include/ccapi_call_info.h',
|
||||
'./src/sipcc/include/ccapi_call_listener.h',
|
||||
'./src/sipcc/include/ccapi_calllog.h',
|
||||
'./src/sipcc/include/ccapi_conf_roster.h',
|
||||
'./src/sipcc/include/ccapi_device.h',
|
||||
'./src/sipcc/include/ccapi_device_info.h',
|
||||
'./src/sipcc/include/ccapi_device_listener.h',
|
||||
'./src/sipcc/include/ccapi_feature_info.h',
|
||||
'./src/sipcc/include/ccapi_line.h',
|
||||
'./src/sipcc/include/ccapi_line_info.h',
|
||||
'./src/sipcc/include/ccapi_line_listener.h',
|
||||
'./src/sipcc/include/ccapi_service.h',
|
||||
'./src/sipcc/include/ccapi_types.h',
|
||||
'./src/sipcc/include/ccsdp.h',
|
||||
'./src/sipcc/include/ccsdp_rtcp_fb.h',
|
||||
'./src/sipcc/include/config_api.h',
|
||||
'./src/sipcc/include/dns_util.h',
|
||||
'./src/sipcc/include/plat_api.h',
|
||||
'./src/sipcc/include/reset_api.h',
|
||||
'./src/sipcc/include/sll_lite.h',
|
||||
'./src/sipcc/include/vcm.h',
|
||||
'./src/sipcc/include/xml_parser_defines.h',
|
||||
|
||||
# PLAT
|
||||
'./src/sipcc/plat/csf2g/model.c',
|
||||
'./src/sipcc/plat/csf2g/reset_api.c',
|
||||
#
|
||||
# './src/sipcc/plat/common/plat_debug.h',
|
||||
# './src/sipcc/plat/common/tnp_blf.h',
|
||||
|
||||
# STUB
|
||||
#'./src/sipcc/stub/cc_blf_stub.c',
|
||||
#'./src/sipcc/stub/vcm_stub.c',
|
||||
|
||||
],
|
||||
|
||||
#
|
||||
# DEFINES
|
||||
#
|
||||
|
||||
'defines' : [
|
||||
# CPR timers are needed by SIP, but are disabled for now
|
||||
# to avoid the extra timer thread and stale cleanup code
|
||||
# 'CPR_TIMERS_ENABLED',
|
||||
],
|
||||
|
||||
'cflags_mozilla': [
|
||||
'$(NSPR_CFLAGS)',
|
||||
],
|
||||
|
||||
#
|
||||
# OS SPECIFIC
|
||||
#
|
||||
'conditions': [
|
||||
['(OS=="android") or (OS=="linux")', {
|
||||
'include_dirs': [
|
||||
],
|
||||
|
||||
'defines' : [
|
||||
'SIP_OS_LINUX',
|
||||
'_GNU_SOURCE',
|
||||
'CPR_MEMORY_LITTLE_ENDIAN',
|
||||
'NO_SOCKET_POLLING',
|
||||
'USE_TIMER_SELECT_BASED',
|
||||
'FULL_BUILD',
|
||||
'STUBBED_OUT',
|
||||
'USE_PRINTF'
|
||||
'LINUX',
|
||||
],
|
||||
|
||||
'cflags_mozilla': [
|
||||
],
|
||||
}],
|
||||
['OS=="android"', {
|
||||
'sources': [
|
||||
# SIPSTACK
|
||||
'./src/sipcc/core/sipstack/sip_platform_task.c',
|
||||
|
||||
# PLAT
|
||||
'./src/sipcc/plat/common/dns_utils.c',
|
||||
|
||||
# CPR
|
||||
'./src/sipcc/cpr/android/cpr_android_errno.c',
|
||||
'./src/sipcc/cpr/android/cpr_android_init.c',
|
||||
'./src/sipcc/cpr/android/cpr_android_socket.c',
|
||||
'./src/sipcc/cpr/android/cpr_android_stdio.c',
|
||||
'./src/sipcc/cpr/android/cpr_android_string.c',
|
||||
'./src/sipcc/cpr/android/cpr_android_threads.c',
|
||||
'./src/sipcc/cpr/android/cpr_android_timers_using_select.c',
|
||||
|
||||
'./src/sipcc/cpr/android/cpr_assert.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_align.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_assert.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_errno.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_in.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_private.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_rand.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_socket.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_stdio.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_string.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_strings.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_time.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_timers.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_tst.h',
|
||||
'./src/sipcc/cpr/android/cpr_android_types.h',
|
||||
],
|
||||
}],
|
||||
['OS=="linux"', {
|
||||
'sources': [
|
||||
# SIPSTACK
|
||||
'./src/sipcc/core/sipstack/sip_platform_task.c',
|
||||
|
||||
# PLAT
|
||||
'./src/sipcc/plat/common/dns_utils.c',
|
||||
|
||||
# CPR
|
||||
'./src/sipcc/cpr/linux/cpr_linux_errno.c',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_init.c',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_socket.c',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_stdio.c',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_string.c',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_threads.c',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_timers_using_select.c',
|
||||
|
||||
'./src/sipcc/cpr/linux/cpr_assert.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_align.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_assert.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_errno.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_in.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_private.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_rand.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_socket.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_stdio.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_string.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_strings.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_time.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_timers.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_tst.h',
|
||||
'./src/sipcc/cpr/linux/cpr_linux_types.h',
|
||||
|
||||
],
|
||||
}],
|
||||
['OS=="win"', {
|
||||
'include_dirs': [
|
||||
],
|
||||
|
||||
'sources': [
|
||||
# SIPSTACK
|
||||
'./src/sipcc/core/sipstack/sip_platform_win32_task.c',
|
||||
|
||||
# PLAT
|
||||
'./src/sipcc/plat/win32/dns_utils.c',
|
||||
'./src/sipcc/plat/win32/mystub.c',
|
||||
'./src/sipcc/plat/win32/plat_api_stub.c',
|
||||
'./src/sipcc/plat/win32/plat_api_win.c',
|
||||
'./src/sipcc/plat/win32/StdAfx.h',
|
||||
|
||||
# CPR
|
||||
'./src/sipcc/cpr/win32/cpr_win_assert.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_debug.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_debug.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_defines.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_errno.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_errno.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_in.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_init.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_locks.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_locks.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_rand.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_rand.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_socket.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_socket.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_stdio.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_stdio.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_string.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_string.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_strings.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_threads.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_time.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_timers.c',
|
||||
'./src/sipcc/cpr/win32/cpr_win_timers.h',
|
||||
'./src/sipcc/cpr/win32/cpr_win_types.h',
|
||||
|
||||
],
|
||||
|
||||
'defines' : [
|
||||
'SIP_OS_WINDOWS',
|
||||
'WIN32',
|
||||
'SIPCC_BUILD',
|
||||
'SDP_WIN32',
|
||||
'STUBBED_OUT',
|
||||
'EXTERNAL_TICK_REQUIRED',
|
||||
'GIPS_VER=3480',
|
||||
],
|
||||
|
||||
'cflags_mozilla': [
|
||||
],
|
||||
|
||||
}],
|
||||
['OS=="mac" or os_bsd==1', {
|
||||
|
||||
'include_dirs': [
|
||||
],
|
||||
|
||||
'sources': [
|
||||
# SIPSTACK
|
||||
'./src/sipcc/core/sipstack/sip_platform_task.c',
|
||||
|
||||
# PLAT
|
||||
'./src/sipcc/plat/common/dns_utils.c',
|
||||
#'./src/sipcc/plat/darwin/netif.c',
|
||||
'./src/sipcc/plat/darwin/plat_api_stub.c',
|
||||
#'./src/sipcc/plat/unix-common/random.c',
|
||||
|
||||
# CPR
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_assert.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_errno.c',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_errno.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_in.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_init.c',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_private.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_rand.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_socket.c',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_socket.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_stdio.c',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_stdio.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_string.c',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_string.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_strings.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_threads.c',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_time.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_timers.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_timers_using_select.c',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_tst.h',
|
||||
'./src/sipcc/cpr/darwin/cpr_darwin_types.h',
|
||||
],
|
||||
|
||||
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'defines' : [
|
||||
'SIP_OS_OSX',
|
||||
'_POSIX_SOURCE',
|
||||
'CPR_MEMORY_LITTLE_ENDIAN',
|
||||
'NO_SOCKET_POLLING',
|
||||
'USE_TIMER_SELECT_BASED',
|
||||
'FULL_BUILD',
|
||||
'STUBBED_OUT',
|
||||
'USE_PRINTF',
|
||||
'_DARWIN_C_SOURCE',
|
||||
'NO_NSPR_10_SUPPORT',
|
||||
],
|
||||
}],
|
||||
['os_bsd==1', {
|
||||
'defines' : [
|
||||
'SIP_OS_OSX',
|
||||
'CPR_MEMORY_LITTLE_ENDIAN',
|
||||
'NO_SOCKET_POLLING',
|
||||
'USE_TIMER_SELECT_BASED',
|
||||
'FULL_BUILD',
|
||||
'STUBBED_OUT',
|
||||
'USE_PRINTF',
|
||||
'NO_NSPR_10_SUPPORT',
|
||||
],
|
||||
}],
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
],
|
||||
}],
|
||||
],
|
||||
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CC_CallTypes.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
namespace CC_CallCapabilityEnum
|
||||
{
|
||||
|
||||
std::string toString(CC_CallCapability cap)
|
||||
{
|
||||
switch(cap)
|
||||
{
|
||||
case canSetRemoteWindow:
|
||||
return "canSetRemoteWindow";
|
||||
case canSetLocalWindow:
|
||||
return "canSetLocalWindow";
|
||||
case canSendIFrame:
|
||||
return "canSendIFrame";
|
||||
case canOriginateCall:
|
||||
return "canOriginateCall";
|
||||
case canAnswerCall:
|
||||
return "canAnswerCall";
|
||||
case canHold:
|
||||
return "canHold";
|
||||
case canResume:
|
||||
return "canResume";
|
||||
case canEndCall:
|
||||
return "canEndCall";
|
||||
case canSendDigit:
|
||||
return "canSendDigit";
|
||||
case canBackspace:
|
||||
return "canBackspace";
|
||||
case canRedial:
|
||||
return "canRedial";
|
||||
case canInitiateCallForwardAll:
|
||||
return "canInitiateCallForwardAll";
|
||||
case canEndConsultativeCall:
|
||||
return "canEndConsultativeCall";
|
||||
case canConferenceStart:
|
||||
return "canConferenceStart";
|
||||
case canConferenceComplete:
|
||||
return "canConferenceComplete";
|
||||
case canTransferStart:
|
||||
return "canTransferStart";
|
||||
case canTransferComplete:
|
||||
return "canTransferComplete";
|
||||
case canCancelTransferOrConferenceFeature:
|
||||
return "canCancelTransferOrConferenceFeature";
|
||||
case canDirectTransfer:
|
||||
return "canDirectTransfer";
|
||||
case canJoinAcrossLine:
|
||||
return "canJoinAcrossLine";
|
||||
case canBlfCallPickup:
|
||||
return "canBlfCallPickup";
|
||||
case canSelect:
|
||||
return "canSelect";
|
||||
case canUpdateVideoMediaCap:
|
||||
return "canUpdateVideoMediaCap";
|
||||
case canSendInfo:
|
||||
return "canSendInfo";
|
||||
case canMuteAudio:
|
||||
return "canMuteAudio";
|
||||
case canUnmuteAudio:
|
||||
return "canUnmuteAudio";
|
||||
case canMuteVideo:
|
||||
return "canMuteVideo";
|
||||
case canUnmuteVideo:
|
||||
return "canUnmuteVideo";
|
||||
case canSetVolume:
|
||||
return "canSetVolume";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string toString(std::set<CC_CallCapability>& caps)
|
||||
{
|
||||
string result;
|
||||
for(std::set<CC_CallCapability>::iterator it = caps.begin(); it != caps.end(); it++)
|
||||
{
|
||||
if(!result.empty())
|
||||
result += ",";
|
||||
result += toString(*it);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CallControlManager.h"
|
||||
#include "CallControlManagerImpl.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
CallControlManagerPtr CallControlManager::create()
|
||||
{
|
||||
CallControlManagerPtr instance(new CallControlManagerImpl());
|
||||
return instance;
|
||||
}
|
||||
|
||||
CallControlManager::~CallControlManager()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,537 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
#include <prcvar.h>
|
||||
#include <prlock.h>
|
||||
|
||||
#include "CSFLog.h"
|
||||
|
||||
#include "CC_SIPCCDevice.h"
|
||||
#include "CC_SIPCCDeviceInfo.h"
|
||||
#include "CC_SIPCCFeatureInfo.h"
|
||||
#include "CC_SIPCCLine.h"
|
||||
#include "CC_SIPCCLineInfo.h"
|
||||
#include "CC_SIPCCCallInfo.h"
|
||||
#include "CallControlManagerImpl.h"
|
||||
#include "csf_common.h"
|
||||
|
||||
#include "base/platform_thread.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "config_api.h"
|
||||
}
|
||||
|
||||
|
||||
static const char logTag[] = "CallControlManager";
|
||||
|
||||
using namespace std;
|
||||
using namespace CSFUnified;
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
|
||||
|
||||
CallControlManagerImpl::CallControlManagerImpl()
|
||||
: m_lock("CallControlManagerImpl"),
|
||||
multiClusterMode(false),
|
||||
sipccLoggingMask(0xFFFFFFFF),
|
||||
authenticationStatus(AuthenticationStatusEnum::eNotAuthenticated),
|
||||
connectionState(ConnectionStatusEnum::eIdle)
|
||||
{
|
||||
CSFLogInfo(logTag, "CallControlManagerImpl()");
|
||||
}
|
||||
|
||||
CallControlManagerImpl::~CallControlManagerImpl()
|
||||
{
|
||||
CSFLogInfo(logTag, "~CallControlManagerImpl()");
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool CallControlManagerImpl::destroy()
|
||||
{
|
||||
CSFLogInfo(logTag, "destroy()");
|
||||
bool retval = disconnect();
|
||||
if(retval == false)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Observers
|
||||
void CallControlManagerImpl::addCCObserver ( CC_Observer * observer )
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
if (observer == nullptr)
|
||||
{
|
||||
CSFLogError(logTag, "NULL value for \"observer\" passed to addCCObserver().");
|
||||
return;
|
||||
}
|
||||
|
||||
ccObservers.insert(observer);
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::removeCCObserver ( CC_Observer * observer )
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
ccObservers.erase(observer);
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::addECCObserver ( ECC_Observer * observer )
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
if (observer == nullptr)
|
||||
{
|
||||
CSFLogError(logTag, "NULL value for \"observer\" passed to addECCObserver().");
|
||||
return;
|
||||
}
|
||||
|
||||
eccObservers.insert(observer);
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::removeECCObserver ( ECC_Observer * observer )
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
eccObservers.erase(observer);
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::setMultiClusterMode(bool allowMultipleClusters)
|
||||
{
|
||||
CSFLogInfo(logTag, "setMultiClusterMode(%s)",
|
||||
allowMultipleClusters ? "TRUE" : "FALSE");
|
||||
multiClusterMode = allowMultipleClusters;
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::setSIPCCLoggingMask(const cc_int32_t mask)
|
||||
{
|
||||
CSFLogInfo(logTag, "setSIPCCLoggingMask(%u)", mask);
|
||||
sipccLoggingMask = mask;
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::setAuthenticationString(const std::string &authString)
|
||||
{
|
||||
CSFLogInfo(logTag, "setAuthenticationString()");
|
||||
this->authString = authString;
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::setSecureCachePath(const std::string &secureCachePath)
|
||||
{
|
||||
CSFLogInfo(logTag, "setSecureCachePath(%s)", secureCachePath.c_str());
|
||||
this->secureCachePath = secureCachePath;
|
||||
}
|
||||
|
||||
// Add local codecs
|
||||
void CallControlManagerImpl::setAudioCodecs(int codecMask)
|
||||
{
|
||||
CSFLogDebug(logTag, "setAudioCodecs %X", codecMask);
|
||||
|
||||
VcmSIPCCBinding::setAudioCodecs(codecMask);
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::setVideoCodecs(int codecMask)
|
||||
{
|
||||
CSFLogDebug(logTag, "setVideoCodecs %X", codecMask);
|
||||
|
||||
VcmSIPCCBinding::setVideoCodecs(codecMask);
|
||||
}
|
||||
|
||||
AuthenticationStatusEnum::AuthenticationStatus CallControlManagerImpl::getAuthenticationStatus()
|
||||
{
|
||||
return authenticationStatus;
|
||||
}
|
||||
|
||||
bool CallControlManagerImpl::registerUser( const std::string& deviceName, const std::string& user, const std::string& password, const std::string& domain )
|
||||
{
|
||||
setConnectionState(ConnectionStatusEnum::eRegistering);
|
||||
|
||||
CSFLogInfo(logTag, "registerUser(%s, %s )", user.c_str(), domain.c_str());
|
||||
if(phone != nullptr)
|
||||
{
|
||||
setConnectionState(ConnectionStatusEnum::eReady);
|
||||
|
||||
CSFLogError(logTag, "registerUser() failed - already connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
softPhone = CC_SIPCCServicePtr(new CC_SIPCCService());
|
||||
phone = softPhone;
|
||||
phone->init(user, password, domain, deviceName);
|
||||
softPhone->setLoggingMask(sipccLoggingMask);
|
||||
phone->addCCObserver(this);
|
||||
|
||||
phone->setP2PMode(false);
|
||||
|
||||
bool bStarted = phone->startService();
|
||||
if (!bStarted) {
|
||||
setConnectionState(ConnectionStatusEnum::eFailed);
|
||||
} else {
|
||||
setConnectionState(ConnectionStatusEnum::eReady);
|
||||
}
|
||||
|
||||
return bStarted;
|
||||
}
|
||||
|
||||
bool CallControlManagerImpl::startP2PMode(const std::string& user)
|
||||
{
|
||||
setConnectionState(ConnectionStatusEnum::eRegistering);
|
||||
|
||||
CSFLogInfo(logTag, "startP2PMode(%s)", user.c_str());
|
||||
if(phone != nullptr)
|
||||
{
|
||||
setConnectionState(ConnectionStatusEnum::eReady);
|
||||
|
||||
CSFLogError(logTag, "startP2PMode() failed - already started in p2p mode!");
|
||||
return false;
|
||||
}
|
||||
|
||||
softPhone = CC_SIPCCServicePtr(new CC_SIPCCService());
|
||||
phone = softPhone;
|
||||
phone->init(user, "", "127.0.0.1", "sipdevice");
|
||||
softPhone->setLoggingMask(sipccLoggingMask);
|
||||
phone->addCCObserver(this);
|
||||
|
||||
phone->setP2PMode(true);
|
||||
|
||||
bool bStarted = phone->startService();
|
||||
if (!bStarted) {
|
||||
setConnectionState(ConnectionStatusEnum::eFailed);
|
||||
} else {
|
||||
setConnectionState(ConnectionStatusEnum::eReady);
|
||||
}
|
||||
|
||||
return bStarted;
|
||||
}
|
||||
|
||||
bool CallControlManagerImpl::startSDPMode()
|
||||
{
|
||||
CSFLogInfo(logTag, "startSDPMode");
|
||||
if(phone != nullptr)
|
||||
{
|
||||
CSFLogError(logTag, "%s failed - already started in SDP mode!",__FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
softPhone = CC_SIPCCServicePtr(new CC_SIPCCService());
|
||||
phone = softPhone;
|
||||
phone->init("JSEP", "", "127.0.0.1", "sipdevice");
|
||||
softPhone->setLoggingMask(sipccLoggingMask);
|
||||
phone->addCCObserver(this);
|
||||
phone->setSDPMode(true);
|
||||
|
||||
return phone->startService();
|
||||
}
|
||||
|
||||
bool CallControlManagerImpl::disconnect()
|
||||
{
|
||||
CSFLogInfo(logTag, "disconnect()");
|
||||
if(phone == nullptr)
|
||||
return true;
|
||||
|
||||
connectionState = ConnectionStatusEnum::eIdle;
|
||||
phone->removeCCObserver(this);
|
||||
phone->stop();
|
||||
phone->destroy();
|
||||
phone = nullptr;
|
||||
softPhone = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CallControlManagerImpl::getPreferredDeviceName()
|
||||
{
|
||||
return preferredDevice;
|
||||
}
|
||||
|
||||
std::string CallControlManagerImpl::getPreferredLineDN()
|
||||
{
|
||||
return preferredLineDN;
|
||||
}
|
||||
|
||||
ConnectionStatusEnum::ConnectionStatus CallControlManagerImpl::getConnectionStatus()
|
||||
{
|
||||
return connectionState;
|
||||
}
|
||||
|
||||
std::string CallControlManagerImpl::getCurrentServer()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Currently controlled device
|
||||
CC_DevicePtr CallControlManagerImpl::getActiveDevice()
|
||||
{
|
||||
if(phone != nullptr)
|
||||
return phone->getActiveDevice();
|
||||
|
||||
return CC_DevicePtr();
|
||||
}
|
||||
|
||||
// All known devices
|
||||
PhoneDetailsVtrPtr CallControlManagerImpl::getAvailablePhoneDetails()
|
||||
{
|
||||
PhoneDetailsVtrPtr result = PhoneDetailsVtrPtr(new PhoneDetailsVtr());
|
||||
for(PhoneDetailsMap::iterator it = phoneDetailsMap.begin(); it != phoneDetailsMap.end(); it++)
|
||||
{
|
||||
PhoneDetailsPtr details = it->second.get();
|
||||
result->push_back(details);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
PhoneDetailsPtr CallControlManagerImpl::getAvailablePhoneDetails(const std::string& deviceName)
|
||||
{
|
||||
PhoneDetailsMap::iterator it = phoneDetailsMap.find(deviceName);
|
||||
if(it != phoneDetailsMap.end())
|
||||
{
|
||||
return it->second.get();
|
||||
}
|
||||
return PhoneDetailsPtr();
|
||||
}
|
||||
// Media setup
|
||||
VideoControlPtr CallControlManagerImpl::getVideoControl()
|
||||
{
|
||||
if(phone != nullptr)
|
||||
return phone->getVideoControl();
|
||||
|
||||
return VideoControlPtr();
|
||||
}
|
||||
|
||||
AudioControlPtr CallControlManagerImpl::getAudioControl()
|
||||
{
|
||||
if(phone != nullptr)
|
||||
return phone->getAudioControl();
|
||||
|
||||
return AudioControlPtr();
|
||||
}
|
||||
|
||||
bool CallControlManagerImpl::setProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key, std::string& value)
|
||||
{
|
||||
unsigned long strtoul_result;
|
||||
char *strtoul_end;
|
||||
|
||||
CSFLogInfo(logTag, "setProperty( %s )", value.c_str());
|
||||
|
||||
if (key == ConfigPropertyKeysEnum::eLocalVoipPort) {
|
||||
errno = 0;
|
||||
strtoul_result = strtoul(value.c_str(), &strtoul_end, 10);
|
||||
|
||||
if (errno || value.c_str() == strtoul_end || strtoul_result > USHRT_MAX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CCAPI_Config_set_local_voip_port((int) strtoul_result);
|
||||
} else if (key == ConfigPropertyKeysEnum::eRemoteVoipPort) {
|
||||
errno = 0;
|
||||
strtoul_result = strtoul(value.c_str(), &strtoul_end, 10);
|
||||
|
||||
if (errno || value.c_str() == strtoul_end || strtoul_result > USHRT_MAX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CCAPI_Config_set_remote_voip_port((int) strtoul_result);
|
||||
} else if (key == ConfigPropertyKeysEnum::eTransport) {
|
||||
if (value == "tcp")
|
||||
CCAPI_Config_set_transport_udp(false);
|
||||
else
|
||||
CCAPI_Config_set_transport_udp(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CallControlManagerImpl::getProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key)
|
||||
{
|
||||
std::string retValue = "NONESET";
|
||||
char tmpString[11];
|
||||
|
||||
CSFLogInfo(logTag, "getProperty()");
|
||||
|
||||
if (key == ConfigPropertyKeysEnum::eLocalVoipPort) {
|
||||
csf_sprintf(tmpString, sizeof(tmpString), "%u", CCAPI_Config_get_local_voip_port());
|
||||
retValue = tmpString;
|
||||
} else if (key == ConfigPropertyKeysEnum::eRemoteVoipPort) {
|
||||
csf_sprintf(tmpString, sizeof(tmpString), "%u", CCAPI_Config_get_remote_voip_port());
|
||||
retValue = tmpString;
|
||||
} else if (key == ConfigPropertyKeysEnum::eVersion) {
|
||||
const char* version = CCAPI_Config_get_version();
|
||||
retValue = version;
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
/*
|
||||
There are a number of factors that determine PhoneAvailabilityType::PhoneAvailability. The supported states for this enum are:
|
||||
{ eUnknown, eAvailable, eUnAvailable, eNotAllowed }. eUnknown is the default value, which is set when there is no information
|
||||
available that would otherwise determine the availability value. The factors that can influence PhoneAvailability are:
|
||||
phone mode, and for a given device (described by DeviceInfo) the model, and the name of the device. For phone control mode, the
|
||||
device registration and whether CUCM says the device is CTI controllable (or not) is a factor.
|
||||
|
||||
For Phone Control mode the state machine is:
|
||||
|
||||
is blacklisted model name? -> Yes -> NOT_ALLOWED
|
||||
(see Note1 below)
|
||||
||
|
||||
\/
|
||||
No
|
||||
||
|
||||
\/
|
||||
is CTI Controllable?
|
||||
(determined from CUCM) -> No -> NOT_ALLOWED
|
||||
||
|
||||
\/
|
||||
Yes
|
||||
||
|
||||
\/
|
||||
Can we tell if it's registered? -> No -> ?????? TODO: Seems to depends on other factors (look at suggestedAvailability parameter
|
||||
|| in DeviceSubProviderImpl.addOrUpdateDevice() in CSF1G Java code.
|
||||
\/
|
||||
Yes
|
||||
||
|
||||
\/
|
||||
is Registered?
|
||||
(determined from CUCM) -> No -> NOT_AVAILABLE
|
||||
||
|
||||
\/
|
||||
Yes
|
||||
||
|
||||
\/
|
||||
AVAILABLE
|
||||
|
||||
========
|
||||
|
||||
For Softphone mode the state machine is:
|
||||
|
||||
is device excluded?
|
||||
(based on "ExcludedDevices" -> Yes -> NOT_ALLOWED
|
||||
config settings
|
||||
(see Note2 below))
|
||||
||
|
||||
\/
|
||||
No
|
||||
||
|
||||
\/
|
||||
isSoftphone?
|
||||
|
||||
|
||||
|
||||
Note1: model name has to match completely, ie it's not a sub-string match, but we are ignoring case. So, if the blacklist
|
||||
contains a string "Cisco Unified Personal Communicator" then the model has to match this completely (but can be a
|
||||
different case) to be a match. In CSF1G the blacklist is hard-wired to:
|
||||
{ "Cisco Unified Personal Communicator",
|
||||
"Cisco Unified Client Services Framework",
|
||||
"Client Services Framework",
|
||||
"Client Services Core" }
|
||||
|
||||
Note2: The "ExcludedDevices" is a comma-separated list of device name prefixes (not model name). Unlike the above, this is
|
||||
a sub-string match, but only a "starts with" sub-string match, not anywhere in the string. If the device name
|
||||
is a complete match then this is also excluded, ie doesn't have to be a sub-string. For example, if the
|
||||
ExcludeDevices list contains { "ECP", "UPC" } then assuming we're in softphone mode, then any device whose
|
||||
name starts with the strings ECP or UPC, or whose complete name is either of these will be deemed to be excluded
|
||||
and will be marked as NOT_ALLOWED straightaway. In Phone Control mode the "ExcludedDevices" list i not taken into
|
||||
account at all in the determination of availability.
|
||||
|
||||
Note3: isSoftphone() function
|
||||
|
||||
The config service provides a list of "blacklisted" device name prefixes, that is, if the name of the device starts with a
|
||||
sub-string that matches an entry in the blacklist, then it is straightaway removed from the list? marked as NOT_ALLOWED.
|
||||
*/
|
||||
|
||||
// CC_Observers
|
||||
void CallControlManagerImpl::onDeviceEvent(ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info)
|
||||
{
|
||||
notifyDeviceEventObservers(deviceEvent, devicePtr, info);
|
||||
}
|
||||
void CallControlManagerImpl::onFeatureEvent(ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info)
|
||||
{
|
||||
notifyFeatureEventObservers(deviceEvent, devicePtr, info);
|
||||
}
|
||||
void CallControlManagerImpl::onLineEvent(ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info)
|
||||
{
|
||||
notifyLineEventObservers(lineEvent, linePtr, info);
|
||||
}
|
||||
void CallControlManagerImpl::onCallEvent(ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info)
|
||||
{
|
||||
notifyCallEventObservers(callEvent, callPtr, info);
|
||||
}
|
||||
|
||||
|
||||
void CallControlManagerImpl::notifyDeviceEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
set<CC_Observer*>::const_iterator it = ccObservers.begin();
|
||||
for ( ; it != ccObservers.end(); it++ )
|
||||
{
|
||||
(*it)->onDeviceEvent(deviceEvent, devicePtr, info);
|
||||
}
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::notifyFeatureEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
set<CC_Observer*>::const_iterator it = ccObservers.begin();
|
||||
for ( ; it != ccObservers.end(); it++ )
|
||||
{
|
||||
(*it)->onFeatureEvent(deviceEvent, devicePtr, info);
|
||||
}
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::notifyLineEventObservers (ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
set<CC_Observer*>::const_iterator it = ccObservers.begin();
|
||||
for ( ; it != ccObservers.end(); it++ )
|
||||
{
|
||||
(*it)->onLineEvent(lineEvent, linePtr, info);
|
||||
}
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::notifyCallEventObservers (ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
set<CC_Observer*>::const_iterator it = ccObservers.begin();
|
||||
for ( ; it != ccObservers.end(); it++ )
|
||||
{
|
||||
(*it)->onCallEvent(callEvent, callPtr, info);
|
||||
}
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::notifyAvailablePhoneEvent (AvailablePhoneEventType::AvailablePhoneEvent event,
|
||||
const PhoneDetailsPtr availablePhoneDetails)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
set<ECC_Observer*>::const_iterator it = eccObservers.begin();
|
||||
for ( ; it != eccObservers.end(); it++ )
|
||||
{
|
||||
(*it)->onAvailablePhoneEvent(event, availablePhoneDetails);
|
||||
}
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::notifyAuthenticationStatusChange (AuthenticationStatusEnum::AuthenticationStatus status)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
set<ECC_Observer*>::const_iterator it = eccObservers.begin();
|
||||
for ( ; it != eccObservers.end(); it++ )
|
||||
{
|
||||
(*it)->onAuthenticationStatusChange(status);
|
||||
}
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::notifyConnectionStatusChange(ConnectionStatusEnum::ConnectionStatus status)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(m_lock);
|
||||
set<ECC_Observer*>::const_iterator it = eccObservers.begin();
|
||||
for ( ; it != eccObservers.end(); it++ )
|
||||
{
|
||||
(*it)->onConnectionStatusChange(status);
|
||||
}
|
||||
}
|
||||
|
||||
void CallControlManagerImpl::setConnectionState(ConnectionStatusEnum::ConnectionStatus status)
|
||||
{
|
||||
connectionState = status;
|
||||
notifyConnectionStatusChange(status);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CallControlManager.h"
|
||||
#include "PhoneDetailsImpl.h"
|
||||
#include "CC_SIPCCService.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class CallControlManagerImpl: public CallControlManager, public CC_Observer
|
||||
{
|
||||
public:
|
||||
CallControlManagerImpl();
|
||||
virtual bool destroy();
|
||||
virtual ~CallControlManagerImpl();
|
||||
|
||||
// Observers
|
||||
virtual void addCCObserver ( CC_Observer * observer );
|
||||
virtual void removeCCObserver ( CC_Observer * observer );
|
||||
|
||||
virtual void addECCObserver ( ECC_Observer * observer );
|
||||
virtual void removeECCObserver ( ECC_Observer * observer );
|
||||
|
||||
// Config and global setup
|
||||
virtual void setMultiClusterMode(bool allowMultipleClusters);
|
||||
virtual void setSIPCCLoggingMask(const cc_int32_t mask);
|
||||
virtual void setAuthenticationString(const std::string &authString);
|
||||
virtual void setSecureCachePath(const std::string &secureCachePath);
|
||||
|
||||
// Add local codecs
|
||||
virtual void setAudioCodecs(int codecMask);
|
||||
virtual void setVideoCodecs(int codecMask);
|
||||
|
||||
virtual AuthenticationStatusEnum::AuthenticationStatus getAuthenticationStatus();
|
||||
|
||||
virtual bool registerUser( const std::string& deviceName, const std::string& user, const std::string& password, const std::string& domain );
|
||||
|
||||
virtual bool startP2PMode(const std::string& user);
|
||||
|
||||
virtual bool startSDPMode();
|
||||
|
||||
virtual bool disconnect();
|
||||
virtual std::string getPreferredDeviceName();
|
||||
virtual std::string getPreferredLineDN();
|
||||
virtual ConnectionStatusEnum::ConnectionStatus getConnectionStatus();
|
||||
virtual std::string getCurrentServer();
|
||||
|
||||
// Currently controlled device
|
||||
virtual CC_DevicePtr getActiveDevice();
|
||||
|
||||
// All known devices
|
||||
virtual PhoneDetailsVtrPtr getAvailablePhoneDetails();
|
||||
virtual PhoneDetailsPtr getAvailablePhoneDetails(const std::string& deviceName);
|
||||
|
||||
// Media setup
|
||||
virtual VideoControlPtr getVideoControl();
|
||||
virtual AudioControlPtr getAudioControl();
|
||||
|
||||
virtual bool setProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key, std::string& value);
|
||||
virtual std::string getProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key);
|
||||
|
||||
private: // Data Storage
|
||||
|
||||
// Observers
|
||||
mozilla::Mutex m_lock;
|
||||
std::set<CC_Observer *> ccObservers;
|
||||
std::set<ECC_Observer *> eccObservers;
|
||||
|
||||
// Config and global setup
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string authString;
|
||||
std::string secureCachePath;
|
||||
bool multiClusterMode;
|
||||
cc_int32_t sipccLoggingMask;
|
||||
|
||||
AuthenticationStatusEnum::AuthenticationStatus authenticationStatus;
|
||||
|
||||
std::string preferredDevice;
|
||||
std::string preferredLineDN;
|
||||
CC_ServicePtr phone; // The generic handle, for simple operations.
|
||||
CC_SIPCCServicePtr softPhone; // For setup operations not available on the generic API.
|
||||
|
||||
// All known devices
|
||||
typedef std::map<std::string, PhoneDetailsImplPtr> PhoneDetailsMap;
|
||||
PhoneDetailsMap phoneDetailsMap;
|
||||
|
||||
// store connection state
|
||||
ConnectionStatusEnum::ConnectionStatus connectionState;
|
||||
|
||||
public: // Listeners for stacks controlled by CallControlManager
|
||||
// CC_Observers
|
||||
void onDeviceEvent (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info);
|
||||
void onFeatureEvent (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info);
|
||||
void onLineEvent (ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info);
|
||||
void onCallEvent (ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info);
|
||||
|
||||
private: //member functions
|
||||
|
||||
// CC_Observers
|
||||
void notifyDeviceEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info);
|
||||
void notifyFeatureEventObservers (ccapi_device_event_e deviceEvent, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info);
|
||||
void notifyLineEventObservers (ccapi_line_event_e lineEvent, CC_LinePtr linePtr, CC_LineInfoPtr info);
|
||||
void notifyCallEventObservers (ccapi_call_event_e callEvent, CC_CallPtr callPtr, CC_CallInfoPtr info);
|
||||
|
||||
// ECC_Observers
|
||||
void notifyAvailablePhoneEvent (AvailablePhoneEventType::AvailablePhoneEvent event,
|
||||
const PhoneDetailsPtr phoneDetails);
|
||||
void notifyAuthenticationStatusChange (AuthenticationStatusEnum::AuthenticationStatus);
|
||||
void notifyConnectionStatusChange(ConnectionStatusEnum::ConnectionStatus status);
|
||||
void setConnectionState(ConnectionStatusEnum::ConnectionStatus status);
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <string>
|
||||
#include "ECC_Types.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
|
||||
namespace AuthenticationFailureCodeType
|
||||
{
|
||||
std::string ECC_API toString(AuthenticationFailureCode value)
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case eNoError:
|
||||
return "eNoError";
|
||||
case eNoServersConfigured:
|
||||
return "eNoServersConfigured";
|
||||
case eNoCredentialsConfigured:
|
||||
return "eNoCredentialsConfigured";
|
||||
case eCouldNotConnect:
|
||||
return "eCouldNotConnect";
|
||||
case eServerCertificateRejected:
|
||||
return "eServerCertificateRejected";
|
||||
case eCredentialsRejected:
|
||||
return "eCredentialsRejected";
|
||||
case eResponseEmpty:
|
||||
return "eResponseEmpty";
|
||||
case eResponseInvalid:
|
||||
return "eResponseInvalid";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace AuthenticationStatusEnum
|
||||
{
|
||||
std::string ECC_API toString(AuthenticationStatus value)
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case eNotAuthenticated:
|
||||
return "eNotAuthenticated";
|
||||
case eInProgress:
|
||||
return "eInProgress";
|
||||
case eAuthenticated:
|
||||
return "eAuthenticated";
|
||||
case eFailed:
|
||||
return "eFailed";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace DeviceRetrievalFailureCodeType
|
||||
{
|
||||
std::string ECC_API toString(DeviceRetrievalFailureCode value)
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case eNoError:
|
||||
return "eNoError";
|
||||
case eNoServersConfigured:
|
||||
return "eNoServersConfigured";
|
||||
case eNoDeviceNameConfigured:
|
||||
return "eNoDeviceNameConfigured";
|
||||
case eCouldNotConnect:
|
||||
return "eCouldNotConnect";
|
||||
case eFileNotFound:
|
||||
return "eFileNotFound";
|
||||
case eFileEmpty:
|
||||
return "eFileEmpty";
|
||||
case eFileInvalid:
|
||||
return "eFileInvalid";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ConnectionStatusEnum
|
||||
{
|
||||
std::string ECC_API toString(ConnectionStatus value)
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case eIdle:
|
||||
return "eIdle";
|
||||
case eNone:
|
||||
return "eNone";
|
||||
case eFetchingDeviceConfig:
|
||||
return "eFetchingDeviceConfig";
|
||||
case eRegistering:
|
||||
return "eRegistering";
|
||||
case eReady:
|
||||
return "eReady";
|
||||
case eConnectedButNoDeviceReady:
|
||||
return "eConnectedButNoDeviceReady";
|
||||
case eRetrying:
|
||||
return "eRetrying";
|
||||
case eFailed:
|
||||
return "eFailed";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ServiceStateType
|
||||
{
|
||||
std::string ECC_API toString(ServiceState value)
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case eUnknown:
|
||||
return "eUnknown";
|
||||
case eInService:
|
||||
return "eInService";
|
||||
case eOutOfService:
|
||||
return "eOutOfService";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace AvailablePhoneEventType
|
||||
{
|
||||
std::string ECC_API toString(AvailablePhoneEvent value)
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case eFound:
|
||||
return "eFound";
|
||||
case eUpdated:
|
||||
return "eUpdated";
|
||||
case eLost:
|
||||
return "eLost";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PhoneDetailsImpl.h"
|
||||
|
||||
#include "csf_common.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
|
||||
PhoneDetailsImpl::PhoneDetailsImpl()
|
||||
: model(-1),
|
||||
state(ServiceStateType::eUnknown)
|
||||
{
|
||||
}
|
||||
|
||||
PhoneDetailsImpl::~PhoneDetailsImpl()
|
||||
{
|
||||
}
|
||||
|
||||
static const char * _softphoneSupportedModelNames[] = { "Cisco Unified Client Services Framework",
|
||||
"Client Services Framework",
|
||||
"Client Services Core" };
|
||||
|
||||
bool PhoneDetailsImpl::isSoftPhone()
|
||||
{
|
||||
if(model == -1 && modelDescription != "")
|
||||
{
|
||||
// Evaluate based on model description.
|
||||
for(int i = 0; i < (int) csf_countof(_softphoneSupportedModelNames); i++)
|
||||
{
|
||||
if(modelDescription == _softphoneSupportedModelNames[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhoneDetailsImpl::setName(const std::string& name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
void PhoneDetailsImpl::setDescription(const std::string& description)
|
||||
{
|
||||
this->description = description;
|
||||
}
|
||||
// Note that setting model and model description are mutually exclusive.
|
||||
void PhoneDetailsImpl::setModel(int model)
|
||||
{
|
||||
this->model = model;
|
||||
this->modelDescription = "";
|
||||
}
|
||||
void PhoneDetailsImpl::setModelDescription(const std::string& description)
|
||||
{
|
||||
this->model = -1;
|
||||
this->modelDescription = description;
|
||||
}
|
||||
void PhoneDetailsImpl::setLineDNs(const std::vector<std::string> & lineDNs)
|
||||
{
|
||||
this->lineDNs.assign(lineDNs.begin(), lineDNs.end());
|
||||
}
|
||||
void PhoneDetailsImpl::setServiceState(ServiceStateType::ServiceState state)
|
||||
{
|
||||
this->state = state;
|
||||
}
|
||||
void PhoneDetailsImpl::setConfig(const std::string& config)
|
||||
{
|
||||
this->config = config;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PhoneDetails.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(PhoneDetailsImpl);
|
||||
class PhoneDetailsImpl: public PhoneDetails
|
||||
{
|
||||
public:
|
||||
virtual std::string getName() const {return name; }
|
||||
virtual std::string getDescription() const {return description; }
|
||||
virtual int getModel() const {return model;}
|
||||
virtual std::string getModelDescription() const {return modelDescription; }
|
||||
virtual bool isSoftPhone();
|
||||
virtual std::vector<std::string> getLineDNs() const {return lineDNs; }
|
||||
virtual ServiceStateType::ServiceState getServiceState() const { return state; }
|
||||
virtual std::string getConfig() const { return config; }
|
||||
|
||||
protected:
|
||||
PhoneDetailsImpl();
|
||||
virtual ~PhoneDetailsImpl();
|
||||
|
||||
public:
|
||||
virtual void setName(const std::string& name);
|
||||
virtual void setDescription(const std::string& description);
|
||||
// Note that setting model and model description are mutually exclusive.
|
||||
virtual void setModel(int model);
|
||||
virtual void setModelDescription(const std::string& description);
|
||||
virtual void setLineDNs(const std::vector<std::string> & lineDNs);
|
||||
virtual void setServiceState(ServiceStateType::ServiceState state);
|
||||
virtual void setConfig(const std::string& config);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string description;
|
||||
int model;
|
||||
std::string modelDescription;
|
||||
std::vector<std::string> lineDNs;
|
||||
ServiceStateType::ServiceState state;
|
||||
std::string config;
|
||||
|
||||
};
|
||||
}
|
|
@ -0,0 +1,479 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "debug-psipcc-types.h"
|
||||
|
||||
struct ename {
|
||||
int v;
|
||||
cc_string_t name;
|
||||
};
|
||||
|
||||
#define ENAME_DECL(v) \
|
||||
{ v, #v }
|
||||
|
||||
/*
|
||||
* Get a symbolic representation of a numeric identifier.
|
||||
*/
|
||||
static cc_string_t
|
||||
egetname(const struct ename *index, int event)
|
||||
{
|
||||
const struct ename *ename;
|
||||
|
||||
for (ename = index; !(ename->v == 0 && ename->name == nullptr); ename++) {
|
||||
if (event == ename->v)
|
||||
return ename->name;
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
#define CC_EVENT _e
|
||||
#define CC_TYPE _t
|
||||
|
||||
#define DEFINE_NO_PREPEND_TYPE_NAME_FUNCTION(typeName, eventOrType, ...)\
|
||||
DEFINE_TYPE_NAME_FUNCTION_HELPER(, typeName, eventOrType, __VA_ARGS__)
|
||||
|
||||
#define DEFINE_CCAPI_TYPE_NAME_FUNCTION(typeName, eventOrType, ...)\
|
||||
DEFINE_TYPE_NAME_FUNCTION_HELPER(ccapi_, typeName, eventOrType, __VA_ARGS__)
|
||||
|
||||
#define DEFINE_CC_TYPE_NAME_FUNCTION(typeName, eventOrType, ...)\
|
||||
DEFINE_TYPE_NAME_FUNCTION_HELPER(cc_, typeName, eventOrType, __VA_ARGS__)
|
||||
|
||||
#define DEFINE_TYPE_NAME_FUNCTION_HELPER(tokenPrepend, typeName, eventOrType, ...)\
|
||||
static struct ename tokenPrepend##typeName##_names[] = {\
|
||||
__VA_ARGS__, \
|
||||
{ 0, nullptr } \
|
||||
};\
|
||||
\
|
||||
ECC_API cc_string_t typeName##_getname(tokenPrepend##typeName##eventOrType ev) \
|
||||
{\
|
||||
return egetname(&tokenPrepend##typeName##_names[0], (int) ev);\
|
||||
}
|
||||
|
||||
//stringizing enums from ccapi_types.h
|
||||
|
||||
//define device_event_getname(ccapi_device_event_e);
|
||||
DEFINE_CCAPI_TYPE_NAME_FUNCTION(device_event, CC_EVENT,
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_CONFIG_CHANGED),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_STATE),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_IDLE_SET),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_MWI_LAMP),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_NOTIFYPROMPT),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_SERVER_STATUS),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_BLF),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_CAMERA_ADMIN_CONFIG_CHANGED),
|
||||
ENAME_DECL(CCAPI_DEVICE_EV_VIDEO_CAP_ADMIN_CONFIG_CHANGED)
|
||||
);
|
||||
|
||||
//define call_event_getname(ccapi_call_event_e);
|
||||
DEFINE_CCAPI_TYPE_NAME_FUNCTION(call_event, CC_EVENT,
|
||||
ENAME_DECL(CCAPI_CALL_EV_CREATED),
|
||||
ENAME_DECL(CCAPI_CALL_EV_STATE),
|
||||
ENAME_DECL(CCAPI_CALL_EV_CALLINFO),
|
||||
ENAME_DECL(CCAPI_CALL_EV_ATTR),
|
||||
ENAME_DECL(CCAPI_CALL_EV_SECURITY),
|
||||
ENAME_DECL(CCAPI_CALL_EV_LOG_DISP),
|
||||
ENAME_DECL(CCAPI_CALL_EV_PLACED_CALLINFO),
|
||||
ENAME_DECL(CCAPI_CALL_EV_STATUS),
|
||||
ENAME_DECL(CCAPI_CALL_EV_SELECT),
|
||||
ENAME_DECL(CCAPI_CALL_EV_LAST_DIGIT_DELETED),
|
||||
ENAME_DECL(CCAPI_CALL_EV_GCID),
|
||||
ENAME_DECL(CCAPI_CALL_EV_XFR_OR_CNF_CANCELLED),
|
||||
ENAME_DECL(CCAPI_CALL_EV_PRESERVATION),
|
||||
ENAME_DECL(CCAPI_CALL_EV_CAPABILITY),
|
||||
ENAME_DECL(CCAPI_CALL_EV_VIDEO_AVAIL),
|
||||
ENAME_DECL(CCAPI_CALL_EV_VIDEO_OFFERED),
|
||||
ENAME_DECL(CCAPI_CALL_EV_RECEIVED_INFO),
|
||||
ENAME_DECL(CCAPI_CALL_EV_RINGER_STATE),
|
||||
ENAME_DECL(CCAPI_CALL_EV_CONF_PARTICIPANT_INFO),
|
||||
ENAME_DECL(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_BEGIN),
|
||||
ENAME_DECL(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_SUCCESSFUL),
|
||||
ENAME_DECL(CCAPI_CALL_EV_MEDIA_INTERFACE_UPDATE_FAIL)
|
||||
);
|
||||
|
||||
//define line_event_getname(ccapi_line_event_e);
|
||||
DEFINE_CCAPI_TYPE_NAME_FUNCTION(line_event, CC_EVENT,
|
||||
ENAME_DECL(CCAPI_LINE_EV_CONFIG_CHANGED),
|
||||
ENAME_DECL(CCAPI_LINE_EV_REG_STATE),
|
||||
ENAME_DECL(CCAPI_LINE_EV_CAPSET_CHANGED),
|
||||
ENAME_DECL(CCAPI_LINE_EV_CFWDALL),
|
||||
ENAME_DECL(CCAPI_LINE_EV_MWI)
|
||||
);
|
||||
|
||||
//
|
||||
//
|
||||
//stringizing enums from cc_constants.h
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
//define digit_getname(cc_digit_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(digit, CC_TYPE,
|
||||
ENAME_DECL(KEY_1),
|
||||
ENAME_DECL(KEY_2),
|
||||
ENAME_DECL(KEY_3),
|
||||
ENAME_DECL(KEY_4),
|
||||
ENAME_DECL(KEY_5),
|
||||
ENAME_DECL(KEY_6),
|
||||
ENAME_DECL(KEY_7),
|
||||
ENAME_DECL(KEY_8),
|
||||
ENAME_DECL(KEY_9),
|
||||
ENAME_DECL(KEY_0),
|
||||
ENAME_DECL(KEY_STAR),
|
||||
ENAME_DECL(KEY_POUND),
|
||||
ENAME_DECL(KEY_A),
|
||||
ENAME_DECL(KEY_B),
|
||||
ENAME_DECL(KEY_C),
|
||||
ENAME_DECL(KEY_D)
|
||||
);
|
||||
|
||||
//define cucm_mode_getname(cc_cucm_mode_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(cucm_mode, CC_TYPE,
|
||||
ENAME_DECL(CC_MODE_INVALID),
|
||||
ENAME_DECL(CC_MODE_CCM),
|
||||
ENAME_DECL(CC_MODE_NONCCM)
|
||||
);
|
||||
|
||||
//define line_feature_getname(cc_line_feature_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(line_feature, CC_TYPE,
|
||||
ENAME_DECL(CC_LINE_FEATURE_NONE),
|
||||
ENAME_DECL(CC_LINE_FEATURE_REDIAL),
|
||||
ENAME_DECL(CC_LINE_FEATURE_SPEEDDIAL),
|
||||
ENAME_DECL(CC_LINE_FEATURE_DN),
|
||||
ENAME_DECL(CC_LINE_FEATURE_SERVICE),
|
||||
ENAME_DECL(CC_LINE_FEATURE_SPEEDDIALBLF),
|
||||
ENAME_DECL(CC_LINE_FEATURE_MALICIOUSCALLID),
|
||||
ENAME_DECL(CC_LINE_FEATURE_QUALREPORTTOOL),
|
||||
ENAME_DECL(CC_LINE_FEATURE_ALLCALLS),
|
||||
ENAME_DECL(CC_LINE_FEATURE_ANSWEROLDEST),
|
||||
ENAME_DECL(CC_LINE_FEATURE_SERVICES),
|
||||
ENAME_DECL(CC_LINE_FEATURE_BLF)
|
||||
);
|
||||
|
||||
//define feature_option_mask_getname(cc_feature_option_mask_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(feature_option_mask, CC_TYPE,
|
||||
ENAME_DECL(CC_FEATUREOPTIONMASK_NONE),
|
||||
ENAME_DECL(CC_FEATUREOPTIONMASK_BLF_PICKUP)
|
||||
);
|
||||
|
||||
//define service_cause_getname(cc_service_cause_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(service_cause, CC_TYPE,
|
||||
ENAME_DECL(CC_CAUSE_NONE),
|
||||
ENAME_DECL(CC_CAUSE_FAILOVER),
|
||||
ENAME_DECL(CC_CAUSE_FALLBACK),
|
||||
ENAME_DECL(CC_CAUSE_REG_ALL_FAILED),
|
||||
ENAME_DECL(CC_CAUSE_SHUTDOWN),
|
||||
ENAME_DECL(CC_CAUSE_UNREG_ALL),
|
||||
ENAME_DECL(CC_CAUSE_LOGOUT_RESET)
|
||||
);
|
||||
|
||||
//define service_state_getname(cc_service_state_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(service_state, CC_TYPE,
|
||||
ENAME_DECL(CC_STATE_IDLE),
|
||||
ENAME_DECL(CC_STATE_INS),
|
||||
ENAME_DECL(CC_STATE_OOS),
|
||||
ENAME_DECL(CC_STATE_PRO_BASE)
|
||||
);
|
||||
|
||||
//define ccm_status_getname(cc_ccm_status_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(ccm_status, CC_TYPE,
|
||||
ENAME_DECL(CC_CCM_STATUS_NONE),
|
||||
ENAME_DECL(CC_CCM_STATUS_STANDBY),
|
||||
ENAME_DECL(CC_CCM_STATUS_ACTIVE)
|
||||
);
|
||||
|
||||
//define reg_state_getname(cc_line_reg_state_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(line_reg_state, CC_TYPE,
|
||||
ENAME_DECL(CC_UNREGISTERED),
|
||||
ENAME_DECL(CC_REGISTERED)
|
||||
);
|
||||
|
||||
//define shutdown_reason_getname(cc_shutdown_reason_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(shutdown_reason, CC_TYPE,
|
||||
ENAME_DECL(CC_SHUTDOWN_NORMAL),
|
||||
ENAME_DECL(CC_SHUTDOWN_UNSPECIFIED),
|
||||
ENAME_DECL(CC_SHUTDOWN_VERMISMATCH)
|
||||
);
|
||||
|
||||
//define kpml_config_getname(cc_kpml_config_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(kpml_config, CC_TYPE,
|
||||
ENAME_DECL(CC_KPML_NONE),
|
||||
ENAME_DECL(CC_KPML_SIGNAL_ONLY),
|
||||
ENAME_DECL(CC_KPML_DTMF_ONLY),
|
||||
ENAME_DECL(CC_KPML_BOTH)
|
||||
);
|
||||
|
||||
//define upgrade_getname(cc_upgrade_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(upgrade, CC_TYPE,
|
||||
ENAME_DECL(CC_UPGRADE_NONE),
|
||||
ENAME_DECL(CC_UPGRADE_NOW),
|
||||
ENAME_DECL(CC_UPGRADE_LATER)
|
||||
);
|
||||
|
||||
//define sdp_direction_getname(cc_sdp_direction_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(sdp_direction, CC_TYPE,
|
||||
ENAME_DECL(CC_SDP_DIRECTION_INACTIVE),
|
||||
ENAME_DECL(CC_SDP_DIRECTION_SENDONLY),
|
||||
ENAME_DECL(CC_SDP_DIRECTION_RECVONLY),
|
||||
ENAME_DECL(CC_SDP_DIRECTION_SENDRECV),
|
||||
ENAME_DECL(CC_SDP_MAX_QOS_DIRECTIONS)
|
||||
);
|
||||
|
||||
//define blf_state_getname(cc_blf_state_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION(blf_state, CC_TYPE,
|
||||
ENAME_DECL(CC_SIP_BLF_UNKNOWN),
|
||||
ENAME_DECL(CC_SIP_BLF_IDLE),
|
||||
ENAME_DECL(CC_SIP_BLF_INUSE),
|
||||
ENAME_DECL(CC_SIP_BLF_EXPIRED),
|
||||
ENAME_DECL(CC_SIP_BLF_REJECTED),
|
||||
ENAME_DECL(CC_SIP_BLF_ALERTING)
|
||||
);
|
||||
|
||||
//define blf_feature_mask_getname(cc_blf_feature_mask_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (blf_feature_mask, CC_TYPE,
|
||||
ENAME_DECL(CC_BLF_FEATURE_MASK_NONE),
|
||||
ENAME_DECL(CC_BLF_FEATURE_MASK_PICKUP)
|
||||
);
|
||||
|
||||
//define call_state_getname(cc_call_state_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (call_state, CC_TYPE,
|
||||
ENAME_DECL(OFFHOOK),
|
||||
ENAME_DECL(ONHOOK),
|
||||
ENAME_DECL(RINGOUT),
|
||||
ENAME_DECL(RINGIN),
|
||||
ENAME_DECL(PROCEED),
|
||||
ENAME_DECL(CONNECTED),
|
||||
ENAME_DECL(HOLD),
|
||||
ENAME_DECL(REMHOLD),
|
||||
ENAME_DECL(RESUME),
|
||||
ENAME_DECL(BUSY),
|
||||
ENAME_DECL(REORDER),
|
||||
ENAME_DECL(CONFERENCE),
|
||||
ENAME_DECL(DIALING),
|
||||
ENAME_DECL(REMINUSE),
|
||||
ENAME_DECL(HOLDREVERT),
|
||||
ENAME_DECL(WHISPER),
|
||||
ENAME_DECL(PRESERVATION),
|
||||
ENAME_DECL(WAITINGFORDIGITS),
|
||||
ENAME_DECL(MAX_CALL_STATES)
|
||||
);
|
||||
|
||||
//define call_attr_getname(cc_call_attr_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (call_attr, CC_TYPE,
|
||||
ENAME_DECL(CC_ATTR_NOT_DEFINED),
|
||||
ENAME_DECL(CC_ATTR_NORMAL),
|
||||
ENAME_DECL(CC_ATTR_XFR_CONSULT),
|
||||
ENAME_DECL(CC_ATTR_CONF_CONSULT),
|
||||
ENAME_DECL(CC_ATTR_BARGING),
|
||||
ENAME_DECL(CC_ATTR_RIUHELD_LOCKED),
|
||||
ENAME_DECL(CC_ATTR_LOCAL_CONF_CONSULT),
|
||||
ENAME_DECL(CC_ATTR_LOCAL_XFER_CONSULT),
|
||||
ENAME_DECL(CC_ATTR_CFWDALL),
|
||||
ENAME_DECL(CC_ATTR_CFWD_ALL),
|
||||
ENAME_DECL(CC_ATTR_MAX)
|
||||
);
|
||||
|
||||
//define hold_reason_getname(cc_hold_reason_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (hold_reason, CC_TYPE,
|
||||
ENAME_DECL(CC_HOLD_REASON_NONE),
|
||||
ENAME_DECL(CC_HOLD_REASON_XFER),
|
||||
ENAME_DECL(CC_HOLD_REASON_CONF),
|
||||
ENAME_DECL(CC_HOLD_REASON_SWAP),
|
||||
ENAME_DECL(CC_HOLD_REASON_INTERNAL)
|
||||
);
|
||||
|
||||
//define call_type_getname(cc_call_type_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (call_type, CC_TYPE,
|
||||
ENAME_DECL(CC_CALL_TYPE_NONE),
|
||||
ENAME_DECL(CC_CALL_TYPE_INCOMING),
|
||||
ENAME_DECL(CC_CALL_TYPE_OUTGOING),
|
||||
ENAME_DECL(CC_CALL_TYPE_FORWARDED)
|
||||
);
|
||||
|
||||
//define call_security_getname(cc_call_security_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (call_security, CC_TYPE,
|
||||
ENAME_DECL(CC_SECURITY_NONE),
|
||||
ENAME_DECL(CC_SECURITY_UNKNOWN),
|
||||
ENAME_DECL(CC_SECURITY_AUTHENTICATED),
|
||||
ENAME_DECL(CC_SECURITY_NOT_AUTHENTICATED),
|
||||
ENAME_DECL(CC_SECURITY_ENCRYPTED)
|
||||
);
|
||||
|
||||
//define call_policy_getname(cc_call_policy_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (call_policy, CC_TYPE,
|
||||
ENAME_DECL(CC_POLICY_NONE),
|
||||
ENAME_DECL(CC_POLICY_UNKNOWN),
|
||||
ENAME_DECL(CC_POLICY_CHAPERONE)
|
||||
);
|
||||
|
||||
//define log_disposition_getname(cc_log_disposition_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (log_disposition, CC_TYPE,
|
||||
ENAME_DECL(CC_LOGD_MISSED),
|
||||
ENAME_DECL(CC_LOGD_RCVD),
|
||||
ENAME_DECL(CC_LOGD_SENT),
|
||||
ENAME_DECL(CC_LOGD_UNKNWN),
|
||||
ENAME_DECL(CC_LOGD_DELETE)
|
||||
);
|
||||
|
||||
//define call_priority_getname(cc_call_priority_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (call_priority, CC_TYPE,
|
||||
ENAME_DECL(CC_PRIORITY_NORMAL),
|
||||
ENAME_DECL(CC_PRIORITY_URGENT)
|
||||
);
|
||||
|
||||
//define call_selection_getname(cc_call_selection_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (call_selection, CC_TYPE,
|
||||
ENAME_DECL(CC_CALL_SELECT_NONE),
|
||||
ENAME_DECL(CC_CALL_SELECT_LOCKED),
|
||||
ENAME_DECL(CC_CALL_SELECT_UNLOCKED),
|
||||
ENAME_DECL(CC_CALL_SELECT_REMOTE_LOCKED)
|
||||
);
|
||||
|
||||
//cc_string_t call_capability_getname(ccapi_call_capability_e);
|
||||
DEFINE_CCAPI_TYPE_NAME_FUNCTION(call_capability, CC_EVENT,
|
||||
ENAME_DECL(CCAPI_CALL_CAP_NEWCALL),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_ANSWER),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_ENDCALL),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_HOLD),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_RESUME),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_CALLFWD),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_DIAL),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_BACKSPACE),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_SENDDIGIT),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_TRANSFER),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_CONFERENCE),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_SWAP),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_REDIAL),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_JOIN),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_SELECT),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_RMVLASTPARTICIPANT),
|
||||
ENAME_DECL(CCAPI_CALL_CAP_MAX)
|
||||
);
|
||||
|
||||
//define srv_ctrl_req_getname(cc_srv_ctrl_req_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (srv_ctrl_req, CC_TYPE,
|
||||
ENAME_DECL(CC_DEVICE_RESET),
|
||||
ENAME_DECL(CC_DEVICE_RESTART),
|
||||
ENAME_DECL(CC_DEVICE_ICMP_UNREACHABLE)
|
||||
);
|
||||
|
||||
//define srv_ctrl_cmd_getname(cc_srv_ctrl_cmd_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (srv_ctrl_cmd, CC_TYPE,
|
||||
ENAME_DECL(CC_ACTION_RESET),
|
||||
ENAME_DECL(CC_ACTION_RESTART)
|
||||
);
|
||||
|
||||
//define message_type_getname(cc_message_type_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (message_type, CC_TYPE,
|
||||
ENAME_DECL(CC_VOICE_MESSAGE),
|
||||
ENAME_DECL(CC_TEXT_MESSAGE)
|
||||
);
|
||||
|
||||
//define lamp_state_getname(cc_lamp_state_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (lamp_state, CC_TYPE,
|
||||
ENAME_DECL(CC_LAMP_NONE),
|
||||
ENAME_DECL(CC_LAMP_ON),
|
||||
ENAME_DECL(CC_LAMP_BLINK),
|
||||
ENAME_DECL(CC_LAMP_FRESH)
|
||||
);
|
||||
|
||||
//define cause_getname(cc_cause_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (cause, CC_TYPE,
|
||||
ENAME_DECL(CC_CAUSE_MIN),
|
||||
ENAME_DECL(CC_CAUSE_BASE),
|
||||
ENAME_DECL(CC_CAUSE_OK),
|
||||
ENAME_DECL(CC_CAUSE_ERROR),
|
||||
ENAME_DECL(CC_CAUSE_UNASSIGNED_NUM),
|
||||
ENAME_DECL(CC_CAUSE_NO_RESOURCE),
|
||||
ENAME_DECL(CC_CAUSE_NO_ROUTE),
|
||||
ENAME_DECL(CC_CAUSE_NORMAL),
|
||||
ENAME_DECL(CC_CAUSE_BUSY),
|
||||
ENAME_DECL(CC_CAUSE_NO_USER_RESP),
|
||||
ENAME_DECL(CC_CAUSE_NO_USER_ANS),
|
||||
ENAME_DECL(CC_CAUSE_REJECT),
|
||||
ENAME_DECL(CC_CAUSE_INVALID_NUMBER),
|
||||
ENAME_DECL(CC_CAUSE_FACILITY_REJECTED),
|
||||
ENAME_DECL(CC_CAUSE_CALL_ID_IN_USE),
|
||||
ENAME_DECL(CC_CAUSE_XFER_LOCAL),
|
||||
ENAME_DECL(CC_CAUSE_XFER_REMOTE),
|
||||
ENAME_DECL(CC_CAUSE_XFER_BY_REMOTE),
|
||||
ENAME_DECL(CC_CAUSE_XFER_CNF),
|
||||
ENAME_DECL(CC_CAUSE_CONGESTION),
|
||||
ENAME_DECL(CC_CAUSE_ANONYMOUS),
|
||||
ENAME_DECL(CC_CAUSE_REDIRECT),
|
||||
ENAME_DECL(CC_CAUSE_PAYLOAD_MISMATCH),
|
||||
ENAME_DECL(CC_CAUSE_CONF),
|
||||
ENAME_DECL(CC_CAUSE_REPLACE),
|
||||
ENAME_DECL(CC_CAUSE_NO_REPLACE_CALL),
|
||||
ENAME_DECL(CC_CAUSE_NO_RESUME),
|
||||
ENAME_DECL(CC_CAUSE_NO_MEDIA),
|
||||
ENAME_DECL(CC_CAUSE_REQUEST_PENDING),
|
||||
ENAME_DECL(CC_CAUSE_INVALID_PARTICIPANT),
|
||||
ENAME_DECL(CC_CAUSE_NO_CNF_BRIDE),
|
||||
ENAME_DECL(CC_MAXIMUM_PARTICIPANT),
|
||||
ENAME_DECL(CC_KEY_NOT_ACTIVE),
|
||||
ENAME_DECL(CC_TEMP_NOT_AVAILABLE),
|
||||
ENAME_DECL(CC_CAUSE_REMOTE_SERVER_ERROR),
|
||||
ENAME_DECL(CC_CAUSE_NOT_FOUND),
|
||||
ENAME_DECL(CC_CAUSE_SECURITY_FAILURE),
|
||||
ENAME_DECL(CC_CAUSE_MONITOR),
|
||||
ENAME_DECL(CC_CAUSE_UI_STATE_BUSY),
|
||||
ENAME_DECL(CC_SIP_CAUSE_ANSWERED_ELSEWHERE),
|
||||
ENAME_DECL(CC_CAUSE_RETRIEVED),
|
||||
ENAME_DECL(CC_CAUSE_FORWARDED),
|
||||
ENAME_DECL(CC_CAUSE_ABANDONED),
|
||||
ENAME_DECL(CC_CAUSE_XFER_LOCAL_WITH_DIALSTRING),
|
||||
ENAME_DECL(CC_CAUSE_BW_OK),
|
||||
ENAME_DECL(CC_CAUSE_XFER_COMPLETE),
|
||||
ENAME_DECL(CC_CAUSE_RESP_TIMEOUT),
|
||||
ENAME_DECL(CC_CAUSE_SERV_ERR_UNAVAIL),
|
||||
ENAME_DECL(CC_CAUSE_REMOTE_DISCONN_REQ_PLAYTONE),
|
||||
ENAME_DECL(CC_CAUSE_OUT_OF_MEM),
|
||||
ENAME_DECL(CC_CAUSE_VALUE_NOT_FOUND),
|
||||
ENAME_DECL(CC_CAUSE_BAD_ICE_ATTRIBUTE),
|
||||
ENAME_DECL(CC_CAUSE_DTLS_ATTRIBUTE_ERROR),
|
||||
ENAME_DECL(CC_CAUSE_DTLS_DIGEST_ALGORITHM_EMPTY),
|
||||
ENAME_DECL(CC_CAUSE_DTLS_DIGEST_ALGORITHM_TOO_LONG),
|
||||
ENAME_DECL(CC_CAUSE_DTLS_DIGEST_EMPTY),
|
||||
ENAME_DECL(CC_CAUSE_DTLS_DIGEST_TOO_LONG),
|
||||
ENAME_DECL(CC_CAUSE_DTLS_FINGERPRINT_PARSE_ERROR),
|
||||
ENAME_DECL(CC_CAUSE_DTLS_FINGERPRINT_TOO_LONG),
|
||||
ENAME_DECL(CC_CAUSE_INVALID_SDP_POINTER),
|
||||
ENAME_DECL(CC_CAUSE_NO_AUDIO),
|
||||
ENAME_DECL(CC_CAUSE_NO_DTLS_FINGERPRINT),
|
||||
ENAME_DECL(CC_CAUSE_MISSING_ICE_ATTRIBUTES),
|
||||
ENAME_DECL(CC_CAUSE_NO_MEDIA_CAPABILITY),
|
||||
ENAME_DECL(CC_CAUSE_NO_M_LINE),
|
||||
ENAME_DECL(CC_CAUSE_NO_PEERCONNECTION),
|
||||
ENAME_DECL(CC_CAUSE_NO_SDP),
|
||||
ENAME_DECL(CC_CAUSE_NULL_POINTER),
|
||||
ENAME_DECL(CC_CAUSE_SDP_CREATE_FAILED),
|
||||
ENAME_DECL(CC_CAUSE_SDP_ENCODE_FAILED),
|
||||
ENAME_DECL(CC_CAUSE_SDP_PARSE_FAILED),
|
||||
ENAME_DECL(CC_CAUSE_SETTING_ICE_SESSION_PARAMETERS_FAILED),
|
||||
ENAME_DECL(CC_CAUSE_MAX)
|
||||
);
|
||||
|
||||
//define subscriptions_ext_getname(cc_subscriptions_ext_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (subscriptions_ext, CC_TYPE,
|
||||
ENAME_DECL(CC_SUBSCRIPTIONS_KPML_EXT),
|
||||
ENAME_DECL(CC_SUBSCRIPTIONS_PRESENCE_EXT),
|
||||
ENAME_DECL(CC_SUBSCRIPTIONS_REMOTECC_EXT),
|
||||
ENAME_DECL(CC_SUBSCRIPTIONS_REMOTECC_OPTIONSIND_EXT),
|
||||
ENAME_DECL(CC_SUBSCRIPTIONS_CONFIGAPP_EXT),
|
||||
ENAME_DECL(CC_SUBSCRIPTIONS_MEDIA_INFO_EXT)
|
||||
);
|
||||
|
||||
//define apply_config_result_getname(cc_apply_config_result_t);
|
||||
DEFINE_CC_TYPE_NAME_FUNCTION (apply_config_result, CC_TYPE,
|
||||
ENAME_DECL(APPLY_CONFIG_NONE),
|
||||
ENAME_DECL(APPLY_DYNAMICALLY),
|
||||
ENAME_DECL(RESTART_NEEDED)
|
||||
);
|
||||
|
||||
|
||||
|
|
@ -10,9 +10,19 @@
|
|||
#include "base/basictypes.h"
|
||||
|
||||
#include <map>
|
||||
#include "cpr_threads.h"
|
||||
#include "prrwlock.h"
|
||||
#include "prthread.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#ifndef WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#ifdef OS_MACOSX
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#ifdef OS_LINUX
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
static PRLogModuleInfo *gLogModuleInfo = nullptr;
|
||||
|
||||
|
@ -34,6 +44,81 @@ PRLogModuleInfo *GetWebRTCLogInfo()
|
|||
return gWebRTCLogModuleInfo;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void CSFLogRegisterThread(const cprThread_t thread);
|
||||
void CSFLogUnregisterThread(const cprThread_t thread);
|
||||
#ifndef WIN32
|
||||
pthread_t cprGetThreadId(cprThread_t thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
typedef unsigned int thread_key_t;
|
||||
#else
|
||||
typedef pthread_t thread_key_t;
|
||||
#endif
|
||||
static PRRWLock *maplock = PR_NewRWLock(0,"thread map");
|
||||
typedef std::map<thread_key_t,const cpr_thread_t*> threadMap_t;
|
||||
static threadMap_t threadMap;
|
||||
|
||||
void CSFLogRegisterThread(const cprThread_t thread) {
|
||||
const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread);
|
||||
thread_key_t key;
|
||||
#ifdef WIN32
|
||||
key = t->threadId;
|
||||
#else
|
||||
key = cprGetThreadId(thread);
|
||||
#endif
|
||||
|
||||
CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log",
|
||||
"Registering new thread with logging system: %s", t->name);
|
||||
PR_RWLock_Wlock(maplock);
|
||||
threadMap[key] = t;
|
||||
PR_RWLock_Unlock(maplock);
|
||||
}
|
||||
|
||||
void CSFLogUnregisterThread(const cprThread_t thread) {
|
||||
const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread);
|
||||
thread_key_t key;
|
||||
#ifdef WIN32
|
||||
key = t->threadId;
|
||||
#else
|
||||
key = cprGetThreadId(thread);
|
||||
#endif
|
||||
CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log",
|
||||
"Unregistering thread from logging system: %s", t->name);
|
||||
PR_RWLock_Wlock(maplock);
|
||||
threadMap.erase(key);
|
||||
PR_RWLock_Unlock(maplock);
|
||||
}
|
||||
|
||||
const char *CSFCurrentThreadName() {
|
||||
const char *name = nullptr;
|
||||
#ifdef WIN32
|
||||
thread_key_t key = GetCurrentThreadId();
|
||||
#else
|
||||
thread_key_t key = pthread_self();
|
||||
#endif
|
||||
PR_RWLock_Rlock(maplock);
|
||||
threadMap_t::iterator i = threadMap.find(key);
|
||||
if (i != threadMap.end()) {
|
||||
name = i->second->name;
|
||||
}
|
||||
PR_RWLock_Unlock(maplock);
|
||||
return name;
|
||||
}
|
||||
|
||||
#ifdef OS_MACOSX
|
||||
// pthread_getname_np isn't available on all versions of OS X, so
|
||||
// we need to load it in dynamically and check for its presence
|
||||
static int (*dynamic_pthread_getname_np)(pthread_t,char*,size_t);
|
||||
bool init_pthread_getname() {
|
||||
*reinterpret_cast<void**>(&dynamic_pthread_getname_np) =
|
||||
dlsym(RTLD_DEFAULT, "pthread_getname_np");
|
||||
return dynamic_pthread_getname_np;
|
||||
}
|
||||
static bool have_pthread_getname_np = init_pthread_getname();
|
||||
#endif
|
||||
|
||||
void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args)
|
||||
{
|
||||
|
@ -66,16 +151,40 @@ void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const
|
|||
|
||||
#define MAX_MESSAGE_LENGTH 1024
|
||||
char message[MAX_MESSAGE_LENGTH];
|
||||
char buffer[64] = "";
|
||||
|
||||
const char *threadName = NULL;
|
||||
const char *threadName = CSFCurrentThreadName();
|
||||
|
||||
// Check if we're the main thread...
|
||||
if (NS_IsMainThread()) {
|
||||
if (!threadName && NS_IsMainThread()) {
|
||||
threadName = "main";
|
||||
} else {
|
||||
}
|
||||
|
||||
// If null, the name wasn't set up by CPR -- try NSPR
|
||||
if (!threadName) {
|
||||
threadName = PR_GetThreadName(PR_GetCurrentThread());
|
||||
}
|
||||
|
||||
// If not NSPR, it might be from some other imported library that uses
|
||||
// one of the variety of non-portable means of naming threads.
|
||||
#ifdef OS_LINUX
|
||||
if (!threadName &&
|
||||
!prctl(PR_GET_NAME,reinterpret_cast<uintptr_t>(buffer),0,0,0)) {
|
||||
buffer[16]='\0';
|
||||
if (buffer[0] != '\0') {
|
||||
threadName = buffer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef OS_MACOSX
|
||||
if (!threadName && have_pthread_getname_np) {
|
||||
dynamic_pthread_getname_np(pthread_self(), buffer, sizeof(buffer));
|
||||
if (buffer[0] != '\0') {
|
||||
threadName = buffer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we can't find it anywhere, use a blank string
|
||||
if (!threadName) {
|
||||
threadName = "";
|
||||
|
|
|
@ -88,9 +88,8 @@ print_timecard(Timecard *tc)
|
|||
}
|
||||
}
|
||||
|
||||
printf("\nTimecard created %4ld.%6.6ld\n\n",
|
||||
(long)(tc->start_time / PR_USEC_PER_SEC),
|
||||
(long)(tc->start_time % PR_USEC_PER_SEC));
|
||||
printf("\nTimecard created %4lld.%6.6lld\n\n",
|
||||
tc->start_time / PR_USEC_PER_SEC, tc->start_time % PR_USEC_PER_SEC);
|
||||
|
||||
line_width = 1 + 11 + 11 + event_width + file_width + 6 +
|
||||
function_width + (4 * 3);
|
||||
|
@ -114,9 +113,9 @@ print_timecard(Timecard *tc)
|
|||
} else {
|
||||
delta = entry->timestamp - tc->start_time;
|
||||
}
|
||||
printf(" %4ld.%6.6ld | %4ld.%6.6ld | %-*s | %*s:%-5d | %-*s\n",
|
||||
(long)(offset / PR_USEC_PER_SEC), (long)(offset % PR_USEC_PER_SEC),
|
||||
(long)(delta / PR_USEC_PER_SEC), (long)(delta % PR_USEC_PER_SEC),
|
||||
printf(" %4lld.%6.6lld | %4lld.%6.6lld | %-*s | %*s:%-5d | %-*s\n",
|
||||
offset / PR_USEC_PER_SEC, offset % PR_USEC_PER_SEC,
|
||||
delta / PR_USEC_PER_SEC, delta % PR_USEC_PER_SEC,
|
||||
(int)event_width, entry->event,
|
||||
(int)file_width, entry->file, entry->line,
|
||||
(int)function_width, entry->function);
|
||||
|
|
|
@ -1,620 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _JSEPCODECDESCRIPTION_H_
|
||||
#define _JSEPCODECDESCRIPTION_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#define JSEP_CODEC_CLONE(T) \
|
||||
virtual JsepCodecDescription* Clone() const MOZ_OVERRIDE \
|
||||
{ \
|
||||
return new T(*this); \
|
||||
}
|
||||
|
||||
// A single entry in our list of known codecs.
|
||||
struct JsepCodecDescription {
|
||||
JsepCodecDescription(mozilla::SdpMediaSection::MediaType type,
|
||||
const std::string& defaultPt,
|
||||
const std::string& name,
|
||||
uint32_t clock,
|
||||
uint32_t channels,
|
||||
bool enabled)
|
||||
: mType(type),
|
||||
mDefaultPt(defaultPt),
|
||||
mName(name),
|
||||
mClock(clock),
|
||||
mChannels(channels),
|
||||
mEnabled(enabled)
|
||||
{
|
||||
}
|
||||
virtual ~JsepCodecDescription() {}
|
||||
|
||||
virtual JsepCodecDescription* Clone() const = 0;
|
||||
virtual void AddFmtps(SdpFmtpAttributeList& fmtp) const = 0;
|
||||
virtual void AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const = 0;
|
||||
virtual bool LoadFmtps(const SdpFmtpAttributeList::Parameters& params) = 0;
|
||||
virtual bool LoadRtcpFbs(
|
||||
const SdpRtcpFbAttributeList::Feedback& feedback) = 0;
|
||||
|
||||
static bool
|
||||
GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam)
|
||||
{
|
||||
char* end;
|
||||
unsigned long pt = strtoul(ptString.c_str(), &end, 10);
|
||||
size_t length = static_cast<size_t>(end - ptString.c_str());
|
||||
if ((pt > UINT16_MAX) || (length != ptString.size())) {
|
||||
return false;
|
||||
}
|
||||
*ptOutparam = pt;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GetPtAsInt(uint16_t* ptOutparam) const
|
||||
{
|
||||
return GetPtAsInt(mDefaultPt, ptOutparam);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
Matches(const std::string& fmt, const SdpMediaSection& remoteMsection) const
|
||||
{
|
||||
auto& attrs = remoteMsection.GetAttributeList();
|
||||
if (!attrs.HasAttribute(SdpAttribute::kRtpmapAttribute)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const SdpRtpmapAttributeList& rtpmap = attrs.GetRtpmap();
|
||||
if (!rtpmap.HasEntry(fmt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const SdpRtpmapAttributeList::Rtpmap& entry = rtpmap.GetEntry(fmt);
|
||||
|
||||
if (mType == remoteMsection.GetMediaType()
|
||||
&& (mName == entry.name)
|
||||
&& (mClock == entry.clock)
|
||||
&& (mChannels == entry.channels)) {
|
||||
return ParametersMatch(FindParameters(entry.pt, remoteMsection));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
ParametersMatch(const SdpFmtpAttributeList::Parameters* fmtp) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const SdpFmtpAttributeList::Parameters*
|
||||
FindParameters(const std::string& pt,
|
||||
const mozilla::SdpMediaSection& remoteMsection)
|
||||
{
|
||||
const SdpAttributeList& attrs = remoteMsection.GetAttributeList();
|
||||
|
||||
if (attrs.HasAttribute(SdpAttribute::kFmtpAttribute)) {
|
||||
const SdpFmtpAttributeList& fmtps = attrs.GetFmtp();
|
||||
for (auto i = fmtps.mFmtps.begin(); i != fmtps.mFmtps.end(); ++i) {
|
||||
if (i->format == pt && i->parameters) {
|
||||
return i->parameters.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual JsepCodecDescription*
|
||||
MakeNegotiatedCodec(const mozilla::SdpMediaSection& remoteMsection,
|
||||
const std::string& pt,
|
||||
bool sending) const
|
||||
{
|
||||
UniquePtr<JsepCodecDescription> negotiated(Clone());
|
||||
negotiated->mDefaultPt = pt;
|
||||
|
||||
const SdpAttributeList& attrs = remoteMsection.GetAttributeList();
|
||||
|
||||
if (sending) {
|
||||
auto* parameters = FindParameters(negotiated->mDefaultPt, remoteMsection);
|
||||
if (parameters) {
|
||||
if (!negotiated->LoadFmtps(*parameters)) {
|
||||
// Remote parameters were invalid
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If a receive track, we need to pay attention to remote end's rtcp-fb
|
||||
if (attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) {
|
||||
auto& rtcpfbs = attrs.GetRtcpFb().mFeedbacks;
|
||||
for (auto i = rtcpfbs.begin(); i != rtcpfbs.end(); ++i) {
|
||||
if (i->pt == negotiated->mDefaultPt) {
|
||||
if (!negotiated->LoadRtcpFbs(*i)) {
|
||||
// Remote parameters were invalid
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return negotiated.release();
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddToMediaSection(SdpMediaSection& msection) const
|
||||
{
|
||||
if (mEnabled && msection.GetMediaType() == mType) {
|
||||
if (mType == SdpMediaSection::kApplication) {
|
||||
// Hack: using mChannels for number of streams
|
||||
msection.AddDataChannel(mDefaultPt, mName, mChannels);
|
||||
} else {
|
||||
msection.AddCodec(mDefaultPt, mName, mClock, mChannels);
|
||||
}
|
||||
AddFmtpsToMSection(msection);
|
||||
AddRtcpFbsToMSection(msection);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddFmtpsToMSection(SdpMediaSection& msection) const
|
||||
{
|
||||
SdpAttributeList& attrs = msection.GetAttributeList();
|
||||
|
||||
UniquePtr<SdpFmtpAttributeList> fmtps;
|
||||
|
||||
if (attrs.HasAttribute(SdpAttribute::kFmtpAttribute)) {
|
||||
fmtps.reset(new SdpFmtpAttributeList(attrs.GetFmtp()));
|
||||
} else {
|
||||
fmtps.reset(new SdpFmtpAttributeList);
|
||||
}
|
||||
|
||||
AddFmtps(*fmtps);
|
||||
|
||||
if (!fmtps->mFmtps.empty()) {
|
||||
attrs.SetAttribute(fmtps.release());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddRtcpFbsToMSection(SdpMediaSection& msection) const
|
||||
{
|
||||
SdpAttributeList& attrs = msection.GetAttributeList();
|
||||
|
||||
UniquePtr<SdpRtcpFbAttributeList> rtcpfbs;
|
||||
|
||||
if (attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) {
|
||||
rtcpfbs.reset(new SdpRtcpFbAttributeList(attrs.GetRtcpFb()));
|
||||
} else {
|
||||
rtcpfbs.reset(new SdpRtcpFbAttributeList);
|
||||
}
|
||||
|
||||
AddRtcpFbs(*rtcpfbs);
|
||||
|
||||
if (!rtcpfbs->mFeedbacks.empty()) {
|
||||
attrs.SetAttribute(rtcpfbs.release());
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::SdpMediaSection::MediaType mType;
|
||||
std::string mDefaultPt;
|
||||
std::string mName;
|
||||
uint32_t mClock;
|
||||
uint32_t mChannels;
|
||||
bool mEnabled;
|
||||
};
|
||||
|
||||
struct JsepAudioCodecDescription : public JsepCodecDescription {
|
||||
JsepAudioCodecDescription(const std::string& defaultPt,
|
||||
const std::string& name,
|
||||
uint32_t clock,
|
||||
uint32_t channels,
|
||||
uint32_t packetSize,
|
||||
uint32_t bitRate,
|
||||
bool enabled = true)
|
||||
: JsepCodecDescription(mozilla::SdpMediaSection::kAudio, defaultPt, name,
|
||||
clock, channels, enabled),
|
||||
mPacketSize(packetSize),
|
||||
mBitrate(bitRate)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddFmtps(SdpFmtpAttributeList& fmtp) const MOZ_OVERRIDE
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const MOZ_OVERRIDE
|
||||
{
|
||||
// TODO: Do we want to add anything?
|
||||
}
|
||||
|
||||
virtual bool
|
||||
LoadFmtps(const SdpFmtpAttributeList::Parameters& params) MOZ_OVERRIDE
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) MOZ_OVERRIDE
|
||||
{
|
||||
// Nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
JSEP_CODEC_CLONE(JsepAudioCodecDescription)
|
||||
|
||||
uint32_t mPacketSize;
|
||||
uint32_t mBitrate;
|
||||
};
|
||||
|
||||
struct JsepVideoCodecDescription : public JsepCodecDescription {
|
||||
JsepVideoCodecDescription(const std::string& defaultPt,
|
||||
const std::string& name,
|
||||
uint32_t clock,
|
||||
bool enabled = true)
|
||||
: JsepCodecDescription(mozilla::SdpMediaSection::kVideo, defaultPt, name,
|
||||
clock, 0, enabled),
|
||||
mMaxFs(0),
|
||||
mMaxFr(0),
|
||||
mPacketizationMode(0),
|
||||
mMaxMbps(0),
|
||||
mMaxCpb(0),
|
||||
mMaxDpb(0),
|
||||
mMaxBr(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddFmtps(SdpFmtpAttributeList& fmtp) const MOZ_OVERRIDE
|
||||
{
|
||||
if (mName == "H264") {
|
||||
UniquePtr<SdpFmtpAttributeList::H264Parameters> params =
|
||||
MakeUnique<SdpFmtpAttributeList::H264Parameters>();
|
||||
|
||||
params->packetization_mode = mPacketizationMode;
|
||||
// Hard-coded, may need to change someday?
|
||||
params->level_asymmetry_allowed = true;
|
||||
params->profile_level_id = mProfileLevelId;
|
||||
params->max_mbps = mMaxMbps;
|
||||
params->max_fs = mMaxFs;
|
||||
params->max_cpb = mMaxCpb;
|
||||
params->max_dpb = mMaxDpb;
|
||||
params->max_br = mMaxBr;
|
||||
strncpy(params->sprop_parameter_sets,
|
||||
mSpropParameterSets.c_str(),
|
||||
sizeof(params->sprop_parameter_sets) - 1);
|
||||
fmtp.PushEntry(mDefaultPt, "", mozilla::Move(params));
|
||||
} else if (mName == "VP8") {
|
||||
UniquePtr<SdpFmtpAttributeList::VP8Parameters> params =
|
||||
MakeUnique<SdpFmtpAttributeList::VP8Parameters>();
|
||||
|
||||
params->max_fs = mMaxFs;
|
||||
params->max_fr = mMaxFr;
|
||||
fmtp.PushEntry(mDefaultPt, "", mozilla::Move(params));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const MOZ_OVERRIDE
|
||||
{
|
||||
// Just hard code for now
|
||||
rtcpfb.PushEntry(mDefaultPt, SdpRtcpFbAttributeList::kNack);
|
||||
rtcpfb.PushEntry(
|
||||
mDefaultPt, SdpRtcpFbAttributeList::kNack, SdpRtcpFbAttributeList::pli);
|
||||
rtcpfb.PushEntry(
|
||||
mDefaultPt, SdpRtcpFbAttributeList::kCcm, SdpRtcpFbAttributeList::fir);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
LoadFmtps(const SdpFmtpAttributeList::Parameters& params) MOZ_OVERRIDE
|
||||
{
|
||||
switch (params.codec_type) {
|
||||
case SdpRtpmapAttributeList::kH264:
|
||||
LoadH264Parameters(params);
|
||||
break;
|
||||
case SdpRtpmapAttributeList::kVP8:
|
||||
LoadVP8Parameters(params);
|
||||
break;
|
||||
case SdpRtpmapAttributeList::kVP9:
|
||||
case SdpRtpmapAttributeList::kiLBC:
|
||||
case SdpRtpmapAttributeList::kiSAC:
|
||||
case SdpRtpmapAttributeList::kOpus:
|
||||
case SdpRtpmapAttributeList::kG722:
|
||||
case SdpRtpmapAttributeList::kPCMU:
|
||||
case SdpRtpmapAttributeList::kPCMA:
|
||||
case SdpRtpmapAttributeList::kOtherCodec:
|
||||
MOZ_ASSERT(false, "Invalid codec type for video");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) MOZ_OVERRIDE
|
||||
{
|
||||
switch (feedback.type) {
|
||||
case SdpRtcpFbAttributeList::kAck:
|
||||
mAckFbTypes.push_back(feedback.parameter);
|
||||
break;
|
||||
case SdpRtcpFbAttributeList::kCcm:
|
||||
mCcmFbTypes.push_back(feedback.parameter);
|
||||
break;
|
||||
case SdpRtcpFbAttributeList::kNack:
|
||||
mNackFbTypes.push_back(feedback.parameter);
|
||||
break;
|
||||
case SdpRtcpFbAttributeList::kApp:
|
||||
case SdpRtcpFbAttributeList::kTrrInt:
|
||||
// We don't support these, ignore.
|
||||
{}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
enum Subprofile {
|
||||
kH264ConstrainedBaseline,
|
||||
kH264Baseline,
|
||||
kH264Main,
|
||||
kH264Extended,
|
||||
kH264High,
|
||||
kH264High10,
|
||||
kH264High42,
|
||||
kH264High44,
|
||||
kH264High10I,
|
||||
kH264High42I,
|
||||
kH264High44I,
|
||||
kH264CALVC44,
|
||||
kH264UnknownSubprofile
|
||||
};
|
||||
|
||||
static Subprofile
|
||||
GetSubprofile(uint32_t profileLevelId)
|
||||
{
|
||||
// Based on Table 5 from RFC 6184:
|
||||
// Profile profile_idc profile-iop
|
||||
// (hexadecimal) (binary)
|
||||
|
||||
// CB 42 (B) x1xx0000
|
||||
// same as: 4D (M) 1xxx0000
|
||||
// same as: 58 (E) 11xx0000
|
||||
// B 42 (B) x0xx0000
|
||||
// same as: 58 (E) 10xx0000
|
||||
// M 4D (M) 0x0x0000
|
||||
// E 58 00xx0000
|
||||
// H 64 00000000
|
||||
// H10 6E 00000000
|
||||
// H42 7A 00000000
|
||||
// H44 F4 00000000
|
||||
// H10I 6E 00010000
|
||||
// H42I 7A 00010000
|
||||
// H44I F4 00010000
|
||||
// C44I 2C 00010000
|
||||
|
||||
if ((profileLevelId & 0xFF4F00) == 0x424000) {
|
||||
// 01001111 (mask, 0x4F)
|
||||
// x1xx0000 (from table)
|
||||
// 01000000 (expected value, 0x40)
|
||||
return kH264ConstrainedBaseline;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFF8F00) == 0x4D8000) {
|
||||
// 10001111 (mask, 0x8F)
|
||||
// 1xxx0000 (from table)
|
||||
// 10000000 (expected value, 0x80)
|
||||
return kH264ConstrainedBaseline;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFCF00) == 0x58C000) {
|
||||
// 11001111 (mask, 0xCF)
|
||||
// 11xx0000 (from table)
|
||||
// 11000000 (expected value, 0xC0)
|
||||
return kH264ConstrainedBaseline;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFF4F00) == 0x420000) {
|
||||
// 01001111 (mask, 0x4F)
|
||||
// x0xx0000 (from table)
|
||||
// 00000000 (expected value)
|
||||
return kH264Baseline;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFCF00) == 0x588000) {
|
||||
// 11001111 (mask, 0xCF)
|
||||
// 10xx0000 (from table)
|
||||
// 10000000 (expected value, 0x80)
|
||||
return kH264Baseline;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFAF00) == 0x4D0000) {
|
||||
// 10101111 (mask, 0xAF)
|
||||
// 0x0x0000 (from table)
|
||||
// 00000000 (expected value)
|
||||
return kH264Main;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFF0000) == 0x580000) {
|
||||
// 11001111 (mask, 0xCF)
|
||||
// 00xx0000 (from table)
|
||||
// 00000000 (expected value)
|
||||
return kH264Extended;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0x640000) {
|
||||
return kH264High;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0x6E0000) {
|
||||
return kH264High10;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0x7A0000) {
|
||||
return kH264High42;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0xF40000) {
|
||||
return kH264High44;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0x6E1000) {
|
||||
return kH264High10I;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0x7A1000) {
|
||||
return kH264High42I;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0xF41000) {
|
||||
return kH264High44I;
|
||||
}
|
||||
|
||||
if ((profileLevelId & 0xFFFF00) == 0x2C1000) {
|
||||
return kH264CALVC44;
|
||||
}
|
||||
|
||||
return kH264UnknownSubprofile;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
ParametersMatch(const SdpFmtpAttributeList::Parameters* fmtp) const
|
||||
MOZ_OVERRIDE
|
||||
{
|
||||
if (mName == "H264") {
|
||||
if (!fmtp) {
|
||||
// No fmtp means that we cannot assume level asymmetry is allowed,
|
||||
// and since we have no way of knowing the profile-level-id, we can't
|
||||
// say that we match.
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* h264Params =
|
||||
static_cast<const SdpFmtpAttributeList::H264Parameters*>(fmtp);
|
||||
|
||||
if (!h264Params->level_asymmetry_allowed) {
|
||||
if (GetSubprofile(h264Params->profile_level_id) !=
|
||||
GetSubprofile(mProfileLevelId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (h264Params->packetization_mode != mPacketizationMode) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LoadH264Parameters(const SdpFmtpAttributeList::Parameters& params)
|
||||
{
|
||||
const SdpFmtpAttributeList::H264Parameters& h264Params =
|
||||
static_cast<const SdpFmtpAttributeList::H264Parameters&>(params);
|
||||
|
||||
mMaxFs = h264Params.max_fs;
|
||||
mProfileLevelId = h264Params.profile_level_id;
|
||||
mPacketizationMode = h264Params.packetization_mode;
|
||||
mMaxMbps = h264Params.max_mbps;
|
||||
mMaxCpb = h264Params.max_cpb;
|
||||
mMaxDpb = h264Params.max_dpb;
|
||||
mMaxBr = h264Params.max_br;
|
||||
mSpropParameterSets = h264Params.sprop_parameter_sets;
|
||||
}
|
||||
|
||||
void
|
||||
LoadVP8Parameters(const SdpFmtpAttributeList::Parameters& params)
|
||||
{
|
||||
const SdpFmtpAttributeList::VP8Parameters& vp8Params =
|
||||
static_cast<const SdpFmtpAttributeList::VP8Parameters&>(params);
|
||||
|
||||
mMaxFs = vp8Params.max_fs;
|
||||
mMaxFr = vp8Params.max_fr;
|
||||
}
|
||||
|
||||
JSEP_CODEC_CLONE(JsepVideoCodecDescription)
|
||||
|
||||
std::vector<std::string> mAckFbTypes;
|
||||
std::vector<std::string> mNackFbTypes;
|
||||
std::vector<std::string> mCcmFbTypes;
|
||||
|
||||
uint32_t mMaxFs;
|
||||
|
||||
// H264-specific stuff
|
||||
uint32_t mProfileLevelId;
|
||||
uint32_t mMaxFr;
|
||||
uint32_t mPacketizationMode;
|
||||
uint32_t mMaxMbps;
|
||||
uint32_t mMaxCpb;
|
||||
uint32_t mMaxDpb;
|
||||
uint32_t mMaxBr;
|
||||
std::string mSpropParameterSets;
|
||||
};
|
||||
|
||||
struct JsepApplicationCodecDescription : public JsepCodecDescription {
|
||||
JsepApplicationCodecDescription(const std::string& defaultPt,
|
||||
const std::string& name,
|
||||
uint16_t channels,
|
||||
bool enabled = true)
|
||||
: JsepCodecDescription(mozilla::SdpMediaSection::kApplication, defaultPt,
|
||||
name, 0, channels, enabled)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddFmtps(SdpFmtpAttributeList& fmtp) const MOZ_OVERRIDE
|
||||
{
|
||||
// TODO: Is there anything to do here?
|
||||
}
|
||||
|
||||
virtual void
|
||||
AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const MOZ_OVERRIDE
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
virtual bool
|
||||
LoadFmtps(const SdpFmtpAttributeList::Parameters& params) MOZ_OVERRIDE
|
||||
{
|
||||
// TODO: Is there anything to do here?
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) MOZ_OVERRIDE
|
||||
{
|
||||
// Nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
JSEP_CODEC_CLONE(JsepApplicationCodecDescription)
|
||||
|
||||
// Override, uses sctpmap instead of rtpmap
|
||||
virtual bool
|
||||
Matches(const std::string& fmt,
|
||||
const SdpMediaSection& remoteMsection) const MOZ_OVERRIDE
|
||||
{
|
||||
auto& attrs = remoteMsection.GetAttributeList();
|
||||
if (!attrs.HasAttribute(SdpAttribute::kSctpmapAttribute)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const SdpSctpmapAttributeList& sctpmap = attrs.GetSctpmap();
|
||||
if (!sctpmap.HasEntry(fmt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const SdpSctpmapAttributeList::Sctpmap& entry = sctpmap.GetEntry(fmt);
|
||||
|
||||
if (mType == remoteMsection.GetMediaType() && (mName == entry.name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,164 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _JSEPSESSION_H_
|
||||
#define _JSEPSESSION_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepTransport.h"
|
||||
#include "signaling/src/sdp/Sdp.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Forward declarations
|
||||
struct JsepCodecDescription;
|
||||
class JsepTrack;
|
||||
struct JsepTrackPair;
|
||||
|
||||
enum JsepSignalingState {
|
||||
kJsepStateStable,
|
||||
kJsepStateHaveLocalOffer,
|
||||
kJsepStateHaveRemoteOffer,
|
||||
kJsepStateHaveLocalPranswer,
|
||||
kJsepStateHaveRemotePranswer,
|
||||
kJsepStateClosed
|
||||
};
|
||||
|
||||
enum JsepSdpType {
|
||||
kJsepSdpOffer,
|
||||
kJsepSdpAnswer,
|
||||
kJsepSdpPranswer,
|
||||
};
|
||||
|
||||
struct JsepOAOptions {};
|
||||
struct JsepOfferOptions : public JsepOAOptions {
|
||||
Maybe<size_t> mOfferToReceiveAudio;
|
||||
Maybe<size_t> mOfferToReceiveVideo;
|
||||
Maybe<bool> mDontOfferDataChannel;
|
||||
};
|
||||
struct JsepAnswerOptions : public JsepOAOptions {};
|
||||
|
||||
class JsepSession
|
||||
{
|
||||
public:
|
||||
explicit JsepSession(const std::string& name)
|
||||
: mName(name), mState(kJsepStateStable)
|
||||
{
|
||||
}
|
||||
virtual ~JsepSession() {}
|
||||
|
||||
virtual nsresult Init() = 0;
|
||||
|
||||
// Accessors for basic properties.
|
||||
virtual const std::string&
|
||||
GetName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
virtual JsepSignalingState
|
||||
GetState() const
|
||||
{
|
||||
return mState;
|
||||
}
|
||||
|
||||
// Set up the ICE And DTLS data.
|
||||
virtual nsresult SetIceCredentials(const std::string& ufrag,
|
||||
const std::string& pwd) = 0;
|
||||
virtual bool RemoteIsIceLite() const = 0;
|
||||
virtual std::vector<std::string> GetIceOptions() const = 0;
|
||||
|
||||
virtual nsresult AddDtlsFingerprint(const std::string& algorithm,
|
||||
const std::vector<uint8_t>& value) = 0;
|
||||
|
||||
virtual nsresult AddAudioRtpExtension(const std::string& extensionName) = 0;
|
||||
virtual nsresult AddVideoRtpExtension(const std::string& extensionName) = 0;
|
||||
|
||||
// Kinda gross to be locking down the data structure type like this, but
|
||||
// returning by value is problematic due to the lack of stl move semantics in
|
||||
// our build config, since we can't use UniquePtr in the container. The
|
||||
// alternative is writing a raft of accessor functions that allow arbitrary
|
||||
// manipulation (which will be unwieldy), or allowing functors to be injected
|
||||
// that manipulate the data structure (still pretty unwieldy).
|
||||
virtual std::vector<JsepCodecDescription*>& Codecs() = 0;
|
||||
|
||||
// Manage tracks. We take shared ownership of any track.
|
||||
virtual nsresult AddTrack(const RefPtr<JsepTrack>& track) = 0;
|
||||
virtual nsresult RemoveTrack(size_t track_index) = 0;
|
||||
virtual nsresult ReplaceTrack(size_t track_index,
|
||||
const RefPtr<JsepTrack>& track) = 0;
|
||||
|
||||
virtual size_t GetLocalTrackCount() const = 0;
|
||||
virtual nsresult GetLocalTrack(size_t index,
|
||||
RefPtr<JsepTrack>* track) const = 0;
|
||||
|
||||
virtual size_t GetRemoteTrackCount() const = 0;
|
||||
virtual nsresult GetRemoteTrack(size_t index,
|
||||
RefPtr<JsepTrack>* track) const = 0;
|
||||
|
||||
// Access the negotiated track pairs.
|
||||
virtual size_t GetNegotiatedTrackPairCount() const = 0;
|
||||
virtual nsresult GetNegotiatedTrackPair(size_t index,
|
||||
const JsepTrackPair** pair) const = 0;
|
||||
|
||||
// Access transports.
|
||||
virtual size_t GetTransportCount() const = 0;
|
||||
virtual nsresult GetTransport(size_t index,
|
||||
RefPtr<JsepTransport>* transport) const = 0;
|
||||
|
||||
// Basic JSEP operations.
|
||||
virtual nsresult CreateOffer(const JsepOfferOptions& options,
|
||||
std::string* offer) = 0;
|
||||
virtual nsresult CreateAnswer(const JsepAnswerOptions& options,
|
||||
std::string* answer) = 0;
|
||||
virtual std::string GetLocalDescription() const = 0;
|
||||
virtual std::string GetRemoteDescription() const = 0;
|
||||
virtual nsresult SetLocalDescription(JsepSdpType type,
|
||||
const std::string& sdp) = 0;
|
||||
virtual nsresult SetRemoteDescription(JsepSdpType type,
|
||||
const std::string& sdp) = 0;
|
||||
virtual nsresult AddRemoteIceCandidate(const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint16_t level) = 0;
|
||||
virtual nsresult AddLocalIceCandidate(const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint16_t level) = 0;
|
||||
virtual nsresult EndOfLocalCandidates(const std::string& defaultCandidateAddr,
|
||||
uint16_t defaultCandidatePort,
|
||||
uint16_t level) = 0;
|
||||
virtual nsresult Close() = 0;
|
||||
|
||||
// ICE controlling or controlled
|
||||
virtual bool IsIceControlling() const = 0;
|
||||
|
||||
virtual const std::string
|
||||
GetLastError() const
|
||||
{
|
||||
return "Error";
|
||||
}
|
||||
|
||||
static const char*
|
||||
GetStateStr(JsepSignalingState state)
|
||||
{
|
||||
static const char* states[] = { "stable", "have-local-offer",
|
||||
"have-remote-offer", "have-local-pranswer",
|
||||
"have-remote-pranswer", "closed" };
|
||||
|
||||
return states[state];
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::string mName;
|
||||
JsepSignalingState mState;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,302 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _JSEPSESSIONIMPL_H_
|
||||
#define _JSEPSESSIONIMPL_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "signaling/src/jsep/JsepCodecDescription.h"
|
||||
#include "signaling/src/jsep/JsepTrack.h"
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "signaling/src/jsep/JsepTrack.h"
|
||||
#include "signaling/src/jsep/JsepTrackImpl.h"
|
||||
#include "signaling/src/sdp/SipccSdpParser.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class JsepUuidGenerator
|
||||
{
|
||||
public:
|
||||
virtual ~JsepUuidGenerator() {}
|
||||
virtual bool Generate(std::string* id) = 0;
|
||||
};
|
||||
|
||||
class JsepSessionImpl : public JsepSession
|
||||
{
|
||||
public:
|
||||
JsepSessionImpl(const std::string& name, UniquePtr<JsepUuidGenerator> uuidgen)
|
||||
: JsepSession(name),
|
||||
mIsOfferer(false),
|
||||
mIceControlling(false),
|
||||
mRemoteIsIceLite(false),
|
||||
mSessionId(0),
|
||||
mSessionVersion(0),
|
||||
mUuidGen(Move(uuidgen))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~JsepSessionImpl();
|
||||
|
||||
// Implement JsepSession methods.
|
||||
virtual nsresult Init() MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult AddTrack(const RefPtr<JsepTrack>& track) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult
|
||||
RemoveTrack(size_t trackIndex) MOZ_OVERRIDE
|
||||
{
|
||||
mLastError.clear();
|
||||
MOZ_CRASH(); // Stub
|
||||
}
|
||||
|
||||
virtual nsresult SetIceCredentials(const std::string& ufrag,
|
||||
const std::string& pwd) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RemoteIsIceLite() const MOZ_OVERRIDE
|
||||
{
|
||||
return mRemoteIsIceLite;
|
||||
}
|
||||
|
||||
virtual std::vector<std::string>
|
||||
GetIceOptions() const MOZ_OVERRIDE
|
||||
{
|
||||
return mIceOptions;
|
||||
}
|
||||
|
||||
virtual nsresult AddDtlsFingerprint(const std::string& algorithm,
|
||||
const std::vector<uint8_t>& value) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult AddAudioRtpExtension(
|
||||
const std::string& extensionName) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult AddVideoRtpExtension(
|
||||
const std::string& extensionName) MOZ_OVERRIDE;
|
||||
|
||||
virtual std::vector<JsepCodecDescription*>&
|
||||
Codecs() MOZ_OVERRIDE
|
||||
{
|
||||
return mCodecs;
|
||||
}
|
||||
|
||||
virtual nsresult
|
||||
ReplaceTrack(size_t trackIndex, const RefPtr<JsepTrack>& track) MOZ_OVERRIDE
|
||||
{
|
||||
mLastError.clear();
|
||||
MOZ_CRASH(); // Stub
|
||||
}
|
||||
|
||||
virtual size_t
|
||||
GetLocalTrackCount() const MOZ_OVERRIDE
|
||||
{
|
||||
return mLocalTracks.size();
|
||||
}
|
||||
|
||||
virtual nsresult GetLocalTrack(size_t index,
|
||||
RefPtr<JsepTrack>* track) const MOZ_OVERRIDE;
|
||||
|
||||
virtual size_t
|
||||
GetRemoteTrackCount() const MOZ_OVERRIDE
|
||||
{
|
||||
return mRemoteTracks.size();
|
||||
}
|
||||
|
||||
virtual nsresult GetRemoteTrack(size_t index,
|
||||
RefPtr<JsepTrack>* track) const MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult CreateOffer(const JsepOfferOptions& options,
|
||||
std::string* offer) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult CreateAnswer(const JsepAnswerOptions& options,
|
||||
std::string* answer) MOZ_OVERRIDE;
|
||||
|
||||
virtual std::string GetLocalDescription() const MOZ_OVERRIDE;
|
||||
|
||||
virtual std::string GetRemoteDescription() const MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult SetLocalDescription(JsepSdpType type,
|
||||
const std::string& sdp) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult SetRemoteDescription(JsepSdpType type,
|
||||
const std::string& sdp) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult AddRemoteIceCandidate(const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint16_t level) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult AddLocalIceCandidate(const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint16_t level) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult EndOfLocalCandidates(const std::string& defaultCandidateAddr,
|
||||
uint16_t defaultCandidatePort,
|
||||
uint16_t level) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult Close() MOZ_OVERRIDE;
|
||||
|
||||
virtual const std::string GetLastError() const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
IsIceControlling() const
|
||||
{
|
||||
return mIceControlling;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
IsOfferer() const
|
||||
{
|
||||
return mIsOfferer;
|
||||
}
|
||||
|
||||
// Access transports.
|
||||
virtual size_t
|
||||
GetTransportCount() const MOZ_OVERRIDE
|
||||
{
|
||||
return mTransports.size();
|
||||
}
|
||||
|
||||
virtual nsresult
|
||||
GetTransport(size_t index,
|
||||
RefPtr<JsepTransport>* transport) const MOZ_OVERRIDE
|
||||
{
|
||||
if (index >= mTransports.size())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
*transport = mTransports[index];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Access the negotiated track pairs.
|
||||
virtual size_t
|
||||
GetNegotiatedTrackPairCount() const MOZ_OVERRIDE
|
||||
{
|
||||
return mNegotiatedTrackPairs.size();
|
||||
}
|
||||
|
||||
virtual nsresult
|
||||
GetNegotiatedTrackPair(size_t index, const JsepTrackPair** pair) const
|
||||
{
|
||||
if (index >= mNegotiatedTrackPairs.size())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
*pair = &mNegotiatedTrackPairs[index];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
struct JsepDtlsFingerprint {
|
||||
std::string mAlgorithm;
|
||||
std::vector<uint8_t> mValue;
|
||||
};
|
||||
|
||||
struct JsepSendingTrack {
|
||||
RefPtr<JsepTrack> mTrack;
|
||||
Maybe<size_t> mAssignedMLine;
|
||||
};
|
||||
|
||||
struct JsepReceivingTrack {
|
||||
RefPtr<JsepTrack> mTrack;
|
||||
Maybe<size_t> mAssignedMLine;
|
||||
};
|
||||
|
||||
// Non-const so it can set mLastError
|
||||
nsresult CreateGenericSDP(UniquePtr<Sdp>* sdp);
|
||||
void AddCodecs(SdpMediaSection* msection) const;
|
||||
void AddExtmap(SdpMediaSection* msection) const;
|
||||
JsepCodecDescription* FindMatchingCodec(
|
||||
const std::string& pt,
|
||||
const SdpMediaSection& msection) const;
|
||||
const std::vector<SdpExtmapAttributeList::Extmap>* GetRtpExtensions(
|
||||
SdpMediaSection::MediaType type) const;
|
||||
void AddCommonCodecs(const SdpMediaSection& remoteMsection,
|
||||
SdpMediaSection* msection);
|
||||
void AddCommonExtmaps(const SdpMediaSection& remoteMsection,
|
||||
SdpMediaSection* msection);
|
||||
void SetupDefaultCodecs();
|
||||
void SetupDefaultRtpExtensions();
|
||||
void SetState(JsepSignalingState state);
|
||||
// Non-const so it can set mLastError
|
||||
nsresult ParseSdp(const std::string& sdp, UniquePtr<Sdp>* parsedp);
|
||||
nsresult SetLocalDescriptionOffer(UniquePtr<Sdp> offer);
|
||||
nsresult SetLocalDescriptionAnswer(JsepSdpType type, UniquePtr<Sdp> answer);
|
||||
nsresult SetRemoteDescriptionOffer(UniquePtr<Sdp> offer);
|
||||
nsresult SetRemoteDescriptionAnswer(JsepSdpType type, UniquePtr<Sdp> answer);
|
||||
nsresult ValidateLocalDescription(const Sdp& description);
|
||||
nsresult SetRemoteTracksFromDescription(const Sdp& remoteDescription);
|
||||
// Non-const because we use our Uuid generator
|
||||
nsresult CreateReceivingTrack(size_t mline, const SdpMediaSection& msection);
|
||||
nsresult HandleNegotiatedSession(const UniquePtr<Sdp>& local,
|
||||
const UniquePtr<Sdp>& remote);
|
||||
nsresult DetermineSendingDirection(SdpDirectionAttribute::Direction offer,
|
||||
SdpDirectionAttribute::Direction answer,
|
||||
bool* sending, bool* receiving);
|
||||
nsresult AddTransportAttributes(SdpMediaSection* msection,
|
||||
SdpSetupAttribute::Role dtlsRole);
|
||||
// Non-const so it can assign m-line index to tracks
|
||||
nsresult AddOfferMSectionsByType(SdpMediaSection::MediaType type,
|
||||
Maybe<size_t> offerToReceive,
|
||||
Sdp* sdp);
|
||||
nsresult CreateOfferMSection(SdpMediaSection::MediaType type,
|
||||
SdpDirectionAttribute::Direction direction,
|
||||
SdpMediaSection::Protocol proto,
|
||||
Sdp* sdp);
|
||||
nsresult CreateAnswerMSection(const JsepAnswerOptions& options,
|
||||
size_t mlineIndex,
|
||||
const SdpMediaSection& remoteMsection,
|
||||
SdpMediaSection* msection,
|
||||
Sdp* sdp);
|
||||
nsresult DetermineAnswererSetupRole(const SdpMediaSection& remoteMsection,
|
||||
SdpSetupAttribute::Role* rolep);
|
||||
nsresult NegotiateTrack(const SdpMediaSection& remoteMsection,
|
||||
const SdpMediaSection& localMsection,
|
||||
JsepTrack::Direction,
|
||||
RefPtr<JsepTrack>* track);
|
||||
|
||||
nsresult CreateTransport(const SdpMediaSection& msection,
|
||||
RefPtr<JsepTransport>* transport);
|
||||
|
||||
nsresult SetupTransport(const SdpAttributeList& remote,
|
||||
const SdpAttributeList& answer,
|
||||
const RefPtr<JsepTransport>& transport);
|
||||
|
||||
nsresult AddCandidateToSdp(Sdp* sdp,
|
||||
const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint16_t level);
|
||||
|
||||
std::vector<JsepSendingTrack> mLocalTracks;
|
||||
std::vector<JsepReceivingTrack> mRemoteTracks;
|
||||
std::vector<RefPtr<JsepTransport> > mTransports;
|
||||
std::vector<JsepTrackPair> mNegotiatedTrackPairs;
|
||||
|
||||
bool mIsOfferer;
|
||||
bool mIceControlling;
|
||||
std::string mIceUfrag;
|
||||
std::string mIcePwd;
|
||||
bool mRemoteIsIceLite;
|
||||
std::vector<std::string> mIceOptions;
|
||||
std::vector<JsepDtlsFingerprint> mDtlsFingerprints;
|
||||
uint64_t mSessionId;
|
||||
uint64_t mSessionVersion;
|
||||
std::vector<SdpExtmapAttributeList::Extmap> mAudioRtpExtensions;
|
||||
std::vector<SdpExtmapAttributeList::Extmap> mVideoRtpExtensions;
|
||||
UniquePtr<JsepUuidGenerator> mUuidGen;
|
||||
std::string mDefaultRemoteStreamId;
|
||||
UniquePtr<Sdp> mGeneratedLocalDescription; // Created but not set.
|
||||
UniquePtr<Sdp> mCurrentLocalDescription;
|
||||
UniquePtr<Sdp> mCurrentRemoteDescription;
|
||||
UniquePtr<Sdp> mPendingLocalDescription;
|
||||
UniquePtr<Sdp> mPendingRemoteDescription;
|
||||
std::vector<JsepCodecDescription*> mCodecs;
|
||||
std::string mLastError;
|
||||
SipccSdpParser mParser;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,120 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _JSEPTRACK_H_
|
||||
#define _JSEPTRACK_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <mozilla/RefPtr.h>
|
||||
#include <mozilla/UniquePtr.h>
|
||||
#include <mozilla/Maybe.h>
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepTransport.h"
|
||||
#include "signaling/src/sdp/Sdp.h"
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Forward reference.
|
||||
struct JsepCodecDescription;
|
||||
|
||||
class JsepTrackNegotiatedDetails
|
||||
{
|
||||
public:
|
||||
virtual ~JsepTrackNegotiatedDetails() {}
|
||||
|
||||
virtual mozilla::SdpMediaSection::Protocol GetProtocol() const = 0;
|
||||
virtual Maybe<std::string> GetBandwidth(const std::string& type) const = 0;
|
||||
virtual size_t GetCodecCount() const = 0;
|
||||
virtual nsresult GetCodec(size_t index,
|
||||
const JsepCodecDescription** config) const = 0;
|
||||
virtual const SdpExtmapAttributeList::Extmap* GetExt(
|
||||
const std::string& ext_name) const = 0;
|
||||
};
|
||||
|
||||
class JsepTrack
|
||||
{
|
||||
public:
|
||||
enum Direction { kJsepTrackSending, kJsepTrackReceiving };
|
||||
|
||||
JsepTrack(mozilla::SdpMediaSection::MediaType type,
|
||||
const std::string& streamid,
|
||||
const std::string& trackid,
|
||||
Direction direction = kJsepTrackSending)
|
||||
: mType(type),
|
||||
mStreamId(streamid),
|
||||
mTrackId(trackid),
|
||||
mDirection(direction)
|
||||
{
|
||||
}
|
||||
|
||||
virtual mozilla::SdpMediaSection::MediaType
|
||||
GetMediaType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
virtual const std::string&
|
||||
GetStreamId() const
|
||||
{
|
||||
return mStreamId;
|
||||
}
|
||||
|
||||
virtual const std::string&
|
||||
GetTrackId() const
|
||||
{
|
||||
return mTrackId;
|
||||
}
|
||||
|
||||
virtual Direction
|
||||
GetDirection() const
|
||||
{
|
||||
return mDirection;
|
||||
}
|
||||
|
||||
// This will be set when negotiation is carried out.
|
||||
virtual const JsepTrackNegotiatedDetails*
|
||||
GetNegotiatedDetails() const
|
||||
{
|
||||
if (mNegotiatedDetails) {
|
||||
return mNegotiatedDetails.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This is for JsepSession's use.
|
||||
virtual void
|
||||
SetNegotiatedDetails(UniquePtr<JsepTrackNegotiatedDetails> details)
|
||||
{
|
||||
mNegotiatedDetails = Move(details);
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(JsepTrack);
|
||||
|
||||
protected:
|
||||
virtual ~JsepTrack() {}
|
||||
|
||||
private:
|
||||
const mozilla::SdpMediaSection::MediaType mType;
|
||||
const std::string mStreamId;
|
||||
const std::string mTrackId;
|
||||
const Direction mDirection;
|
||||
UniquePtr<JsepTrackNegotiatedDetails> mNegotiatedDetails;
|
||||
};
|
||||
|
||||
// Need a better name for this.
|
||||
struct JsepTrackPair {
|
||||
size_t mLevel;
|
||||
RefPtr<JsepTrack> mSending;
|
||||
RefPtr<JsepTrack> mReceiving;
|
||||
RefPtr<JsepTransport> mRtpTransport;
|
||||
RefPtr<JsepTransport> mRtcpTransport;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,79 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _JSEPTRACKIMPL_H_
|
||||
#define _JSEPTRACKIMPL_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <mozilla/RefPtr.h>
|
||||
#include <mozilla/UniquePtr.h>
|
||||
|
||||
#include "signaling/src/jsep/JsepCodecDescription.h"
|
||||
#include "signaling/src/jsep/JsepTrack.h"
|
||||
#include "signaling/src/sdp/Sdp.h"
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class JsepTrackNegotiatedDetailsImpl : public JsepTrackNegotiatedDetails
|
||||
{
|
||||
public:
|
||||
virtual ~JsepTrackNegotiatedDetailsImpl()
|
||||
{
|
||||
for (auto c = mCodecs.begin(); c != mCodecs.end(); ++c) {
|
||||
delete *c;
|
||||
}
|
||||
}
|
||||
|
||||
// Implement JsepTrackNegotiatedDetails.
|
||||
virtual mozilla::SdpMediaSection::Protocol
|
||||
GetProtocol() const MOZ_OVERRIDE
|
||||
{
|
||||
return mProtocol;
|
||||
}
|
||||
virtual Maybe<std::string>
|
||||
GetBandwidth(const std::string& type) const MOZ_OVERRIDE
|
||||
{
|
||||
return mBandwidth;
|
||||
}
|
||||
virtual size_t
|
||||
GetCodecCount() const MOZ_OVERRIDE
|
||||
{
|
||||
return mCodecs.size();
|
||||
}
|
||||
virtual nsresult
|
||||
GetCodec(size_t index, const JsepCodecDescription** config) const MOZ_OVERRIDE
|
||||
{
|
||||
if (index >= mCodecs.size()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
*config = mCodecs[index];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual const SdpExtmapAttributeList::Extmap*
|
||||
GetExt(const std::string& ext_name) const MOZ_OVERRIDE
|
||||
{
|
||||
auto it = mExtmap.find(ext_name);
|
||||
if (it != mExtmap.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// Make these friends to JsepSessionImpl to avoid having to
|
||||
// write setters.
|
||||
friend class JsepSessionImpl;
|
||||
|
||||
mozilla::SdpMediaSection::Protocol mProtocol;
|
||||
Maybe<std::string> mBandwidth;
|
||||
std::vector<JsepCodecDescription*> mCodecs;
|
||||
std::map<std::string, SdpExtmapAttributeList::Extmap> mExtmap;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,117 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _JSEPTRANSPORT_H_
|
||||
#define _JSEPTRANSPORT_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <mozilla/RefPtr.h>
|
||||
#include <mozilla/UniquePtr.h>
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "signaling/src/sdp/SdpAttribute.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class JsepDtlsTransport
|
||||
{
|
||||
public:
|
||||
JsepDtlsTransport() : mRole(kJsepDtlsInvalidRole) {}
|
||||
|
||||
virtual ~JsepDtlsTransport() {}
|
||||
|
||||
enum Role {
|
||||
kJsepDtlsClient,
|
||||
kJsepDtlsServer,
|
||||
kJsepDtlsInvalidRole
|
||||
};
|
||||
|
||||
virtual const SdpFingerprintAttributeList&
|
||||
GetFingerprints() const
|
||||
{
|
||||
return mFingerprints;
|
||||
}
|
||||
|
||||
virtual Role
|
||||
GetRole() const
|
||||
{
|
||||
return mRole;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class JsepSessionImpl;
|
||||
|
||||
SdpFingerprintAttributeList mFingerprints;
|
||||
Role mRole;
|
||||
};
|
||||
|
||||
class JsepIceTransport
|
||||
{
|
||||
public:
|
||||
JsepIceTransport() {}
|
||||
|
||||
virtual ~JsepIceTransport() {}
|
||||
|
||||
const std::string&
|
||||
GetUfrag() const
|
||||
{
|
||||
return mUfrag;
|
||||
}
|
||||
const std::string&
|
||||
GetPassword() const
|
||||
{
|
||||
return mPwd;
|
||||
}
|
||||
const std::vector<std::string>&
|
||||
GetCandidates() const
|
||||
{
|
||||
return mCandidates;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class JsepSessionImpl;
|
||||
|
||||
std::string mUfrag;
|
||||
std::string mPwd;
|
||||
std::vector<std::string> mCandidates;
|
||||
};
|
||||
|
||||
class JsepTransport
|
||||
{
|
||||
public:
|
||||
JsepTransport(const std::string& id, size_t components)
|
||||
: mTransportId(id), mState(kJsepTransportOffered), mComponents(components)
|
||||
{
|
||||
}
|
||||
|
||||
enum State {
|
||||
kJsepTransportOffered,
|
||||
kJsepTransportAccepted,
|
||||
kJsepTransportClosed
|
||||
};
|
||||
|
||||
// Unique identifier for this transport within this call. Group?
|
||||
std::string mTransportId;
|
||||
|
||||
// State.
|
||||
State mState;
|
||||
|
||||
// ICE stuff.
|
||||
UniquePtr<JsepIceTransport> mIce;
|
||||
UniquePtr<JsepDtlsTransport> mDtls;
|
||||
|
||||
// Number of required components.
|
||||
size_t mComponents;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(JsepTransport);
|
||||
|
||||
protected:
|
||||
~JsepTransport() {}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -861,10 +861,6 @@ WebrtcAudioConduit::CodecConfigToWebRTCCodec(const AudioCodecConfig* codecInfo,
|
|||
cinst.rate = codecInfo->mRate;
|
||||
cinst.pacsize = codecInfo->mPacSize;
|
||||
cinst.plfreq = codecInfo->mFreq;
|
||||
if (codecInfo->mName == "G722") {
|
||||
// Compensate for G.722 spec error in RFC 1890
|
||||
cinst.plfreq = 16000;
|
||||
}
|
||||
cinst.channels = codecInfo->mChannels;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define CODEC_CONFIG_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ccsdp_rtcp_fb.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -76,11 +76,7 @@ public:
|
|||
*/
|
||||
int mType; // payload type
|
||||
std::string mName;
|
||||
|
||||
std::vector<std::string> mAckFbTypes;
|
||||
std::vector<std::string> mNackFbTypes;
|
||||
std::vector<std::string> mCcmFbTypes;
|
||||
|
||||
uint32_t mRtcpFbTypes;
|
||||
unsigned int mMaxFrameSize;
|
||||
unsigned int mMaxFrameRate;
|
||||
unsigned int mMaxMBPS; // in macroblocks-per-second
|
||||
|
@ -95,11 +91,13 @@ public:
|
|||
|
||||
VideoCodecConfig(int type,
|
||||
std::string name,
|
||||
int rtcpFbTypes,
|
||||
unsigned int max_fs = 0,
|
||||
unsigned int max_fr = 0,
|
||||
const struct VideoCodecConfigH264 *h264 = nullptr) :
|
||||
mType(type),
|
||||
mName(name),
|
||||
mRtcpFbTypes(rtcpFbTypes),
|
||||
mMaxFrameSize(max_fs), // may be overridden
|
||||
mMaxFrameRate(max_fr),
|
||||
mMaxMBPS(0),
|
||||
|
@ -123,36 +121,19 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Nothing seems to use this right now. Do we intend to support this
|
||||
// someday?
|
||||
bool RtcpFbAckIsSet(const std::string& type) const
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_nack_type_e type) const
|
||||
{
|
||||
for (auto i = mAckFbTypes.begin(); i != mAckFbTypes.end(); ++i) {
|
||||
if (*i == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return mRtcpFbTypes & sdp_rtcp_fb_nack_to_bitmap(type);
|
||||
}
|
||||
|
||||
bool RtcpFbNackIsSet(const std::string& type) const
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_ack_type_e type) const
|
||||
{
|
||||
for (auto i = mNackFbTypes.begin(); i != mNackFbTypes.end(); ++i) {
|
||||
if (*i == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return mRtcpFbTypes & sdp_rtcp_fb_ack_to_bitmap(type);
|
||||
}
|
||||
|
||||
bool RtcpFbCcmIsSet(const std::string& type) const
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_ccm_type_e type) const
|
||||
{
|
||||
for (auto i = mCcmFbTypes.begin(); i != mCcmFbTypes.end(); ++i) {
|
||||
if (*i == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return mRtcpFbTypes & sdp_rtcp_fb_ccm_to_bitmap(type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -288,21 +288,21 @@ MediaConduitErrorCode WebrtcVideoConduit::Init(WebrtcVideoConduit *other)
|
|||
if (branch)
|
||||
{
|
||||
int32_t temp;
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable)));
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.min_bitrate", &temp)));
|
||||
NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable)));
|
||||
NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.min_bitrate", &temp)));
|
||||
if (temp >= 0) {
|
||||
mMinBitrate = temp;
|
||||
}
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.start_bitrate", &temp)));
|
||||
NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.start_bitrate", &temp)));
|
||||
if (temp >= 0) {
|
||||
mStartBitrate = temp;
|
||||
}
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.max_bitrate", &temp)));
|
||||
NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.max_bitrate", &temp)));
|
||||
if (temp >= 0) {
|
||||
mMaxBitrate = temp;
|
||||
}
|
||||
bool use_loadmanager = false;
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.navigator.load_adapt", &use_loadmanager)));
|
||||
NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.navigator.load_adapt", &use_loadmanager)));
|
||||
if (use_loadmanager) {
|
||||
mLoadManager = LoadManagerBuild();
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
|||
mSendingWidth = 0;
|
||||
mSendingHeight = 0;
|
||||
|
||||
if(codecConfig->RtcpFbNackIsSet("")) {
|
||||
if(codecConfig->RtcpFbIsSet(SDP_RTCP_FB_NACK_BASIC)) {
|
||||
CSFLogDebug(logTag, "Enabling NACK (send) for video stream\n");
|
||||
if (mPtrRTP->SetNACKStatus(mChannel, true) != 0)
|
||||
{
|
||||
|
@ -740,17 +740,17 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
|
|||
|
||||
// Check for the keyframe request type: PLI is preferred
|
||||
// over FIR, and FIR is preferred over none.
|
||||
if (codecConfigList[i]->RtcpFbNackIsSet("pli"))
|
||||
if (codecConfigList[i]->RtcpFbIsSet(SDP_RTCP_FB_NACK_PLI))
|
||||
{
|
||||
kf_request = webrtc::kViEKeyFrameRequestPliRtcp;
|
||||
} else if(kf_request == webrtc::kViEKeyFrameRequestNone &&
|
||||
codecConfigList[i]->RtcpFbCcmIsSet("fir"))
|
||||
codecConfigList[i]->RtcpFbIsSet(SDP_RTCP_FB_CCM_FIR))
|
||||
{
|
||||
kf_request = webrtc::kViEKeyFrameRequestFirRtcp;
|
||||
}
|
||||
|
||||
// Check whether NACK is requested
|
||||
if(codecConfigList[i]->RtcpFbNackIsSet(""))
|
||||
if(codecConfigList[i]->RtcpFbIsSet(SDP_RTCP_FB_NACK_BASIC))
|
||||
{
|
||||
use_nack_basic = true;
|
||||
}
|
||||
|
@ -1278,7 +1278,7 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo,
|
|||
// hand or from a config fetched with GetConfig(); this modifies the config
|
||||
// to match parameters from VideoCodecConfig
|
||||
cinst.plType = codecInfo->mType;
|
||||
if (codecInfo->mName == "H264") {
|
||||
if (codecInfo->mName == "H264_P0" || codecInfo->mName == "H264_P1") {
|
||||
cinst.codecType = webrtc::kVideoCodecH264;
|
||||
PL_strncpyz(cinst.plName, "H264", sizeof(cinst.plName));
|
||||
} else if (codecInfo->mName == "VP8") {
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CSFLog.h"
|
||||
#include "CSFVideoControlWrapper.h"
|
||||
|
||||
static const char* logTag = "VcmSipccBinding";
|
||||
|
||||
namespace CSF {
|
||||
|
||||
void VideoControlWrapper::setVideoMode( bool enable )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
_realVideoControl->setVideoMode(enable);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to setVideoMode to %s for expired video control",
|
||||
enable ? "TRUE" : "FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
void VideoControlWrapper::setPreviewWindow( VideoWindowHandle window, int top, int left, int bottom, int right, RenderScaling style )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
_realVideoControl->setPreviewWindow(window, top, left, bottom, right, style);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to setPreviewWindow for expired video control");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VideoControlWrapper::showPreviewWindow( bool show )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
_realVideoControl->showPreviewWindow(show);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to showPreviewWindow( %s ) for expired video control",
|
||||
show ? "TRUE" : "FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> VideoControlWrapper::getCaptureDevices()
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
return _realVideoControl->getCaptureDevices();
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to getCaptureDevices for expired video control");
|
||||
std::vector<std::string> vec;
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string VideoControlWrapper::getCaptureDevice()
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
return _realVideoControl->getCaptureDevice();
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to getCaptureDevice for expired video control");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoControlWrapper::setCaptureDevice( const std::string& name )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
return _realVideoControl->setCaptureDevice(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to setCaptureDevice to %s for expired video control",
|
||||
name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,90 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _CSF_VCM_SIPCC_BINDING_H_
|
||||
#define _CSF_VCM_SIPCC_BINDING_H_
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
|
||||
class nsIThread;
|
||||
class nsIEventTarget;
|
||||
class nsIPrefBranch;
|
||||
|
||||
namespace mozilla {
|
||||
class NrIceMediaStream;
|
||||
};
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class AudioTermination;
|
||||
class VideoTermination;
|
||||
class AudioControl;
|
||||
class VideoControl;
|
||||
class MediaProvider;
|
||||
class MediaProviderObserver;
|
||||
|
||||
class StreamObserver
|
||||
{
|
||||
public:
|
||||
virtual void registerStream(cc_call_handle_t call, int streamId, bool isVideo) = 0;
|
||||
virtual void deregisterStream(cc_call_handle_t call, int streamId) = 0;
|
||||
virtual void dtmfBurst(int digit, int direction, int duration) = 0;
|
||||
virtual void sendIFrame(cc_call_handle_t call) = 0;
|
||||
};
|
||||
|
||||
class VcmSIPCCBinding
|
||||
{
|
||||
public:
|
||||
VcmSIPCCBinding ();
|
||||
virtual ~VcmSIPCCBinding();
|
||||
|
||||
// The getter is only for use by the vcm_* impl functions.
|
||||
void setStreamObserver(StreamObserver*);
|
||||
static StreamObserver* getStreamObserver();
|
||||
|
||||
static AudioTermination * getAudioTermination();
|
||||
static VideoTermination * getVideoTermination();
|
||||
|
||||
static AudioControl * getAudioControl();
|
||||
static VideoControl * getVideoControl();
|
||||
|
||||
void setMediaProviderObserver(MediaProviderObserver* obs);
|
||||
static MediaProviderObserver * getMediaProviderObserver();
|
||||
|
||||
static void setAudioCodecs(int codecMask);
|
||||
static void setVideoCodecs(int codecMask);
|
||||
|
||||
static int getAudioCodecs();
|
||||
static int getVideoCodecs();
|
||||
static int getVideoCodecsGmp();
|
||||
static int getVideoCodecsHw();
|
||||
|
||||
static void setMainThread(nsIThread *thread);
|
||||
static nsIThread *getMainThread();
|
||||
|
||||
static nsCOMPtr<nsIPrefBranch> getPrefBranch();
|
||||
|
||||
static int gVideoCodecGmpMask;
|
||||
private:
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mGMPService;
|
||||
static VcmSIPCCBinding * gSelf;
|
||||
StreamObserver* streamObserver;
|
||||
MediaProviderObserver *mediaProviderObserver;
|
||||
static bool gInitGmpCodecs;
|
||||
static int gAudioCodecMask;
|
||||
static int gVideoCodecMask;
|
||||
static nsIThread *gMainThread;
|
||||
static nsIEventTarget *gSTSThread;
|
||||
static nsCOMPtr<nsIPrefBranch> gBranch;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _Included_cip_sipcc_CodecMask
|
||||
#define _Included_cip_sipcc_CodecMask
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G711
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G711 1L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G729A
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G729A 2L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G729B
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G729B 4L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_LINEAR
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_LINEAR 8L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G722
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G722 16L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_iLBC
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_iLBC 32L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_iSAC
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_iSAC 64L
|
||||
#undef cip_sipcc_CodecMask_DSP_DECODEONLY
|
||||
#define cip_sipcc_CodecMask_DSP_DECODEONLY 0L
|
||||
#undef cip_sipcc_CodecMask_DSP_ENCODEONLY
|
||||
#define cip_sipcc_CodecMask_DSP_ENCODEONLY 1L
|
||||
#undef cip_sipcc_CodecMask_DSP_FULLDUPLEX
|
||||
#define cip_sipcc_CodecMask_DSP_FULLDUPLEX 2L
|
||||
#undef cip_sipcc_CodecMask_DSP_IGNORE
|
||||
#define cip_sipcc_CodecMask_DSP_IGNORE 3L
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -366,6 +366,7 @@ public:
|
|||
nsCOMPtr<nsIEventTarget> main_thread,
|
||||
nsCOMPtr<nsIEventTarget> sts_thread,
|
||||
DOMMediaStream *domstream,
|
||||
int pipeline_index, // For PeerConnectionMedia/mPipelines
|
||||
int level,
|
||||
bool is_video,
|
||||
RefPtr<MediaSessionConduit> conduit,
|
||||
|
@ -376,6 +377,7 @@ public:
|
|||
conduit, rtp_transport, rtcp_transport),
|
||||
listener_(new PipelineListener(conduit)),
|
||||
domstream_(domstream),
|
||||
pipeline_index_(pipeline_index),
|
||||
is_video_(is_video)
|
||||
{}
|
||||
|
||||
|
@ -385,6 +387,7 @@ public:
|
|||
virtual void AttachToTrack(TrackID track_id);
|
||||
|
||||
// Index used to refer to this before we know the TrackID
|
||||
virtual TrackID pipeline_index() const { return pipeline_index_; }
|
||||
// Note: unlike MediaPipeline::trackid(), this is threadsafe
|
||||
// Not set until first media is received
|
||||
virtual TrackID const trackid_locked() { return listener_->trackid(); }
|
||||
|
@ -518,6 +521,7 @@ public:
|
|||
private:
|
||||
RefPtr<PipelineListener> listener_;
|
||||
DOMMediaStream *domstream_;
|
||||
int pipeline_index_; // for lookups in LocalSourceStreamInfo::mPipelines;
|
||||
bool is_video_;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,703 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionMedia.h"
|
||||
#include "MediaPipelineFactory.h"
|
||||
#include "transportflow.h"
|
||||
#include "transportlayer.h"
|
||||
#include "transportlayerdtls.h"
|
||||
#include "transportlayerice.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepTrack.h"
|
||||
#include "signaling/src/jsep/JsepTransport.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#endif
|
||||
|
||||
#include "GmpVideoCodec.h"
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
#include "OMXVideoCodec.h"
|
||||
#include "OMXCodecWrapper.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MOZ_MTLOG_MODULE("MediaPipelineFactory")
|
||||
|
||||
// Trivial wrapper class around a vector of ptrs.
|
||||
template <class T> class PtrVector
|
||||
{
|
||||
public:
|
||||
~PtrVector()
|
||||
{
|
||||
for (auto it = values.begin(); it != values.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<T*> values;
|
||||
};
|
||||
|
||||
static nsresult
|
||||
JsepCodecDescToCodecConfig(const JsepCodecDescription& aCodec,
|
||||
AudioCodecConfig** aConfig)
|
||||
{
|
||||
MOZ_ASSERT(aCodec.mType == SdpMediaSection::kAudio);
|
||||
if (aCodec.mType != SdpMediaSection::kAudio)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
const JsepAudioCodecDescription& desc =
|
||||
static_cast<const JsepAudioCodecDescription&>(aCodec);
|
||||
|
||||
uint16_t pt;
|
||||
|
||||
if (!desc.GetPtAsInt(&pt)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid payload type: " << desc.mDefaultPt);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*aConfig = new AudioCodecConfig(pt,
|
||||
desc.mName,
|
||||
desc.mClock,
|
||||
desc.mPacketSize,
|
||||
desc.mChannels,
|
||||
desc.mBitrate);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
JsepCodecDescToCodecConfig(const JsepCodecDescription& aCodec,
|
||||
VideoCodecConfig** aConfig)
|
||||
{
|
||||
MOZ_ASSERT(aCodec.mType == SdpMediaSection::kVideo);
|
||||
if (aCodec.mType != SdpMediaSection::kVideo) {
|
||||
MOZ_ASSERT(false, "JsepCodecDescription has wrong type");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const JsepVideoCodecDescription& desc =
|
||||
static_cast<const JsepVideoCodecDescription&>(aCodec);
|
||||
|
||||
uint16_t pt;
|
||||
|
||||
if (!desc.GetPtAsInt(&pt)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid payload type: " << desc.mDefaultPt);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ScopedDeletePtr<VideoCodecConfigH264> h264Config;
|
||||
|
||||
if (desc.mName == "H264") {
|
||||
h264Config = new VideoCodecConfigH264;
|
||||
size_t spropSize = sizeof(h264Config->sprop_parameter_sets);
|
||||
strncpy(h264Config->sprop_parameter_sets,
|
||||
desc.mSpropParameterSets.c_str(),
|
||||
spropSize);
|
||||
h264Config->sprop_parameter_sets[spropSize - 1] = '\0';
|
||||
h264Config->packetization_mode = desc.mPacketizationMode;
|
||||
h264Config->profile_level_id = desc.mProfileLevelId;
|
||||
h264Config->max_mbps = desc.mMaxMbps;
|
||||
h264Config->max_fs = desc.mMaxFs;
|
||||
h264Config->max_cpb = desc.mMaxCpb;
|
||||
h264Config->max_dpb = desc.mMaxDpb;
|
||||
h264Config->max_br = desc.mMaxBr;
|
||||
h264Config->tias_bw = 0; // TODO. Issue 165.
|
||||
}
|
||||
|
||||
VideoCodecConfig* configRaw;
|
||||
configRaw = new VideoCodecConfig(
|
||||
pt, desc.mName, desc.mMaxFs, desc.mMaxFr, h264Config);
|
||||
|
||||
configRaw->mAckFbTypes = desc.mAckFbTypes;
|
||||
configRaw->mNackFbTypes = desc.mNackFbTypes;
|
||||
configRaw->mCcmFbTypes = desc.mCcmFbTypes;
|
||||
|
||||
*aConfig = configRaw;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Accessing the PCMedia should be safe here because we shouldn't
|
||||
// have enqueued this function unless it was still active and
|
||||
// the ICE data is destroyed on the STS.
|
||||
static void
|
||||
FinalizeTransportFlow_s(RefPtr<PeerConnectionMedia> aPCMedia,
|
||||
RefPtr<TransportFlow> aFlow, size_t aLevel,
|
||||
bool aIsRtcp,
|
||||
nsAutoPtr<PtrVector<TransportLayer> > aLayerList)
|
||||
{
|
||||
TransportLayerIce* ice =
|
||||
static_cast<TransportLayerIce*>(aLayerList->values.front());
|
||||
ice->SetParameters(
|
||||
aPCMedia->ice_ctx(), aPCMedia->ice_media_stream(aLevel), aIsRtcp ? 2 : 1);
|
||||
nsAutoPtr<std::queue<TransportLayer*> > layerQueue(
|
||||
new std::queue<TransportLayer*>);
|
||||
for (auto i = aLayerList->values.begin(); i != aLayerList->values.end();
|
||||
++i) {
|
||||
layerQueue->push(*i);
|
||||
}
|
||||
aLayerList->values.clear();
|
||||
(void)aFlow->PushLayers(layerQueue); // TODO(bug 854518): Process errors.
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateOrGetTransportFlow(
|
||||
size_t aLevel,
|
||||
bool aIsRtcp,
|
||||
const JsepTransport& aTransport,
|
||||
RefPtr<TransportFlow>* aFlowOutparam)
|
||||
{
|
||||
nsresult rv;
|
||||
RefPtr<TransportFlow> flow;
|
||||
|
||||
flow = mPCMedia->GetTransportFlow(aLevel, aIsRtcp);
|
||||
if (flow) {
|
||||
*aFlowOutparam = flow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
std::ostringstream osId;
|
||||
osId << mPC->GetHandle() << ":" << aLevel << ","
|
||||
<< (aIsRtcp ? "rtcp" : "rtp");
|
||||
flow = new TransportFlow(osId.str());
|
||||
|
||||
// The media streams are made on STS so we need to defer setup.
|
||||
auto ice = MakeUnique<TransportLayerIce>(mPC->GetHandle());
|
||||
auto dtls = MakeUnique<TransportLayerDtls>();
|
||||
dtls->SetRole(aTransport.mDtls->GetRole() ==
|
||||
JsepDtlsTransport::kJsepDtlsClient
|
||||
? TransportLayerDtls::CLIENT
|
||||
: TransportLayerDtls::SERVER);
|
||||
|
||||
RefPtr<DtlsIdentity> pcid = mPC->GetIdentity();
|
||||
if (!pcid) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get DTLS identity.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
dtls->SetIdentity(pcid);
|
||||
|
||||
const SdpFingerprintAttributeList& fingerprints =
|
||||
aTransport.mDtls->GetFingerprints();
|
||||
for (auto fp = fingerprints.mFingerprints.begin();
|
||||
fp != fingerprints.mFingerprints.end();
|
||||
++fp) {
|
||||
std::ostringstream ss;
|
||||
ss << fp->hashFunc;
|
||||
rv = dtls->SetVerificationDigest(ss.str(), &fp->fingerprint[0],
|
||||
fp->fingerprint.size());
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Could not set fingerprint");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint16_t> srtpCiphers;
|
||||
srtpCiphers.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
|
||||
srtpCiphers.push_back(SRTP_AES128_CM_HMAC_SHA1_32);
|
||||
|
||||
rv = dtls->SetSrtpCiphers(srtpCiphers);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't set SRTP ciphers");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoPtr<PtrVector<TransportLayer> > layers(new PtrVector<TransportLayer>);
|
||||
layers->values.push_back(ice.release());
|
||||
layers->values.push_back(dtls.release());
|
||||
|
||||
rv = mPCMedia->GetSTSThread()->Dispatch(
|
||||
WrapRunnableNM(FinalizeTransportFlow_s, mPCMedia, flow, aLevel, aIsRtcp,
|
||||
layers),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to dispatch FinalizeTransportFlow_s");
|
||||
return rv;
|
||||
}
|
||||
|
||||
mPCMedia->AddTransportFlow(aLevel, aIsRtcp, flow);
|
||||
|
||||
*aFlowOutparam = flow;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateMediaPipeline(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack)
|
||||
{
|
||||
MOZ_MTLOG(ML_DEBUG,
|
||||
"Creating media pipeline"
|
||||
<< " m-line index=" << aTrackPair.mLevel
|
||||
<< " type=" << aTrack.GetMediaType()
|
||||
<< " direction=" << aTrack.GetDirection());
|
||||
|
||||
MOZ_ASSERT(aTrackPair.mRtpTransport);
|
||||
|
||||
// First make sure the transport flow exists.
|
||||
RefPtr<TransportFlow> rtpFlow;
|
||||
nsresult rv = CreateOrGetTransportFlow(
|
||||
aTrackPair.mLevel, false, *aTrackPair.mRtpTransport, &rtpFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
MOZ_ASSERT(rtpFlow);
|
||||
|
||||
RefPtr<TransportFlow> rtcpFlow;
|
||||
if (aTrackPair.mRtcpTransport) {
|
||||
rv = CreateOrGetTransportFlow(
|
||||
aTrackPair.mLevel, true, *aTrackPair.mRtcpTransport, &rtcpFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
MOZ_ASSERT(rtcpFlow);
|
||||
}
|
||||
|
||||
// TODO(bug 1016476): If bundle is in play, grab the TransportFlows for the
|
||||
// bundle level too.
|
||||
|
||||
bool receiving =
|
||||
aTrack.GetDirection() == JsepTrack::Direction::kJsepTrackReceiving;
|
||||
|
||||
RefPtr<MediaSessionConduit> conduit;
|
||||
if (aTrack.GetMediaType() == SdpMediaSection::kAudio) {
|
||||
rv = CreateAudioConduit(aTrackPair, aTrack, &conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
} else if (aTrack.GetMediaType() == SdpMediaSection::kVideo) {
|
||||
rv = CreateVideoConduit(aTrackPair, aTrack, &conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
} else {
|
||||
// We've created the TransportFlow, nothing else to do here.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (receiving) {
|
||||
rv = CreateMediaPipelineReceiving(rtpFlow, rtcpFlow, nullptr, nullptr,
|
||||
aTrackPair, aTrack, conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
} else {
|
||||
rv = CreateMediaPipelineSending(rtpFlow, rtcpFlow, nullptr, nullptr,
|
||||
aTrackPair, aTrack, conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateMediaPipelineReceiving(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit)
|
||||
{
|
||||
|
||||
// Find the stream we need
|
||||
nsRefPtr<RemoteSourceStreamInfo> stream =
|
||||
mPCMedia->GetRemoteStreamById(aTrack.GetStreamId());
|
||||
MOZ_ASSERT(stream);
|
||||
if (!stream) {
|
||||
// This should never happen
|
||||
MOZ_ASSERT(false);
|
||||
MOZ_MTLOG(ML_ERROR, "Stream not found: " << aTrack.GetStreamId());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<MediaPipelineReceive> pipeline;
|
||||
|
||||
// TODO(bug 1016476): Need bundle filter.
|
||||
nsAutoPtr<MediaPipelineFilter> filter(nullptr);
|
||||
|
||||
if (aTrack.GetMediaType() == SdpMediaSection::kAudio) {
|
||||
pipeline = new MediaPipelineReceiveAudio(
|
||||
mPC->GetHandle(),
|
||||
mPC->GetMainThread().get(),
|
||||
mPC->GetSTSThread(),
|
||||
stream->GetMediaStream()->GetStream(),
|
||||
// Use the level + 1 as the track id. 0 is forbidden
|
||||
aTrackPair.mLevel + 1,
|
||||
aTrackPair.mLevel,
|
||||
static_cast<AudioSessionConduit*>(aConduit.get()), // Ugly downcast.
|
||||
aRtpFlow,
|
||||
aRtcpFlow,
|
||||
aBundleRtpFlow,
|
||||
aBundleRtcpFlow,
|
||||
filter);
|
||||
|
||||
} else if (aTrack.GetMediaType() == SdpMediaSection::kVideo) {
|
||||
pipeline = new MediaPipelineReceiveVideo(
|
||||
mPC->GetHandle(),
|
||||
mPC->GetMainThread().get(),
|
||||
mPC->GetSTSThread(),
|
||||
stream->GetMediaStream()->GetStream(),
|
||||
// Use the level + 1 as the track id. 0 is forbidden
|
||||
aTrackPair.mLevel + 1,
|
||||
aTrackPair.mLevel,
|
||||
static_cast<VideoSessionConduit*>(aConduit.get()), // Ugly downcast.
|
||||
aRtpFlow,
|
||||
aRtcpFlow,
|
||||
aBundleRtpFlow,
|
||||
aBundleRtcpFlow,
|
||||
filter);
|
||||
} else {
|
||||
MOZ_ASSERT(false);
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid media type in CreateMediaPipelineReceiving");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = pipeline->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't initialize receiving pipeline");
|
||||
return rv;
|
||||
}
|
||||
|
||||
stream->StorePipeline(aTrackPair.mLevel, SdpMediaSection::kVideo, pipeline);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateMediaPipelineSending(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsRefPtr<LocalSourceStreamInfo> stream =
|
||||
mPCMedia->GetLocalStreamById(aTrack.GetStreamId());
|
||||
MOZ_ASSERT(stream);
|
||||
if (!stream) {
|
||||
// This should never happen
|
||||
MOZ_MTLOG(ML_ERROR, "Stream not found: " << aTrack.GetStreamId());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Now we have all the pieces, create the pipeline
|
||||
RefPtr<MediaPipelineTransmit> pipeline = new MediaPipelineTransmit(
|
||||
mPC->GetHandle(), mPC->GetMainThread().get(), mPC->GetSTSThread(),
|
||||
stream->GetMediaStream(), aTrackPair.mLevel,
|
||||
aTrack.GetMediaType() == SdpMediaSection::kVideo, aConduit, aRtpFlow,
|
||||
aRtcpFlow);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// implement checking for peerIdentity (where failure == black/silence)
|
||||
nsIDocument* doc = mPC->GetWindow()->GetExtantDoc();
|
||||
if (doc) {
|
||||
pipeline->UpdateSinkIdentity_m(doc->NodePrincipal(),
|
||||
mPC->GetPeerIdentity());
|
||||
} else {
|
||||
MOZ_MTLOG(ML_ERROR, "Cannot initialize pipeline without attached doc");
|
||||
return NS_ERROR_FAILURE; // Don't remove this till we know it's safe.
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = pipeline->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't initialize sending pipeline");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// TODO(bug 1016476): Copied from vcmSIPCCBinding. Need to unifdef and port in.
|
||||
#if 0
|
||||
// This tells the receive MediaPipeline (if there is one) whether we are
|
||||
// doing bundle, and if so, updates the filter. Once the filter is finalized,
|
||||
// it is then copied to the transmit pipeline so it can filter RTCP.
|
||||
if (attrs->bundle_level) {
|
||||
nsAutoPtr<MediaPipelineFilter> filter (new MediaPipelineFilter);
|
||||
for (int s = 0; s < attrs->num_ssrcs; ++s) {
|
||||
filter->AddRemoteSSRC(attrs->ssrcs[s]);
|
||||
}
|
||||
pc.impl()->media()->SetUsingBundle_m(level, true);
|
||||
pc.impl()->media()->UpdateFilterFromRemoteDescription_m(level, filter);
|
||||
} else {
|
||||
// This will also clear the filter.
|
||||
pc.impl()->media()->SetUsingBundle_m(level, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
stream->StorePipeline(aTrackPair.mLevel, pipeline);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateAudioConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp)
|
||||
{
|
||||
|
||||
if (!aTrack.GetNegotiatedDetails()) {
|
||||
MOZ_ASSERT(false, "Track is missing negotiated details");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool receiving =
|
||||
aTrack.GetDirection() == JsepTrack::Direction::kJsepTrackReceiving;
|
||||
|
||||
RefPtr<MediaSessionConduit> otherConduit =
|
||||
mPCMedia->GetConduit(aTrackPair.mLevel, !receiving);
|
||||
MOZ_ASSERT_IF(otherConduit,
|
||||
otherConduit->type() == MediaSessionConduit::AUDIO);
|
||||
// The two sides of a send/receive pair of conduits each keep a raw pointer
|
||||
// to the other, and are responsible for cleanly shutting down.
|
||||
RefPtr<AudioSessionConduit> conduit = AudioSessionConduit::Create(
|
||||
static_cast<AudioSessionConduit*>(otherConduit.get()));
|
||||
|
||||
if (!conduit) {
|
||||
MOZ_MTLOG(ML_ERROR, "Could not create audio conduit");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPCMedia->AddConduit(aTrackPair.mLevel, receiving, conduit);
|
||||
|
||||
size_t numCodecs = aTrack.GetNegotiatedDetails()->GetCodecCount();
|
||||
if (numCodecs == 0) {
|
||||
MOZ_MTLOG(ML_ERROR, "Can't set up a conduit with 0 codecs");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (receiving) {
|
||||
PtrVector<AudioCodecConfig> configs;
|
||||
|
||||
for (size_t i = 0; i < numCodecs; i++) {
|
||||
const JsepCodecDescription* cdesc;
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(i, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
AudioCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
configs.values.push_back(configRaw);
|
||||
}
|
||||
|
||||
auto error = conduit->ConfigureRecvMediaCodecs(configs.values);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureRecvMediaCodecs failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
const JsepCodecDescription* cdesc;
|
||||
// Best codec.
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(0, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
AudioCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
ScopedDeletePtr<AudioCodecConfig> config(configRaw);
|
||||
auto error = conduit->ConfigureSendMediaCodec(config.get());
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureSendMediaCodec failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const SdpExtmapAttributeList::Extmap* audioLevelExt =
|
||||
aTrack.GetNegotiatedDetails()->GetExt(
|
||||
"urn:ietf:params:rtp-hdrext:ssrc-audio-level");
|
||||
|
||||
if (audioLevelExt) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Calling EnableAudioLevelExtension");
|
||||
error = conduit->EnableAudioLevelExtension(true, audioLevelExt->entry);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "EnableAudioLevelExtension failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aConduitp = conduit;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateVideoConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp)
|
||||
{
|
||||
|
||||
if (!aTrack.GetNegotiatedDetails()) {
|
||||
MOZ_ASSERT(false, "Track is missing negotiated details");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool receiving =
|
||||
aTrack.GetDirection() == JsepTrack::Direction::kJsepTrackReceiving;
|
||||
|
||||
// Instantiate an appropriate conduit
|
||||
RefPtr<MediaSessionConduit> peerConduit =
|
||||
mPCMedia->GetConduit(aTrackPair.mLevel, !receiving);
|
||||
MOZ_ASSERT_IF(peerConduit, peerConduit->type() == MediaSessionConduit::VIDEO);
|
||||
|
||||
// The two sides of a send/receive pair of conduits each keep a raw
|
||||
// pointer to the other, and are responsible for cleanly shutting down.
|
||||
RefPtr<VideoSessionConduit> conduit = VideoSessionConduit::Create(
|
||||
static_cast<VideoSessionConduit*>(peerConduit.get()));
|
||||
|
||||
if (!conduit) {
|
||||
MOZ_MTLOG(ML_ERROR, "Could not create video conduit");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPCMedia->AddConduit(aTrackPair.mLevel, receiving, conduit);
|
||||
|
||||
size_t numCodecs = aTrack.GetNegotiatedDetails()->GetCodecCount();
|
||||
if (numCodecs == 0) {
|
||||
MOZ_MTLOG(ML_ERROR, "Can't set up a conduit with 0 codecs");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (receiving) {
|
||||
PtrVector<VideoCodecConfig> configs;
|
||||
|
||||
for (size_t i = 0; i < numCodecs; i++) {
|
||||
const JsepCodecDescription* cdesc;
|
||||
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(i, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
VideoCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
UniquePtr<VideoCodecConfig> config(configRaw);
|
||||
if (EnsureExternalCodec(*conduit, config.get(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
configs.values.push_back(config.release());
|
||||
}
|
||||
|
||||
auto error = conduit->ConfigureRecvMediaCodecs(configs.values);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureRecvMediaCodecs failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
const JsepCodecDescription* cdesc;
|
||||
// Best codec.
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(0, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
VideoCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Take possession of this pointer
|
||||
ScopedDeletePtr<VideoCodecConfig> config(configRaw);
|
||||
|
||||
if (EnsureExternalCodec(*conduit, config, true)) {
|
||||
MOZ_MTLOG(ML_ERROR, "External codec not available");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
auto error = conduit->ConfigureSendMediaCodec(config);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureSendMediaCodec failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
*aConduitp = conduit;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add external H.264 video codec.
|
||||
*/
|
||||
MediaConduitErrorCode
|
||||
MediaPipelineFactory::EnsureExternalCodec(VideoSessionConduit& aConduit,
|
||||
VideoCodecConfig* aConfig,
|
||||
bool aIsSend)
|
||||
{
|
||||
if (aConfig->mName == "VP8") {
|
||||
return kMediaConduitNoError;
|
||||
} else if (aConfig->mName == "H264") {
|
||||
// Register H.264 codec.
|
||||
if (aIsSend) {
|
||||
VideoEncoder* encoder = nullptr;
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
encoder =
|
||||
OMXVideoCodec::CreateEncoder(OMXVideoCodec::CodecType::CODEC_H264);
|
||||
#else
|
||||
encoder = GmpVideoCodec::CreateEncoder();
|
||||
#endif
|
||||
if (encoder) {
|
||||
return aConduit.SetExternalSendCodec(aConfig, encoder);
|
||||
} else {
|
||||
return kMediaConduitInvalidSendCodec;
|
||||
}
|
||||
} else {
|
||||
VideoDecoder* decoder;
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
decoder =
|
||||
OMXVideoCodec::CreateDecoder(OMXVideoCodec::CodecType::CODEC_H264);
|
||||
#else
|
||||
decoder = GmpVideoCodec::CreateDecoder();
|
||||
#endif
|
||||
if (decoder) {
|
||||
return aConduit.SetExternalRecvCodec(aConfig, decoder);
|
||||
} else {
|
||||
return kMediaConduitInvalidReceiveCodec;
|
||||
}
|
||||
}
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
} else {
|
||||
MOZ_MTLOG(ML_ERROR,
|
||||
"Invalid video codec configured: " << aConfig->mName.c_str());
|
||||
return aIsSend ? kMediaConduitInvalidSendCodec
|
||||
: kMediaConduitInvalidReceiveCodec;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -1,72 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _MEDIAPIPELINEFACTORY_H_
|
||||
#define _MEDIAPIPELINEFACTORY_H_
|
||||
|
||||
#include "MediaConduitInterface.h"
|
||||
#include "PeerConnectionMedia.h"
|
||||
#include "transportflow.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepTrack.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class MediaPipelineFactory
|
||||
{
|
||||
public:
|
||||
explicit MediaPipelineFactory(PeerConnectionMedia* aPCMedia)
|
||||
: mPCMedia(aPCMedia), mPC(aPCMedia->GetPC())
|
||||
{
|
||||
}
|
||||
|
||||
nsresult CreateMediaPipeline(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack);
|
||||
|
||||
private:
|
||||
nsresult CreateMediaPipelineReceiving(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit);
|
||||
|
||||
nsresult CreateMediaPipelineSending(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit);
|
||||
|
||||
nsresult CreateAudioConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp);
|
||||
|
||||
nsresult CreateVideoConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp);
|
||||
|
||||
MediaConduitErrorCode EnsureExternalCodec(VideoSessionConduit& aConduit,
|
||||
VideoCodecConfig* aConfig,
|
||||
bool aIsSend);
|
||||
|
||||
nsresult CreateOrGetTransportFlow(size_t aLevel, bool aIsRtcp,
|
||||
const JsepTransport& transport,
|
||||
RefPtr<TransportFlow>* out);
|
||||
|
||||
private:
|
||||
// Not owned, and assumed to exist as long as the factory.
|
||||
// The factory is a transient object, so this is fairly easy.
|
||||
PeerConnectionMedia* mPCMedia;
|
||||
PeerConnectionImpl* mPC;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -15,7 +15,7 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
MediaStreamList::MediaStreamList(PeerConnectionImpl* peerConnection,
|
||||
MediaStreamList::MediaStreamList(sipcc::PeerConnectionImpl* peerConnection,
|
||||
StreamType type)
|
||||
: mPeerConnection(peerConnection),
|
||||
mType(type)
|
||||
|
@ -83,11 +83,11 @@ MediaStreamList::IndexedGetter(uint32_t index, bool& found)
|
|||
}
|
||||
if (mType == Local) {
|
||||
return GetStreamFromInfo(mPeerConnection->media()->
|
||||
GetLocalStreamByIndex(index), found);
|
||||
GetLocalStream(index), found);
|
||||
}
|
||||
|
||||
return GetStreamFromInfo(mPeerConnection->media()->
|
||||
GetRemoteStreamByIndex(index), found);
|
||||
GetRemoteStream(index), found);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
|
|
@ -16,8 +16,11 @@
|
|||
#include "DOMMediaStream.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace sipcc {
|
||||
class PeerConnectionImpl;
|
||||
} // namespace sipcc
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class MediaStreamList : public nsISupports,
|
||||
|
@ -29,7 +32,7 @@ public:
|
|||
Remote
|
||||
};
|
||||
|
||||
MediaStreamList(PeerConnectionImpl* peerConnection, StreamType type);
|
||||
MediaStreamList(sipcc::PeerConnectionImpl* peerConnection, StreamType type);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaStreamList)
|
||||
|
@ -44,7 +47,7 @@ public:
|
|||
private:
|
||||
virtual ~MediaStreamList();
|
||||
|
||||
nsRefPtr<PeerConnectionImpl> mPeerConnection;
|
||||
nsRefPtr<sipcc::PeerConnectionImpl> mPeerConnection;
|
||||
StreamType mType;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,9 +5,20 @@
|
|||
#include "CSFLog.h"
|
||||
|
||||
#include "base/histogram.h"
|
||||
#include "CallControlManager.h"
|
||||
#include "CC_Device.h"
|
||||
#include "CC_Call.h"
|
||||
#include "CC_Observer.h"
|
||||
#include "ccapi_call_info.h"
|
||||
#include "CC_SIPCCCallInfo.h"
|
||||
#include "ccapi_device_info.h"
|
||||
#include "CC_SIPCCDeviceInfo.h"
|
||||
#include "vcm.h"
|
||||
#include "VcmSIPCCBinding.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionCtx.h"
|
||||
#include "runnable_utils.h"
|
||||
#include "debug-psipcc-types.h"
|
||||
#include "prcvar.h"
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -31,6 +42,56 @@ namespace mozilla {
|
|||
|
||||
using namespace dom;
|
||||
|
||||
// Convert constraints to C structures
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
static void
|
||||
Apply(const Optional<bool> &aSrc, cc_boolean_option_t *aDst) {
|
||||
if (aSrc.WasPassed()) {
|
||||
aDst->was_passed = true;
|
||||
aDst->value = aSrc.Value();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Apply(const Optional<int32_t> &aSrc, cc_int32_option_t *aDst) {
|
||||
if (aSrc.WasPassed()) {
|
||||
aDst->was_passed = true;
|
||||
aDst->value = aSrc.Value();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SipccOfferOptions::SipccOfferOptions() {
|
||||
memset(&mOptions, 0, sizeof(mOptions));
|
||||
}
|
||||
|
||||
SipccOfferOptions::SipccOfferOptions(
|
||||
const RTCOfferOptions &aSrc) {
|
||||
cc_media_options_t* c = &mOptions;
|
||||
memset(c, 0, sizeof(*c));
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
Apply(aSrc.mOfferToReceiveAudio, &c->offer_to_receive_audio);
|
||||
Apply(aSrc.mOfferToReceiveVideo, &c->offer_to_receive_video);
|
||||
if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
|
||||
c->offer_to_receive_video.was_passed = true;
|
||||
c->offer_to_receive_video.value = false;
|
||||
}
|
||||
Apply(aSrc.mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel);
|
||||
Apply(aSrc.mMozBundleOnly, &c->moz_bundle_only);
|
||||
#endif
|
||||
}
|
||||
|
||||
cc_media_options_t*
|
||||
SipccOfferOptions::build() const {
|
||||
cc_media_options_t* cc = (cc_media_options_t*)
|
||||
cpr_malloc(sizeof(cc_media_options_t));
|
||||
if (cc) {
|
||||
*cc = mOptions;
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
|
||||
class PeerConnectionCtxShutdown : public nsIObserver
|
||||
{
|
||||
public:
|
||||
|
@ -60,7 +121,7 @@ public:
|
|||
const char16_t* aData) {
|
||||
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
CSFLogDebug(logTag, "Shutting down PeerConnectionCtx");
|
||||
PeerConnectionCtx::Destroy();
|
||||
sipcc::PeerConnectionCtx::Destroy();
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
services::GetObserverService();
|
||||
|
@ -73,7 +134,7 @@ public:
|
|||
|
||||
// Make sure we're not deleted while still inside ::Observe()
|
||||
nsRefPtr<PeerConnectionCtxShutdown> kungFuDeathGrip(this);
|
||||
PeerConnectionCtx::gPeerConnectionCtxShutdown = nullptr;
|
||||
sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -91,7 +152,8 @@ private:
|
|||
NS_IMPL_ISUPPORTS(PeerConnectionCtxShutdown, nsIObserver);
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
using namespace mozilla;
|
||||
namespace sipcc {
|
||||
|
||||
PeerConnectionCtx* PeerConnectionCtx::gInstance;
|
||||
nsIThread* PeerConnectionCtx::gMainThread;
|
||||
|
@ -101,6 +163,7 @@ nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread,
|
|||
nsIEventTarget* stsThread) {
|
||||
if (!gMainThread) {
|
||||
gMainThread = mainThread;
|
||||
CSF::VcmSIPCCBinding::setMainThread(gMainThread);
|
||||
} else {
|
||||
MOZ_ASSERT(gMainThread == mainThread);
|
||||
}
|
||||
|
@ -120,9 +183,9 @@ nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread,
|
|||
|
||||
gInstance = ctx;
|
||||
|
||||
if (!PeerConnectionCtx::gPeerConnectionCtxShutdown) {
|
||||
PeerConnectionCtx::gPeerConnectionCtxShutdown = new PeerConnectionCtxShutdown();
|
||||
PeerConnectionCtx::gPeerConnectionCtxShutdown->Init();
|
||||
if (!sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown) {
|
||||
sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown = new PeerConnectionCtxShutdown();
|
||||
sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown->Init();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,6 +363,51 @@ PeerConnectionCtx::EverySecondTelemetryCallback_m(nsITimer* timer, void *closure
|
|||
nsresult PeerConnectionCtx::Initialize() {
|
||||
initGMP();
|
||||
|
||||
mCCM = CSF::CallControlManager::create();
|
||||
|
||||
NS_ENSURE_TRUE(mCCM.get(), NS_ERROR_FAILURE);
|
||||
|
||||
// Add the local audio codecs
|
||||
// FIX - Get this list from MediaEngine instead
|
||||
int codecMask = 0;
|
||||
codecMask |= VCM_CODEC_RESOURCE_G711;
|
||||
codecMask |= VCM_CODEC_RESOURCE_OPUS;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_LINEAR;
|
||||
codecMask |= VCM_CODEC_RESOURCE_G722;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_iLBC;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_iSAC;
|
||||
mCCM->setAudioCodecs(codecMask);
|
||||
|
||||
//Add the local video codecs
|
||||
// FIX - Get this list from MediaEngine instead
|
||||
// Turning them all on for now
|
||||
codecMask = 0;
|
||||
// Only adding codecs supported
|
||||
//codecMask |= VCM_CODEC_RESOURCE_H263;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
if (Preferences::GetBool("media.peerconnection.video.h264_enabled")) {
|
||||
codecMask |= VCM_CODEC_RESOURCE_H264;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
// Outside MOZILLA_INTERNAL_API ensures H.264 available in unit tests
|
||||
codecMask |= VCM_CODEC_RESOURCE_H264;
|
||||
#endif
|
||||
|
||||
codecMask |= VCM_CODEC_RESOURCE_VP8;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_I420;
|
||||
mCCM->setVideoCodecs(codecMask);
|
||||
mCCM->addCCObserver(this);
|
||||
ChangeSipccState(dom::PCImplSipccState::Starting);
|
||||
|
||||
if (!mCCM->startSDPMode())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mDevice = mCCM->getActiveDevice();
|
||||
NS_ENSURE_TRUE(mDevice.get(), NS_ERROR_FAILURE);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
mConnectionCounter = 0;
|
||||
Telemetry::GetHistogramById(Telemetry::WEBRTC_CALL_COUNT)->Add(0);
|
||||
|
@ -310,8 +418,7 @@ nsresult PeerConnectionCtx::Initialize() {
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mTelemetryTimer->InitWithFuncCallback(EverySecondTelemetryCallback_m, this, 1000,
|
||||
nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP);
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -357,6 +464,9 @@ nsresult PeerConnectionCtx::Cleanup() {
|
|||
|
||||
mQueuedJSEPOperations.Clear();
|
||||
mGMPService = nullptr;
|
||||
|
||||
mCCM->destroy();
|
||||
mCCM->removeCCObserver(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -370,6 +480,10 @@ PeerConnectionCtx::~PeerConnectionCtx() {
|
|||
#endif
|
||||
};
|
||||
|
||||
CSF::CC_CallPtr PeerConnectionCtx::createCall() {
|
||||
return mDevice->createCall();
|
||||
}
|
||||
|
||||
void PeerConnectionCtx::queueJSEPOperation(nsRefPtr<nsIRunnable> aOperation) {
|
||||
mQueuedJSEPOperations.AppendElement(aOperation);
|
||||
}
|
||||
|
@ -382,33 +496,35 @@ void PeerConnectionCtx::onGMPReady() {
|
|||
mQueuedJSEPOperations.Clear();
|
||||
}
|
||||
|
||||
bool PeerConnectionCtx::gmpHasH264() {
|
||||
if (!mGMPService) {
|
||||
return false;
|
||||
void PeerConnectionCtx::onDeviceEvent(ccapi_device_event_e aDeviceEvent,
|
||||
CSF::CC_DevicePtr aDevice,
|
||||
CSF::CC_DeviceInfoPtr aInfo ) {
|
||||
cc_service_state_t state = aInfo->getServiceState();
|
||||
// We are keeping this in a local var to avoid a data race
|
||||
// with ChangeSipccState in the debug message and compound if below
|
||||
dom::PCImplSipccState currentSipccState = mSipccState;
|
||||
|
||||
switch (aDeviceEvent) {
|
||||
case CCAPI_DEVICE_EV_STATE:
|
||||
CSFLogDebug(logTag, "%s - %d : %d", __FUNCTION__, state,
|
||||
static_cast<uint32_t>(currentSipccState));
|
||||
|
||||
if (CC_STATE_INS == state) {
|
||||
// SIPCC is up
|
||||
if (dom::PCImplSipccState::Starting == currentSipccState ||
|
||||
dom::PCImplSipccState::Idle == currentSipccState) {
|
||||
ChangeSipccState(dom::PCImplSipccState::Started);
|
||||
} else {
|
||||
CSFLogError(logTag, "%s PeerConnection already started", __FUNCTION__);
|
||||
}
|
||||
} else {
|
||||
NS_NOTREACHED("Unsupported Signaling State Transition");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CSFLogDebug(logTag, "%s: Ignoring event: %s\n",__FUNCTION__,
|
||||
device_event_getname(aDeviceEvent));
|
||||
}
|
||||
|
||||
// XXX I'd prefer if this was all known ahead of time...
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
|
||||
bool has_gmp;
|
||||
nsresult rv;
|
||||
rv = mGMPService->HasPluginForAPI(NS_LITERAL_CSTRING("encode-video"),
|
||||
&tags,
|
||||
&has_gmp);
|
||||
if (NS_FAILED(rv) || !has_gmp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rv = mGMPService->HasPluginForAPI(NS_LITERAL_CSTRING("decode-video"),
|
||||
&tags,
|
||||
&has_gmp);
|
||||
if (NS_FAILED(rv) || !has_gmp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace sipcc
|
||||
|
|
|
@ -8,6 +8,17 @@
|
|||
#include <string>
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "CallControlManager.h"
|
||||
#include "CC_Device.h"
|
||||
#include "CC_DeviceInfo.h"
|
||||
#include "CC_Call.h"
|
||||
#include "CC_CallInfo.h"
|
||||
#include "CC_Line.h"
|
||||
#include "CC_LineInfo.h"
|
||||
#include "CC_Observer.h"
|
||||
#include "CC_FeatureInfo.h"
|
||||
#include "cpr_stdlib.h"
|
||||
|
||||
#include "StaticPtr.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
|
@ -20,17 +31,52 @@ namespace dom {
|
|||
class WebrtcGlobalInformation;
|
||||
}
|
||||
|
||||
// Unit-test helper, because cc_media_options_t is hard to forward-declare
|
||||
|
||||
class SipccOfferOptions {
|
||||
public:
|
||||
SipccOfferOptions();
|
||||
explicit SipccOfferOptions(const dom::RTCOfferOptions &aOther);
|
||||
cc_media_options_t* build() const;
|
||||
protected:
|
||||
cc_media_options_t mOptions;
|
||||
};
|
||||
}
|
||||
|
||||
namespace sipcc {
|
||||
|
||||
class OnCallEventArgs {
|
||||
public:
|
||||
OnCallEventArgs(ccapi_call_event_e aCallEvent, CSF::CC_CallInfoPtr aInfo)
|
||||
: mCallEvent(aCallEvent), mInfo(aInfo) {}
|
||||
|
||||
ccapi_call_event_e mCallEvent;
|
||||
CSF::CC_CallInfoPtr mInfo;
|
||||
};
|
||||
|
||||
// A class to hold some of the singleton objects we need:
|
||||
// * The global PeerConnectionImpl table and its associated lock.
|
||||
// * Stats report objects for PCs that are gone
|
||||
// * GMP related state
|
||||
class PeerConnectionCtx {
|
||||
// * Currently SIPCC only allows a single stack instance to exist in a process
|
||||
// at once. This class implements a singleton object that wraps that.
|
||||
// * The observer class that demuxes events onto individual PCs.
|
||||
class PeerConnectionCtx : public CSF::CC_Observer {
|
||||
public:
|
||||
static nsresult InitializeGlobal(nsIThread *mainThread, nsIEventTarget *stsThread);
|
||||
static PeerConnectionCtx* GetInstance();
|
||||
static bool isActive();
|
||||
static void Destroy();
|
||||
|
||||
// Implementations of CC_Observer methods
|
||||
virtual void onDeviceEvent(ccapi_device_event_e deviceEvent, CSF::CC_DevicePtr device, CSF::CC_DeviceInfoPtr info);
|
||||
virtual void onFeatureEvent(ccapi_device_event_e deviceEvent, CSF::CC_DevicePtr device, CSF::CC_FeatureInfoPtr feature_info) {}
|
||||
virtual void onLineEvent(ccapi_line_event_e lineEvent, CSF::CC_LinePtr line, CSF::CC_LineInfoPtr info) {}
|
||||
virtual void onCallEvent(ccapi_call_event_e callEvent, CSF::CC_CallPtr call, CSF::CC_CallInfoPtr info) {}
|
||||
|
||||
// Create a SIPCC Call
|
||||
CSF::CC_CallPtr createCall();
|
||||
|
||||
mozilla::dom::PCImplSipccState sipcc_state() { return mSipccState; }
|
||||
|
||||
bool isReady() {
|
||||
// If mGMPService is not set, we aren't using GMP.
|
||||
if (mGMPService) {
|
||||
|
@ -42,8 +88,6 @@ class PeerConnectionCtx {
|
|||
void queueJSEPOperation(nsRefPtr<nsIRunnable> aJSEPOperation);
|
||||
void onGMPReady();
|
||||
|
||||
bool gmpHasH264();
|
||||
|
||||
// Make these classes friend so that they can access mPeerconnections.
|
||||
friend class PeerConnectionImpl;
|
||||
friend class PeerConnectionWrapper;
|
||||
|
@ -60,7 +104,8 @@ class PeerConnectionCtx {
|
|||
// We could make these available only via accessors but it's too much trouble.
|
||||
std::map<const std::string, PeerConnectionImpl *> mPeerConnections;
|
||||
|
||||
PeerConnectionCtx() : mGMPReady(false) {}
|
||||
PeerConnectionCtx() : mSipccState(mozilla::dom::PCImplSipccState::Idle),
|
||||
mCCM(nullptr), mDevice(nullptr), mGMPReady(false) {}
|
||||
// This is a singleton, so don't copy construct it, etc.
|
||||
PeerConnectionCtx(const PeerConnectionCtx& other) MOZ_DELETE;
|
||||
void operator=(const PeerConnectionCtx& other) MOZ_DELETE;
|
||||
|
@ -69,6 +114,10 @@ class PeerConnectionCtx {
|
|||
nsresult Initialize();
|
||||
nsresult Cleanup();
|
||||
|
||||
void ChangeSipccState(mozilla::dom::PCImplSipccState aState) {
|
||||
mSipccState = aState;
|
||||
}
|
||||
|
||||
void initGMP();
|
||||
|
||||
static void
|
||||
|
@ -87,6 +136,11 @@ public:
|
|||
private:
|
||||
#endif
|
||||
|
||||
// SIPCC objects
|
||||
mozilla::dom::PCImplSipccState mSipccState; // TODO(ekr@rtfm.com): refactor this out? What does it do?
|
||||
CSF::CallControlManagerPtr mCCM;
|
||||
CSF::CC_DevicePtr mDevice;
|
||||
|
||||
// We cannot form offers/answers properly until the Gecko Media Plugin stuff
|
||||
// has been initted, which is a complicated mess of thread dispatches,
|
||||
// including sync dispatches to main. So, we need to be able to queue up
|
||||
|
@ -102,6 +156,6 @@ public:
|
|||
static mozilla::StaticRefPtr<mozilla::PeerConnectionCtxShutdown> gPeerConnectionCtxShutdown;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace sipcc
|
||||
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -22,13 +22,8 @@
|
|||
#include "nricemediastream.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsIThread.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "signaling/src/jsep/JsepSessionImpl.h"
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/PeerConnectionImplEnumsBinding.h"
|
||||
#include "StreamBuffer.h"
|
||||
|
@ -93,6 +88,7 @@ class PeerConnectionObserver;
|
|||
typedef NS_ConvertUTF8toUTF16 PCObserverString;
|
||||
#endif
|
||||
}
|
||||
class SipccOfferOptions;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
|
@ -114,7 +110,7 @@ already_AddRefed<resulttype> func (__VA_ARGS__, rv)
|
|||
|
||||
struct MediaStreamTable;
|
||||
|
||||
namespace mozilla {
|
||||
namespace sipcc {
|
||||
|
||||
using mozilla::dom::PeerConnectionObserver;
|
||||
using mozilla::dom::RTCConfiguration;
|
||||
|
@ -134,15 +130,6 @@ class PeerConnectionWrapper;
|
|||
class PeerConnectionMedia;
|
||||
class RemoteSourceStreamInfo;
|
||||
|
||||
// Uuid Generator
|
||||
class PCUuidGenerator : public mozilla::JsepUuidGenerator {
|
||||
public:
|
||||
virtual bool Generate(std::string* idp) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIUUIDGenerator> mGenerator;
|
||||
};
|
||||
|
||||
class IceConfiguration
|
||||
{
|
||||
public:
|
||||
|
@ -239,7 +226,6 @@ public:
|
|||
|
||||
enum Error {
|
||||
kNoError = 0,
|
||||
kInvalidCandidate = 2,
|
||||
kInvalidMediastreamTrack = 3,
|
||||
kInvalidState = 4,
|
||||
kInvalidSessionDescription = 5,
|
||||
|
@ -261,8 +247,7 @@ public:
|
|||
IceConfiguration *aDst);
|
||||
already_AddRefed<DOMMediaStream> MakeMediaStream(uint32_t aHint);
|
||||
|
||||
nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo,
|
||||
const std::string& aId);
|
||||
nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo);
|
||||
|
||||
// DataConnection observers
|
||||
void NotifyDataChannel(already_AddRefed<mozilla::DataChannel> aChannel);
|
||||
|
@ -287,10 +272,6 @@ public:
|
|||
NrIceCtx::ConnectionState state);
|
||||
void IceGatheringStateChange(NrIceCtx* ctx,
|
||||
NrIceCtx::GatheringState state);
|
||||
// TODO(bug 1096795): Need a |component| id here for rtcp.
|
||||
void EndOfLocalCandidates(const std::string& defaultAddr,
|
||||
uint16_t defaultPort,
|
||||
uint16_t level);
|
||||
void IceStreamReady(NrIceMediaStream *aStream);
|
||||
|
||||
static void ListenThread(void *aData);
|
||||
|
@ -310,6 +291,9 @@ public:
|
|||
|
||||
// Get the DTLS identity (local side)
|
||||
mozilla::RefPtr<DtlsIdentity> const GetIdentity() const;
|
||||
std::string GetFingerprint() const;
|
||||
std::string GetFingerprintAlgorithm() const;
|
||||
std::string GetFingerprintHexValue() const;
|
||||
|
||||
// Create a fake media stream
|
||||
nsresult CreateFakeMediaStream(uint32_t hint, mozilla::DOMMediaStream** retval);
|
||||
|
@ -352,8 +336,7 @@ public:
|
|||
rv = CreateAnswer();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP CreateOffer(
|
||||
const mozilla::JsepOfferOptions& aConstraints);
|
||||
NS_IMETHODIMP CreateOffer(const mozilla::SipccOfferOptions& aConstraints);
|
||||
|
||||
NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP);
|
||||
|
||||
|
@ -385,6 +368,8 @@ public:
|
|||
NS_ConvertUTF16toUTF8(aMid).get(), aLevel);
|
||||
}
|
||||
|
||||
void OnRemoteStreamAdded(const MediaStreamTable& aStream);
|
||||
|
||||
NS_IMETHODIMP CloseStreams();
|
||||
|
||||
void CloseStreams(ErrorResult &rv)
|
||||
|
@ -492,6 +477,15 @@ public:
|
|||
return state;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP SipccState(mozilla::dom::PCImplSipccState* aState);
|
||||
|
||||
mozilla::dom::PCImplSipccState SipccState()
|
||||
{
|
||||
mozilla::dom::PCImplSipccState state;
|
||||
SipccState(&state);
|
||||
return state;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP IceConnectionState(
|
||||
mozilla::dom::PCImplIceConnectionState* aState);
|
||||
|
||||
|
@ -523,7 +517,8 @@ public:
|
|||
const nsAString& aPluginName,
|
||||
const nsAString& aPluginDumpID);
|
||||
|
||||
nsresult InitializeDataChannel();
|
||||
nsresult InitializeDataChannel(int track_id, uint16_t aLocalport,
|
||||
uint16_t aRemoteport, uint16_t aNumstreams);
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(ConnectDataConnection, ErrorResult &rv,
|
||||
uint16_t aLocalport,
|
||||
|
@ -565,6 +560,16 @@ public:
|
|||
// is called to start the list over.
|
||||
void ClearSdpParseErrorMessages();
|
||||
|
||||
void StartTrickle();
|
||||
|
||||
// Called by VcmSIPCCBinding::vcmRxAllocICE; this is how sipcc tells us about
|
||||
// each m-line it has put in the sdp.
|
||||
void OnNewMline(uint16_t level) {
|
||||
if (level > mNumMlines) {
|
||||
mNumMlines = level;
|
||||
}
|
||||
}
|
||||
|
||||
void OnAddIceCandidateError() {
|
||||
++mAddCandidateErrorCount;
|
||||
}
|
||||
|
@ -575,7 +580,7 @@ public:
|
|||
// Sets the RTC Signaling State
|
||||
void SetSignalingState_m(mozilla::dom::PCImplSignalingState aSignalingState);
|
||||
|
||||
// Updates the RTC signaling state based on the JsepSession state
|
||||
// Updates the RTC signaling state based on the sipcc state
|
||||
void UpdateSignalingState();
|
||||
|
||||
bool IsClosed() const;
|
||||
|
@ -608,9 +613,6 @@ private:
|
|||
const IceConfiguration* aConfiguration,
|
||||
const RTCConfiguration* aRTCConfiguration,
|
||||
nsISupports* aThread);
|
||||
nsresult CalculateFingerprint(const std::string& algorithm,
|
||||
std::vector<uint8_t>& fingerprint) const;
|
||||
nsresult ConfigureJsepSessionCodecs();
|
||||
|
||||
NS_IMETHODIMP EnsureDataConnection(uint16_t aNumstreams);
|
||||
|
||||
|
@ -644,10 +646,11 @@ private:
|
|||
void SendLocalIceCandidateToContent(uint16_t level,
|
||||
const std::string& mid,
|
||||
const std::string& candidate);
|
||||
void FoundIceCandidate(const std::string& candidate, uint16_t level);
|
||||
|
||||
NS_IMETHOD FingerprintSplitHelper(
|
||||
std::string& fingerprint, size_t& spaceIdx) const;
|
||||
|
||||
nsresult GetDatachannelParameters(
|
||||
const mozilla::JsepApplicationCodecDescription** codec,
|
||||
uint16_t* level) const;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
static void GetStatsForPCObserver_s(
|
||||
|
@ -673,6 +676,8 @@ private:
|
|||
// any other attributes of this class.
|
||||
Timecard *mTimeCard;
|
||||
|
||||
// The call
|
||||
mozilla::ScopedDeletePtr<Internal> mInternal;
|
||||
mozilla::dom::PCImplSignalingState mSignalingState;
|
||||
|
||||
// ICE State
|
||||
|
@ -692,6 +697,12 @@ private:
|
|||
// The SDP sent in from JS - here for debugging.
|
||||
std::string mLocalRequestedSDP;
|
||||
std::string mRemoteRequestedSDP;
|
||||
// The SDP we are using.
|
||||
std::string mLocalSDP;
|
||||
std::string mRemoteSDP;
|
||||
|
||||
// Holding tank for trickle candidates that arrive before setLocal is done.
|
||||
std::vector<std::pair<std::string, uint16_t>> mCandidateBuffer;
|
||||
|
||||
// DTLS fingerprint
|
||||
std::string mFingerprint;
|
||||
|
@ -729,10 +740,6 @@ private:
|
|||
bool mAllowIceLoopback;
|
||||
nsRefPtr<PeerConnectionMedia> mMedia;
|
||||
|
||||
// The JSEP negotiation session.
|
||||
mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
|
||||
mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// Start time of ICE, used for telemetry
|
||||
mozilla::TimeStamp mIceStartTime;
|
||||
|
@ -749,6 +756,10 @@ private:
|
|||
|
||||
bool mHaveDataStream;
|
||||
|
||||
uint16_t mNumMlines;
|
||||
|
||||
// Holder for error messages from parsing SDP
|
||||
std::vector<std::string> mSDPParseErrorMessages;
|
||||
unsigned int mAddCandidateErrorCount;
|
||||
|
||||
bool mTrickle;
|
||||
|
@ -772,7 +783,7 @@ class PeerConnectionWrapper
|
|||
nsRefPtr<PeerConnectionImpl> impl_;
|
||||
};
|
||||
|
||||
} // end mozilla namespace
|
||||
} // end sipcc namespace
|
||||
|
||||
#undef NS_IMETHODIMP_TO_ERRORRESULT
|
||||
#undef NS_IMETHODIMP_TO_ERRORRESULT_RETREF
|
||||
|
|
|
@ -1,27 +1,21 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "CSFLog.h"
|
||||
|
||||
#include "nspr.h"
|
||||
#include "cc_constants.h"
|
||||
|
||||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "MediaPipelineFactory.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionMedia.h"
|
||||
#include "AudioConduit.h"
|
||||
#include "VideoConduit.h"
|
||||
#include "runnable_utils.h"
|
||||
#include "transportlayerice.h"
|
||||
#include "transportlayerdtls.h"
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "signaling/src/jsep/JsepTransport.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#include "MediaStreamList.h"
|
||||
|
@ -30,10 +24,10 @@
|
|||
#include "mozilla/dom/RTCStatsReportBinding.h"
|
||||
#endif
|
||||
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
namespace sipcc {
|
||||
|
||||
static const char* logTag = "PeerConnectionMedia";
|
||||
static const mozilla::TrackID TRACK_AUDIO = 0;
|
||||
|
@ -140,12 +134,12 @@ int LocalSourceStreamInfo::HasTrackType(DOMMediaStream* aStream, bool aIsVideo)
|
|||
}
|
||||
|
||||
// XXX revisit once we support multiple tracks of a type - bug 1056650
|
||||
nsresult LocalSourceStreamInfo::ReplaceTrack(int aMLine,
|
||||
nsresult LocalSourceStreamInfo::ReplaceTrack(int aIndex,
|
||||
DOMMediaStream* aNewStream,
|
||||
TrackID aNewTrack)
|
||||
{
|
||||
// Note aMLine != aOldTrack!
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> pipeline = mPipelines[aMLine];
|
||||
// Note aIndex != aOldTrack!
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> pipeline = mPipelines[aIndex];
|
||||
MOZ_ASSERT(pipeline);
|
||||
if (NS_SUCCEEDED(static_cast<mozilla::MediaPipelineTransmit*>(pipeline.get())->ReplaceTrack(aNewStream, aNewTrack))) {
|
||||
return NS_OK;
|
||||
|
@ -172,7 +166,7 @@ void RemoteSourceStreamInfo::DetachMedia_m()
|
|||
// walk through all the MediaPipelines and call the shutdown
|
||||
// media functions. Must be on the main thread.
|
||||
for (std::map<int, mozilla::RefPtr<mozilla::MediaPipeline> >::iterator it =
|
||||
mPipelines.begin(); it != mPipelines.end();
|
||||
mPipelines.begin(); it != mPipelines.end();
|
||||
++it) {
|
||||
it->second->ShutdownMedia_m();
|
||||
}
|
||||
|
@ -202,13 +196,15 @@ PeerConnectionImpl* PeerConnectionImpl::CreatePeerConnection()
|
|||
PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
||||
: mParent(parent),
|
||||
mParentHandle(parent->GetHandle()),
|
||||
mParentName(parent->GetName()),
|
||||
mAllowIceLoopback(false),
|
||||
mIceCtx(nullptr),
|
||||
mDNSResolver(new mozilla::NrIceResolver()),
|
||||
mUuidGen(MakeUnique<PCUuidGenerator>()),
|
||||
mMainThread(mParent->GetMainThread()),
|
||||
mSTSThread(mParent->GetSTSThread()) {
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
mAllowIceLoopback = Preferences::GetBool(
|
||||
"media.peerconnection.ice.loopback", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
|
||||
|
@ -216,7 +212,7 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
|||
{
|
||||
// TODO(ekr@rtfm.com): need some way to set not offerer later
|
||||
// Looks like a bug in the NrIceCtx API.
|
||||
mIceCtx = NrIceCtx::Create("PC:" + mParentName,
|
||||
mIceCtx = NrIceCtx::Create("PC:" + mParent->GetName(),
|
||||
true, // Offerer
|
||||
true, // Trickle
|
||||
mAllowIceLoopback);
|
||||
|
@ -258,274 +254,59 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
|||
this,
|
||||
&PeerConnectionMedia::IceConnectionStateChange_s);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
// Create three streams to start with.
|
||||
// One each for audio, video and DataChannel
|
||||
// TODO: this will be re-visited
|
||||
RefPtr<NrIceMediaStream> audioStream =
|
||||
mIceCtx->CreateStream((mParent->GetName()+": stream1/audio").c_str(), 2);
|
||||
RefPtr<NrIceMediaStream> videoStream =
|
||||
mIceCtx->CreateStream((mParent->GetName()+": stream2/video").c_str(), 2);
|
||||
RefPtr<NrIceMediaStream> dcStream =
|
||||
mIceCtx->CreateStream((mParent->GetName()+": stream3/data").c_str(), 2);
|
||||
|
||||
void
|
||||
PeerConnectionMedia::UpdateTransports(const mozilla::JsepSession& session) {
|
||||
|
||||
size_t numTransports = session.GetTransportCount();
|
||||
for (size_t i = 0; i < numTransports; ++i) {
|
||||
RefPtr<JsepTransport> transport;
|
||||
|
||||
nsresult rv = session.GetTransport(i, &transport);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
std::string ufrag;
|
||||
std::string pwd;
|
||||
std::vector<std::string> candidates;
|
||||
|
||||
bool hasAttrs = false;
|
||||
if (transport->mIce) {
|
||||
hasAttrs = true;
|
||||
ufrag = transport->mIce->GetUfrag();
|
||||
pwd = transport->mIce->GetPassword();
|
||||
candidates = transport->mIce->GetCandidates();
|
||||
}
|
||||
|
||||
// Update the transport.
|
||||
// TODO(bug 1017888): don't repeat candidates on renegotiation. Perhaps
|
||||
// suppress inside nICEr?
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::UpdateIceMediaStream_s,
|
||||
i,
|
||||
transport->mComponents,
|
||||
hasAttrs,
|
||||
ufrag,
|
||||
pwd,
|
||||
candidates),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
// TODO(bug 1017888): Need to deal properly with renegotatiation.
|
||||
// For now just start gathering.
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::EnsureIceGathering_s),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
}
|
||||
|
||||
nsresult PeerConnectionMedia::UpdateMediaPipelines(
|
||||
const mozilla::JsepSession& session) {
|
||||
size_t numPairs = session.GetNegotiatedTrackPairCount();
|
||||
mozilla::MediaPipelineFactory factory(this);
|
||||
const mozilla::JsepTrackPair* pair;
|
||||
|
||||
for (size_t i = 0; i < numPairs; ++i) {
|
||||
nsresult rv = session.GetNegotiatedTrackPair(i, &pair);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(false);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// TODO(bug 1099318): We are forced to do receive then transmit, because of
|
||||
// a bug in the VideoConduit code. This will need to be fixed for
|
||||
// renegotiation.
|
||||
if (pair->mReceiving) {
|
||||
rv = factory.CreateMediaPipeline(*pair, *pair->mReceiving);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Failed to create receiving pipeline, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (pair->mSending) {
|
||||
rv = factory.CreateMediaPipeline(*pair, *pair->mSending);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Failed to create sending pipeline, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::StartIceChecks(const mozilla::JsepSession& session) {
|
||||
|
||||
std::vector<size_t> numComponentsByLevel;
|
||||
for (size_t i = 0; i < session.GetTransportCount(); ++i) {
|
||||
RefPtr<JsepTransport> transport;
|
||||
nsresult rv = session.GetTransport(i, &transport);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "JsepSession::GetTransport() failed: %u",
|
||||
static_cast<unsigned>(rv));
|
||||
MOZ_ASSERT(false, "JsepSession::GetTransport() failed!");
|
||||
break;
|
||||
}
|
||||
|
||||
if (transport->mState == JsepTransport::kJsepTransportClosed) {
|
||||
numComponentsByLevel.push_back(0);
|
||||
} else {
|
||||
numComponentsByLevel.push_back(transport->mComponents);
|
||||
}
|
||||
}
|
||||
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::StartIceChecks_s,
|
||||
session.IsIceControlling(),
|
||||
session.RemoteIsIceLite(),
|
||||
// Copy, just in case API changes to return a ref
|
||||
std::vector<std::string>(session.GetIceOptions()),
|
||||
numComponentsByLevel),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::StartIceChecks_s(
|
||||
bool aIsControlling,
|
||||
bool aIsIceLite,
|
||||
const std::vector<std::string>& aIceOptionsList,
|
||||
const std::vector<size_t>& aComponentCountByLevel) {
|
||||
|
||||
CSFLogDebug(logTag, "Starting ICE Checking");
|
||||
|
||||
std::vector<std::string> attributes;
|
||||
if (aIsIceLite) {
|
||||
attributes.push_back("ice-lite");
|
||||
}
|
||||
|
||||
if (!aIceOptionsList.empty()) {
|
||||
attributes.push_back("ice-options:");
|
||||
for (auto i = aIceOptionsList.begin(); i != aIceOptionsList.end(); ++i) {
|
||||
attributes.back() += *i + ' ';
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = mIceCtx->ParseGlobalAttributes(attributes);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "%s: couldn't parse global parameters", __FUNCTION__ );
|
||||
}
|
||||
|
||||
mIceCtx->SetControlling(aIsControlling ?
|
||||
NrIceCtx::ICE_CONTROLLING :
|
||||
NrIceCtx::ICE_CONTROLLED);
|
||||
|
||||
for (size_t i = 0; i < aComponentCountByLevel.size(); ++i) {
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtx->GetStream(i));
|
||||
if (!stream) {
|
||||
MOZ_ASSERT(false, "JsepSession has more streams than the ICE ctx");
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t c = aComponentCountByLevel[i]; c < stream->components(); ++c) {
|
||||
// components are 1-indexed
|
||||
stream->DisableComponent(c + 1);
|
||||
}
|
||||
}
|
||||
|
||||
mIceCtx->StartChecks();
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::AddIceCandidate(const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint32_t aMLine) {
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::AddIceCandidate_s,
|
||||
std::string(candidate), // Make copies.
|
||||
std::string(mid),
|
||||
aMLine),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
void
|
||||
PeerConnectionMedia::AddIceCandidate_s(const std::string& aCandidate,
|
||||
const std::string& aMid,
|
||||
uint32_t aMLine) {
|
||||
if (aMLine >= mIceStreams.size()) {
|
||||
CSFLogError(logTag, "Couldn't process ICE candidate for bogus level %u",
|
||||
aMLine);
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = mIceStreams[aMLine]->ParseTrickleCandidate(aCandidate);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Couldn't process ICE candidate at level %u",
|
||||
aMLine);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::EnsureIceGathering_s() {
|
||||
if (mIceCtx->gathering_state() == NrIceCtx::ICE_CTX_GATHER_INIT) {
|
||||
mIceCtx->StartGathering();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::UpdateIceMediaStream_s(size_t aMLine,
|
||||
size_t aComponentCount,
|
||||
bool aHasAttrs,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPassword,
|
||||
const std::vector<std::string>&
|
||||
aCandidateList) {
|
||||
if (aMLine > mIceStreams.size()) {
|
||||
CSFLogError(logTag, "Missing stream for previous m-line %u, this can "
|
||||
"happen if we failed to create a stream earlier.",
|
||||
static_cast<unsigned>(aMLine - 1));
|
||||
return;
|
||||
}
|
||||
|
||||
CSFLogDebug(logTag, "%s: Creating ICE media stream=%u components=%u",
|
||||
mParentHandle.c_str(),
|
||||
static_cast<unsigned>(aMLine),
|
||||
static_cast<unsigned>(aComponentCount));
|
||||
RefPtr<NrIceMediaStream> stream;
|
||||
|
||||
if (mIceStreams.size() == aMLine) {
|
||||
std::ostringstream os;
|
||||
os << mParentName << " level=" << aMLine;
|
||||
stream = mIceCtx->CreateStream(os.str().c_str(), aComponentCount);
|
||||
|
||||
if (!stream) {
|
||||
CSFLogError(logTag, "Failed to create ICE stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
stream->SetLevel(aMLine);
|
||||
stream->SignalReady.connect(this, &PeerConnectionMedia::IceStreamReady_s);
|
||||
stream->SignalCandidate.connect(this,
|
||||
&PeerConnectionMedia::OnCandidateFound_s);
|
||||
|
||||
mIceStreams.push_back(stream);
|
||||
if (!audioStream) {
|
||||
CSFLogError(logTag, "%s: audio stream is NULL", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
stream = mIceStreams[aMLine];
|
||||
mIceStreams.push_back(audioStream);
|
||||
}
|
||||
|
||||
if (aHasAttrs) {
|
||||
std::vector<std::string> attrs;
|
||||
for (auto i = aCandidateList.begin(); i != aCandidateList.end(); ++i) {
|
||||
attrs.push_back("candidate:" + *i);
|
||||
}
|
||||
attrs.push_back("ice-ufrag:" + aUfrag);
|
||||
attrs.push_back("ice-pwd:" + aPassword);
|
||||
|
||||
nsresult rv = stream->ParseAttributes(attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Couldn't parse ICE attributes, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
}
|
||||
if (!videoStream) {
|
||||
CSFLogError(logTag, "%s: video stream is NULL", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
mIceStreams.push_back(videoStream);
|
||||
}
|
||||
|
||||
if (!dcStream) {
|
||||
CSFLogError(logTag, "%s: datachannel stream is NULL", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
mIceStreams.push_back(dcStream);
|
||||
}
|
||||
|
||||
// TODO(ekr@rtfm.com): This is not connected to the PCCimpl.
|
||||
// Will need to do that later.
|
||||
for (std::size_t i=0; i<mIceStreams.size(); i++) {
|
||||
mIceStreams[i]->SetLevel(i + 1);
|
||||
mIceStreams[i]->SignalReady.connect(this, &PeerConnectionMedia::IceStreamReady);
|
||||
mIceStreams[i]->SignalCandidate.connect(
|
||||
this,
|
||||
&PeerConnectionMedia::OnCandidateFound_s);
|
||||
}
|
||||
|
||||
// TODO(ekr@rtfm.com): When we have a generic error reporting mechanism,
|
||||
// figure out how to report that StartGathering failed. Bug 827982.
|
||||
RUN_ON_THREAD(mIceCtx->thread(),
|
||||
WrapRunnable(mIceCtx, &NrIceCtx::StartGathering), NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
|
||||
uint32_t hints,
|
||||
std::string *stream_id)
|
||||
uint32_t *stream_id)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
|
@ -564,20 +345,14 @@ PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
|
|||
}
|
||||
if (aMediaStream == lss->GetMediaStream()) {
|
||||
localSourceStream = lss;
|
||||
*stream_id = lss->GetId();
|
||||
*stream_id = u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!localSourceStream) {
|
||||
std::string id;
|
||||
if (!mUuidGen->Generate(&id)) {
|
||||
CSFLogError(logTag, "Failed to generate UUID for stream");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
localSourceStream = new LocalSourceStreamInfo(aMediaStream, this, id);
|
||||
localSourceStream = new LocalSourceStreamInfo(aMediaStream, this);
|
||||
mLocalSourceStreams.AppendElement(localSourceStream);
|
||||
*stream_id = id;
|
||||
*stream_id = mLocalSourceStreams.Length() - 1;
|
||||
}
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
|
@ -690,7 +465,7 @@ PeerConnectionMedia::ShutdownMediaTransport_s()
|
|||
}
|
||||
|
||||
LocalSourceStreamInfo*
|
||||
PeerConnectionMedia::GetLocalStreamByIndex(int aIndex)
|
||||
PeerConnectionMedia::GetLocalStream(int aIndex)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
if(aIndex < 0 || aIndex >= (int) mLocalSourceStreams.Length()) {
|
||||
|
@ -701,57 +476,30 @@ PeerConnectionMedia::GetLocalStreamByIndex(int aIndex)
|
|||
return mLocalSourceStreams[aIndex];
|
||||
}
|
||||
|
||||
LocalSourceStreamInfo*
|
||||
PeerConnectionMedia::GetLocalStreamById(const std::string& id)
|
||||
RemoteSourceStreamInfo*
|
||||
PeerConnectionMedia::GetRemoteStream(int aIndex)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
for (size_t i = 0; i < mLocalSourceStreams.Length(); ++i) {
|
||||
if (id == mLocalSourceStreams[i]->GetId()) {
|
||||
return mLocalSourceStreams[i];
|
||||
}
|
||||
if(aIndex < 0 || aIndex >= (int) mRemoteSourceStreams.Length()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RemoteSourceStreamInfo*
|
||||
PeerConnectionMedia::GetRemoteStreamByIndex(size_t aIndex)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
MOZ_ASSERT(mRemoteSourceStreams.SafeElementAt(aIndex));
|
||||
return mRemoteSourceStreams.SafeElementAt(aIndex);
|
||||
}
|
||||
|
||||
RemoteSourceStreamInfo*
|
||||
PeerConnectionMedia::GetRemoteStreamById(const std::string& id)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
for (size_t i = 0; i < mRemoteSourceStreams.Length(); ++i) {
|
||||
if (id == mRemoteSourceStreams[i]->GetId()) {
|
||||
return mRemoteSourceStreams[i];
|
||||
}
|
||||
}
|
||||
|
||||
// This does not have a MOZ_ASSERT like GetLocalStreamById because in the
|
||||
// case of local streams, the stream id and stream info are created
|
||||
// simultaneously, whereas in the remote case the stream id exists first,
|
||||
// meaning we have to be able to check.
|
||||
return nullptr;
|
||||
MOZ_ASSERT(mRemoteSourceStreams[aIndex]);
|
||||
return mRemoteSourceStreams[aIndex];
|
||||
}
|
||||
|
||||
bool
|
||||
PeerConnectionMedia::SetUsingBundle_m(int aMLine, bool decision)
|
||||
PeerConnectionMedia::SetUsingBundle_m(int level, bool decision)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
for (size_t i = 0; i < mRemoteSourceStreams.Length(); ++i) {
|
||||
if (mRemoteSourceStreams[i]->SetUsingBundle_m(aMLine, decision)) {
|
||||
// Found the MediaPipeline for |aMLine|
|
||||
if (mRemoteSourceStreams[i]->SetUsingBundle_m(level, decision)) {
|
||||
// Found the MediaPipeline for |level|
|
||||
return true;
|
||||
}
|
||||
}
|
||||
CSFLogWarn(logTag, "Could not locate level %d to set bundle flag to %s",
|
||||
static_cast<int>(aMLine),
|
||||
static_cast<int>(level),
|
||||
decision ? "true" : "false");
|
||||
return false;
|
||||
}
|
||||
|
@ -776,19 +524,19 @@ UpdateFilterFromRemoteDescription_s(
|
|||
|
||||
bool
|
||||
PeerConnectionMedia::UpdateFilterFromRemoteDescription_m(
|
||||
int aMLine,
|
||||
int level,
|
||||
nsAutoPtr<mozilla::MediaPipelineFilter> filter)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
RefPtr<mozilla::MediaPipeline> receive;
|
||||
for (size_t i = 0; !receive && i < mRemoteSourceStreams.Length(); ++i) {
|
||||
receive = mRemoteSourceStreams[i]->GetPipelineByLevel_m(aMLine);
|
||||
receive = mRemoteSourceStreams[i]->GetPipelineByLevel_m(level);
|
||||
}
|
||||
|
||||
RefPtr<mozilla::MediaPipeline> transmit;
|
||||
for (size_t i = 0; !transmit && i < mLocalSourceStreams.Length(); ++i) {
|
||||
transmit = mLocalSourceStreams[i]->GetPipelineByLevel_m(aMLine);
|
||||
transmit = mLocalSourceStreams[i]->GetPipelineByLevel_m(level);
|
||||
}
|
||||
|
||||
if (receive && transmit) {
|
||||
|
@ -807,15 +555,19 @@ PeerConnectionMedia::UpdateFilterFromRemoteDescription_m(
|
|||
return true;
|
||||
} else {
|
||||
CSFLogWarn(logTag, "Could not locate level %d to update filter",
|
||||
static_cast<int>(aMLine));
|
||||
static_cast<int>(level));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo)
|
||||
PeerConnectionMedia::AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo,
|
||||
int *aIndex)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
MOZ_ASSERT(aIndex);
|
||||
|
||||
*aIndex = mRemoteSourceStreams.Length();
|
||||
|
||||
mRemoteSourceStreams.AppendElement(aInfo);
|
||||
|
||||
|
@ -848,31 +600,6 @@ PeerConnectionMedia::IceGatheringStateChange_s(NrIceCtx* ctx,
|
|||
NrIceCtx::GatheringState state)
|
||||
{
|
||||
ASSERT_ON_THREAD(mSTSThread);
|
||||
|
||||
if (state == NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
|
||||
// Fire off EndOfLocalCandidates for each stream
|
||||
for (size_t i = 0; ; ++i) {
|
||||
RefPtr<NrIceMediaStream> stream(ctx->GetStream(i));
|
||||
if (!stream) {
|
||||
break;
|
||||
}
|
||||
|
||||
NrIceCandidate candidate;
|
||||
nsresult res = stream->GetDefaultCandidate(&candidate);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
EndOfLocalCandidates(candidate.cand_addr.host,
|
||||
candidate.cand_addr.port,
|
||||
i);
|
||||
} else {
|
||||
CSFLogError(logTag, "%s: GetDefaultCandidate failed for level %u, "
|
||||
"res=%u",
|
||||
__FUNCTION__,
|
||||
static_cast<unsigned>(i),
|
||||
static_cast<unsigned>(res));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ShutdownMediaTransport_s has not run yet because it unhooks this function
|
||||
// from its signal, which means that SelfDestruct_m has not been dispatched
|
||||
// yet either, so this PCMedia will still be around when this dispatch reaches
|
||||
|
@ -923,18 +650,6 @@ PeerConnectionMedia::OnCandidateFound_s(NrIceMediaStream *aStream,
|
|||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::EndOfLocalCandidates(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine) {
|
||||
// We will still be around because we have not started teardown yet
|
||||
GetMainThread()->Dispatch(
|
||||
WrapRunnable(this,
|
||||
&PeerConnectionMedia::EndOfLocalCandidates_m,
|
||||
aDefaultAddr, aDefaultPort, aMLine),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::IceGatheringStateChange_m(NrIceCtx* ctx,
|
||||
NrIceCtx::GatheringState state)
|
||||
|
@ -952,7 +667,7 @@ PeerConnectionMedia::IceConnectionStateChange_m(NrIceCtx* ctx,
|
|||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::IceStreamReady_s(NrIceMediaStream *aStream)
|
||||
PeerConnectionMedia::IceStreamReady(NrIceMediaStream *aStream)
|
||||
{
|
||||
MOZ_ASSERT(aStream);
|
||||
|
||||
|
@ -961,18 +676,13 @@ PeerConnectionMedia::IceStreamReady_s(NrIceMediaStream *aStream)
|
|||
|
||||
void
|
||||
PeerConnectionMedia::OnCandidateFound_m(const std::string &candidate,
|
||||
uint16_t aMLine)
|
||||
uint16_t level)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
SignalCandidate(candidate, aMLine);
|
||||
SignalCandidate(candidate, level);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::EndOfLocalCandidates_m(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine) {
|
||||
SignalEndOfLocalCandidates(aDefaultAddr, aDefaultPort, aMLine);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerConnectionMedia::DtlsConnected_s(TransportLayer *dtlsLayer,
|
||||
|
@ -1131,29 +841,29 @@ RemoteSourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
|
|||
|
||||
void
|
||||
LocalSourceStreamInfo::StorePipeline(
|
||||
int aMLine, mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline)
|
||||
int aTrack, mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline)
|
||||
{
|
||||
MOZ_ASSERT(mPipelines.find(aMLine) == mPipelines.end());
|
||||
if (mPipelines.find(aMLine) != mPipelines.end()) {
|
||||
MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end());
|
||||
if (mPipelines.find(aTrack) != mPipelines.end()) {
|
||||
CSFLogError(logTag, "%s: Storing duplicate track", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
//TODO: Revisit once we start supporting multiple streams or multiple tracks
|
||||
// of same type bug 1056650
|
||||
mPipelines[aMLine] = aPipeline;
|
||||
mPipelines[aTrack] = aPipeline;
|
||||
}
|
||||
|
||||
void
|
||||
RemoteSourceStreamInfo::StorePipeline(
|
||||
int aMLine, bool aIsVideo,
|
||||
int aTrack, bool aIsVideo,
|
||||
mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline)
|
||||
{
|
||||
MOZ_ASSERT(mPipelines.find(aMLine) == mPipelines.end());
|
||||
if (mPipelines.find(aMLine) != mPipelines.end()) {
|
||||
CSFLogError(logTag, "%s: Request to store duplicate track %d", __FUNCTION__, aMLine);
|
||||
MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end());
|
||||
if (mPipelines.find(aTrack) != mPipelines.end()) {
|
||||
CSFLogError(logTag, "%s: Request to store duplicate track %d", __FUNCTION__, aTrack);
|
||||
return;
|
||||
}
|
||||
CSFLogDebug(logTag, "%s track %d %s = %p", __FUNCTION__, aMLine, aIsVideo ? "video" : "audio",
|
||||
CSFLogDebug(logTag, "%s track %d %s = %p", __FUNCTION__, aTrack, aIsVideo ? "video" : "audio",
|
||||
aPipeline.get());
|
||||
// See if we have both audio and video here, and if so cross the streams and sync them
|
||||
// XXX Needs to be adjusted when we support multiple streams of the same type bug 1056650
|
||||
|
@ -1170,17 +880,17 @@ RemoteSourceStreamInfo::StorePipeline(
|
|||
mPipelines[it->first]->Conduit());
|
||||
video_conduit->SyncTo(audio_conduit);
|
||||
CSFLogDebug(logTag, "Syncing %p to %p, %d to %d", video_conduit, audio_conduit,
|
||||
aMLine, it->first);
|
||||
aTrack, it->first);
|
||||
}
|
||||
}
|
||||
//TODO: Revisit once we start supporting multiple streams or multiple tracks
|
||||
// of same type bug 1056650
|
||||
mPipelines[aMLine] = aPipeline;
|
||||
mPipelines[aTrack] = aPipeline;
|
||||
//TODO: move to attribute on Pipeline
|
||||
mTypes[aMLine] = aIsVideo;
|
||||
mTypes[aTrack] = aIsVideo;
|
||||
}
|
||||
|
||||
RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int aMLine) {
|
||||
RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int level) {
|
||||
ASSERT_ON_THREAD(mParent->GetMainThread());
|
||||
|
||||
// Refuse to hand out references if we're tearing down.
|
||||
|
@ -1190,7 +900,7 @@ RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int aMLine) {
|
|||
// standing)
|
||||
if (mMediaStream) {
|
||||
for (auto p = mPipelines.begin(); p != mPipelines.end(); ++p) {
|
||||
if (p->second->level() == aMLine) {
|
||||
if (p->second->level() == level) {
|
||||
return p->second;
|
||||
}
|
||||
}
|
||||
|
@ -1199,11 +909,11 @@ RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int aMLine) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool RemoteSourceStreamInfo::SetUsingBundle_m(int aMLine, bool decision) {
|
||||
bool RemoteSourceStreamInfo::SetUsingBundle_m(int aLevel, bool decision) {
|
||||
ASSERT_ON_THREAD(mParent->GetMainThread());
|
||||
|
||||
// Avoid adding and dropping an extra ref
|
||||
MediaPipeline *pipeline = GetPipelineByLevel_m(aMLine);
|
||||
MediaPipeline *pipeline = GetPipelineByLevel_m(aLevel);
|
||||
|
||||
if (pipeline) {
|
||||
RUN_ON_THREAD(mParent->GetSTSThread(),
|
||||
|
@ -1218,4 +928,4 @@ bool RemoteSourceStreamInfo::SetUsingBundle_m(int aMLine, bool decision) {
|
|||
return false;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace sipcc
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "MediaSegment.h"
|
||||
#endif
|
||||
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "AudioSegment.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
|
@ -37,7 +36,6 @@ class nsIPrincipal;
|
|||
namespace mozilla {
|
||||
class DataChannel;
|
||||
class PeerIdentity;
|
||||
class MediaPipelineFactory;
|
||||
namespace dom {
|
||||
struct RTCInboundRTPStreamStats;
|
||||
struct RTCOutboundRTPStreamStats;
|
||||
|
@ -49,15 +47,16 @@ struct RTCOutboundRTPStreamStats;
|
|||
#include "nricemediastream.h"
|
||||
#include "MediaPipeline.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace sipcc {
|
||||
|
||||
class PeerConnectionImpl;
|
||||
class PeerConnectionMedia;
|
||||
class PCUuidGenerator;
|
||||
|
||||
/* Temporary for providing audio data */
|
||||
class Fake_AudioGenerator {
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
explicit Fake_AudioGenerator(DOMMediaStream* aStream) : mStream(aStream), mCount(0) {
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
MOZ_ASSERT(mTimer);
|
||||
|
@ -97,6 +96,7 @@ class Fake_AudioGenerator {
|
|||
#ifdef MOZILLA_INTERNAL_API
|
||||
class Fake_VideoGenerator {
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
typedef mozilla::gfx::IntSize IntSize;
|
||||
|
||||
explicit Fake_VideoGenerator(DOMMediaStream* aStream) {
|
||||
|
@ -174,21 +174,19 @@ class Fake_VideoGenerator {
|
|||
|
||||
class SourceStreamInfo {
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
SourceStreamInfo(DOMMediaStream* aMediaStream,
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
PeerConnectionMedia *aParent)
|
||||
: mMediaStream(aMediaStream),
|
||||
mParent(aParent),
|
||||
mId(aId) {
|
||||
mParent(aParent) {
|
||||
MOZ_ASSERT(mMediaStream);
|
||||
}
|
||||
|
||||
SourceStreamInfo(already_AddRefed<DOMMediaStream>& aMediaStream,
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
PeerConnectionMedia *aParent)
|
||||
: mMediaStream(aMediaStream),
|
||||
mParent(aParent),
|
||||
mId(aId) {
|
||||
mParent(aParent) {
|
||||
MOZ_ASSERT(mMediaStream);
|
||||
}
|
||||
|
||||
|
@ -200,14 +198,12 @@ public:
|
|||
// It allows visibility into the pipelines and flows.
|
||||
const std::map<mozilla::TrackID, mozilla::RefPtr<mozilla::MediaPipeline>>&
|
||||
GetPipelines() const { return mPipelines; }
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> GetPipelineByLevel_m(int aMLine);
|
||||
const std::string& GetId() const { return mId; }
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> GetPipelineByLevel_m(int level);
|
||||
|
||||
protected:
|
||||
std::map<mozilla::TrackID, mozilla::RefPtr<mozilla::MediaPipeline>> mPipelines;
|
||||
nsRefPtr<DOMMediaStream> mMediaStream;
|
||||
PeerConnectionMedia *mParent;
|
||||
const std::string mId;
|
||||
};
|
||||
|
||||
// TODO(ekr@rtfm.com): Refactor {Local,Remote}SourceStreamInfo
|
||||
|
@ -217,28 +213,28 @@ class LocalSourceStreamInfo : public SourceStreamInfo {
|
|||
mMediaStream = nullptr;
|
||||
}
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
LocalSourceStreamInfo(DOMMediaStream *aMediaStream,
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
: SourceStreamInfo(aMediaStream, aParent, aId) {}
|
||||
PeerConnectionMedia *aParent)
|
||||
: SourceStreamInfo(aMediaStream, aParent) {}
|
||||
|
||||
// Returns the mPipelines index for the track or -1.
|
||||
#if 0
|
||||
int HasTrack(DOMMediaStream* aStream, mozilla::TrackID aMLine);
|
||||
int HasTrack(DOMMediaStream* aStream, mozilla::TrackID aTrack);
|
||||
#endif
|
||||
int HasTrackType(DOMMediaStream* aStream, bool aIsVideo);
|
||||
// XXX NOTE: does not change mMediaStream, even if it replaces the last track
|
||||
// in a LocalSourceStreamInfo. Revise when we have support for multiple tracks
|
||||
// of a type.
|
||||
// Note aMLine != aOldTrack! It's the result of HasTrackType()
|
||||
nsresult ReplaceTrack(int aMLine, DOMMediaStream* aNewStream, mozilla::TrackID aNewTrack);
|
||||
// Note aIndex != aOldTrack! It's the result of HasTrackType()
|
||||
nsresult ReplaceTrack(int aIndex, DOMMediaStream* aNewStream, mozilla::TrackID aNewTrack);
|
||||
|
||||
void StorePipeline(int aMLine,
|
||||
void StorePipeline(int aTrack,
|
||||
mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal,
|
||||
const mozilla::PeerIdentity* aSinkIdentity);
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, const PeerIdentity* aSinkIdentity);
|
||||
#endif
|
||||
|
||||
void ExpectAudio(const mozilla::TrackID);
|
||||
|
@ -261,17 +257,17 @@ private:
|
|||
class RemoteSourceStreamInfo : public SourceStreamInfo {
|
||||
~RemoteSourceStreamInfo() {}
|
||||
public:
|
||||
RemoteSourceStreamInfo(already_AddRefed<DOMMediaStream> aMediaStream,
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
: SourceStreamInfo(aMediaStream, aParent, aId),
|
||||
mTrackTypeHints(0) {
|
||||
}
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
void StorePipeline(int aMLine, bool aIsVideo,
|
||||
RemoteSourceStreamInfo(already_AddRefed<DOMMediaStream> aMediaStream,
|
||||
PeerConnectionMedia *aParent)
|
||||
: SourceStreamInfo(aMediaStream, aParent),
|
||||
mTrackTypeHints(0) {}
|
||||
|
||||
void StorePipeline(int aTrack, bool aIsVideo,
|
||||
mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline);
|
||||
|
||||
bool SetUsingBundle_m(int aMLine, bool decision);
|
||||
bool SetUsingBundle_m(int aLevel, bool decision);
|
||||
|
||||
void DetachTransport_s();
|
||||
void DetachMedia_m();
|
||||
|
@ -296,7 +292,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
public:
|
||||
explicit PeerConnectionMedia(PeerConnectionImpl *parent);
|
||||
|
||||
PeerConnectionImpl* GetPC() { return mParent; }
|
||||
nsresult Init(const std::vector<mozilla::NrIceStunServer>& stun_servers,
|
||||
const std::vector<mozilla::NrIceTurnServer>& turn_servers);
|
||||
// WARNING: This destroys the object!
|
||||
|
@ -320,22 +315,9 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
return mIceStreams.size();
|
||||
}
|
||||
|
||||
// Create and modify transports in response to negotiation events.
|
||||
void UpdateTransports(const mozilla::JsepSession& session);
|
||||
|
||||
// Start ICE checks.
|
||||
void StartIceChecks(const mozilla::JsepSession& session);
|
||||
|
||||
// Process a trickle ICE candidate.
|
||||
void AddIceCandidate(const std::string& candidate, const std::string& mid,
|
||||
uint32_t aMLine);
|
||||
|
||||
// Handle complete media pipelines.
|
||||
nsresult UpdateMediaPipelines(const mozilla::JsepSession& session);
|
||||
|
||||
// Add a stream (main thread only)
|
||||
nsresult AddStream(DOMMediaStream* aMediaStream, uint32_t hints,
|
||||
std::string* stream_id);
|
||||
uint32_t *stream_id);
|
||||
|
||||
// Remove a stream (main thread only)
|
||||
nsresult RemoveStream(DOMMediaStream* aMediaStream,
|
||||
|
@ -347,33 +329,29 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
{
|
||||
return mLocalSourceStreams.Length();
|
||||
}
|
||||
LocalSourceStreamInfo* GetLocalStreamByIndex(int index);
|
||||
LocalSourceStreamInfo* GetLocalStreamById(const std::string& id);
|
||||
LocalSourceStreamInfo* GetLocalStream(int index);
|
||||
|
||||
// Get a specific remote stream
|
||||
uint32_t RemoteStreamsLength()
|
||||
{
|
||||
return mRemoteSourceStreams.Length();
|
||||
}
|
||||
RemoteSourceStreamInfo* GetRemoteStream(int index);
|
||||
|
||||
RemoteSourceStreamInfo* GetRemoteStreamByIndex(size_t index);
|
||||
RemoteSourceStreamInfo* GetRemoteStreamById(const std::string& id);
|
||||
|
||||
bool SetUsingBundle_m(int aMLine, bool decision);
|
||||
bool SetUsingBundle_m(int level, bool decision);
|
||||
bool UpdateFilterFromRemoteDescription_m(
|
||||
int aMLine,
|
||||
int level,
|
||||
nsAutoPtr<mozilla::MediaPipelineFilter> filter);
|
||||
|
||||
// Add a remote stream.
|
||||
nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo);
|
||||
// Add a remote stream. Returns the index in index
|
||||
nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo, int *aIndex);
|
||||
nsresult AddRemoteStreamHint(int aIndex, bool aIsVideo);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// In cases where the peer isn't yet identified, we disable the pipeline (not
|
||||
// the stream, that would potentially affect others), so that it sends
|
||||
// black/silence. Once the peer is identified, re-enable those streams.
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal,
|
||||
const mozilla::PeerIdentity* aSinkIdentity);
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, const PeerIdentity* aSinkIdentity);
|
||||
// this determines if any stream is peerIdentity constrained
|
||||
bool AnyLocalStreamHasPeerIdentity() const;
|
||||
// When we finally learn who is on the other end, we need to change the ownership
|
||||
|
@ -430,11 +408,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
SignalIceGatheringStateChange;
|
||||
sigslot::signal2<mozilla::NrIceCtx*, mozilla::NrIceCtx::ConnectionState>
|
||||
SignalIceConnectionStateChange;
|
||||
// This passes a candidate:... attribute and level
|
||||
sigslot::signal2<const std::string&, uint16_t> SignalCandidate;
|
||||
// This passes address, port, level of the default candidate.
|
||||
sigslot::signal3<const std::string&, uint16_t, uint16_t>
|
||||
SignalEndOfLocalCandidates;
|
||||
|
||||
private:
|
||||
// Shutdown media transport. Must be called on STS thread.
|
||||
|
@ -444,50 +418,26 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
// thread.
|
||||
void SelfDestruct_m();
|
||||
|
||||
// Manage ICE transports.
|
||||
void UpdateIceMediaStream_s(size_t aMLine, size_t aComponentCount,
|
||||
bool aHasAttrs,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPassword,
|
||||
const std::vector<std::string>& aCandidateList);
|
||||
void EnsureIceGathering_s();
|
||||
void StartIceChecks_s(bool aIsControlling,
|
||||
bool aIsIceLite,
|
||||
const std::vector<std::string>& aIceOptionsList,
|
||||
const std::vector<size_t>& aComponentCountByLevel);
|
||||
|
||||
// Process a trickle ICE candidate.
|
||||
void AddIceCandidate_s(const std::string& aCandidate, const std::string& aMid,
|
||||
uint32_t aMLine);
|
||||
|
||||
|
||||
// ICE events
|
||||
void IceGatheringStateChange_s(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::GatheringState state);
|
||||
void IceConnectionStateChange_s(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::ConnectionState state);
|
||||
void IceStreamReady_s(mozilla::NrIceMediaStream *aStream);
|
||||
void IceStreamReady(mozilla::NrIceMediaStream *aStream);
|
||||
void OnCandidateFound_s(mozilla::NrIceMediaStream *aStream,
|
||||
const std::string &candidate);
|
||||
void EndOfLocalCandidates(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine);
|
||||
|
||||
void IceGatheringStateChange_m(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::GatheringState state);
|
||||
void IceConnectionStateChange_m(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::ConnectionState state);
|
||||
void OnCandidateFound_m(const std::string &candidate, uint16_t aMLine);
|
||||
void EndOfLocalCandidates_m(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine);
|
||||
void OnCandidateFound_m(const std::string &candidate, uint16_t level);
|
||||
|
||||
|
||||
// The parent PC
|
||||
PeerConnectionImpl *mParent;
|
||||
// and a loose handle on it for event driven stuff
|
||||
std::string mParentHandle;
|
||||
std::string mParentName;
|
||||
|
||||
// A list of streams returned from GetUserMedia
|
||||
// This is only accessed on the main thread (with one special exception)
|
||||
|
@ -514,9 +464,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
// flows)
|
||||
std::map<int, mozilla::RefPtr<mozilla::MediaSessionConduit> > mConduits;
|
||||
|
||||
// UUID Generator
|
||||
mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
|
||||
|
||||
// The main thread.
|
||||
nsCOMPtr<nsIThread> mMainThread;
|
||||
|
||||
|
@ -526,5 +473,5 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace sipcc
|
||||
#endif
|
||||
|
|
|
@ -25,15 +25,18 @@
|
|||
#include "PeerConnectionImpl.h"
|
||||
#include "webrtc/system_wrappers/interface/trace.h"
|
||||
|
||||
using sipcc::PeerConnectionImpl;
|
||||
using sipcc::PeerConnectionCtx;
|
||||
using sipcc::RTCStatsQuery;
|
||||
|
||||
static const char* logTag = "WebrtcGlobalInformation";
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef Vector<nsAutoPtr<RTCStatsQuery>> RTCStatsQueries;
|
||||
|
||||
static PeerConnectionCtx* GetPeerConnectionCtx()
|
||||
static sipcc::PeerConnectionCtx* GetPeerConnectionCtx()
|
||||
{
|
||||
if(PeerConnectionCtx::isActive()) {
|
||||
MOZ_ASSERT(PeerConnectionCtx::GetInstance());
|
||||
|
@ -497,7 +500,7 @@ static void GetStatsForLongTermStorage_s(
|
|||
}
|
||||
|
||||
void WebrtcGlobalInformation::StoreLongTermICEStatistics(
|
||||
PeerConnectionImpl& aPc) {
|
||||
sipcc::PeerConnectionImpl& aPc) {
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_ICE_FINAL_CONNECTION_STATE,
|
||||
static_cast<uint32_t>(aPc.IceConnectionState()));
|
||||
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
#include "nsString.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h" // for Optional
|
||||
|
||||
namespace mozilla {
|
||||
namespace sipcc {
|
||||
class PeerConnectionImpl;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
@ -36,7 +39,7 @@ public:
|
|||
static void SetAecDebug(const GlobalObject& aGlobal, bool aEnable);
|
||||
static bool AecDebug(const GlobalObject& aGlobal);
|
||||
|
||||
static void StoreLongTermICEStatistics(PeerConnectionImpl& aPc);
|
||||
static void StoreLongTermICEStatistics(sipcc::PeerConnectionImpl& aPc);
|
||||
|
||||
private:
|
||||
WebrtcGlobalInformation() MOZ_DELETE;
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
|
||||
,-----. ,--. ,--.
|
||||
' .--./ ,--,--.,--.,--.,-' '-.`--' ,---. ,--,--,
|
||||
| | ' ,-. || || |'-. .-',--.| .-. || `
|
||||
' '--'\\ '-' |' '' ' | | | |' '-' '| || |
|
||||
`-----' `--`--' `----' `--' `--' `---' `--''--'
|
||||
|
||||
:+o+-
|
||||
-dNNNNNd.
|
||||
yNNNNNNNs
|
||||
:mNNNNNm-
|
||||
`/sso/``-://-
|
||||
.:+sydNNNNNNms: `://`
|
||||
`-/+shmNNNNNNNNNNNNNNNms- :mNNNm/
|
||||
`-/oydmNNNNNNNNNNNNNNNNNNNNNNNNdo- +NNNNNN+
|
||||
.shmNNNNNNNNNNNmdyo/:dNNNNNNNNNNNNNNNNdo. `sNNNNNm+
|
||||
hNNNNNNNNmhs+:-` .dNNNNNNNNNNNNNNNNNNNNh+-` `hNNNNNm:
|
||||
-yddyo/:. -dNNNNm::ymNNNNNNNNNNNNNNNmdy+/dNNNNNd.
|
||||
:mNNNNd. `/ymNNNNNNNNNNNNNNNNNNNNNNh`
|
||||
+NNNNNh` `+hNNNNNNNNNNNNNNNNNNNs
|
||||
sNNNNNy` .yNNNNNm`-/oymNNNm+
|
||||
`yNNNNNo oNNNNNm` `-.
|
||||
.dNNNNm/ oNNNNNm`
|
||||
oNNNNm: +NNNNNm`
|
||||
`+yho. +NNNNNm`
|
||||
+NNNNNNs.
|
||||
`yNNNNNNmy-
|
||||
-smNNNNNNh:
|
||||
.smNNNNNNh/
|
||||
`omNNNNNNd:
|
||||
`+dNNNNNd
|
||||
````......```` /hmdy-
|
||||
`.:/+osyhddmNNMMMMMMMMMMMMMMMMMMMMNNmddhyso+/:.`
|
||||
`-+shmNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNmhs+-`
|
||||
-smMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMds-
|
||||
hMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh
|
||||
yMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMs
|
||||
.ohNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNh+.
|
||||
./oydmMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmhyo:.
|
||||
`.:/+osyyhddmmNNMMMMMMMMMMMMMMNNmmddhyyso+/:.`
|
||||
|
||||
,--------.,--. ,--. ,--.
|
||||
'--. .--'| ,---. `--' ,---. | | ,---.
|
||||
| | | .-. |,--.( .-' | |( .-'
|
||||
| | | | | || |.-' `) | |.-' `)
|
||||
`--' `--' `--'`--'`----' `--'`----'
|
||||
,--.
|
||||
,---. ,------. ,------. ,--. | |
|
||||
' .-' | .-. \ | .--. ' ,--,--.,--.--.,-' '-. ,--,--.| |
|
||||
`. `-. | | \ :| '--' |' ,-. || .--''-. .-'' ,-. || |
|
||||
.-' || '--' /| | --' \ '-' || | | | \ '-' |`--'
|
||||
`-----' `-------' `--' `--`--'`--' `--' `--`--'.--.
|
||||
'__'
|
||||
*/
|
||||
|
||||
#ifndef _SDP_H_
|
||||
#define _SDP_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
#include "signaling/src/sdp/SdpAttributeList.h"
|
||||
#include "signaling/src/sdp/SdpEnum.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class SdpOrigin;
|
||||
class SdpEncryptionKey;
|
||||
class SdpMediaSection;
|
||||
|
||||
/**
|
||||
* Base class for an SDP
|
||||
*/
|
||||
class Sdp
|
||||
{
|
||||
public:
|
||||
Sdp(){};
|
||||
virtual ~Sdp(){};
|
||||
|
||||
virtual const SdpOrigin& GetOrigin() const = 0;
|
||||
// Note: connection information is always retrieved from media sections
|
||||
virtual uint32_t GetBandwidth(const std::string& type) const = 0;
|
||||
|
||||
virtual const SdpAttributeList& GetAttributeList() const = 0;
|
||||
virtual SdpAttributeList& GetAttributeList() = 0;
|
||||
|
||||
virtual size_t GetMediaSectionCount() const = 0;
|
||||
virtual const SdpMediaSection& GetMediaSection(size_t level) const = 0;
|
||||
virtual SdpMediaSection& GetMediaSection(size_t level) = 0;
|
||||
|
||||
virtual SdpMediaSection& AddMediaSection(SdpMediaSection::MediaType media,
|
||||
SdpDirectionAttribute::Direction dir,
|
||||
uint16_t port,
|
||||
SdpMediaSection::Protocol proto,
|
||||
sdp::AddrType addrType,
|
||||
const std::string& addr) = 0;
|
||||
|
||||
virtual void Serialize(std::ostream&) const = 0;
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Sdp& sdp)
|
||||
{
|
||||
sdp.Serialize(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
Sdp::ToString() const
|
||||
{
|
||||
std::stringstream s;
|
||||
s << *this;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
class SdpOrigin
|
||||
{
|
||||
public:
|
||||
SdpOrigin(const std::string& username, uint64_t sessId, uint64_t sessVer,
|
||||
sdp::AddrType addrType, const std::string& addr)
|
||||
: mUsername(username),
|
||||
mSessionId(sessId),
|
||||
mSessionVersion(sessVer),
|
||||
mAddrType(addrType),
|
||||
mAddress(addr)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string&
|
||||
GetUsername() const
|
||||
{
|
||||
return mUsername;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GetSessionId() const
|
||||
{
|
||||
return mSessionId;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GetSessionVersion() const
|
||||
{
|
||||
return mSessionVersion;
|
||||
}
|
||||
|
||||
const sdp::AddrType
|
||||
GetAddrType() const
|
||||
{
|
||||
return mAddrType;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
GetAddress() const
|
||||
{
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
void
|
||||
Serialize(std::ostream& os) const
|
||||
{
|
||||
sdp::NetType netType = sdp::kInternet;
|
||||
os << "o=" << mUsername << " " << mSessionId << " " << mSessionVersion
|
||||
<< " " << netType << " " << mAddrType << " " << mAddress << "\r\n";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string mUsername;
|
||||
uint64_t mSessionId;
|
||||
uint64_t mSessionVersion;
|
||||
sdp::AddrType mAddrType;
|
||||
std::string mAddress;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const SdpOrigin& origin)
|
||||
{
|
||||
origin.Serialize(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -1,588 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "signaling/src/sdp/SdpAttribute.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#ifdef CRLF
|
||||
#undef CRLF
|
||||
#endif
|
||||
#define CRLF "\r\n"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
void
|
||||
SdpConnectionAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mValue << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpDirectionAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mValue << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpExtmapAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mExtmaps.begin(); i != mExtmaps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->entry;
|
||||
if (i->direction_specified) {
|
||||
os << "/" << i->direction;
|
||||
}
|
||||
os << " " << i->extensionname;
|
||||
if (i->extensionattributes.length()) {
|
||||
os << " " << i->extensionattributes;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpFingerprintAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mFingerprints.begin(); i != mFingerprints.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->hashFunc << " "
|
||||
<< FormatFingerprint(i->fingerprint) << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
// Format the fingerprint in RFC 4572 Section 5 attribute format
|
||||
std::string
|
||||
SdpFingerprintAttributeList::FormatFingerprint(const std::vector<uint8_t>& fp)
|
||||
{
|
||||
if (fp.empty()) {
|
||||
MOZ_ASSERT(false, "Cannot format an empty fingerprint.");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
for (auto i = fp.begin(); i != fp.end(); ++i) {
|
||||
os << ":" << std::hex << std::uppercase << std::setw(2) << std::setfill('0')
|
||||
<< static_cast<uint32_t>(*i);
|
||||
}
|
||||
return os.str().substr(1);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
FromUppercaseHex(char ch)
|
||||
{
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
return ch - '0';
|
||||
}
|
||||
if ((ch >= 'A') && (ch <= 'F')) {
|
||||
return ch - 'A' + 10;
|
||||
}
|
||||
return 16; // invalid
|
||||
}
|
||||
|
||||
// Parse the fingerprint from RFC 4572 Section 5 attribute format
|
||||
std::vector<uint8_t>
|
||||
SdpFingerprintAttributeList::ParseFingerprint(const std::string& str)
|
||||
{
|
||||
size_t targetSize = (str.length() + 1) / 3;
|
||||
std::vector<uint8_t> fp(targetSize);
|
||||
size_t fpIndex = 0;
|
||||
|
||||
if (str.length() % 3 != 2) {
|
||||
fp.clear();
|
||||
return fp;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < str.length(); i += 3) {
|
||||
uint8_t high = FromUppercaseHex(str[i]);
|
||||
uint8_t low = FromUppercaseHex(str[i + 1]);
|
||||
if (high > 0xf || low > 0xf ||
|
||||
(i + 2 < str.length() && str[i + 2] != ':')) {
|
||||
fp.clear(); // error
|
||||
return fp;
|
||||
}
|
||||
fp[fpIndex++] = high << 4 | low;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
void
|
||||
SdpFmtpAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mFmtps.begin(); i != mFmtps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->format << " ";
|
||||
if (i->parameters) {
|
||||
i->parameters->Serialize(os);
|
||||
} else {
|
||||
os << i->parameters_string;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpGroupAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mGroups.begin(); i != mGroups.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->semantics;
|
||||
for (auto j = i->tags.begin(); j != i->tags.end(); ++j) {
|
||||
os << " " << (*j);
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
// We're just using an SdpStringAttribute for this right now
|
||||
#if 0
|
||||
void SdpIdentityAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mAssertion;
|
||||
for (auto i = mExtensions.begin(); i != mExtensions.end(); i++) {
|
||||
os << (i == mExtensions.begin() ? " " : ";") << (*i);
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
SdpImageattrAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
MOZ_ASSERT(false, "Serializer not yet implemented");
|
||||
}
|
||||
|
||||
void
|
||||
SdpMsidAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mMsids.begin(); i != mMsids.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->identifier;
|
||||
if (i->appdata.length()) {
|
||||
os << " " << i->appdata;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpRemoteCandidatesAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
if (mCandidates.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
os << "a=" << mType;
|
||||
for (auto i = mCandidates.begin(); i != mCandidates.end(); i++) {
|
||||
os << (i == mCandidates.begin() ? ":" : " ") << i->id << " " << i->address
|
||||
<< " " << i->port;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpRtcpAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mPort;
|
||||
if (mNetType != sdp::kNetTypeNone && mAddrType != sdp::kAddrTypeNone) {
|
||||
os << " " << mNetType << " " << mAddrType << " " << mAddress;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
|
||||
const char* SdpRtcpFbAttributeList::pli = "pli";
|
||||
const char* SdpRtcpFbAttributeList::sli = "sli";
|
||||
const char* SdpRtcpFbAttributeList::rpsi = "rpsi";
|
||||
const char* SdpRtcpFbAttributeList::app = "app";
|
||||
|
||||
const char* SdpRtcpFbAttributeList::fir = "fir";
|
||||
const char* SdpRtcpFbAttributeList::tmmbr = "tmmbr";
|
||||
const char* SdpRtcpFbAttributeList::tstr = "tstr";
|
||||
const char* SdpRtcpFbAttributeList::vbcm = "vbcm";
|
||||
|
||||
void
|
||||
SdpRtcpFbAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mFeedbacks.begin(); i != mFeedbacks.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->pt << " " << i->type;
|
||||
if (i->parameter.length()) {
|
||||
os << " " << i->parameter;
|
||||
if (i->extra.length()) {
|
||||
os << " " << i->extra;
|
||||
}
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldSerializeChannels(SdpRtpmapAttributeList::CodecType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SdpRtpmapAttributeList::kOpus:
|
||||
case SdpRtpmapAttributeList::kG722:
|
||||
return true;
|
||||
case SdpRtpmapAttributeList::kPCMU:
|
||||
case SdpRtpmapAttributeList::kPCMA:
|
||||
case SdpRtpmapAttributeList::kVP8:
|
||||
case SdpRtpmapAttributeList::kVP9:
|
||||
case SdpRtpmapAttributeList::kiLBC:
|
||||
case SdpRtpmapAttributeList::kiSAC:
|
||||
case SdpRtpmapAttributeList::kH264:
|
||||
return false;
|
||||
case SdpRtpmapAttributeList::kOtherCodec:
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
void
|
||||
SdpRtpmapAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mRtpmaps.begin(); i != mRtpmaps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->pt << " " << i->name << "/" << i->clock;
|
||||
if (i->channels && ShouldSerializeChannels(i->codec)) {
|
||||
os << "/" << i->channels;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpSctpmapAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mSctpmaps.begin(); i != mSctpmaps.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->pt << " " << i->name;
|
||||
if (i->streams) {
|
||||
os << " " << i->streams;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpSetupAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mRole << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpSsrcAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mSsrcs.begin(); i != mSsrcs.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->ssrc << " " << i->attribute << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpSsrcGroupAttributeList::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mSsrcGroups.begin(); i != mSsrcGroups.end(); ++i) {
|
||||
os << "a=" << mType << ":" << i->semantics;
|
||||
for (auto j = i->ssrcs.begin(); j != i->ssrcs.end(); ++j) {
|
||||
os << " " << (*j);
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpMultiStringAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
for (auto i = mValues.begin(); i != mValues.end(); ++i) {
|
||||
os << "a=" << mType << ":" << *i << CRLF;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SdpOptionsAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
if (mValues.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
os << "a=" << mType << ":";
|
||||
|
||||
for (auto i = mValues.begin(); i != mValues.end(); ++i) {
|
||||
if (i != mValues.begin()) {
|
||||
os << " ";
|
||||
}
|
||||
os << *i;
|
||||
}
|
||||
os << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpOptionsAttribute::Load(const std::string& value)
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t end = value.find(' ');
|
||||
while (end != std::string::npos) {
|
||||
PushEntry(value.substr(start, end));
|
||||
start = end + 1;
|
||||
end = value.find(' ', start);
|
||||
}
|
||||
PushEntry(value.substr(start));
|
||||
}
|
||||
|
||||
void
|
||||
SdpFlagAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpStringAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mValue << CRLF;
|
||||
}
|
||||
|
||||
void
|
||||
SdpNumberAttribute::Serialize(std::ostream& os) const
|
||||
{
|
||||
os << "a=" << mType << ":" << mValue << CRLF;
|
||||
}
|
||||
|
||||
bool
|
||||
SdpAttribute::IsAllowedAtMediaLevel(AttributeType type)
|
||||
{
|
||||
switch (type) {
|
||||
case kBundleOnlyAttribute:
|
||||
return true;
|
||||
case kCandidateAttribute:
|
||||
return true;
|
||||
case kConnectionAttribute:
|
||||
return true;
|
||||
case kDirectionAttribute:
|
||||
return true;
|
||||
case kEndOfCandidatesAttribute:
|
||||
return true;
|
||||
case kExtmapAttribute:
|
||||
return true;
|
||||
case kFingerprintAttribute:
|
||||
return true;
|
||||
case kFmtpAttribute:
|
||||
return true;
|
||||
case kGroupAttribute:
|
||||
return false;
|
||||
case kIceLiteAttribute:
|
||||
return false;
|
||||
case kIceMismatchAttribute:
|
||||
return true;
|
||||
// RFC 5245 says this is session-level only, but
|
||||
// draft-ietf-mmusic-ice-sip-sdp-03 updates this to allow at the media
|
||||
// level.
|
||||
case kIceOptionsAttribute:
|
||||
return true;
|
||||
case kIcePwdAttribute:
|
||||
return true;
|
||||
case kIceUfragAttribute:
|
||||
return true;
|
||||
case kIdentityAttribute:
|
||||
return false;
|
||||
case kImageattrAttribute:
|
||||
return true;
|
||||
case kInactiveAttribute:
|
||||
return true;
|
||||
case kLabelAttribute:
|
||||
return true;
|
||||
case kMaxptimeAttribute:
|
||||
return true;
|
||||
case kMidAttribute:
|
||||
return true;
|
||||
case kMsidAttribute:
|
||||
return true;
|
||||
case kMsidSemanticAttribute:
|
||||
return false;
|
||||
case kPtimeAttribute:
|
||||
return true;
|
||||
case kRecvonlyAttribute:
|
||||
return true;
|
||||
case kRemoteCandidatesAttribute:
|
||||
return true;
|
||||
case kRtcpAttribute:
|
||||
return true;
|
||||
case kRtcpFbAttribute:
|
||||
return true;
|
||||
case kRtcpMuxAttribute:
|
||||
return true;
|
||||
case kRtcpRsizeAttribute:
|
||||
return true;
|
||||
case kRtpmapAttribute:
|
||||
return true;
|
||||
case kSctpmapAttribute:
|
||||
return true;
|
||||
case kSendonlyAttribute:
|
||||
return true;
|
||||
case kSendrecvAttribute:
|
||||
return true;
|
||||
case kSetupAttribute:
|
||||
return true;
|
||||
case kSsrcAttribute:
|
||||
return true;
|
||||
case kSsrcGroupAttribute:
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH("Unknown attribute type");
|
||||
}
|
||||
|
||||
bool
|
||||
SdpAttribute::IsAllowedAtSessionLevel(AttributeType type)
|
||||
{
|
||||
switch (type) {
|
||||
case kBundleOnlyAttribute:
|
||||
return false;
|
||||
case kCandidateAttribute:
|
||||
return false;
|
||||
case kConnectionAttribute:
|
||||
return true;
|
||||
case kDirectionAttribute:
|
||||
return true;
|
||||
case kEndOfCandidatesAttribute:
|
||||
return true;
|
||||
case kExtmapAttribute:
|
||||
return true;
|
||||
case kFingerprintAttribute:
|
||||
return true;
|
||||
case kFmtpAttribute:
|
||||
return false;
|
||||
case kGroupAttribute:
|
||||
return true;
|
||||
case kIceLiteAttribute:
|
||||
return true;
|
||||
case kIceMismatchAttribute:
|
||||
return false;
|
||||
case kIceOptionsAttribute:
|
||||
return true;
|
||||
case kIcePwdAttribute:
|
||||
return true;
|
||||
case kIceUfragAttribute:
|
||||
return true;
|
||||
case kIdentityAttribute:
|
||||
return true;
|
||||
case kImageattrAttribute:
|
||||
return false;
|
||||
case kInactiveAttribute:
|
||||
return true;
|
||||
case kLabelAttribute:
|
||||
return false;
|
||||
case kMaxptimeAttribute:
|
||||
return false;
|
||||
case kMidAttribute:
|
||||
return false;
|
||||
case kMsidSemanticAttribute:
|
||||
return true;
|
||||
case kMsidAttribute:
|
||||
return false;
|
||||
case kPtimeAttribute:
|
||||
return false;
|
||||
case kRecvonlyAttribute:
|
||||
return true;
|
||||
case kRemoteCandidatesAttribute:
|
||||
return false;
|
||||
case kRtcpAttribute:
|
||||
return false;
|
||||
case kRtcpFbAttribute:
|
||||
return false;
|
||||
case kRtcpMuxAttribute:
|
||||
return false;
|
||||
case kRtcpRsizeAttribute:
|
||||
return false;
|
||||
case kRtpmapAttribute:
|
||||
return false;
|
||||
case kSctpmapAttribute:
|
||||
return false;
|
||||
case kSendonlyAttribute:
|
||||
return true;
|
||||
case kSendrecvAttribute:
|
||||
return true;
|
||||
case kSetupAttribute:
|
||||
return true;
|
||||
case kSsrcAttribute:
|
||||
return false;
|
||||
case kSsrcGroupAttribute:
|
||||
return false;
|
||||
}
|
||||
MOZ_CRASH("Unknown attribute type");
|
||||
}
|
||||
|
||||
const std::string
|
||||
SdpAttribute::GetAttributeTypeString(AttributeType type)
|
||||
{
|
||||
switch (type) {
|
||||
case kBundleOnlyAttribute:
|
||||
return "bundle-only";
|
||||
case kCandidateAttribute:
|
||||
return "candidate";
|
||||
case kConnectionAttribute:
|
||||
return "connection";
|
||||
case kEndOfCandidatesAttribute:
|
||||
return "end-of-candidates";
|
||||
case kExtmapAttribute:
|
||||
return "extmap";
|
||||
case kFingerprintAttribute:
|
||||
return "fingerprint";
|
||||
case kFmtpAttribute:
|
||||
return "fmtp";
|
||||
case kGroupAttribute:
|
||||
return "group";
|
||||
case kIceLiteAttribute:
|
||||
return "ice-lite";
|
||||
case kIceMismatchAttribute:
|
||||
return "ice-mismatch";
|
||||
case kIceOptionsAttribute:
|
||||
return "ice-options";
|
||||
case kIcePwdAttribute:
|
||||
return "ice-pwd";
|
||||
case kIceUfragAttribute:
|
||||
return "ice-ufrag";
|
||||
case kIdentityAttribute:
|
||||
return "identity";
|
||||
case kImageattrAttribute:
|
||||
return "imageattr";
|
||||
case kInactiveAttribute:
|
||||
return "inactive";
|
||||
case kLabelAttribute:
|
||||
return "label";
|
||||
case kMaxptimeAttribute:
|
||||
return "maxptime";
|
||||
case kMidAttribute:
|
||||
return "mid";
|
||||
case kMsidAttribute:
|
||||
return "msid";
|
||||
case kMsidSemanticAttribute:
|
||||
return "msid-semantic";
|
||||
case kPtimeAttribute:
|
||||
return "ptime";
|
||||
case kRecvonlyAttribute:
|
||||
return "recvonly";
|
||||
case kRemoteCandidatesAttribute:
|
||||
return "remote-candidates";
|
||||
case kRtcpAttribute:
|
||||
return "rtcp";
|
||||
case kRtcpFbAttribute:
|
||||
return "rtcp-fb";
|
||||
case kRtcpMuxAttribute:
|
||||
return "rtcp-mux";
|
||||
case kRtcpRsizeAttribute:
|
||||
return "rtcp-rsize";
|
||||
case kRtpmapAttribute:
|
||||
return "rtpmap";
|
||||
case kSctpmapAttribute:
|
||||
return "sctpmap";
|
||||
case kSendonlyAttribute:
|
||||
return "sendonly";
|
||||
case kSendrecvAttribute:
|
||||
return "sendrecv";
|
||||
case kSetupAttribute:
|
||||
return "setup";
|
||||
case kSsrcAttribute:
|
||||
return "ssrc";
|
||||
case kSsrcGroupAttribute:
|
||||
return "ssrc-group";
|
||||
case kDirectionAttribute:
|
||||
MOZ_CRASH("kDirectionAttribute not valid here");
|
||||
}
|
||||
MOZ_CRASH("Unknown attribute type");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче