📄 sipconnection.cpp
字号:
UtlString method; mReferMessage->getCSeqField(&num , &method); UtlString event; event.append(SIP_EVENT_REFER); event.append(";cseq="); char buff[50]; sprintf(buff,"%d", num); event.append(buff); // Generate an appropriate NOTIFY message to indicate the // outcome SipMessage referNotify; HttpBody* body = NULL; lastLocalSequenceNumber++; referNotify.setNotifyData(mReferMessage, lastLocalSequenceNumber, mRouteField, NULL, event, "id"); if(callState == CONNECTION_ESTABLISHED) { //transferResponse.setReferOkData(mReferMessage); body = new HttpBody(SIP_REFER_SUCCESS_STATUS, -1, CONTENT_TYPE_MESSAGE_SIPFRAG); } else if(callState == CONNECTION_ALERTING) { SipMessage alertingMessage; switch(returnCode) { case SIP_EARLY_MEDIA_CODE: alertingMessage.setResponseFirstHeaderLine(SIP_PROTOCOL_VERSION, returnCode, SIP_RINGING_TEXT); break; default: alertingMessage.setResponseFirstHeaderLine(SIP_PROTOCOL_VERSION, returnCode, SIP_RINGING_TEXT); break; } UtlString messageBody; int len; alertingMessage.getBytes(&messageBody,&len); body = new HttpBody(messageBody.data(), -1, CONTENT_TYPE_MESSAGE_SIPFRAG); } else { //transferResponse.setReferFailedData(mReferMessage); body = new HttpBody(SIP_REFER_FAILURE_STATUS, -1, CONTENT_TYPE_MESSAGE_SIPFRAG); } referNotify.setBody(body); // Add the content type for the body referNotify.setContentType(CONTENT_TYPE_MESSAGE_SIPFRAG); // Add the content length int len; UtlString bodyString; body->getBytes(&bodyString, &len); referNotify.setContentLength(len); referResponseSent = send(referNotify); // Only delete if this is a final notify if(callState != CONNECTION_ALERTING && mReferMessage) { delete mReferMessage; mReferMessage = NULL; } } // Should be BYE Also type transfer else { SipMessage transferResponse; if(callState == CONNECTION_ESTABLISHED) { transferResponse.setOkResponseData(mReferMessage, mLocalContact); } else { transferResponse.setReferFailedData(mReferMessage); } referResponseSent = send(transferResponse); if(mReferMessage) delete mReferMessage; mReferMessage = NULL; } } else { osPrintf("SipConnection::transfereeStatus FAILED callType: %d mReferMessage: %p\n", mpCall->getCallType() , mReferMessage); } return(referResponseSent);}UtlBoolean SipConnection::doHangUp(const char* dialString, const char* callerId){ int cause; // always get remote connection state int currentState = getState(0, cause); UtlBoolean hangUpOk = FALSE; const char* callerDisplayName = NULL; SipMessage sipRequest; UtlString alsoUri; // If blind transfer if(dialString && *dialString) { UtlString dummyFrom; buildFromToAddresses(dialString, callerId, callerDisplayName, dummyFrom, alsoUri); } // Tell the other end that we are hanging up // Need to send SIP CANCEL if we are the caller // and the callee connection state is not finalized if(mRemoteIsCallee && currentState != CONNECTION_FAILED && currentState != CONNECTION_ESTABLISHED && currentState != CONNECTION_DISCONNECTED && currentState != CONNECTION_UNKNOWN) { // We are the caller, cancel the incomplete call // Send a CANCEL //sipRequest = new SipMessage(); // We are calling and the call is not setup yet so // cancel. If we get a subsequent OK, we need to send // a BYE. if(inviteFromThisSide) { sipRequest.setCancelData(inviteMsg); mLastRequestMethod = SIP_CANCEL_METHOD; // If this was a canceled transfer INVITE, send back a status if(!mOriginalCallConnectionAddress.isNull()) { UtlString originalCallId; mpCall->getOriginalCallId(originalCallId); CpMultiStringMessage transfereeStatus(CallManager::CP_TRANSFEREE_CONNECTION_STATUS, originalCallId.data(), mOriginalCallConnectionAddress.data(), NULL, NULL, NULL, CONNECTION_FAILED, SIP_REQUEST_TIMEOUT_CODE);#ifdef TEST_PRINT osPrintf("SipConnection::processResponse posting CP_TRANSFEREE_CONNECTION_STATUS to call: %s\n", originalCallId.data());#endif mpCallManager->postMessage(transfereeStatus); } } // Someone is calling us and we are hanging up before the // call is setup. This is not likely to occur and I am // not sure what the right thing to do here CANCEL or BYE. else { lastLocalSequenceNumber++;#ifdef TEST_PRINT osPrintf("doHangup BYE route: %s\n", mRouteField.data());#endif sipRequest.setByeData(inviteMsg, mRemoteContact, inviteFromThisSide, lastLocalSequenceNumber, mRouteField.data(), alsoUri.data(), mLocalContact.data()); mLastRequestMethod = SIP_BYE_METHOD; } if(send(sipRequest)) {#ifdef TEST_PRINT if(inviteFromThisSide) osPrintf("unsetup call CANCEL message sent\n"); else osPrintf("unsetup call BYE message sent\n");#endif // Lets try not setting this to disconected until // we get the response or a timeout //setState(CONNECTION_DISCONNECTED, CONNECTION_REMOTE, CONNECTION_CAUSE_CANCELLED); // However we need something to indicate that the call // is being cancelled to handle a race condition when the callee responds with 200 OK // before it receives the Cancel. mbCancelling = TRUE; hangUpOk = TRUE; } } // We are the Caller or callee else if(currentState == CONNECTION_ESTABLISHED) { // the call is connected // Send a BYE //sipRequest = new SipMessage(); //UtlString directoryServerUri; //if(!inviteFromThisSide) //{ //UtlString dirAddress; //UtlString dirProtocol; //int dirPort; //sipUserAgent->getDirectoryServer(0, &dirAddress, // &dirPort, &dirProtocol); //SipMessage::buildSipUrl(&directoryServerUri, // dirAddress.data(), dirPort, dirProtocol.data()); //} lastLocalSequenceNumber++;#ifdef TEST_PRINT osPrintf("setup call BYE route: %s remote contact: %s\n", mRouteField.data(), mRemoteContact.data());#endif sipRequest.setByeData(inviteMsg, mRemoteContact, inviteFromThisSide, lastLocalSequenceNumber, mRouteField.data(), alsoUri.data(), mLocalContact.data()); mLastRequestMethod = SIP_BYE_METHOD; if (!send(sipRequest)) { // If sending the BYE failed, we will receive no response to end // the connection. So we have to generate it here, as we cannot // allow the inability to send a BYE to make it impossible to // disconnect a call. OsSysLog::add(FAC_CP, PRI_DEBUG, "SipConnection::doHangUp: Sending BYE failed. " "Terminating connection."); setState(CONNECTION_DISCONNECTED, CONNECTION_REMOTE); fireSipXEvent(CALLSTATE_DISCONNECTED, CALLSTATE_DISCONNECTED_NORMAL); } hangUpOk = TRUE; } if (mpMediaInterface != NULL) { mpMediaInterface->stopRtpSend(mConnectionId); mpMediaInterface->stopRtpReceive(mConnectionId); fireSipXEvent(CALLSTATE_AUDIO_EVENT, CALLSTATE_AUDIO_STOP); } return(hangUpOk);}void SipConnection::buildFromToAddresses(const char* dialString, const char* callerId, const char* callerDisplayName, UtlString& fromAddress, UtlString& goodToAddress) const{ UtlString sipAddress; int sipPort; UtlString sipProtocol; fromAddress.remove(0); goodToAddress.remove(0); // Build a From address sipUserAgent->getFromAddress(&sipAddress, &sipPort, &sipProtocol); SipMessage::buildSipUrl(&fromAddress, sipAddress.data(), sipPort, sipProtocol.data(), callerId, callerDisplayName, mFromTag.data()); // Check the to Address UtlString toAddress; UtlString toProtocol; UtlString toUser; UtlString toUserLabel; int toPort;#ifdef TEST_PRINT osPrintf("SipConnection::dial got dial string: \"%s\"\n", dialString);#endif // Use the Url object to perserve parameters and display name Url toUrl(dialString); toUrl.getHostAddress(toAddress); //SipMessage::parseAddressFromUri(dialString, &toAddress, &toPort, // &toProtocol, &toUser, &toUserLabel); if(toAddress.isNull()) { sipUserAgent->getDirectoryServer(0, &toAddress, &toPort, &toProtocol);#ifdef TEST_PRINT osPrintf("Got directory server: \"%s\"\n", toAddress.data());#endif toUrl.setHostAddress(toAddress.data()); toUrl.setHostPort(toPort); if(!toProtocol.isNull()) { toUrl.setUrlParameter("transport", toProtocol.data()); } } //SipMessage::buildSipUrl(&goodToAddress, toAddress.data(), // toPort, toProtocol.data(), toUser.data(), // toUserLabel.data()); toUrl.toString(goodToAddress);}UtlBoolean SipConnection::processMessage(OsMsg& eventMessage, UtlBoolean callInFocus, UtlBoolean onHook){ int msgType = eventMessage.getMsgType(); int msgSubType = eventMessage.getMsgSubType(); UtlBoolean processedOk = TRUE; const SipMessage* sipMsg = NULL; int messageType; if(msgType == OsMsg::PHONE_APP && msgSubType == CallManager::CP_SIP_MESSAGE) { sipMsg = ((SipMessageEvent&)eventMessage).getMessage(); messageType = ((SipMessageEvent&)eventMessage).getMessageStatus();#ifdef TEST_PRINT osPrintf("SipConnection::messageType: %d\n", messageType);#endif UtlBoolean messageIsResponse = sipMsg->isResponse(); UtlString method; if(!messageIsResponse) sipMsg->getRequestMethod(&method); // This is a request which failed to get sent if(messageType == SipMessageEvent::TRANSPORT_ERROR) {#ifdef TEST_PRINT osPrintf("Processing message transport error method: %s\n", messageIsResponse ? method.data() : "response");#endif if(!inviteMsg) {#ifdef TEST_PRINT osPrintf("SipConnection::processMessage failed response\n");#endif // THis call was not setup (i.e. did not try to sent an // invite and we did not receive one. This is a bad call setState(CONNECTION_FAILED, CONNECTION_REMOTE, CONNECTION_CAUSE_DEST_NOT_OBTAINABLE); fireSipXEvent(CALLSTATE_DISCONNECTED, CALLSTATE_DISCONNECTED_BADADDRESS) ; } // We only care about INVITE. // BYE, CANCLE and ACK are someone else's problem. // REGISTER and OPTIONS are handled else where else if(sipMsg->isSameMessage(inviteMsg) && getState() == CONNECTION_OFFERING) {#ifdef TEST_PRINT osPrintf("No response to INVITE\n");#endif setState(CONNECTION_FAILED, CONNECTION_REMOTE, CONNECTION_CAUSE_DEST_NOT_OBTAINABLE); fireSipXEvent(CALLSTATE_DISCONNECTED, CALLSTATE_DISCONNECTED_BADADDRESS) ;#ifdef TEST_PRINT osPrintf("SipConnection::processMessage originalConnectionAddress: %s connection state: CONNECTION_FAILED transport failed\n", mOriginalCallConnectionAddress.data());#endif // If this was a failed transfer INVITE, send back a status if(!mOriginalCallConnectionAddress.isNull()) { UtlString originalCallId; mpCall->getOriginalCallId(originalCallId); CpMultiStringMessage transfereeStatus(CallManager::CP_TRANSFEREE_CONNECTION_STATUS, originalCallId.data(), mOriginalCallConnectionAddress.data(), NULL, NULL, NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -