Skip to content

Commit ed5d509

Browse files
authored
Add support for consumption reporting fields clientEndpointAddress and serverEndpointAddress as defined in TS 26512 17.7.0 (#24)
1 parent 8174cff commit ed5d509

File tree

5 files changed

+136
-7
lines changed

5 files changed

+136
-7
lines changed

app/src/main/java/com/fivegmag/a5gmscommonlibrary/consumptionReporting/ConsumptionReport.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ data class ConsumptionReport(
3030
@JsonFilter("consumptionReportingUnitFilter")
3131
data class ConsumptionReportingUnit(
3232
val mediaConsumed: String,
33-
var mediaEndpointAddress: EndpointAddress? = null,
33+
var clientEndpointAddress: EndpointAddress? = null,
34+
var serverEndpointAddress: EndpointAddress? = null,
3435
val startTime: String,
3536
var duration: Int,
3637
var locations: ArrayList<TypedLocation>? = ArrayList(),
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
package com.fivegmag.a5gmscommonlibrary.eventbus
22

33
import android.telephony.CellInfo
4-
import androidx.media3.exoplayer.analytics.AnalyticsListener
4+
import androidx.media3.exoplayer.analytics.AnalyticsListener.EventTime
5+
import androidx.media3.exoplayer.source.LoadEventInfo
56
import androidx.media3.exoplayer.source.MediaLoadData
67

78
class DownstreamFormatChangedEvent(
8-
val eventTime: AnalyticsListener.EventTime,
9+
val eventTime: EventTime,
910
val mediaLoadData: MediaLoadData
1011
)
1112

1213
class PlaybackStateChangedEvent(
13-
val eventTime: AnalyticsListener.EventTime,
14+
val eventTime: EventTime,
1415
val playbackState: String
1516
)
1617

18+
class LoadStartedEvent(
19+
val eventTime: EventTime,
20+
val loadEventInfo: LoadEventInfo,
21+
val mediaLoadData: MediaLoadData
22+
)
23+
1724
class CellInfoUpdatedEvent(
1825
val cellInfoList: MutableList<CellInfo>
1926
)

app/src/main/java/com/fivegmag/a5gmscommonlibrary/helpers/Utils.kt

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package com.fivegmag.a5gmscommonlibrary.helpers
22

3+
import com.fivegmag.a5gmscommonlibrary.models.EndpointAddress
34
import java.text.SimpleDateFormat
45
import java.time.Duration
56
import java.util.Date
67
import java.util.Random
78
import java.util.TimeZone
89
import okhttp3.Headers
10+
import java.net.Inet6Address
11+
import java.net.InetAddress
912
import java.net.NetworkInterface
13+
import java.net.URI
14+
import java.net.URL
1015
import java.time.Instant
1116
import java.util.Locale
1217
import java.util.UUID
@@ -110,9 +115,9 @@ class Utils {
110115
while (addresses.hasMoreElements()) {
111116
val address = addresses.nextElement()
112117
if (!address.isLoopbackAddress && address.isSiteLocalAddress) {
113-
if ((ipVer == 4 && address.hostAddress.contains("."))||
118+
if ((ipVer == 4 && address.hostAddress.contains(".")) ||
114119
(ipVer == 6 && address.hostAddress.contains(":"))
115-
){
120+
) {
116121
return address.hostAddress.toString()
117122
}
118123
}
@@ -122,4 +127,66 @@ class Utils {
122127
return null
123128
}
124129

130+
fun getDomainName(url: String): String? {
131+
return try {
132+
val uri = URI(url)
133+
val domain = uri.host
134+
domain?.removePrefix("www.")
135+
} catch (e: Exception) {
136+
null
137+
}
138+
}
139+
140+
fun getPort(url: String): Int? {
141+
try {
142+
val url = URL(url)
143+
val port = url.port
144+
if (port == -1) {
145+
return url.defaultPort
146+
}
147+
148+
return port
149+
} catch (e: Exception) {
150+
return null
151+
}
152+
}
153+
154+
/**
155+
* Network operations are not allowed on the main thread.
156+
* Perform the IP lookup in a different thread and then call a callback function
157+
*
158+
* @param requestUrl
159+
* @param callback
160+
*/
161+
fun getEndpointAddressByRequestUrl(
162+
requestUrl: String,
163+
callback: (EndpointAddress?) -> Unit
164+
) {
165+
Thread {
166+
try {
167+
val domainName = getDomainName(requestUrl)
168+
val port = getPort(requestUrl)
169+
var ipv4Addr: String? = null
170+
var ipv6Addr: String? = null
171+
val inetAddresses = InetAddress.getAllByName(domainName)
172+
for (inetAddress in inetAddresses) {
173+
val ipAddress = inetAddress.hostAddress
174+
if (inetAddress is Inet6Address) {
175+
ipv6Addr = ipAddress
176+
} else {
177+
ipv4Addr = ipAddress
178+
}
179+
}
180+
if (port != null) {
181+
callback(EndpointAddress(domainName, ipv4Addr, ipv6Addr, port))
182+
}
183+
184+
callback(null)
185+
186+
} catch (e: Exception) {
187+
callback(null)
188+
}
189+
}.start()
190+
}
191+
125192
}

app/src/main/java/com/fivegmag/a5gmscommonlibrary/models/SharedDataTypes.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ data class EndpointAddress(
2323
val domainName: String? = null,
2424
val ipv4Addr: String? = null,
2525
val ipv6Addr: String? = null,
26-
val portNumber: UInt
26+
val portNumber: Int
2727
) : Parcelable
2828

2929
@Parcelize
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.fivegmag.a5gmscommonlibrary
2+
3+
import com.fivegmag.a5gmscommonlibrary.helpers.Utils
4+
import com.fivegmag.a5gmscommonlibrary.models.EndpointAddress
5+
import kotlinx.coroutines.CompletableDeferred
6+
import kotlinx.coroutines.runBlocking
7+
import org.junit.Test
8+
import org.junit.Assert.*
9+
10+
class UtilsUnitTest {
11+
12+
@Test
13+
fun getHttpsPort() {
14+
val url = "https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd"
15+
val utils = Utils()
16+
val port = utils.getPort(url)
17+
18+
assertEquals(443, port)
19+
}
20+
21+
@Test
22+
fun getHttpPort() {
23+
val url = "http://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd"
24+
val utils = Utils()
25+
val port = utils.getPort(url)
26+
27+
assertEquals(80, port)
28+
}
29+
30+
@Test
31+
fun getDomainName() {
32+
val url = "http://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd"
33+
val utils = Utils()
34+
val domainName = utils.getDomainName(url)
35+
36+
assertEquals("dash.akamaized.net", domainName)
37+
}
38+
39+
@Test
40+
fun getEndpointAddressByRequestUrl() = runBlocking {
41+
val url = "https://livesim.dashif.org/livesim2/testpic_2s/V300/852746919.m4s"
42+
val utils = Utils()
43+
val deferredEndpointAddress = CompletableDeferred<EndpointAddress?>()
44+
utils.getEndpointAddressByRequestUrl(url) {endpointAddress ->
45+
deferredEndpointAddress.complete(endpointAddress)
46+
}
47+
val endpointAddress = deferredEndpointAddress.await()
48+
if (endpointAddress != null) {
49+
assertEquals("livesim.dashif.org", endpointAddress.domainName)
50+
assertEquals(443, endpointAddress.portNumber)
51+
assertNotNull(endpointAddress.ipv4Addr)
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)