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/

Reply via email to