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