iOS linPhone 源碼編譯和應(yīng)用

  • 最近兩三個月會研究網(wǎng)絡(luò)電話linPhone的iOS應(yīng)用莺奔,網(wǎng)上的學(xué)習(xí)資料比較少鸠珠,所以這里記錄整理一下學(xué)習(xí)到的東西饺蔑,分享一下锌介,希望可以幫助到其他人。

1.linPhone源碼編譯

  • linphone源碼GitLab
  • linphone源碼GitHub
    源碼編譯完成可以得到linphoneiOS集成用到的SDK猾警,同時源碼中還有一個官方的linphoneDemo應(yīng)用孔祸。所有的API調(diào)用基本都是需要從這個官方的linphoneDemo中學(xué)習(xí)。
    源碼編譯方法发皿,只有官方上面兩個源碼地址的ReadMe文件中的幾步崔慧,寫的很簡單,但是實(shí)際操作起來問題會比較多穴墅。
    這邊提供當(dāng)時看的幾篇文章惶室,應(yīng)該可以解決大部分問題。
    1.linphone-iphone的安裝與調(diào)試
    2.快速移植Linphone到自己的項(xiàng)目
    3.最新linphone-iphone Demo編譯運(yùn)行
    另外遇到問題也可以去GitHub上的issues欄搜索下問題玄货。我之前是在移動硬盤中進(jìn)行源碼編譯皇钞,移動硬盤的名字要是英文的,如果是中文可能會遇到問題松捉。我之前一直編譯不成功之后改了英文就可以了夹界。
  • 另外linphone支持cocoapods安裝了,具體如何操作沒有研究

2.linphoneSDK 方法介紹

  • 源碼編譯雖然問題比較多隘世,但是本文還是專注方法介紹掉盅。

2.1初始化、注冊以舒、撥打趾痘、接聽、掛斷蔓钟、狀態(tài)監(jiān)聽

可以參考快速移植Linphone到自己的項(xiàng)目 基本已經(jīng)列出
transport有三種方式UDP永票、TCP、TLS。前面兩個不需要配置什么侣集,TLS應(yīng)該是需要配置證書键俱,具體如何操作還沒有弄明白。
每次調(diào)用注冊方法都會把配置信息添加到LinphoneCore中世分,LinphoneCore做了本地持久處理编振,所以LinphoneCore中的帳號配置信息會越來越多,需要調(diào)用

    linphone_core_clear_proxy_config([LinphoneManager getLc]);
    linphone_core_clear_all_auth_info([LinphoneManager getLc]);

可以清理到所有配置信息臭埋。

2.2 部分操作方法

每個LinphoneCore的有一個默認(rèn)的配置信息踪央,和多個其他配置信息。一個配置信息對應(yīng)一個sip帳號瓢阴。
配置信息對應(yīng)結(jié)構(gòu)體 LinphoneProxyConfig

  • LinphoneProxyConfig操作方法
//獲取所有配置列表
const bctbx_list_t *accounts = linphone_core_get_proxy_config_list(LC);
size_t count = bctbx_list_size(accounts);
for (size_t i = 1; i <= count; i++, accounts = accounts->next) {
    LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)accounts->data;
}
//獲取注冊狀態(tài)
LinphoneRegistrationState state = linphone_proxy_config_get_state(proxy);
//獲取整個sip注冊帳號地址信息
const LinphoneAddress *adrs = linphone_proxy_config_get_identity_address(proxy);
//獲取注冊地址
NSString *domain = [[NSString alloc] initWithUTF8String:linphone_address_get_domain(adrs)];
//獲取注冊sip帳號
NSString *userName = [[NSString alloc] initWithUTF8String:linphone_address_get_username(adrs)];
//獲取注冊sip昵稱
NSString *domain = [[NSString alloc] initWithUTF8String:linphone_address_get_display_name(adrs)];
//獲取注冊端口
NSString *domain = [[NSString alloc] initWithUTF8String:linphone_address_get_port(adrs)];
//獲取注冊transport
LinphoneTransportType transport = linphone_address_get_transport(adrs);

//編輯配置信息
    //開始編輯
    linphone_proxy_config_edit(proxy);
    linphone_proxy_config_enable_register(proxy, TRUE);
    //結(jié)束編輯
    linphone_proxy_config_done(proxy);

  • LinphoneCore操作方法(大部分初始化和配置設(shè)置都是通過linphone_core設(shè)置)
//設(shè)置超時
    linphone_core_set_inc_timeout(LC, 60);
//創(chuàng)建配置表
    LinphoneProxyConfig *proxyCfg = linphone_core_create_proxy_config(LC);
//添加注冊認(rèn)證證書
    linphone_core_add_auth_info(LC, authInfo);
//添加到配置表,添加到linphone_core
    linphone_core_add_proxy_config(LC, proxyCfg);
//設(shè)置成默認(rèn)配置表
        linphone_core_set_default_proxy_config(LC, proxyCfg);
//獲取默認(rèn)配置表
        LinphoneProxyConfig *default_proxy = linphone_core_get_default_proxy_config(LC);
//獲取所有配置列表
const bctbx_list_t *accounts = linphone_core_get_proxy_config_list(LC);
//重新注冊所有配置信息(刷新狀態(tài))
linphone_core_refresh_registers(LC);

2.3音視頻編碼設(shè)置(注冊帳號的時候設(shè)置)

  • 音頻編碼設(shè)置
const bctbx_list_t *codescs = linphone_core_get_audio_codecs(LC);

- (void)synchronizeCodecs:(const MSList *)codecs {
    
    PayloadType *pt;
    const MSList *elem;
    
    for (elem = codecs; elem != NULL; elem = elem->next) {
        
        pt = (PayloadType *)elem->data;
        
        NSString *sreung = [NSString stringWithFormat:@"%s", pt->mime_type];
        NSString *normalBt = [NSString stringWithFormat:@"%d",pt->clock_rate];
//sreung 有這些值 opus,speex,PCMU,PCMA,GSM,G722,G729,iLBC,mpeg4-generic,iSAC,L16
        //設(shè)置音頻編碼格式  G711-u畅蹂,G711-a
       if ([sreung isEqualToString:@"PCMU"]||[sreung isEqualToString:@"PCMA"]) {

           linphone_core_enable_payload_type(LC,pt, TRUE);

        }else
        {

            linphone_core_enable_payload_type(LC, pt, FALSE);
        }
        
    }
}
  • 視頻編碼設(shè)置
const bctbx_list_t *codescs = linphone_core_get_video_codecs(LC);
- (void)synchronizeVideoCodecs:(const MSList *)codecs {
    
    PayloadType *pt;
    const MSList *elem;
    
    for (elem = codecs; elem != NULL; elem = elem->next) {
        
        pt = (PayloadType *)elem->data;
        NSString *sreung = [NSString stringWithFormat:@"%s", pt->mime_type];
        if ([sreung isEqualToString:@"H264"]) {
            
            linphone_core_enable_payload_type(LC, pt, 1);
            
        }else {
            
            linphone_core_enable_payload_type(LC, pt, 0);
        }
    }
}

2.4鈴聲設(shè)置

鈴聲設(shè)置調(diào)用API設(shè)置

NSString *path = [[NSBundle mainBundle] pathForResource:@"notes_of_the_optimistic" ofType:@"caf"];
        const char *cPath = [path UTF8String];
        linphone_core_set_ring(LC, cPath);

2.5通話記錄獲取

官方Demo中的 HistoryListTableView.m 中有代碼荣恐。通話記錄存儲在本地DB中

NSString *db = [NSString stringWithUTF8String:linphone_core_get_call_logs_database_path(LC)];
    NSLog(@"history DB:%@",db);

歷史記錄


//獲取所有本地通話logs
    const bctbx_list_t *logs = linphone_core_get_call_logs(LC);
//獲取1001帳號本地通話logs
// LinphoneAddress *adr = [LinphoneUtils normalizeSipOrPhoneAddress:@"1001"];
// bctbx_list_t *logs = linphone_core_get_call_history_for_address(LC, adr);

//遍歷所有通話記錄
//    while (logs != NULL) {
//    LinphoneCallLog *log = (LinphoneCallLog *)logs->data;
//}

//打印一條記錄
if(logs!=NULL){
LinphoneCallLog *log = (LinphoneCallLog *)logs->data;
        //通話開始時間
        NSDate *startDate = [NSDate
                             dateWithTimeIntervalSince1970:linphone_call_log_get_start_date(log)];
//通話狀態(tài)類型
        LinphoneCallStatus status = linphone_call_log_get_status(log);
//撥打方 LinphoneAddress
        LinphoneAddress *fromAddress = linphone_call_log_get_from_address(log);
//接聽方 LinphoneAddress
        LinphoneAddress *toAddress = linphone_call_log_get_to_address(log);
//對方 LinphoneAddress 
        LinphoneAddress *remoteAddress = linphone_call_log_get_remote_address(log);
        NSString *callStatus = @"None";
        switch (status) {
            case LinphoneCallSuccess:
                callStatus = @"LinphoneCallSuccess";
                break;
            case LinphoneCallAborted:
                callStatus = @"LinphoneCallAborted";
                break;
            case LinphoneCallMissed:
                callStatus = @"LinphoneCallMissed";
                break;
            case LinphoneCallDeclined:
                callStatus = @"LinphoneCallDeclined";
                break;
            case LinphoneCallEarlyAborted:
                callStatus = @"LinphoneCallEarlyAborted";
                break;
            case LinphoneCallAcceptedElsewhere:
                callStatus = @"LinphoneCallAcceptedElsewhere";
                break;
            case LinphoneCallDeclinedElsewhere:
                callStatus = @"LinphoneCallDeclinedElsewhere";
            default:
                break;
        }
//通過address 獲取名字 地址等等
        NSString *fromName = [NSString stringWithUTF8String:linphone_address_get_username(fromAddress)];
        NSString *toName = [NSString stringWithUTF8String:linphone_address_get_username(toAddress)];
        NSString *remoteName = [NSString stringWithUTF8String:linphone_address_get_username(remoteAddress)];
        
        NSString *fromDomain = [NSString stringWithUTF8String:linphone_address_get_domain(fromAddress)];
         NSString *toDomain = [NSString stringWithUTF8String:linphone_address_get_domain(toAddress)];
         NSString *remoteDomain = [NSString stringWithUTF8String:linphone_address_get_domain(remoteAddress)];
        NSString *callDir = @"None";
//獲取通話類型 撥出 打進(jìn)
        LinphoneCallDir direction = linphone_call_log_get_dir(log);
        switch (direction) {
            case LinphoneCallIncoming:
                callDir = @"LinphoneCallIncoming";
                break;
            case LinphoneCallOutgoing:
                callDir = @"LinphoneCallOutgoing";
                break;
            default:
                break;
        }
//通話時長 s
        int duration = linphone_call_log_get_duration(log);
        NSLog(@"startTime:%@,LinphoneCallStatus:%@,fromName:%@,fromDomain:%@,toName:%@,toDomain:%@,remoteName:%@,remoteDomain:%@,callDir:%@,duration:%d",startDate,callStatus,fromName,fromDomain,toName,toDomain,remoteName,remoteDomain,callDir,duration);
}

3.freeSwitch安裝

freeswitch安裝官網(wǎng)

安裝流程鏈接: https://pan.baidu.com/s/1ZamVLvc-fXjmRTyjKvIWIw 提取碼: e7h4

4.sip協(xié)議通話流程

sip協(xié)議呼叫流程詳解

5.linphone源碼修改 (sip信令修改)

linphone源碼都是在執(zhí)行sdk編譯命令的目錄下的submodules里面液斜,如果需要修改就需要看這部分的內(nèi)容。
可以通過命令 查找文件名或者文件內(nèi)容一個個找叠穆。少漆。。硼被。
列舉一下我修改的源碼检疫。主要是sip信令的內(nèi)容。
5.1 CSeq數(shù)字修改
Sequence Number linphone 默認(rèn)從20開始
修改的地方在 Submodules/linphone/src/sal/op.cpp 522行


image.png

5.2 去除Contact參數(shù)后面的+sip.instance +org.linphone.specs
修改的地方也在oc.cpp 710行


image.png

5.3 修改401 unauthorized 之后register 中的Authorization中的CNonce
Submodules/belle-sip/src/auth_helper 25 行 修改生成的位數(shù) 默認(rèn)16位


image.png

修改生成規(guī)則 Submodules/belle-sip/src/belle_sip_utils.c 267行和278行
選取的字符串?dāng)?shù)組


image.png

生成隨機(jī)字符串祷嘶,如果改了symbols,需要修改下圖中的63夺溢。修改為symbols的長度-1论巍;順便提一下 我沒見過 (val & 63)這樣取數(shù)字的方法。??
image.png

其他可以通過sdk api設(shè)置

5.4修改自定義header頭

linphone_proxy_config_set_custom_header(proxyCfg, [@"Accept" UTF8String], [@"application/sdp" UTF8String]);

5.5修改Contact參數(shù)

linphone_proxy_config_set_contact_parameters(proxyCfg, [@"expires=3600" UTF8String]);

5.6修改信令中的expires

linphone_proxy_config_set_expires(proxyCfg,3600);

5.7修改User-Agent

NSString *device = [[NSMutableString alloc]
                        initWithString:[NSString
                                        stringWithFormat:@"%@_iOS%@",
                                        [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"],
                                        UIDevice.currentDevice.systemVersion]];
    device = [device stringByReplacingOccurrencesOfString:@"," withString:@"."];
    device = [device stringByReplacingOccurrencesOfString:@" " withString:@"."];
    linphone_core_set_user_agent(theLinphoneCore, device.UTF8String, "3.16-122-g79a8bb2");
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末风响,一起剝皮案震驚了整個濱河市嘉汰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌状勤,老刑警劉巖鞋怀,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異持搜,居然都是意外死亡密似,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進(jìn)店門葫盼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來残腌,“玉大人,你說我怎么就攤上這事∨酌ǎ” “怎么了蟆盹?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闺金。 經(jīng)常有香客問我逾滥,道長,這世上最難降的妖魔是什么败匹? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任寨昙,我火速辦了婚禮,結(jié)果婚禮上哎壳,老公的妹妹穿的比我還像新娘毅待。我一直安慰自己,他們只是感情好归榕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布尸红。 她就那樣靜靜地躺著,像睡著了一般刹泄。 火紅的嫁衣襯著肌膚如雪外里。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天特石,我揣著相機(jī)與錄音盅蝗,去河邊找鬼。 笑死姆蘸,一個胖子當(dāng)著我的面吹牛墩莫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逞敷,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼狂秦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了推捐?” 一聲冷哼從身側(cè)響起裂问,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎牛柒,沒想到半個月后堪簿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡皮壁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年椭更,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛾魄。...
    茶點(diǎn)故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡甜孤,死狀恐怖协饲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缴川,我是刑警寧澤茉稠,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站把夸,受9級特大地震影響而线,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恋日,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一膀篮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岂膳,春花似錦誓竿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至簸喂,卻和暖如春毙死,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背喻鳄。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工扼倘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人除呵。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓再菊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颜曾。 傳聞我的和親對象是個殘疾皇子纠拔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,606評論 2 350

推薦閱讀更多精彩內(nèi)容

  • feisky云計(jì)算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,833評論 0 5
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,093評論 1 32
  • 點(diǎn)擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,708評論 0 15
  • 很多人舉辦婚禮講究是和和美美秃症,因此會在選擇酒的時候也要用寓意明顯候址、價(jià)格適中、大眾容易接受的口感來作為婚宴用酒种柑。下面...
    酒會開花閱讀 3,616評論 0 0
  • 崢嶸已成回首岗仑,磅礴渾然而出。 2015歲在乙未聚请,過往一切終化為所成荠雕,未來氣象已昭然若見稳其。 不勝欣慰。 阿彌陀佛炸卑。
    木子哲學(xué)閱讀 187評論 2 0