This is called in BS2 after a handover complete is received. It is an inbound handover, but an outoing MO re-INVITE. We take the SIP REFER message created by BS1 and send it to the SIP server as a re-INVITE. Note that the MS may go from BS1 to BS2 and back to BS1, in which case there may already be an existing dialog in some non-Active state.
| 232 | // Note that the MS may go from BS1 to BS2 and back to BS1, in which case there may |
| 233 | // already be an existing dialog in some non-Active state. |
| 234 | SipDialog *SipDialog::newSipDialogHandover(TranEntry *tran, string sipReferStr) |
| 235 | { |
| 236 | LOG(DEBUG)<<LOGVAR(tran) <<LOGVAR(sipReferStr); |
| 237 | static const string inviteStr("INVITE"); |
| 238 | |
| 239 | // Init the Dialog State from the SIP REFER message. |
| 240 | SipMessage *msg = sipParseBuffer(sipReferStr.c_str()); |
| 241 | if (msg == NULL) { return NULL; } // Message already printed. |
| 242 | SipUri referto(msg->msmHeaders.paramFind("Refer-To")); |
| 243 | string proxy = referto.uriHostAndPort(); |
| 244 | // 7-23 wrong: SipDialog *dialog = new SipDialog(SIPDTMTC,proxy); |
| 245 | SipDialog *dialog = new SipDialog(SIPDTMOC,proxy,"REFER message"); |
| 246 | dialog->mIsHandover = true; |
| 247 | dialog->dsSetRemoteHeader(&msg->msmTo); |
| 248 | dialog->dsSetLocalHeader(&msg->msmFrom); |
| 249 | dialog->dsSetCallId(msg->msmCallId); |
| 250 | // TODO: If any other intervening messages were sent by BTS1 between the REFER and now the CSeqNum will not be correct. |
| 251 | dialog->mLocalCSeq = msg->msmCSeqNum + 1; |
| 252 | // We copied the peer SDP we got from the SIP server into the handover message passed from BS1 to BS2; |
| 253 | // I dont think we need to save sdpResponse here - we are going to use it for the last time immediately below. |
| 254 | dialog->mCodec = tran->getCodecs(); // TODO: We need to renegotiate this, or set it from SDP. There is no point even setting this here. |
| 255 | |
| 256 | // Get remote RTP from SIP REFER message, init RTP, create new SDP offer from previous SDP response. |
| 257 | // The incoming SDP has the codec previously negotiated, so it should still be ok. |
| 258 | dialog->mRTPPort = Control::allocateRTPPorts(); |
| 259 | SdpInfo sdpRemote; |
| 260 | sdpRemote.sdpParse(msg->msmBody); |
| 261 | SdpInfo sdpLocal = sdpRemote; // In particular, we are copying the sessionId and versionId. |
| 262 | // Send our local RTP port to the SIP server. |
| 263 | sdpLocal.sdpRtpPort = dialog->mRTPPort; |
| 264 | sdpLocal.sdpHost = dialog->localIP(); |
| 265 | dialog->mSdpOffer = sdpLocal.sdpValue(); |
| 266 | |
| 267 | // Make the re-INVITE |
| 268 | SipMessage *invite = dialog->makeInitialRequest(inviteStr); |
| 269 | invite->smAddBody(string("application/sdp"),dialog->mSdpOffer); |
| 270 | |
| 271 | // Send it off. |
| 272 | ScopedLock lock(dialog->mDialogLock,__FILE__,__LINE__); |
| 273 | gSipInterface.dmAddCallDialog(dialog); |
| 274 | dialog->moWriteLowSide(invite); |
| 275 | delete invite; // moWriteLowSide saved a copy of this. |
| 276 | dialog->setSipState(HandoverInbound); |
| 277 | |
| 278 | return dialog; |
| 279 | } |
| 280 | |
| 281 | |
| 282 | SipDialog::~SipDialog() |
nothing calls this directly
no test coverage detected