If you have a conference with 2 or more participants, and use split
function in sipxtapi, you can't unhold it and you don't get any events.
1.) You cant unhold if there are no calls left in conference after
split, because sessionCallId used in sipxtapi gets overwritten with
wrong value (obviously with just plain CallId of conference which is
wrong), and sipxCallGetCommonData will return this wrong value to unhold
when asked for CallId (it prefers to use sessionId if its present, if
not then CallId).
SessionCallId is Id used in sipxtacklib. It is set for both inbound and
outbound calls.
Since we get wrong CallId from sipxCallGetCommonData , CallManager is
sent also wrong CallId, and hold cannot succeed as we find wrong
CpPeerCall which doesnt have a connection (it is the CpPeerCall of the
conference which is empty). If hold is attempted after split and there
is still a call left in the conference, then hold will be invoked on the
wrong call - on the one in the conference not the one that was split.
Also please fix the manual. It says that after sipxConferenceSplit, call
will remain in held state, this is not true, if its the only call then
it will be unheld, this is what
pCallData->pInst->pCallManager->createCall(&targetCallId) ; does by
default in sipxConferenceSplit.
2.) No events are received - this is because in sipxtapi we register a
handler in sipxtacklib, which sends us call events with the
sessionCallId. Therefore sessionCallId of a call shouldnt be overwritten.
If this was incomprehensible, then the problem was that somebody was
mixing sessionCallId and plain CallId in sipxtapi. They are not the same
and shouldnt be swapped. sessionCallId is used in sipxtacklib and
identifies SipConnection or Connection (which is parent of
SipConnection). Plain CallId identifies CpPeerCall, we could also say
the flow graph (as CpPeerCall has only 1 flowgraph). CpPeerCall can have
multiple Connections and single flow graph with multiple media
connections in case of a conference call. sipXtapi hold operation works
by sending a message to sipxcalllib with a CallId/sessionCallId. It
doesnt matter which one you send, as it asks CpPeerCall whether it has
that CallId and it replies yes if the CallId of CpPeerCall equals or the
sessionCallId (where it is called connectionCallId) of Connection equals.
Attached patch solves described problem with conferences (and XCL-115
<http://track.sipfoundry.org/browse/XCL-115>), and maybe some more. I
tested it with 1 call, 2 calls in coference, added by the sipxtapi add
function or join. After that I used split and watched whether I get the
events and can hold/unhold the call.
The patch basically keeps the old sessionCallId of the split call, as
there is no reason to change it since SipConnection isn't closed.
Moreover it changes way how CallIds are assigned in the
sipxConferenceAdd. This is to fix some other bugs with calls having no
sessionCallId and thus getting no events. It should be noted that calls
in a conference can happily have the same CallId, it isnt a problem at
all, but they must have different sessionCallId. When a call is split,
we generate new CallId for it, sessionCallId stays the same so its ok.
This patch probably won't apply cleanly, it might complain about a
damaged patch or something. It is because I had to edit it by hand (I
can no longer provide clean patches for some files, as I have too many
patches in them). If it doesnt apply cleanly, just delete the section
like "@@ -3371,9 +3379,18 @@" from the patch that was applied
successfuly and try again.
Jaroslav Libak
Index: C:/work/sipfoundry/branches/sipxtapi/sipXcallLib/src/tapi/sipXtapi.cpp
===================================================================
--- C:/work/sipfoundry/branches/sipxtapi/sipXcallLib/src/tapi/sipXtapi.cpp
(revision 8938)
+++ C:/work/sipfoundry/branches/sipxtapi/sipXcallLib/src/tapi/sipXtapi.cpp
(working copy)
@@ -3371,9 +3379,18 @@
}
sipxCallReleaseLock(pCallData, SIPX_LOCK_WRITE, stackLogger) ;
+ sipxConfReleaseLock(pConfData, SIPX_LOCK_WRITE, stackLogger) ;
}
- sipxConfReleaseLock(pConfData, SIPX_LOCK_WRITE, stackLogger) ;
+ else
+ {
+ sipxConfReleaseLock(pConfData, SIPX_LOCK_WRITE, stackLogger) ;
+ return rc;
+ }
}
+ else
+ {
+ return rc;
+ }
if (bDoSplit)
{
@@ -3437,15 +3454,6 @@
// Create a CpPeerCall call to hold connection
pCallData->pInst->pCallManager->createCall(&targetCallId) ;
- // Update call structure
- if (pCallData->sessionCallId)
- {
- *pCallData->sessionCallId = sourceCallId ;
- }
- else
- {
- pCallData->sessionCallId = new UtlString(sourceCallId)
;
- }
*pCallData->callId = targetCallId ;
pCallData->hConf = SIPX_CALL_NULL ;
@@ -3622,10 +3630,9 @@
pData->hCalls[pData->nCalls++] = hNewCall ;
*phNewCall = hNewCall ;
- // Allocate a new session id (to replace call id for
connection)
UtlString sessionId ;
pData->pInst->pCallManager->getNewSessionId(&sessionId) ;
- *pCallData->callId = sessionId.data() ;
+ pCallData->sessionCallId = new UtlString(sessionId);
sipxCallReleaseLock(pCallData, SIPX_LOCK_WRITE,
stackLogger) ;
@@ -3738,7 +3745,8 @@
pNewCallData->pInst = pInst ;
pNewCallData->hConf = hConf ;
- pNewCallData->callId = new UtlString(sessionId) ;
+ pNewCallData->callId = new UtlString(*(pData->strCallId)) ;
+ pNewCallData->sessionCallId = new UtlString(sessionId);
pNewCallData->remoteAddress = NULL ;
pNewCallData->hLine = hLine ;
pNewCallData->lineURI = new UtlString(lineId.data()) ;
_______________________________________________
sipxtapi-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipxtapi-dev/