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 static junit.framework.Assert.assertEquals;
20 import static junit.framework.Assert.assertNotNull;
21 
22 import android.net.Uri;
23 import android.util.ArraySet;
24 import android.util.Base64;
25 
26 import java.nio.ByteBuffer;
27 import java.util.Random;
28 import java.util.Set;
29 
30 public class SipDialogAttributes {
31 
32     // Generates sequential string values starting from a random number.
33     private static volatile int sNextStringCounter;
34     static {
35         sNextStringCounter = new Random().nextInt();
36     }
37 
38     public final String branchId;
39     public final String callId;
40     public final String fromHeader;
41     public final String fromTag;
42     public final String toUri;
43     public final String toHeader;
44     private final String mFromUri;
45     private final Set<String> mAcceptContactTags;
46     private String mToTag;
47 
SipDialogAttributes()48     public SipDialogAttributes() {
49         branchId = getNextString();
50         callId = getNextString();
51         mFromUri = getNextSipUri();
52         fromHeader = generateContactUri(mFromUri);
53         fromTag = getNextString();
54         toUri = getNextSipUri();
55         toHeader = generateContactUri(toUri);
56         mAcceptContactTags = new ArraySet<>();
57     }
58 
SipDialogAttributes(String branchId, String callId, String fromUri, String fromTag, String toUri, String toTag, Set<String> acceptContactTags)59     private SipDialogAttributes(String branchId, String callId, String fromUri,
60             String fromTag, String toUri, String toTag, Set<String> acceptContactTags) {
61         this.branchId = branchId;
62         this.callId = callId;
63         this.mFromUri = fromUri;
64         this.fromHeader = generateContactUri(fromUri);
65         this.fromTag = fromTag;
66         this.toUri = toUri;
67         this.toHeader = generateContactUri(toUri);
68         mToTag = toTag;
69         mAcceptContactTags = acceptContactTags;
70     }
71 
setToTag()72     public void setToTag() {
73         if (mToTag == null) {
74             mToTag = getNextString();
75         }
76     }
77 
getToTag()78     public String getToTag() {
79         return mToTag;
80     }
81 
82     /**
83      * Add a tag to the Accept-Contact header feature tag list.
84      */
addAcceptContactTag(String featureTag)85     public void addAcceptContactTag(String featureTag) {
86         mAcceptContactTags.add(featureTag);
87     }
88 
89     /**
90      * @return The feature tags in the Accept-Contact feature tag list.
91      */
getAcceptContactTags()92     public Set<String> getAcceptContactTags() {
93         return mAcceptContactTags;
94     }
95 
96     /**
97      * @return The same attributes with a refreshed via branch param.
98      */
copyWithNewBranch()99     public SipDialogAttributes copyWithNewBranch() {
100         return new SipDialogAttributes(branchId, callId, mFromUri, fromTag, toUri,
101                 mToTag, mAcceptContactTags);
102     }
103 
fromExisting()104     public SipDialogAttributes fromExisting() {
105         return new SipDialogAttributes(branchId, callId, mFromUri, fromTag, toUri,
106                 null, mAcceptContactTags);
107     }
108 
invertFromTo()109     public SipDialogAttributes invertFromTo() {
110         return new SipDialogAttributes(branchId, callId, toUri, fromTag, mFromUri, mToTag,
111                 mAcceptContactTags);
112     }
113 
getNextSipUri()114     private String getNextSipUri() {
115         return "sip:" + getNextString() + "@" + SipMessageUtils.BASE_ADDRESS;
116     }
117 
getNextString()118     private String getNextString() {
119         // Get a string representation of the entry counter
120         byte[] idByteArray = ByteBuffer.allocate(4).putInt(sNextStringCounter++).array();
121         return Base64.encodeToString(idByteArray,
122                 Base64.NO_WRAP | Base64.NO_PADDING | Base64.URL_SAFE);
123     }
124 
generateContactUri(String sipUri)125     private String generateContactUri(String sipUri) {
126         Uri uri = Uri.parse(sipUri);
127         assertNotNull(uri);
128         String[] user = uri.getSchemeSpecificPart().split("@", 2);
129         assertNotNull(user);
130         assertEquals(2, user.length);
131         return user[0] + " <" + sipUri + ">";
132     }
133 }
134