Added support for making USSD calls
This commit is contained in:
@ -1653,6 +1653,12 @@ class BaresipService: Service() {
|
||||
|
||||
fun runCall(uap: Long, uri: String, conferenceCall: Boolean, onHoldCallp: Long) {
|
||||
|
||||
val ua = UserAgent.ofUap(uap)
|
||||
if (ua != null && ua.account.isMobile && Utils.isUssd(uri)) {
|
||||
sendUssd(Utils.uriUserPart(uri))
|
||||
return
|
||||
}
|
||||
|
||||
val executeCall = {
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
handler.postDelayed({
|
||||
@ -2312,6 +2318,47 @@ class BaresipService: Service() {
|
||||
updateMobileStatus(status)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun sendUssd(ussdCode: String) {
|
||||
val uap = uas.value.find { it.account.isMobile }?.uap ?: 0L
|
||||
if (VERSION.SDK_INT >= 26) {
|
||||
val tm = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
|
||||
try {
|
||||
tm.sendUssdRequest(ussdCode, object : TelephonyManager.UssdResponseCallback() {
|
||||
override fun onReceiveUssdResponse(
|
||||
telephonyManager: TelephonyManager,
|
||||
request: String,
|
||||
response: CharSequence
|
||||
) {
|
||||
super.onReceiveUssdResponse(telephonyManager, request, response)
|
||||
Log.d(TAG, "USSD response for $request: $response")
|
||||
postServiceEvent(ServiceEvent("ussd response", arrayListOf(uap, request, response.toString()), System.nanoTime()))
|
||||
}
|
||||
|
||||
override fun onReceiveUssdResponseFailed(
|
||||
telephonyManager: TelephonyManager,
|
||||
request: String,
|
||||
failureCode: Int
|
||||
) {
|
||||
super.onReceiveUssdResponseFailed(telephonyManager, request, failureCode)
|
||||
Log.d(TAG, "USSD response for $request failed with code $failureCode")
|
||||
val error = when (failureCode) {
|
||||
TelephonyManager.USSD_RETURN_FAILURE -> getString(R.string.ussd_failed)
|
||||
TelephonyManager.USSD_ERROR_SERVICE_UNAVAIL -> getString(R.string.ussd_service_unavailable)
|
||||
else -> getString(R.string.ussd_unknown_error)
|
||||
}
|
||||
postServiceEvent(ServiceEvent("ussd fail", arrayListOf(uap, request, error), System.nanoTime()))
|
||||
}
|
||||
}, Handler(Looper.getMainLooper()))
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Exception sending USSD request: ${e.message}")
|
||||
toast(getString(R.string.ussd_failed))
|
||||
}
|
||||
} else {
|
||||
toast(getString(R.string.ussd_not_supported))
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("FullScreenIntentPolicy")
|
||||
fun handleIncomingCall(call: Call) {
|
||||
val ua = call.ua
|
||||
|
||||
@ -2057,6 +2057,14 @@ private fun makeCall(ctx: Context, viewModel: ViewModel, uriText: String,
|
||||
else if (Utils.isAudioMode(ctx,AudioManager.MODE_IN_CALL) &&
|
||||
!Call.calls().any { it.ua.account.aor == ua.account.aor })
|
||||
Toast.makeText(ctx, R.string.call_already_active, Toast.LENGTH_SHORT).show()
|
||||
else if (ua.account.isMobile && Utils.isUssd(uri)) {
|
||||
viewModel.dialerState.callButtonsEnabled.value = false
|
||||
val baresipService = Intent(ctx, BaresipService::class.java)
|
||||
baresipService.action = "Start Call"
|
||||
baresipService.putExtra("uap", ua.uap)
|
||||
baresipService.putExtra("uri", uri)
|
||||
ContextCompat.startForegroundService(ctx, baresipService)
|
||||
}
|
||||
else {
|
||||
viewModel.dialerState.callButtonsEnabled.value = false
|
||||
var error = ""
|
||||
@ -2330,6 +2338,20 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params
|
||||
val aor = ua.account.aor
|
||||
|
||||
when (ev[0]) {
|
||||
"ussd response" -> {
|
||||
if (aor == viewModel.selectedAor.value)
|
||||
viewModel.dialerState.callButtonsEnabled.value = true
|
||||
handleDialog(ctx, ctx.getString(R.string.info), params[2] as String)
|
||||
handleNextEvent()
|
||||
return
|
||||
}
|
||||
"ussd fail" -> {
|
||||
if (aor == viewModel.selectedAor.value)
|
||||
viewModel.dialerState.callButtonsEnabled.value = true
|
||||
handleDialog(ctx, ctx.getString(R.string.error), params[2] as String)
|
||||
handleNextEvent()
|
||||
return
|
||||
}
|
||||
"call rejected" -> {}
|
||||
"call outgoing" -> {
|
||||
val callp = params[1] as Long
|
||||
|
||||
@ -370,13 +370,18 @@ object Utils {
|
||||
}
|
||||
|
||||
fun isTelNumber(no: String): Boolean {
|
||||
return no.isNotEmpty() && Regex("^([+][1-9])?[0-9- (),*#]{0,24}$").matches(no)
|
||||
return no.isNotEmpty() && Regex("^[0-9- (),*#+]{1,32}$").matches(no)
|
||||
}
|
||||
|
||||
fun isTelUri(uri: String): Boolean {
|
||||
return uri.startsWith("tel:") && isTelNumber(uri.substring(4))
|
||||
}
|
||||
|
||||
fun isUssd(uri: String): Boolean {
|
||||
val user = uriUserPart(uri)
|
||||
return user.startsWith("*") && user.endsWith("#")
|
||||
}
|
||||
|
||||
fun checkUri(uri: String): Boolean {
|
||||
return checkSipUri(uri) || isTelUri(uri)
|
||||
}
|
||||
|
||||
@ -633,6 +633,10 @@
|
||||
<string name="no_network">No network connection!</string>
|
||||
<string name="no_aec">No hardware Acoustic Echo Cancellation!</string>
|
||||
<string name="audio_focus_denied">Audio focus denied!</string>
|
||||
<string name="ussd_failed">USSD failed</string>
|
||||
<string name="ussd_service_unavailable">USSD service unavailable</string>
|
||||
<string name="ussd_unknown_error">USSD unknown error</string>
|
||||
<string name="ussd_not_supported">USSD not supported</string>
|
||||
<string name="permissions_rationale">Permissions rationale</string>
|
||||
<string name="audio_permissions">baresip needs \"Microphone\" permission for voice calls,
|
||||
\"Nearby devices\" permission for Bluetooth microphone/speaker detection,
|
||||
|
||||
Reference in New Issue
Block a user