Skip to content

Commit

Permalink
Merge pull request #454 from handymenny/improve-reparse
Browse files Browse the repository at this point in the history
Make reparse more reliable
  • Loading branch information
handymenny authored Jul 28, 2024
2 parents 9ac87de + cd64e7d commit 40028d7
Show file tree
Hide file tree
Showing 68 changed files with 6,415 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

package it.smartphonecombo.uecapabilityparser.extension

import it.smartphonecombo.uecapabilityparser.model.Rat
import it.smartphonecombo.uecapabilityparser.model.filter.IUeCapabilityFilter
import java.util.Collections
import java.util.Enumeration
import kotlin.collections.ArrayList
Expand Down Expand Up @@ -71,3 +73,5 @@ internal suspend fun <T, R> List<T>.mapAsync(transform: suspend (T) -> R): List<
coroutineScope {
map { async { transform(it) } }.awaitAll()
}

internal fun List<IUeCapabilityFilter>.hasRat(rat: Rat) = any { it.rat == rat }
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ import kotlin.io.path.Path
/** Remove all extensions * */
internal fun File.nameWithoutAnyExtension() = this.name.substringBefore(".")

/** Move file to the given path, replacing and existing file if it exists */
/** Move file to the given path, replacing an existing file if it exists */
internal fun File.moveTo(path: String) {
Files.move(this.toPath(), Path(path), StandardCopyOption.REPLACE_EXISTING)
}

/** Copy file to the given path, replacing an existing file if it exists */
internal fun File.copyTo(path: String) {
Files.copy(this.toPath(), Path(path), StandardCopyOption.REPLACE_EXISTING)
}

internal fun File.deleteIgnoreException() {
try {
Files.delete(toPath())
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/it/smartphonecombo/uecapabilityparser/io/IOUtils.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package it.smartphonecombo.uecapabilityparser.io

import it.smartphonecombo.uecapabilityparser.cli.Cli.echo
import it.smartphonecombo.uecapabilityparser.extension.copyTo
import it.smartphonecombo.uecapabilityparser.extension.gzipCompress
import it.smartphonecombo.uecapabilityparser.extension.moveTo
import it.smartphonecombo.uecapabilityparser.extension.toInputSource
Expand Down Expand Up @@ -309,4 +310,17 @@ object IOUtils {
inputFile.moveTo(dstFile.path)
return dstFile.toInputSource(compressed)
}

/**
* if [compressed] is true, automatically appends ".gz". File is copied from [srcPath] to
* [dstPath].
*/
fun copy(srcPath: String, dstPath: String, compressed: Boolean) {
val addExtension = if (compressed) ".gz" else ""
val inputFile = File(srcPath + addExtension)
if (!inputFile.exists()) return

val dstFile = File(dstPath + addExtension)
return inputFile.copyTo(dstFile.path)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ import io.javalin.http.staticfiles.Location
import it.smartphonecombo.uecapabilityparser.extension.badRequest
import it.smartphonecombo.uecapabilityparser.extension.custom
import it.smartphonecombo.uecapabilityparser.extension.decodeFromInputSource
import it.smartphonecombo.uecapabilityparser.extension.hasRat
import it.smartphonecombo.uecapabilityparser.extension.internalError
import it.smartphonecombo.uecapabilityparser.extension.throwContentTooLargeIfContentTooLarge
import it.smartphonecombo.uecapabilityparser.extension.toInputSource
import it.smartphonecombo.uecapabilityparser.io.IOUtils
import it.smartphonecombo.uecapabilityparser.io.IOUtils.echoSafe
import it.smartphonecombo.uecapabilityparser.io.NullInputSource
import it.smartphonecombo.uecapabilityparser.model.Capabilities
import it.smartphonecombo.uecapabilityparser.model.LogType
import it.smartphonecombo.uecapabilityparser.model.Rat
import it.smartphonecombo.uecapabilityparser.model.index.IndexLine
import it.smartphonecombo.uecapabilityparser.model.index.LibraryIndex
import it.smartphonecombo.uecapabilityparser.util.Config
Expand Down Expand Up @@ -125,9 +129,9 @@ class JavalinApp {
}

private fun reparseItem(indexLine: IndexLine, store: String, compression: Boolean) {
val compressed = indexLine.compressed
val capPath = "/output/${indexLine.id}.json"
try {
val compressed = indexLine.compressed
val capPath = "/output/${indexLine.id}.json"
val capText =
IOUtils.inputSourceAndMove("$store$capPath", "$store/backup$capPath", compressed)
?: NullInputSource
Expand All @@ -147,9 +151,7 @@ class JavalinApp {
*inputMap.toTypedArray(),
type = capabilities.logType,
description = indexLine.description,
defaultNR =
indexLine.defaultNR ||
capabilities.lteBands.isEmpty() && capabilities.nrBands.isNotEmpty()
ratList = guessRats(capabilities, inputMap.size)
)

Parsing.fromRequest(request)?.let {
Expand All @@ -158,9 +160,50 @@ class JavalinApp {
it.capabilities.timestamp = capabilities.timestamp
it.store(null, store, compression)
}
?: throw NullPointerException("Reparsed Capabilities is null")
} catch (ex: Exception) {
ex.printStackTrace()
echoSafe("Error re-parsing ${indexLine.id}:\t${ex.message}", true)
try {
// restore prev version
IOUtils.copy("$store/backup$capPath", "$store$capPath", compressed)
indexLine.inputs.forEach {
IOUtils.copy("$store/backup/input/$it", "$store/input/$it", compressed)
}
} catch (ex: Exception) {
ex.printStackTrace()
}
}
}

private fun guessRats(capabilities: Capabilities, inputsLength: Int): List<Rat> {
if (capabilities.logType != LogType.H) {
return listOf(Rat.EUTRA)
}

val defaultRatList = listOf(Rat.EUTRA, Rat.NR, Rat.EUTRA_NR)

if (inputsLength == 3) {
return defaultRatList
}

val ratList = mutableListOf<Rat>()
if (capabilities.lteBands.isNotEmpty() || capabilities.ueCapFilters.hasRat(Rat.EUTRA)) {
ratList.add(Rat.EUTRA)
}
if (capabilities.nrBands.isNotEmpty() || capabilities.ueCapFilters.hasRat(Rat.NR)) {
ratList.add(Rat.NR)
}
if (
capabilities.enDcCombos.isNotEmpty() || capabilities.ueCapFilters.hasRat(Rat.EUTRA_NR)
) {
ratList.add(Rat.EUTRA_NR)
}

if (ratList.isEmpty()) {
return defaultRatList
}

return ratList
}

private fun buildRoutes(store: String?, index: LibraryIndex, compression: Boolean) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package it.smartphonecombo.uecapabilityparser.server
import it.smartphonecombo.uecapabilityparser.io.InputSource
import it.smartphonecombo.uecapabilityparser.io.InputSourceBase64Serializer
import it.smartphonecombo.uecapabilityparser.model.LogType
import it.smartphonecombo.uecapabilityparser.model.Rat
import it.smartphonecombo.uecapabilityparser.model.combo.ComboEnDc
import it.smartphonecombo.uecapabilityparser.model.combo.ComboLte
import it.smartphonecombo.uecapabilityparser.model.combo.ComboNr
Expand Down Expand Up @@ -49,14 +50,26 @@ class RequestParse(
vararg inputs: InputSource,
type: LogType,
description: String,
defaultNR: Boolean
ratList: List<Rat>
): RequestParse {
val input = inputs.firstOrNull()
val firstInputIsNr = type == LogType.H && defaultNR
val inputNR = if (firstInputIsNr) null else inputs.getOrNull(1)
val inputENDC = if (firstInputIsNr) inputs.getOrNull(1) else inputs.getOrNull(2)
val inputIndex = ratList.indexOf(Rat.EUTRA)
val inputNrIndex = ratList.indexOf(Rat.NR)
val inputEnDcIndex = ratList.indexOf(Rat.EUTRA_NR)

return RequestParse(input, inputNR, inputENDC, defaultNR, type, description)
val input = inputs.getOrNull(inputIndex)
val inputNR = inputs.getOrNull(inputNrIndex)
val inputENDC = inputs.getOrNull(inputEnDcIndex)

require(ratList.size >= inputs.size) { "Something weird, inputs list >= rat List" }

return RequestParse(
input,
inputNR,
inputENDC,
ratList.first() == Rat.NR,
type,
description
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ object ImportCapabilitiesHelpers {
input: InputSource,
inputNR: InputSource?,
inputENDC: InputSource?,
defaultNR: Boolean
defaultRat: Rat
): JsonObject {
val ratContainerMap =
if (type == LogType.H) {
jsonFromHex(input, inputNR, inputENDC, defaultNR)
jsonFromHex(input, inputNR, inputENDC, defaultRat)
} else {
val list = listOfNotNull(input, inputNR, inputENDC)
val inputSource = if (list.size > 1) SequenceInputSource(list) else list.first()
Expand Down Expand Up @@ -161,10 +161,9 @@ object ImportCapabilitiesHelpers {
inputMainText: InputSource,
inputNRText: InputSource?,
inputENDCText: InputSource?,
defaultNR: Boolean
defaultRat: Rat
): Map<String, JsonElement> {
val ratContainerMap = mutableMapOf<String, JsonElement>()
val defaultRat = if (defaultNR) Rat.NR else Rat.EUTRA
ratContainerMap += MtsAsn1Helpers.getUeCapabilityJsonFromHex(defaultRat, inputMainText)
if (inputNRText != null) {
ratContainerMap += MtsAsn1Helpers.getUeCapabilityJsonFromHex(Rat.NR, inputNRText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import it.smartphonecombo.uecapabilityparser.io.NullInputSource
import it.smartphonecombo.uecapabilityparser.io.SequenceInputSource
import it.smartphonecombo.uecapabilityparser.model.LogType
import it.smartphonecombo.uecapabilityparser.model.MultiCapabilities
import it.smartphonecombo.uecapabilityparser.model.Rat
import it.smartphonecombo.uecapabilityparser.model.index.IndexLine
import it.smartphonecombo.uecapabilityparser.model.index.LibraryIndex
import it.smartphonecombo.uecapabilityparser.model.index.MultiIndexLine
Expand Down Expand Up @@ -50,7 +51,7 @@ class MultiParsing(
var inputSource: InputSource = inputs.first()
var inputENDCSource: InputSource? = null
var inputNRSource: InputSource? = null
var defaultNr = false
var defaultRat = Rat.EUTRA
val description = descriptionList.getOrElse(i) { "" }

if (type in LogType.multiImporter) {
Expand Down Expand Up @@ -80,10 +81,16 @@ class MultiParsing(
}
}

if (inputNRSource?.isEmpty() == false && inputSource.isEmpty()) {
inputSource = inputNRSource
inputNRSource = null
defaultNr = true
if (inputSource.isEmpty()) {
if (inputNRSource?.isEmpty() == false) {
inputSource = inputNRSource
inputNRSource = null
defaultRat = Rat.NR
} else if (inputENDCSource?.isEmpty() == false) {
inputSource = inputENDCSource
inputENDCSource = null
defaultRat = Rat.EUTRA_NR
}
}
} else if (inputs.size > 1) {
inputSource = SequenceInputSource(inputs)
Expand All @@ -94,7 +101,7 @@ class MultiParsing(
inputSource,
inputNRSource,
inputENDCSource,
defaultNr,
defaultRat,
type,
description,
jsonFormat
Expand Down
26 changes: 16 additions & 10 deletions src/main/java/it/smartphonecombo/uecapabilityparser/util/Parsing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Parsing(
private val input: InputSource,
private val inputNR: InputSource?,
private val inputENDC: InputSource?,
private val defaultNR: Boolean = false,
private val defaultRat: Rat = Rat.EUTRA,
private val type: LogType,
private val description: String = "",
private val jsonFormat: Json = Json
Expand All @@ -42,7 +42,7 @@ class Parsing(
capabilities.logType = type
capabilities.timestamp = Instant.now().toEpochMilli()
capabilities.setMetadata("processingTime", "${processTime}ms")
if (defaultNR) capabilities.setMetadata("defaultNR", "true")
if (defaultRat == Rat.NR) capabilities.setMetadata("defaultNR", "true")

// Set description
if (description.isNotEmpty()) {
Expand All @@ -64,7 +64,7 @@ class Parsing(
}

if (imports == ImportCapabilityInformation) {
jsonUeCap = convertUeCapabilityToJson(type, input, inputNR, inputENDC, defaultNR)
jsonUeCap = convertUeCapabilityToJson(type, input, inputNR, inputENDC, defaultRat)
val eutra = jsonUeCap?.get(Rat.EUTRA.toString()) as? JsonObject
val eutraNr = jsonUeCap?.get(Rat.EUTRA_NR.toString()) as? JsonObject
val nr = jsonUeCap?.get(Rat.NR.toString()) as? JsonObject
Expand Down Expand Up @@ -110,17 +110,23 @@ class Parsing(

companion object {
fun fromRequest(req: RequestParse): Parsing? {
val defaultNR = req.defaultNR || req.input == null

if (req.input == null && req.inputNR == null || req.type == LogType.INVALID) {
val defaultRat =
when {
req.defaultNR || req.input == null && req.inputNR != null -> Rat.NR
req.input == null && req.inputENDC != null -> Rat.EUTRA_NR
req.input != null -> Rat.EUTRA
else -> null
}

if (defaultRat == null || req.type == LogType.INVALID) {
return null
}

return Parsing(
req.input ?: req.inputNR!!,
if (defaultNR) null else req.inputNR,
req.inputENDC,
defaultNR,
req.input ?: req.inputNR ?: req.inputENDC!!,
if (defaultRat == Rat.NR) null else req.inputNR,
if (defaultRat == Rat.EUTRA_NR) null else req.inputENDC,
defaultRat,
req.type,
req.description
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,22 @@ internal class ServerModeMultiPartParseTest {
)
}

@Test
fun ueCapHexMrDcOnlyJsonOutput() {
javalinJsonTest(
request =
buildJsonArray {
addJsonObject {
put("type", "H")
putJsonArray("inputIndexes") { add(0) }
putJsonArray("subTypes") { add("ENDC") }
}
},
files = listOf("$inputPath/ueCapHexMrdcSplit_eutra-nr.hex"),
oraclePath = "$oraclePath/ueCapHexMrdcSplit_eutra_nr.json",
)
}

@Test
fun ueCapHexSegmentedJsonOutput() {
javalinJsonTest(
Expand Down
Loading

0 comments on commit 40028d7

Please sign in to comment.