Android PJSIP account info

33 Views Asked by At

I have a sip server with a domain, that looks like 111.111.111.111:1111 (UDP), and there is a conference with 2222 number (i think it's a listening port), to which i should call. Also i have login and password to the sip account: 3333/Test3333. How do i create an account with PJSIP library and call to conference.

This error i get when trying to create an account:

FAILED TO CREATE ACCOUNT
java.lang.Exception: Title:       pjsua_acc_add(&pj_acc_cfg, make_default, &
Code:        171039
Description: Invalid URI (PJSIP_EINVALIDURI)    
Location:    ../src/pjsua2/account.cpp:997

Here's my pjsip manager class:

class PJSipManager {

    private val ep = Endpoint()
    private val acc = SipAccount()
    private var call: SipCall? = null
    private var coroutineScope: CoroutineScope? = null


    private val _callInfoFlow = MutableSharedFlow<CallInfo>()
    val callInfoFlow = _callInfoFlow.asSharedFlow()

    fun initLib(scope: CoroutineScope) {
        coroutineScope = scope
        if (ep.libGetState() == pjsua_state.PJSUA_STATE_NULL) {
            val epConfig = EpConfig()
            epConfig.logConfig.writer = BaseSipViewModel.PJLogger()
            epConfig.logConfig.decor = epConfig.logConfig.decor and
                    (pj_log_decoration.PJ_LOG_HAS_CR or
                            pj_log_decoration.PJ_LOG_HAS_NEWLINE).inv().toLong()
            try {
                ep.libCreate()
                ep.libInit(epConfig)
            } catch (e: Exception) {
                Log.e("PJSIP", "LIB DIDNT CREATED")
            }
            try {
                val sipTpConfig = TransportConfig().apply {
                    port = SIP_LISTENING_PORT.toLong()
                }
                ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP, sipTpConfig)

                val accCfg = AccountConfig().apply {
                    idUri = ACC_ID_URI

                }
                acc.create(accCfg, true)
            } catch (e:Exception) {
                Log.e("PJSIP", "FAILED TO CREATE ACCOUNT", e)
            }
            try {
                ep.libStart()
                Log.d("PJSIP", "LIB STARTED")
            } catch (e: Exception) {
                Log.e("PJSIP", "LIB DIDNT STARTED", e)
            }
        }
    }

    fun tryStart() {
        Log.i("PJSIP", "is lib running = ${ep.libGetState() == pjsua_state.PJSUA_STATE_RUNNING}")
        if (ep.libGetState() == pjsua_state.PJSUA_STATE_RUNNING) {
            if (call == null) {
                try {
                    ep.audDevManager().setNullDev()
                    val mCall = SipCall(acc, -1)
                    val prm = CallOpParam(true)
                    mCall.makeCall(CALL_DST_URI, prm)
                    call = mCall
                } catch (e: Exception) {
                    Log.e("PJSIP", "FAILED TO CALL", e)
                }
            } else {
                try {
                    ep.hangupAllCalls()
                } catch (e: Exception) {
                    Log.e("PJSIP", "FAILED TO hangup CALL", e)
                }
            }
        }
    }

    inner class SipAccount: Account() {

        override fun onIncomingCall(prm: OnIncomingCallParam?) {
            if (prm != null) {
                val mCall = SipCall(acc, prm.callId)
                val ansPrm = CallOpParam(true)
                ansPrm.statusCode =
                    if (call == null) pjsip_status_code.PJSIP_SC_OK else pjsip_status_code.PJSIP_SC_BUSY_HERE
                try {
                    mCall.answer(ansPrm)
                    if (call == null)
                        call = mCall
                } catch (e: Exception) {
                    println(e)
                }
            }
        }
    }

    inner class SipCall(acc: Account, callId: Int): Call(acc, callId) {

        private fun getCallInfo(call: Call): CallInfo? {
            var ci : CallInfo? = null
            try {
                ci = call.info
            } catch (e: Exception) {
                println("Failed getting call info: $e")
            }
            return ci
        }

        override fun onCallState(prm: OnCallStateParam?) {
            val ci : CallInfo = getCallInfo(this) ?: return

            ep.utilLogWrite(3, "MyCall", "Call state changed to: " + ci.stateText)
            coroutineScope.launch {
                _callInfoFlow.emit(ci)
            }
            if (ci.state == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) {
                call = null
                ep.utilLogWrite(3, "MyCall", this.dump(true, ""))
            }
        }

        override fun onCallMediaState(prm: OnCallMediaStateParam?) {
            val ci : CallInfo = getCallInfo(this) ?: return
            val cmiv = ci.media
            for (i in cmiv.indices) {
                val cmi = cmiv[i]
                Log.i("PJSIP", cmi.type.toString() + " " + cmi.status.toString())
                if (cmi.type == pjmedia_type.PJMEDIA_TYPE_AUDIO &&
                    (cmi.status == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE ||
                            cmi.status == pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD))
                {
                    /* Connect ports */
                    try {
                        val am = getAudioMedia(i)
                        ep.audDevManager().captureDevMedia.startTransmit(am)
                        am.startTransmit(ep.audDevManager().playbackDevMedia)
                    } catch (e: Exception) {
                        println("Failed connecting media ports" + e.message)
                    }
                }
            }
        }
    }

    companion object {
        const val ACC_ID_URI = "sip:3333:Test333"
        const val CALL_DST_URI = "sip:111.111.111.111:1111"
        const val SIP_LISTENING_PORT = 2222

    }
}

EDIT 1

I figured it out, here's the right URIs for successful connection.

const val ACC_ID_URI = "sip:[email protected]"
const val ACC_REGISTRAR_URI = "sip:111.111.111.1111"
const val CALL_DST_URI = "sip:[email protected]:1111"
const val SIP_LISTENING_PORT = 5061 // this you can specify how you want

Also you should specify registrarUri, becouse without it sip server wont receive any messages from. Account config should look like this:

val accCfg = AccountConfig().apply {
                    idUri = ACC_ID_URI
                    regConfig.registrarUri = ACC_REGISTRAR_URI
                    sipConfig.authCreds.add(
                        AuthCredInfo(
                            "digest" ,
                            "*",
                            "3333",
                            0,
                            "Test3333"
                        )
                    )
                }
0

There are 0 best solutions below