新建PJSIP類(lèi) - 基于Android的VoIP系統(tǒng)設(shè)計(jì)
為各個(gè)待實(shí)現(xiàn)的類(lèi)新建一個(gè)包,可以命名為“com.android.voip.pjsip”,在該包中添加該系統(tǒng)相關(guān)的一些類(lèi),主要有如下6個(gè)類(lèi):
?
這些類(lèi)分別為上節(jié)中原理各個(gè)步驟的實(shí)現(xiàn)。這部分僅僅是為C庫(kù)的調(diào)用提供一個(gè)接口,因此具體的實(shí)現(xiàn)將放在本地C/C++程序中。
2.2.2 頭文件的生成
C庫(kù)與Java間還需通過(guò)一個(gè)后綴為“.h”的頭文件來(lái)銜接,這個(gè)頭文件可以手動(dòng)編寫(xiě),也可以通過(guò)“Javah”來(lái)生成,該工具包含在JDK中,是由SUN公司提供的。
Javah生產(chǎn)的頭文件包含一定的規(guī)則,例如,本例中,它將生成的函數(shù)聲明為“Java_com_android_IMSandroid_pjsip_**”的形式,以便在調(diào)用C庫(kù)時(shí)能正確識(shí)別。
由于Java中的數(shù)據(jù)類(lèi)型與C/C++不盡相同,因此還必須注意參數(shù)傳遞時(shí)參數(shù)類(lèi)型的轉(zhuǎn)換。本文所涉及到的Java數(shù)據(jù)類(lèi)型有String和int型,Javah生成的頭文件中會(huì)先定義好需要傳遞的參數(shù)類(lèi)型以及函數(shù)返回類(lèi)型,例如方法“add_account(String sip_user,Stringsip_dom-ain,String sip_passwd)”,在頭文件中將定義函數(shù)的形式為“JNIEXPORT jint JNICALL Java_com_android_IMSandroid_pjsip_add_lac-count(JNIEnv*,jclass,jstring,jstring,jstring)”,其中JNIEXPORT為JNI外部函數(shù)聲明,jint是“jni.h”中定義C語(yǔ)言中整形的對(duì)應(yīng)類(lèi)型,JNCALL是JNI關(guān)鍵字。比較特殊的是JNIEnv,它是一個(gè)指向類(lèi)型為JNIEnv_的一個(gè)特殊JNI數(shù)據(jù)結(jié)構(gòu)的指針,它的每個(gè)元素都指向一個(gè)JNI函數(shù)的指針,jclass會(huì)根據(jù)引用Java類(lèi)的不同而不同,本文中“pjsip.class”是靜態(tài)類(lèi),因此這里的jclass指的是類(lèi)本身,如果是非靜態(tài)類(lèi)則指的是對(duì)象。后面幾個(gè)就是pjsip類(lèi)需要傳遞的參數(shù),根據(jù)“jni.h”的定義,String類(lèi)型對(duì)應(yīng)jstring,int對(duì)應(yīng)jint。然而這只是函數(shù)申明與類(lèi)中方法的形式對(duì)應(yīng),參數(shù)的具體傳遞還需要相應(yīng)的轉(zhuǎn)化,具體實(shí)現(xiàn)將在下一節(jié)詳細(xì)介紹。
2.2.3 JNI接口函數(shù)的實(shí)現(xiàn)
創(chuàng)建了pjsip庫(kù)類(lèi)和頭文件之后,必須應(yīng)用一個(gè)庫(kù)接口函數(shù),這部分是pjsip接口的實(shí)現(xiàn),限于篇幅,本文只講解幾個(gè)重要函數(shù)的實(shí)現(xiàn)。
(1)init函數(shù)
首先是init函數(shù),對(duì)應(yīng)的接口函數(shù)為JNICALL Java_com_android_IMSandroid_pjsip_init。該函數(shù)在系統(tǒng)初始化時(shí)調(diào)用,其作用是配置相關(guān)參數(shù),并發(fā)起一個(gè)pjsua應(yīng)用。它先通過(guò)函數(shù)“pjsua_create()”創(chuàng)建一個(gè)“pjsua”應(yīng)用,然后通過(guò)三個(gè)函數(shù)“pjsua_config_default
(&cfg)”,“pjsua_logging_config_default(&log_cfg”),“pjsua_media_config_default(&media_cfg)”配置其相關(guān)參數(shù),其中cfg是pjsua的相關(guān)參數(shù),主要是狀態(tài)改變時(shí)的回調(diào)函數(shù);log_cfg用來(lái)配置log級(jí)別;media_cfg中包含時(shí)鐘頻率、聲道數(shù)目等相關(guān)參數(shù)。
完成配置之后就可以使用pjsua_init(&cfg,&log_cfg,&media_cfg)將先前配置的參數(shù)初始化。在初始化之后,還需為pjsua添加一個(gè)udp傳輸,這一步是通過(guò)pjsua_transport_create(PJSIP_TRANSPORT_UDP,&cfg,NULL)來(lái)實(shí)現(xiàn)的,cfg中包含指定的通訊端口,3GPP建議使用5060。
需要注意的是,配置完以上參數(shù)之后,還需指定SPEEX編碼優(yōu)先級(jí),一般將其設(shè)為最大,可以通過(guò)函數(shù)pisua_codec_set_priority(&-speex_codec_id,255)來(lái)實(shí)現(xiàn)。所有配置完成之后,就可以發(fā)起pjsua,即最后調(diào)用pjsua_start()。成功的話,本函數(shù)的返回類(lèi)型為PJ_SUCCESS。
(2)make_call函數(shù)
另一個(gè)很重要的函數(shù)是make_call,其在本接口文件中對(duì)應(yīng)的函數(shù)為Java_com_android_IMSandroid_pjsip_make_lcall,這個(gè)函數(shù)一般在發(fā)起會(huì)話時(shí)調(diào)用,它與上一個(gè)函數(shù)在結(jié)構(gòu)上最大的不同在于本函數(shù)需要傳遞一個(gè)字符串參數(shù),前面提到,Java與C/C++在參數(shù)結(jié)構(gòu)上并不完全相同,因此這里需要將Java傳遞過(guò)來(lái)的String類(lèi)型的參數(shù)轉(zhuǎn)化,可以通過(guò)“url_ptr=(char*)env->GetStringUTFChars(url,&iscopy)”來(lái)實(shí)現(xiàn)。env->GetStringUTFChars在“jni.h”中定義,其功能是將jsting類(lèi)型(Java)的url復(fù)制到char*類(lèi)型(C)的url_ptr中,以此來(lái)完成參數(shù)類(lèi)型的轉(zhuǎn)換。
為了保證傳遞地址的有效性,還需要使用pjsua_verify_sip_url(url_ptr)驗(yàn)證,這個(gè)函數(shù)主要驗(yàn)證url_ptr是符合SIP的規(guī)則,即是否是一個(gè)合法的SIP地址。然而char*型的地址pjsua中還是不能直接使用的,這是因?yàn)閜jsua重新封裝了參數(shù)類(lèi)型,所以最后還需要將其轉(zhuǎn)化成pj_ str_t類(lèi)型,pjlib提供pj_str()函數(shù)可以完成轉(zhuǎn)化。在完成了參數(shù)的轉(zhuǎn)化后,調(diào)用“pjsua_call_make_call()”,將發(fā)起會(huì)話。
(3)hangup函數(shù)和pjsua_destroy函數(shù)
這兩個(gè)函數(shù)用來(lái)銷(xiāo)毀和掛斷會(huì)話,一般在需結(jié)束的時(shí)候調(diào)用,它們?cè)诮涌诤瘮?shù)中對(duì)應(yīng)Java_com_android_
IMSandroid_pjsip_hangup和Java_com_android_IMSandroid_pjsip_destroy,由于沒(méi)有參數(shù)傳遞,也沒(méi)有其他的調(diào)用,因此這兩個(gè)函數(shù)非常簡(jiǎn)單,基本上直接調(diào)用pjsua提供的pjsua_call_hangup_all()和pjsua_destroy()就能實(shí)現(xiàn)。pisua中這兩個(gè)函數(shù)將完成內(nèi)存釋放、賬戶(hù)注銷(xiāo)等工作。
(4)add_account函數(shù)
該函數(shù)在基本的pjsua中并不是必須的,但如果要使用SIP服務(wù)器的話,就必須實(shí)現(xiàn)該函數(shù),它在接口函數(shù)中對(duì)應(yīng)“Java_com_android_I-MSandroid_pjsip_add_1account”,同“make_call”一樣,也需要傳遞參數(shù),不同的是,它傳遞三個(gè)參數(shù),只是原理大體一樣。
首先它將參數(shù)轉(zhuǎn)化后保持到cfg,通過(guò)“pjsua_acc_add(&cfg,PJ_TRUE,&ace_id)”將參數(shù)添加到pjsua。pjsua將以其中的sip服務(wù)器為目的地址,注冊(cè)會(huì)話發(fā)起申請(qǐng),經(jīng)過(guò)一系列的操作之后,與目的地址發(fā)起會(huì)話。
- 第 1 頁(yè):基于Android的VoIP系統(tǒng)設(shè)計(jì)
- 第 2 頁(yè):新建PJSIP類(lèi)
- 第 3 頁(yè):主程序與用戶(hù)界面
本文導(dǎo)航
非常好我支持^.^
(1) 100%
不好我反對(duì)
(0) 0%
相關(guān)閱讀:
- [電子說(shuō)] 社區(qū)說(shuō)|多才多藝: 探索 Android 應(yīng)用更多可能 2023-10-24
- [電子說(shuō)] 浩辰軟件正式登陸上交所科創(chuàng)板 2023-10-23
- [電子說(shuō)] 鴻蒙原生應(yīng)用,對(duì)開(kāi)發(fā)者意味著什么? 2023-10-22
- [電子說(shuō)] Android端自定義鈴聲 MobPush對(duì)安卓端自定義鈴聲的教程 2023-10-21
- [電子說(shuō)] Android推送問(wèn)題排查技巧 針對(duì)MobPush安卓端推送問(wèn)題的解決辦法 2023-10-21
- [電子說(shuō)] 如何使用Proxyman抓取Android的https請(qǐng)求? 2023-10-19
- [編程語(yǔ)言及工具] 基于OkHttp 3.10.0的源碼案例解析 2023-10-17
- [電子說(shuō)] 基于MacroBenchmark的性能測(cè)試量化指標(biāo)方案 2023-10-17
( 發(fā)表人:Spring )