1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telephony.ims.cts; 18 19 import android.telephony.ims.SipMessage; 20 21 import java.util.Set; 22 23 24 public class SipMessageUtils { 25 26 public static final String INVITE_SIP_METHOD = "INVITE"; 27 public static final String CANCEL_SIP_METHOD = "CANCEL"; 28 public static final String BYE_SIP_METHOD = "BYE"; 29 public static final String ACK_SIP_METHOD = "ACK"; 30 public static final String MESSAGE_SIP_METHOD = "MESSAGE"; 31 public static final String BASE_ADDRESS = "client.example.com"; 32 33 private static final String PARAM_SEPARATOR = ";"; 34 private static final String PARAM_KEY_VALUE_SEPARATOR = "="; 35 private static final String BASE_VIA_HEADER_VALUE = "SIP/2.0/TCP " + BASE_ADDRESS + ":5060"; 36 37 public static final SipMessage TEST_SIP_MESSAGE = generateSipRequest(MESSAGE_SIP_METHOD, 38 new SipDialogAttributes()); 39 40 // Example from RFC 3665 41 public static final SipMessage TEST_INVALID_SIP_REGISTER = new SipMessage( 42 "REGISTER sips:ss2.biloxi.example.com SIP/2.0", 43 "Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7\n" 44 + "Max-Forwards: 70\n" 45 + "From: Bob <sips:bob@biloxi.example.com>;tag=a73kszlfl\n" 46 + "To: Bob <sips:bob@biloxi.example.com>\n" 47 + "Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com\n" 48 + "CSeq: 1 REGISTER\n" 49 + "Contact: <sips:bob@client.biloxi.example.com>\n" 50 + "Content-Length: 0", 51 new byte[0]); 52 53 //Example from RFC3903, but does not include PIDF document. PUBLISH is not allowed. 54 public static final SipMessage TEST_INVALID_SIP_PUBLISH = new SipMessage( 55 "PUBLISH sip:presentity@example.com SIP/2.0", 56 "Via: SIP/2.0/UDP pua.example.com;branch=z9hG4bKcdad2\n" 57 + "To: <sip:presentity@example.com>\n" 58 + "From: <sip:presentity@example.com>;tag=54321mm\n" 59 + "Call-ID: 5566778@pua.example.com\n" 60 + "CSeq: 1 PUBLISH\n" 61 + "Max-Forwards: 70\n" 62 + "Expires: 3600\n" 63 + "Event: presence\n" 64 + "Content-Type: application/pidf+xml", 65 new byte[0]); 66 67 //Example from RFC3856 - SUBSCRIBE with event presence is not allowed 68 public static final SipMessage TEST_INVALID_SIP_SUBSCRIBE_PRESENCE = new SipMessage( 69 "SUBSCRIBE sip:resource@example.com SIP/2.0", 70 "Via: SIP/2.0/TCP watcherhost.example.com;branch=z9hG4bKnashds7\n" 71 + "To: <sip:resource@example.com>\n" 72 + "From: <sip:user@example.com>;tag=xfg9\n" 73 + "Call-ID: 2010@watcherhost.example.com\n" 74 + "CSeq: 17766 SUBSCRIBE\n" 75 + "Max-Forwards: 70\n" 76 + "Event: presence\n" 77 + "Accept: application/pidf+xml\n" 78 + "Contact: <sip:user@watcherhost.example.com>\n" 79 + "Expires: 600\n" 80 + "Content-Length: 0", 81 new byte[0]); 82 83 //Example from RFC3261, OPTIONS not allowed from app 84 public static final SipMessage TEST_INVALID_SIP_OPTIONS = new SipMessage( 85 "OPTIONS sip:carol@chicago.com SIP/2.0", 86 "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877\n" 87 + "Max-Forwards: 70\n" 88 + "To: <sip:carol@chicago.com>\n" 89 + "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n" 90 + "Call-ID: a84b4c76e66710\n" 91 + "CSeq: 63104 OPTIONS\n" 92 + "Contact: <sip:alice@pc33.atlanta.com>\n" 93 + "Accept: application/sdp\n" 94 + "Content-Length: 0", 95 new byte[0]); 96 97 // Sample message from RFC 3261, malformed request start line 98 public static final SipMessage TEST_SIP_MESSAGE_INVALID_REQUEST = new SipMessage( 99 "INVITE sip:bob@biloxi.comSIP/2.0", 100 // Typical Via 101 "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK.TeSt\n" 102 + "Max-Forwards: 70\n" 103 + "To: Bob <sip:bob@biloxi.com>\n" 104 + "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n" 105 + "Call-ID: a84b4c76e66710@pc33.atlanta.com\n" 106 + "CSeq: 314159 INVITE\n" 107 + "Contact: <sip:alice@pc33.atlanta.com>\n" 108 + "Content-Type: application/sdp\n" 109 + "Content-Length: 142", 110 new byte[0]); 111 112 // Sample message from RFC 3261, malformed response start line 113 public static final SipMessage TEST_SIP_MESSAGE_INVALID_RESPONSE = new SipMessage( 114 "SIP/2.0 200OK", 115 "Via: SIP/2.0/TCP terminal.vancouver.example.com;" 116 + "branch=z9hG4bKwYb6QREiCL\n" 117 + "To: <sip:adam-buddies@pres.vancouver.example.com>;tag=zpNctbZq\n" 118 + "From: <sip:adam@vancouver.example.com>;tag=ie4hbb8t\n" 119 + "Call-ID: cdB34qLToC@terminal.vancouver.example.com\n" 120 + "CSeq: 322723822 SUBSCRIBE\n" 121 + "Contact: <sip:pres.vancouver.example.com>\n" 122 + "Expires: 7200\n" 123 + "Require: eventlist\n" 124 + "Content-Length: 0", 125 new byte[0]); 126 127 /** 128 * @return A new SIP request from the given parameters. 129 */ generateSipRequest(String requestMethod, String fromContact, String toContact, String toUri, String branchId, String callId, String fromTag, String toTag, Set<String> acceptContactTags)130 public static SipMessage generateSipRequest(String requestMethod, String fromContact, 131 String toContact, String toUri, String branchId, String callId, String fromTag, 132 String toTag, Set<String> acceptContactTags) { 133 String header = "Via: " + addParamToHeader(BASE_VIA_HEADER_VALUE, "branch", branchId); 134 header += "\n"; 135 header += "From: " + addParamToHeader(fromContact, "tag", fromTag); 136 header += "\n"; 137 // To tag is optional 138 header += "To: " + ((toTag != null) 139 ? addParamToHeader(toContact, "tag", toTag) : toContact); 140 header += "\n"; 141 header += "Call-ID: " + callId; 142 if (!acceptContactTags.isEmpty()) { 143 header += "\n"; 144 header += "Accept-Contact: *"; 145 for (String tag : acceptContactTags) { 146 header += ";" + tag; 147 } 148 } 149 return new SipMessage(requestMethod + " " + toUri + " SIP/2.0", header, new byte[0]); 150 } 151 152 /** 153 * @return Generates a SIP response. 154 */ generateSipResponse(String statusCode, String statusString, String fromContact, String toContact, String branchId, String callId, String fromTag, String toTag)155 public static SipMessage generateSipResponse(String statusCode, String statusString, 156 String fromContact, String toContact, String branchId, String callId, String fromTag, 157 String toTag) { 158 String header = "Via: " + addParamToHeader(BASE_VIA_HEADER_VALUE, "branch", branchId); 159 header += "\n"; 160 header += "From: " + addParamToHeader(fromContact, "tag", fromTag); 161 header += "\n"; 162 // To tag is optional 163 header += "To: " + ((toTag != null) 164 ? addParamToHeader(toContact, "tag", toTag) : toContact); 165 header += "\n"; 166 header += "Call-ID: " + callId; 167 return new SipMessage("SIP/2.0 " + statusCode + " " + statusString, header, 168 new byte[0]); 169 } 170 generateSipRequest(String requestMethod, SipDialogAttributes attr)171 public static SipMessage generateSipRequest(String requestMethod, SipDialogAttributes attr) { 172 return generateSipRequest(requestMethod, attr.fromHeader, attr.toHeader, 173 attr.toUri, attr.branchId, attr.callId, attr.fromTag, attr.getToTag(), 174 attr.getAcceptContactTags()); 175 } 176 generateSipResponse(String statusCode, String statusString, SipDialogAttributes attr)177 public static SipMessage generateSipResponse(String statusCode, String statusString, 178 SipDialogAttributes attr) { 179 return generateSipResponse(statusCode, statusString, attr.fromHeader, 180 attr.toHeader, attr.branchId, attr.callId, attr.fromTag, attr.getToTag()); 181 } 182 addParamToHeader(String headerValue, String paramKey, String paramValue)183 private static String addParamToHeader(String headerValue, String paramKey, String paramValue) { 184 headerValue += PARAM_SEPARATOR + paramKey.trim() + PARAM_KEY_VALUE_SEPARATOR 185 + paramValue.trim(); 186 return headerValue; 187 } 188 } 189