SipHelper.java revision 2e45c0b8f84172a004df4e3a1f50dbf1235474eb
19c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan/*
29c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * Copyright (C) 2010 The Android Open Source Project
39c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan *
49c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * Licensed under the Apache License, Version 2.0 (the "License");
59c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * you may not use this file except in compliance with the License.
69c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * You may obtain a copy of the License at
79c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan *
89c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan *      http://www.apache.org/licenses/LICENSE-2.0
99c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan *
109c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * Unless required by applicable law or agreed to in writing, software
119c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * distributed under the License is distributed on an "AS IS" BASIS,
129c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * See the License for the specific language governing permissions and
149c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * limitations under the License.
159c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan */
169c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
179c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanpackage com.android.server.sip;
189c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
199c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport gov.nist.javax.sip.SipStackExt;
209c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport gov.nist.javax.sip.clientauthutils.AccountManager;
219c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport gov.nist.javax.sip.clientauthutils.AuthenticationHelper;
229c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
239c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport android.net.sip.SipProfile;
249c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport android.util.Log;
259c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
269c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport java.text.ParseException;
279c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport java.util.ArrayList;
289c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport java.util.EventObject;
299c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport java.util.List;
309c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.ClientTransaction;
319c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.Dialog;
329c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.DialogTerminatedEvent;
339c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.InvalidArgumentException;
349c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.ListeningPoint;
359c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.PeerUnavailableException;
369c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.RequestEvent;
379c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.ResponseEvent;
389c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.ServerTransaction;
399c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.SipException;
409c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.SipFactory;
419c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.SipProvider;
429c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.SipStack;
439c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.Transaction;
449c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.TransactionAlreadyExistsException;
459c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.TransactionTerminatedEvent;
469c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.TransactionUnavailableException;
479c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.TransactionState;
489c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.address.Address;
499c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.address.AddressFactory;
509c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.address.SipURI;
519c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.CSeqHeader;
529c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.CallIdHeader;
539c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.ContactHeader;
549c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.FromHeader;
559c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.Header;
569c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.HeaderFactory;
579c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.MaxForwardsHeader;
589c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.ToHeader;
599c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.header.ViaHeader;
609c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.message.Message;
619c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.message.MessageFactory;
629c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.message.Request;
639c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanimport javax.sip.message.Response;
649c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
659c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan/**
669c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * Helper class for holding SIP stack related classes and for various low-level
679c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan * SIP tasks like sending messages.
689c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan */
699c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyanclass SipHelper {
709c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private static final String TAG = SipHelper.class.getSimpleName();
719c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private static final boolean DEBUG = true;
729c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
739c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private SipStack mSipStack;
749c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private SipProvider mSipProvider;
759c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private AddressFactory mAddressFactory;
769c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private HeaderFactory mHeaderFactory;
779c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private MessageFactory mMessageFactory;
789c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
799c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public SipHelper(SipStack sipStack, SipProvider sipProvider)
809c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws PeerUnavailableException {
819c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        mSipStack = sipStack;
829c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        mSipProvider = sipProvider;
839c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
849c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        SipFactory sipFactory = SipFactory.getInstance();
859c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        mAddressFactory = sipFactory.createAddressFactory();
869c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        mHeaderFactory = sipFactory.createHeaderFactory();
879c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        mMessageFactory = sipFactory.createMessageFactory();
889c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
899c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
909c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private FromHeader createFromHeader(SipProfile profile, String tag)
919c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws ParseException {
929c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return mHeaderFactory.createFromHeader(profile.getSipAddress(), tag);
939c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
949c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
959c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private ToHeader createToHeader(SipProfile profile) throws ParseException {
969c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return createToHeader(profile, null);
979c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
989c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
999c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private ToHeader createToHeader(SipProfile profile, String tag)
1009c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws ParseException {
1019c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return mHeaderFactory.createToHeader(profile.getSipAddress(), tag);
1029c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1039c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1049c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private CallIdHeader createCallIdHeader() {
1059c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return mSipProvider.getNewCallId();
1069c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1079c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1089c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private CSeqHeader createCSeqHeader(String method)
1099c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws ParseException, InvalidArgumentException {
1109c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        long sequence = (long) (Math.random() * 10000);
1119c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return mHeaderFactory.createCSeqHeader(sequence, method);
1129c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1139c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1149c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private MaxForwardsHeader createMaxForwardsHeader()
1159c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws InvalidArgumentException {
1169c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return mHeaderFactory.createMaxForwardsHeader(70);
1179c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1189c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1199c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private MaxForwardsHeader createMaxForwardsHeader(int max)
1209c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws InvalidArgumentException {
1219c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return mHeaderFactory.createMaxForwardsHeader(max);
1229c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1239c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1249c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private ListeningPoint getListeningPoint() throws SipException {
1259c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ListeningPoint lp = mSipProvider.getListeningPoint(ListeningPoint.UDP);
1269c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (lp == null) lp = mSipProvider.getListeningPoint(ListeningPoint.TCP);
1279c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (lp == null) {
1289c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ListeningPoint[] lps = mSipProvider.getListeningPoints();
1299c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if ((lps != null) && (lps.length > 0)) lp = lps[0];
1309c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
1319c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (lp == null) {
1329c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("no listening point is available");
1339c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
1349c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return lp;
1359c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1369c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1379c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private List<ViaHeader> createViaHeaders()
1389c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws ParseException, SipException {
1399c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        List<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(1);
1409c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ListeningPoint lp = getListeningPoint();
1419c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ViaHeader viaHeader = mHeaderFactory.createViaHeader(lp.getIPAddress(),
1429c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                lp.getPort(), lp.getTransport(), null);
1439c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        viaHeader.setRPort();
1449c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        viaHeaders.add(viaHeader);
1459c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return viaHeaders;
1469c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1479c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1489c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private ContactHeader createContactHeader(SipProfile profile)
1499c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws ParseException, SipException {
1509c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ListeningPoint lp = getListeningPoint();
1519c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        SipURI contactURI =
1529c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                createSipUri(profile.getUserName(), profile.getProtocol(), lp);
1539c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1549c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        Address contactAddress = mAddressFactory.createAddress(contactURI);
1559c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        contactAddress.setDisplayName(profile.getDisplayName());
1569c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1579c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return mHeaderFactory.createContactHeader(contactAddress);
1589c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1599c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1609c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private ContactHeader createWildcardContactHeader() {
1619c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ContactHeader contactHeader  = mHeaderFactory.createContactHeader();
1629c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        contactHeader.setWildCard();
1639c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return contactHeader;
1649c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1659c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1669c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private SipURI createSipUri(String username, String transport,
1679c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ListeningPoint lp) throws ParseException {
1689c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        SipURI uri = mAddressFactory.createSipURI(username, lp.getIPAddress());
1699c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
1709c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            uri.setPort(lp.getPort());
1719c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            uri.setTransportParam(transport);
1729c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (InvalidArgumentException e) {
1739c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new RuntimeException(e);
1749c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
1759c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return uri;
1769c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1779c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1789c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public ClientTransaction sendKeepAlive(SipProfile userProfile, String tag)
1799c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
1809c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
1819c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = createRequest(Request.OPTIONS, userProfile, tag);
1829c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1839c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ClientTransaction clientTransaction =
1849c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    mSipProvider.getNewClientTransaction(request);
1859c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            clientTransaction.sendRequest();
1869c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return clientTransaction;
1879c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (Exception e) {
1889c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendKeepAlive()", e);
1899c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
1909c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
1919c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
1929c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public ClientTransaction sendRegister(SipProfile userProfile, String tag,
1939c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            int expiry) throws SipException {
1949c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
1959c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = createRequest(Request.REGISTER, userProfile, tag);
1969c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (expiry == 0) {
1979c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                // remove all previous registrations by wildcard
1989c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                // rfc3261#section-10.2.2
1999c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                request.addHeader(createWildcardContactHeader());
2009c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            } else {
2019c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                request.addHeader(createContactHeader(userProfile));
2029c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            }
2039c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            request.addHeader(mHeaderFactory.createExpiresHeader(expiry));
2049c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2059c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ClientTransaction clientTransaction =
2069c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    mSipProvider.getNewClientTransaction(request);
2079c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            clientTransaction.sendRequest();
2089c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return clientTransaction;
2099c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
2109c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendRegister()", e);
2119c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
2129c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
2139c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2149c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private Request createRequest(String requestType, SipProfile userProfile,
2159c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            String tag) throws ParseException, SipException {
2169c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        FromHeader fromHeader = createFromHeader(userProfile, tag);
2179c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ToHeader toHeader = createToHeader(userProfile);
2182e45c0b8f84172a004df4e3a1f50dbf1235474ebChung-yih Wang        SipURI requestURI = mAddressFactory.createSipURI(
2192e45c0b8f84172a004df4e3a1f50dbf1235474ebChung-yih Wang                userProfile.getUriString().replaceFirst(
2202e45c0b8f84172a004df4e3a1f50dbf1235474ebChung-yih Wang                userProfile.getUserName() + "@", ""));
2219c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        List<ViaHeader> viaHeaders = createViaHeaders();
2229c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        CallIdHeader callIdHeader = createCallIdHeader();
2239c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        CSeqHeader cSeqHeader = createCSeqHeader(requestType);
2249c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        MaxForwardsHeader maxForwards = createMaxForwardsHeader();
2259c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        Request request = mMessageFactory.createRequest(requestURI,
2269c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                requestType, callIdHeader, cSeqHeader, fromHeader,
2279c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                toHeader, viaHeaders, maxForwards);
2289c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        Header userAgentHeader = mHeaderFactory.createHeader("User-Agent",
2299c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                "SIPAUA/0.1.001");
2309c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        request.addHeader(userAgentHeader);
2319c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return request;
2329c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
2339c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2349c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public ClientTransaction handleChallenge(ResponseEvent responseEvent,
2359c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            AccountManager accountManager) throws SipException {
2369c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        AuthenticationHelper authenticationHelper =
2379c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                ((SipStackExt) mSipStack).getAuthenticationHelper(
2389c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                        accountManager, mHeaderFactory);
2399c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ClientTransaction tid = responseEvent.getClientTransaction();
2409c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ClientTransaction ct = authenticationHelper.handleChallenge(
2419c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                responseEvent.getResponse(), tid, mSipProvider, 5);
242e9fe79e34d2c4100cd391bcf21df8bd50d5f3228Hung-ying Tyan        if (DEBUG) Log.d(TAG, "send request with challenge response: "
243e9fe79e34d2c4100cd391bcf21df8bd50d5f3228Hung-ying Tyan                + ct.getRequest());
2449c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ct.sendRequest();
2459c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return ct;
2469c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
2479c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2489c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public ClientTransaction sendInvite(SipProfile caller, SipProfile callee,
2499c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            String sessionDescription, String tag)
2509c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
2519c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
2529c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            FromHeader fromHeader = createFromHeader(caller, tag);
2539c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ToHeader toHeader = createToHeader(callee);
2549c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            SipURI requestURI = callee.getUri();
2559c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            List<ViaHeader> viaHeaders = createViaHeaders();
2569c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            CallIdHeader callIdHeader = createCallIdHeader();
2579c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            CSeqHeader cSeqHeader = createCSeqHeader(Request.INVITE);
2589c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            MaxForwardsHeader maxForwards = createMaxForwardsHeader();
2599c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2609c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = mMessageFactory.createRequest(requestURI,
2619c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    Request.INVITE, callIdHeader, cSeqHeader, fromHeader,
2629c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    toHeader, viaHeaders, maxForwards);
2639c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2649c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            request.addHeader(createContactHeader(caller));
2659c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            request.setContent(sessionDescription,
2669c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    mHeaderFactory.createContentTypeHeader(
2679c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                            "application", "sdp"));
2689c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2699c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ClientTransaction clientTransaction =
2709c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    mSipProvider.getNewClientTransaction(request);
2719c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (DEBUG) Log.d(TAG, "send INVITE: " + request);
2729c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            clientTransaction.sendRequest();
2739c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return clientTransaction;
2749c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
2759c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendInvite()", e);
2769c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
2779c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
2789c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2799c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public ClientTransaction sendReinvite(Dialog dialog,
2809c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            String sessionDescription) throws SipException {
2819c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
2829c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = dialog.createRequest(Request.INVITE);
2839c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            request.setContent(sessionDescription,
2849c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    mHeaderFactory.createContentTypeHeader(
2859c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                            "application", "sdp"));
2869c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2879c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ClientTransaction clientTransaction =
2889c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    mSipProvider.getNewClientTransaction(request);
2899c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (DEBUG) Log.d(TAG, "send RE-INVITE: " + request);
2909c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            dialog.sendRequest(clientTransaction);
2919c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return clientTransaction;
2929c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
2939c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendReinvite()", e);
2949c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
2959c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
2969c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
2979c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private ServerTransaction getServerTransaction(RequestEvent event)
2989c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
2999c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        ServerTransaction transaction = event.getServerTransaction();
3009c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (transaction == null) {
3019c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = event.getRequest();
3029c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return mSipProvider.getNewServerTransaction(request);
3039c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } else {
3049c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return transaction;
3059c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
3069c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
3079c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3089c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    /**
3099c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan     * @param event the INVITE request event
3109c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan     */
3119c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public ServerTransaction sendRinging(RequestEvent event, String tag)
3129c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
3139c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
3149c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = event.getRequest();
3159c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ServerTransaction transaction = getServerTransaction(event);
3169c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3179c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Response response = mMessageFactory.createResponse(Response.RINGING,
3189c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    request);
3199c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3209c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
3219c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            toHeader.setTag(tag);
3229c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            response.addHeader(toHeader);
3239c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (DEBUG) Log.d(TAG, "send RINGING: " + response);
3249c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            transaction.sendResponse(response);
3259c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return transaction;
3269c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
3279c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendRinging()", e);
3289c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
3299c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
3309c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3319c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    /**
3329c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan     * @param event the INVITE request event
3339c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan     */
3349c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public ServerTransaction sendInviteOk(RequestEvent event,
3359c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            SipProfile localProfile, String sessionDescription,
3369c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ServerTransaction inviteTransaction)
3379c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
3389c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
3399c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = event.getRequest();
3409c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Response response = mMessageFactory.createResponse(Response.OK,
3419c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    request);
3429c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            response.addHeader(createContactHeader(localProfile));
3439c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            response.setContent(sessionDescription,
3449c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    mHeaderFactory.createContentTypeHeader(
3459c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                            "application", "sdp"));
3469c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3479c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (inviteTransaction == null) {
3489c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                inviteTransaction = getServerTransaction(event);
3499c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            }
3509c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3519c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (inviteTransaction.getState() != TransactionState.COMPLETED) {
3529c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                if (DEBUG) Log.d(TAG, "send OK: " + response);
3539c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                inviteTransaction.sendResponse(response);
3549c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            }
3559c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3569c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return inviteTransaction;
3579c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
3589c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendInviteOk()", e);
3599c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
3609c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
3619c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3629c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public void sendInviteBusyHere(RequestEvent event,
3639c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ServerTransaction inviteTransaction) throws SipException {
3649c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
3659c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Request request = event.getRequest();
3669c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Response response = mMessageFactory.createResponse(
3679c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    Response.BUSY_HERE, request);
3689c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
369ed3c0fbbd5457f43ff72cec31b8ab0bb3f7a0047Hung-ying Tyan            if (inviteTransaction == null) {
370ed3c0fbbd5457f43ff72cec31b8ab0bb3f7a0047Hung-ying Tyan                inviteTransaction = getServerTransaction(event);
371ed3c0fbbd5457f43ff72cec31b8ab0bb3f7a0047Hung-ying Tyan            }
372ed3c0fbbd5457f43ff72cec31b8ab0bb3f7a0047Hung-ying Tyan
3739c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (inviteTransaction.getState() != TransactionState.COMPLETED) {
3749c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                if (DEBUG) Log.d(TAG, "send BUSY HERE: " + response);
3759c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                inviteTransaction.sendResponse(response);
3769c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            }
3779c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
3789c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendInviteBusyHere()", e);
3799c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
3809c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
3819c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3829c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    /**
3839c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan     * @param event the INVITE ACK request event
3849c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan     */
3859c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public void sendInviteAck(ResponseEvent event, Dialog dialog)
3869c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
3879c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        Response response = event.getResponse();
3889c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        long cseq = ((CSeqHeader) response.getHeader(CSeqHeader.NAME))
3899c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                .getSeqNumber();
3909c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        Request ack = dialog.createAck(cseq);
3919c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (DEBUG) Log.d(TAG, "send ACK: " + ack);
3929c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        dialog.sendAck(ack);
3939c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
3949c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
3959c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public void sendBye(Dialog dialog) throws SipException {
3969c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        Request byeRequest = dialog.createRequest(Request.BYE);
3979c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (DEBUG) Log.d(TAG, "send BYE: " + byeRequest);
3989c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        dialog.sendRequest(mSipProvider.getNewClientTransaction(byeRequest));
3999c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4009c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
4019c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public void sendCancel(ClientTransaction inviteTransaction)
4029c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
4039c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        Request cancelRequest = inviteTransaction.createCancel();
4049c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (DEBUG) Log.d(TAG, "send CANCEL: " + cancelRequest);
4059c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        mSipProvider.getNewClientTransaction(cancelRequest).sendRequest();
4069c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4079c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
4089c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public void sendResponse(RequestEvent event, int responseCode)
4099c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throws SipException {
4109c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
4119c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Response response = mMessageFactory.createResponse(
4129c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    responseCode, event.getRequest());
4139c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (DEBUG) Log.d(TAG, "send response: " + response);
4149c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            getServerTransaction(event).sendResponse(response);
4159c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
4169c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendResponse()", e);
4179c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
4189c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4199c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
4209c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public void sendInviteRequestTerminated(Request inviteRequest,
4219c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            ServerTransaction inviteTransaction) throws SipException {
4229c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        try {
4239c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Response response = mMessageFactory.createResponse(
4249c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    Response.REQUEST_TERMINATED, inviteRequest);
4259c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (DEBUG) Log.d(TAG, "send response: " + response);
4269c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            inviteTransaction.sendResponse(response);
4279c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } catch (ParseException e) {
4289c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            throw new SipException("sendInviteRequestTerminated()", e);
4299c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
4309c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4319c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
4329c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public static String getCallId(EventObject event) {
4339c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (event == null) return null;
4349c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        if (event instanceof RequestEvent) {
4359c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return getCallId(((RequestEvent) event).getRequest());
4369c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } else if (event instanceof ResponseEvent) {
4379c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return getCallId(((ResponseEvent) event).getResponse());
4389c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } else if (event instanceof DialogTerminatedEvent) {
4399c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Dialog dialog = ((DialogTerminatedEvent) event).getDialog();
4409c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return getCallId(((DialogTerminatedEvent) event).getDialog());
4419c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } else if (event instanceof TransactionTerminatedEvent) {
4429c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            TransactionTerminatedEvent e = (TransactionTerminatedEvent) event;
4439c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            return getCallId(e.isServerTransaction()
4449c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    ? e.getServerTransaction()
4459c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                    : e.getClientTransaction());
4469c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        } else {
4479c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            Object source = event.getSource();
4489c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            if (source instanceof Transaction) {
4499c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                return getCallId(((Transaction) source));
4509c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            } else if (source instanceof Dialog) {
4519c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                return getCallId((Dialog) source);
4529c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan            }
4539c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        }
4549c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return "";
4559c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4569c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
4579c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    public static String getCallId(Transaction transaction) {
4589c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return ((transaction != null) ? getCallId(transaction.getRequest())
4599c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                                      : "");
4609c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4619c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
4629c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private static String getCallId(Message message) {
4639c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        CallIdHeader callIdHeader =
4649c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan                (CallIdHeader) message.getHeader(CallIdHeader.NAME);
4659c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return callIdHeader.getCallId();
4669c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4679c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan
4689c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    private static String getCallId(Dialog dialog) {
4699c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan        return dialog.getCallId().getCallId();
4709c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan    }
4719c1fbe7bca34ac7463079926a401a3ce42717460Hung-ying Tyan}
472