All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.pkts.packet.sip.impl.SipResponseBuilder Maven / Gradle / Ivy

package io.pkts.packet.sip.impl;

import io.pkts.buffer.Buffer;
import io.pkts.buffer.Buffers;
import io.pkts.packet.sip.SipParseException;
import io.pkts.packet.sip.SipResponse;
import io.pkts.packet.sip.header.CSeqHeader;
import io.pkts.packet.sip.header.SipHeader;
import io.pkts.packet.sip.header.ToHeader;

import java.util.List;
import java.util.Map;





/**
 * @author [email protected]
 */
public final class SipResponseBuilder extends SipMessageBuilder implements SipResponse.Builder {

    /**
     * Map of all known response codes to their default reason phrases.
     */
    private static final Buffer[] DEFAULT_RESPONSE_REASON = new Buffer[700];

    /**
     * If the user creates a response that we do not recognize.
     */
    private static final Buffer UNKOWN_REASON = Buffers.wrap("Unknown");

    static {
        // 1xx—Provisional Responses
        DEFAULT_RESPONSE_REASON[100] = Buffers.wrap("Trying");
        DEFAULT_RESPONSE_REASON[180] = Buffers.wrap("Ringing");
        DEFAULT_RESPONSE_REASON[181] = Buffers.wrap("Call is Being Forwarded");
        DEFAULT_RESPONSE_REASON[182] = Buffers.wrap("Queued");
        DEFAULT_RESPONSE_REASON[183] = Buffers.wrap("Session Progress");
        DEFAULT_RESPONSE_REASON[199] = Buffers.wrap("Early Dialog Terminated");

        // 2xx—Successful Responses
        DEFAULT_RESPONSE_REASON[200] = Buffers.wrap("OK");
        DEFAULT_RESPONSE_REASON[202] = Buffers.wrap("Accepted");
        DEFAULT_RESPONSE_REASON[204] = Buffers.wrap("No Notification");

        // 3xx—Redirection Responses
        DEFAULT_RESPONSE_REASON[300] = Buffers.wrap("Multiple Choices");
        DEFAULT_RESPONSE_REASON[301] = Buffers.wrap("Moved Permanently");
        DEFAULT_RESPONSE_REASON[302] = Buffers.wrap("Moved Temporarily");
        DEFAULT_RESPONSE_REASON[305] = Buffers.wrap("Use Proxy");
        DEFAULT_RESPONSE_REASON[380] = Buffers.wrap("Alternative Service");

        // 4xx—Client Failure Responses
        DEFAULT_RESPONSE_REASON[400] = Buffers.wrap("Bad Request");
        DEFAULT_RESPONSE_REASON[401] = Buffers.wrap("Unauthorized");
        DEFAULT_RESPONSE_REASON[402] = Buffers.wrap("Payment Required");
        DEFAULT_RESPONSE_REASON[403] = Buffers.wrap("Forbidden");
        DEFAULT_RESPONSE_REASON[404] = Buffers.wrap("Not Found");
        DEFAULT_RESPONSE_REASON[405] = Buffers.wrap("Method Not Allowed");
        DEFAULT_RESPONSE_REASON[406] = Buffers.wrap("Not Acceptable");
        DEFAULT_RESPONSE_REASON[407] = Buffers.wrap("Proxy Authentication Required");
        DEFAULT_RESPONSE_REASON[408] = Buffers.wrap("Request Timeout");
        DEFAULT_RESPONSE_REASON[409] = Buffers.wrap("Conflict");
        DEFAULT_RESPONSE_REASON[410] = Buffers.wrap("Gone");
        DEFAULT_RESPONSE_REASON[411] = Buffers.wrap("Length Required");
        DEFAULT_RESPONSE_REASON[412] = Buffers.wrap("Conditional Request Failed");
        DEFAULT_RESPONSE_REASON[413] = Buffers.wrap("Request Entity Too Large");
        DEFAULT_RESPONSE_REASON[414] = Buffers.wrap("Request-URI Too Long");
        DEFAULT_RESPONSE_REASON[415] = Buffers.wrap("Unsupported Media Type");
        DEFAULT_RESPONSE_REASON[416] = Buffers.wrap("Unsupported URI Scheme");
        DEFAULT_RESPONSE_REASON[417] = Buffers.wrap("Unknown Resource-Priority");
        DEFAULT_RESPONSE_REASON[420] = Buffers.wrap("Bad Extension");
        DEFAULT_RESPONSE_REASON[421] = Buffers.wrap("Extension Required");
        DEFAULT_RESPONSE_REASON[422] = Buffers.wrap("Session Interval Too Small");
        DEFAULT_RESPONSE_REASON[423] = Buffers.wrap("Interval Too Brief");
        DEFAULT_RESPONSE_REASON[424] = Buffers.wrap("Bad Location Information");
        DEFAULT_RESPONSE_REASON[428] = Buffers.wrap("Use Identity Header");
        DEFAULT_RESPONSE_REASON[429] = Buffers.wrap("Provide Referrer Identity");
        DEFAULT_RESPONSE_REASON[430] = Buffers.wrap("Flow Failed");
        DEFAULT_RESPONSE_REASON[433] = Buffers.wrap("Anonymity Disallowed");
        DEFAULT_RESPONSE_REASON[436] = Buffers.wrap("Bad Identity-Info");
        DEFAULT_RESPONSE_REASON[437] = Buffers.wrap("Unsupported Certificate");
        DEFAULT_RESPONSE_REASON[438] = Buffers.wrap("Invalid Identity Header");
        DEFAULT_RESPONSE_REASON[439] = Buffers.wrap("First Hop Lacks Outbound Support");
        DEFAULT_RESPONSE_REASON[470] = Buffers.wrap("Consent Needed");
        DEFAULT_RESPONSE_REASON[480] = Buffers.wrap("Temporarily Unavailable");
        DEFAULT_RESPONSE_REASON[481] = Buffers.wrap("Call/Transaction Does Not Exist");
        DEFAULT_RESPONSE_REASON[482] = Buffers.wrap("Loop Detected.");
        DEFAULT_RESPONSE_REASON[483] = Buffers.wrap("Too Many Hops");
        DEFAULT_RESPONSE_REASON[484] = Buffers.wrap("Address Incomplete");
        DEFAULT_RESPONSE_REASON[485] = Buffers.wrap("Ambiguous");
        DEFAULT_RESPONSE_REASON[486] = Buffers.wrap("Busy Here");
        DEFAULT_RESPONSE_REASON[487] = Buffers.wrap("Request Terminated");
        DEFAULT_RESPONSE_REASON[488] = Buffers.wrap("Not Acceptable Here");
        DEFAULT_RESPONSE_REASON[489] = Buffers.wrap("Bad Event");
        DEFAULT_RESPONSE_REASON[491] = Buffers.wrap("Request Pending");
        DEFAULT_RESPONSE_REASON[493] = Buffers.wrap("Undecipherable");
        DEFAULT_RESPONSE_REASON[494] = Buffers.wrap("Security Agreement Required");

        // 5xx—Server Failure Responses
        DEFAULT_RESPONSE_REASON[500] = Buffers.wrap("Server Internal Error");
        DEFAULT_RESPONSE_REASON[501] = Buffers.wrap("Not Implemented");
        DEFAULT_RESPONSE_REASON[502] = Buffers.wrap("Bad Gateway");
        DEFAULT_RESPONSE_REASON[503] = Buffers.wrap("Service Unavailable");
        DEFAULT_RESPONSE_REASON[504] = Buffers.wrap("Server Time-out");
        DEFAULT_RESPONSE_REASON[505] = Buffers.wrap("Version Not Supported");
        DEFAULT_RESPONSE_REASON[513] = Buffers.wrap("Message Too Large");
        DEFAULT_RESPONSE_REASON[580] = Buffers.wrap("Precondition Failure");

        // 6xx—Global Failure Responses
        DEFAULT_RESPONSE_REASON[600] = Buffers.wrap("Busy Everywhere");
        DEFAULT_RESPONSE_REASON[603] = Buffers.wrap("Decline");
        DEFAULT_RESPONSE_REASON[604] = Buffers.wrap("Does Not Exist Anywhere");
        DEFAULT_RESPONSE_REASON[606] = Buffers.wrap("Not Acceptable");
    }

    private final int statusCode;

    private Buffer reason;

    public SipResponseBuilder(final int statusCode) {
        // TODO: do some research of what the typical SIP Response header size is.
        super(10);
        this.statusCode = statusCode;
    }

    @Override
    final protected boolean isBuildingResponse() {
        return true;
    }

    @Override
    protected ToHeader generateDefaultToHeader() {
        throw new SipParseException("Not implemented yet and also not sure what a default To-header would be for a response");
    }

    /**
     * For a response the only way we know which method this response is for
     * is from the CSeq-header so if that one doesn't exist then there
     * is simply nothing we can do.
     *
     * @return
     */
    @Override
    protected CSeqHeader generateDefaultCSeqHeader() {
        throw new SipParseException("Unable to generate a default CSeq-header for the response. You must specify it");
    }

    @Override
    protected SipInitialLine buildInitialLine() throws SipParseException {
        return new SipResponseLine(statusCode, reason != null ? reason : getDefaultResponseReason(statusCode));
    }

    @Override
    protected SipResponse internalBuild(final Buffer msg, final SipInitialLine initialLine,
                                        final Map> headers, final SipHeader toHeader,
                                        final SipHeader fromHeader, final SipHeader cSeqHeader,
                                        final SipHeader callIdHeader, final SipHeader maxForwardsHeader,
                                        final SipHeader viaHeader, final SipHeader routeHeader,
                                        final SipHeader recordRouteHeader, final SipHeader contactHeader,
                                        final Buffer body) {

        return new ImmutableSipResponse(msg,
                                        initialLine.toResponseLine(),
                                        headers,
                                        toHeader,
                                        fromHeader,
                                        cSeqHeader,
                                        callIdHeader,
                                        maxForwardsHeader,
                                        viaHeader,
                                        routeHeader,
                                        recordRouteHeader,
                                        contactHeader,
                                        body);
    }

    @Override
    public SipResponse.Builder withReasonPhrase(final String reason) {
        if (reason != null && !reason.isEmpty()) {
            this.reason = Buffers.wrap(reason);
        }
        return this;
    }

    @Override
    public SipResponse.Builder withReasonPhrase(final Buffer reason) {
        if (reason != null && !reason.isEmpty()) {
            // TODO: once buffer is immutable we don't have to do the slice.
            this.reason = reason.slice();
        }
        return this;
    }

    private static Buffer getDefaultResponseReason(final int statusCode) {
        final Buffer reason = DEFAULT_RESPONSE_REASON[statusCode];
        if (reason != null) {
            return reason.slice(); // really need to create immutable buffers
        }
        return UNKOWN_REASON.slice();
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy