12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874 |
- #ifdef RVC_OS_WIN
- #include "stdafx.h"
- #else
- #endif
- #include "endpoint.h"
- #include <sofia-sip/su.h>
- #include <sofia-sip/su_tag_class.h>
- #include <sofia-sip/nua.h>
- #include <sofia-sip/sip_status.h>
- #include <sofia-sip/sdp.h>
- #include <sofia-sip/sip_header.h>
- #include <sofia-sip/su_log.h>
- #include <sofia-sip/su_tagarg.h>
- #include <sofia-sip/su_tag_io.h>
- #include <sofia-sip/soa_tag.h>
- #include <sofia-sip/su_wait.h>
- #include <sofia-sip/nua_tag.h>
- #include "refcnt.h"
- #include "list.h"
- #include "sockutil.h"
- #include "hash.h"
- #include "SpBase.h"
- #include "video_session.h"
- #include "audio_session.h"
- #include "rec_common.h"
- #include "Event.h"
- BOOL g_IsExternalTerminalted = FALSE;
- // default: ptime = 20ms
- #define CONDITION_PARAMS \
- int status, \
- char const *phrase, \
- nua_t *nua, \
- struct endpoint_t *ep, \
- nua_handle_t *nh, \
- struct endpoint_call_t *call, \
- sip_t const *sip, \
- tagi_t tags[]
- // the same with rtp payload type, the same as huawei open-eye
- enum e_audio_rtp_pt
- {
- PCMU = 0, // 64kbps, 4.17
- PCMA = 8, // 64kbps, 4.11
- G729 = 18, // 8kbps, 3.9
- };
- enum e_video_rtp_pt
- {
- H263 = 34, // h263
- };
- enum e_media_dir
- {
- DIR_NONE = 0,
- DIR_TX = 1,
- DIR_RX = 2,
- DIR_BOTH = 3,
- };
- typedef struct sdpvideo_desc_t
- {
- unsigned long local_rtp_ip;
- int local_rtp_port;
- unsigned long remote_rtp_ip;
- int remote_rtp_port;
- int local_pt;
- int remote_pt;
- };
- typedef struct media_desc_t
- {
- unsigned long remote_ip;
- int remote_port;
- unsigned long local_ip;
- int local_port;
- int media_dir;
- int local_pt;
- int local_ptime;
- int remote_pt;
- int remote_ptime;
- int local_telephone_event_pt;
- int remote_telephone_event_pt;
- int param[16];
- }media_desc_t;
- // 1. how to exit
- struct endpoint_call_t {
- struct list_head entry;
- endpoint_call_callback_t cb;
- endpoint_t *ep;
- audio_session_t *audio;
- video_session_t *video;
- int id;
- su_home_t *home;
- nua_handle_t *nh;
- char *remote_uri;
- sdp_session_t *last_sdp;
- int connected;
- int local_media_port;
- int local_video_port;
- unsigned int last_media_desc_hash;
- char local_ip[256];
- DeviceTypeEnum eDeviceType;
- CallingTypeEnum nCallType;
- sdpvideo_desc_t sdpvieo_desc;
- DECLARE_REF_COUNT_MEMBER(ref_cnt);
- };
- DECLARE_REF_COUNT_STATIC(endpoint_call, endpoint_call_t)
- struct endpoint_t {
- su_home_t home[1];
- su_root_t *root;
- nua_t *nua;
- endpoint_call_t *active_call;
- #ifdef RVC_OS_WIN
- HANDLE event_thread;;
- #else
- pthread_t ievent_threadid;
- #endif
-
- int call_seq;
- int media_port_seq;
- CEntityBase *entity;
- struct list_head call_list;
- endpoint_conf_t conf;
- int curr_audio_dev_type; // handfree or pickup
- };
- static const char *state_desc[] = {
- "STATE::INIT",
- "STATE::CALLING",
- "STATE::PROCEEDING",
- "STATE::COMPLETING",
- "STATE::READY",
- "STATE::TERMINATING",
- "STATE::TERMINATED",
- };
- static const char* call_type_table[] = {
- "NORMAL_CALLTYPE",
- "PADRINGUP_CALLTYPE",
- "PADTOPAD_CALLTYPE",
- "MOBILETOPAD_CALLTYPE",
- "DOUBLERECORD_CALLTYPE"
- };
- #ifndef VIDEOPLAYER_FLAG_DOUBLESIZE
- #define VIDEOPLAYER_FLAG_DOUBLESIZE 0x01
- #endif
- #ifndef VIDEOPLAYER_FLAG_NOTIMER
- #define VIDEOPLAYER_FLAG_NOTIMER 0x02
- #endif
- #ifndef VIDEOPLAYER_FLAG_PUSH
- #define VIDEOPLAYER_FLAG_PUSH 0x04
- #endif
- #ifndef VIDEOPLAYER_FLAG_PULL
- #define VIDEOPLAYER_FLAG_PULL 0x08
- #endif
- #ifndef VIDEOPLAYER_FLAG_CHECKTOP
- #define VIDEOPLAYER_FLAG_CHECKTOP 0x10
- #endif
- #ifndef VIDEOPLAYER_FLAG_ZOOMOUTSIZE
- #define VIDEOPLAYER_FLAG_ZOOMOUTSIZE 0x100
- #endif
- static void endpoint_media_change_audio_dev(endpoint_call_t *call, e_dev_type current_dev_type)
- {
- LOG_FUNCTION();
- if (call->audio) {
- Dbg("begin audio_session_change_dev %d", current_dev_type);
- audio_session_change_dev(call->audio, current_dev_type);
- Dbg("end audio_session_change_dev");
- }
- }
- static __inline struct in_addr __lton(unsigned long ip)
- {
- struct in_addr addr;
- addr.s_addr = ip;
- return addr;
- }
- static void endpoint_media_update_video(endpoint_call_t *call, media_desc_t *video_desc, video_session_callback_t* cb)
- {
- LOG_FUNCTION();
- if (video_desc->media_dir == DIR_NONE)
- {
- if (call->video)
- {
- video_session_stop(call->video);
- video_session_destroy(call->video);
- call->video = NULL;
- }
- else
- {
- if (DOUBLERECORD_CALLTYPE == call->nCallType)
- {
- double_record_broadcast_video_session_stop();
- }
- }
- }
- else
- {
- int rc;
- BOOL bCreateAudioObject = FALSE;
- endpoint_conf_t *ep_conf = &call->ep->conf;
- if (!call->audio)
- {
- audio_session_conf_t conf = {0};
- strcpy(&conf.in_dev[DEV_PICKUP][0], ep_conf->audio_pickup_in_dev);
- strcpy(&conf.in_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_in_dev);
- strcpy(&conf.out_dev[DEV_PICKUP][0], ep_conf->audio_pickup_out_dev);
- strcpy(&conf.out_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_out_dev);
- conf.agc_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_agc;
- conf.agc_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_agc;
- conf.agc_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_agc;
- conf.agc_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_agc;
- conf.ns_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_ns;
- conf.ns_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_ns;
- conf.ns_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_ns;
- conf.ns_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_ns;
- conf.aec[DEV_PICKUP] = !!ep_conf->audio_pickup_aec;
- conf.aec[DEV_HANDFREE] = !!ep_conf->audio_handfree_aec;
- rc = audio_session_create(&conf, &call->audio);
- if (rc != 0)
- {
- Dbg("create audio session failed! rc = %d", rc);
- return;
- }
- bCreateAudioObject = TRUE;
- }
- audio_session_remote_recording_conf_t remote_conf = {0};
- remote_conf.local_rtp_ip = video_desc->local_ip;
- remote_conf.local_rtp_port = video_desc->local_port+2;
- remote_conf.ptime = REC_COMMON_AUDIO_FRAME_PTIME; // for remote recording
- remote_conf.remote_rtp_ip = video_desc->remote_ip;
- remote_conf.remote_rtp_port = video_desc->remote_port+2;
- rc = audio_session_start_remote_recording(call->audio, &remote_conf);
- if (rc != 0)
- {
- Dbg("audio_session_start_remote_recording failed! rc = %d", rc);
- if (bCreateAudioObject)
- {
- audio_session_destroy(call->audio);
- call->audio = NULL;
- }
- //return;
- }
- if (call->video) {
- video_session_destroy(call->video);
- call->video = NULL;
- }
- int i = 0;
- int local_view_x = video_desc->param[i++];
- int local_view_y = video_desc->param[i++];
- int local_view_cx = video_desc->param[i++];
- int local_view_cy = video_desc->param[i++];
- int remote_view_x = video_desc->param[i++];
- int remote_view_y = video_desc->param[i++];
- int remote_view_cx = video_desc->param[i++];
- int remote_view_cy = video_desc->param[i++];
- int remote_width = video_desc->param[i++];
- int remote_height = video_desc->param[i++];
- //add by clp 20190823
- int local_hwd_move = video_desc->param[i++];
- int remote_hwd_move = video_desc->param[i++];
- video_session_conf_t video_conf = {0};
- if (eMobilePadType == call->eDeviceType)
- {
- video_conf.bit_rate = 150 * 1024;
- }
- else
- {
- video_conf.bit_rate = 256 * 1024;
- }
- video_conf.local_rtp_ip = video_desc->local_ip;
- video_conf.local_rtp_port = video_desc->local_port;
- video_conf.local_video_view_x = local_view_x;
- video_conf.local_video_view_y = local_view_y;
- video_conf.local_video_view_cx = local_view_cx;
- video_conf.local_video_view_cy = local_view_cy;
- video_conf.mtu = ep_conf->mtu;
- video_conf.video_quant = ep_conf->quant;
- video_conf.remote_rtp_ip = video_desc->remote_ip;
- video_conf.remote_rtp_port = video_desc->remote_port;
- video_conf.remote_video_view_x = remote_view_x;
- video_conf.remote_video_view_y = remote_view_y;
- video_conf.remote_video_view_cx = remote_view_cx;
- video_conf.remote_video_view_cy = remote_view_cy;
- video_conf.remote_video_width = remote_width;
- video_conf.remote_video_height = remote_height;
- video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
- video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
- video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
- video_conf.ref_window_state = call->ep->conf.ref_window_state;
- video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
- //video_conf.ref_active_img = call->ep->conf.ref_active_img;
- //video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
- video_conf.ref_active_img = NULL;
- video_conf.ref_Is_ActiveInspect = NULL;
- video_conf.camera_count = call->ep->conf.camera_count;
- video_conf.screen_count = call->ep->conf.screen_count;
- video_conf.ref_Up_Fps = call->ep->conf.ref_Up_Fps;
- video_conf.eDeviceType = call->eDeviceType;
- video_conf.nCallType = call->nCallType;
- video_conf.local_move = local_hwd_move;
- video_conf.remote_move = remote_hwd_move;
- video_conf.video_echo_cb = cb;
- video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP;
- video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
-
- if (video_conf.nCallType == MOBILETOPAD_CALLTYPE ) //如果与手机连接使用标准H264
- {
- video_conf.local_pt = video_desc->local_pt;
- video_conf.remote_pt = video_desc->remote_pt;
- }
- else //如果与pad连接或者常规连接模式使用H264+
- {
- //huchen modify, now we use standard h264
- //video_conf.local_pt = REC_COMMON_VIDEO_PT;
- //video_conf.remote_pt = REC_COMMON_VIDEO_PT;
- video_conf.local_pt = REC_COMMON_VIDEO_H264_PT;
- video_conf.remote_pt = REC_COMMON_VIDEO_H264_PT;
- }
- rc = video_session_create(&video_conf, &call->video);
- if (rc != 0) {
- Dbg("create video session failed! rc = %d", rc);
- return;
- }
- else{
- Dbg("make remote call session addr is %0x.",call->video);
- }
- rc = video_session_start(call->video);
- if (rc != 0) {
- Dbg("start video session failed! rc = %d", rc);
- video_session_destroy(call->video);
- call->video = NULL;
- return;
- }
- else{
- Dbg("endpoint media update video, video session start suc, and session is %0x.", call->video);
- }
- }
- }
- static void endpoint_media_update_audio(endpoint_call_t *call, media_desc_t *audio_desc, int dev_type)
- {
- LOG_FUNCTION();
- LOG_TRACE("audio dir:%d", audio_desc->media_dir);
- if (audio_desc->media_dir == DIR_NONE) {
- if (call->audio) {
- LOG_TRACE("stop audio...");
- audio_session_stop(call->audio);
- audio_session_destroy(call->audio);
- call->audio = NULL;
- LOG_TRACE("stop audio ok!");
- }
- else{
- LOG_TRACE("call->audio is null.");
- }
- if (call->video) { // close video also
- LOG_TRACE("stop video...");
- video_session_stop(call->video);
- video_session_destroy(call->video);
- call->video = NULL;
- LOG_TRACE("stop video ok!");
- }
- else{
- LOG_TRACE("call->video is null.");
- }
- } else {
- int rc;
- if (call->audio) {
- LOG_TRACE("stop audio...");
- audio_session_stop(call->audio);
- audio_session_destroy(call->audio);
- call->audio = NULL;
- LOG_TRACE("stop audio ok!");
- }
- if (!call->audio) {
- endpoint_conf_t *ep_conf = &call->ep->conf;
- audio_session_conf_t conf = {0};
- strcpy(&conf.in_dev[DEV_PICKUP][0], ep_conf->audio_pickup_in_dev);
- strcpy(&conf.in_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_in_dev);
- strcpy(&conf.out_dev[DEV_PICKUP][0], ep_conf->audio_pickup_out_dev);
- strcpy(&conf.out_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_out_dev);
- conf.agc_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_agc;
- conf.agc_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_agc;
- conf.agc_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_agc;
- conf.agc_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_agc;
- conf.ns_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_ns;
- conf.ns_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_ns;
- conf.ns_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_ns;
- conf.ns_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_ns;
- conf.aec[DEV_PICKUP] = !!ep_conf->audio_pickup_aec;
- conf.aec[DEV_HANDFREE] = !!ep_conf->audio_handfree_aec;
- rc = audio_session_create(&conf, &call->audio);
- if (rc != 0) {
- Dbg("create audio session failed! rc = %d", rc);
- return;
- }
- }
- audio_session_phonemedia_conf_t phone_conf = {0};
- phone_conf.dir = audio_desc->media_dir;
- phone_conf.dev_type = (e_dev_type)dev_type;
- phone_conf.local_dtmf_pt = audio_desc->local_telephone_event_pt;
- phone_conf.local_pt = audio_desc->local_pt;
- phone_conf.local_ptime = audio_desc->local_ptime;
- phone_conf.local_rtp_ip = audio_desc->local_ip;
- phone_conf.local_rtp_port = audio_desc->local_port;
- phone_conf.remote_dtmf_pt = audio_desc->remote_telephone_event_pt;
- phone_conf.remote_pt = audio_desc->remote_pt;
- phone_conf.remote_ptime = audio_desc->remote_ptime;
- phone_conf.remote_rtp_ip = audio_desc->remote_ip;
- phone_conf.remote_rtp_port = audio_desc->remote_port;
-
- if (NULL != call){
- phone_conf.eCalltype = call->nCallType;
- phone_conf.eDeviceType = call->eDeviceType;
- }
-
- rc = audio_session_start_phonemedia(call->audio, &phone_conf);
- if (rc != 0) {
- Dbg("start audio session failed! rc = %d", rc);
- LogError(Severity_High,Error_DevMedia,ERROR_MOD_SIP_AUDIO_INITFAIL,"audio initialize fail");
- audio_session_destroy(call->audio);
- call->audio = NULL;
- return;
- }
- else {
- Dbg("start audio session success!");
- }
- }
- }
- static unsigned int __hash_media_desc(media_desc_t *media_desc, unsigned int hash_code)
- {
- if (media_desc) {
- hash_code += (unsigned int)media_desc->local_ip * 33;
- hash_code += (unsigned int)media_desc->remote_ip * 33;
- hash_code += (unsigned int)media_desc->local_port * 33;
- hash_code += (unsigned int)media_desc->remote_port * 33;
- hash_code += (unsigned int)media_desc->media_dir * 33;
- hash_code += (unsigned int)media_desc->local_pt * 33;
- hash_code += (unsigned int)media_desc->local_ptime * 33;
- hash_code += (unsigned int)media_desc->remote_pt * 33;
- hash_code += (unsigned int)media_desc->remote_ptime * 33;
- hash_code += (unsigned int)media_desc->local_telephone_event_pt * 33;
- hash_code += (unsigned int)media_desc->remote_telephone_event_pt * 33;
- }
- return hash_code;
- }
- static unsigned int hash_media_desc(media_desc_t *audio)
- {
- unsigned int hash_code = 0;
- hash_code = __hash_media_desc(audio, hash_code);
- return hash_code;
- }
- #define USE_ALAW 1
- static const char *call_make_offer(endpoint_call_t *call, char *buf, int size)
- {
- int local_audio_rtp_port = call->local_media_port;
- int local_video_rtp_port = call->local_video_port;
- int local_video_pt = REC_COMMON_VIDEO_PT;
- int need;
- const char *fmt;
- Dbg("make call offer,device type is %s, Call Type is %s", Device_Type_Table[call->eDeviceType], call_type_table[call->nCallType]);
- if ((eMobilePadType == call->eDeviceType) || (ePadtype == call->eDeviceType)||(eDesk2SType == call->eDeviceType)||(eDesk1SType==call->eDeviceType)||(eDesk2SIntegratedType==call->eDeviceType)) //pad
- {
- if (call->nCallType == MOBILETOPAD_CALLTYPE) //如果跟手机对接
- {
- local_video_pt = REC_COMMON_VIDEO_H264_PT;
- fmt = "c=IN IP4 %s\r\n"
- "m=audio %d RTP/AVP 8\r\n"
- "a=rtpmap:8 PCMA/8000\r\n"
- "a=ptime:30\r\n"
- "m=video %d RTP/AVP %d\r\n"
- "a=rtpmap:%d H264/90000\r\n";
- need = _scprintf(fmt, call->local_ip, local_audio_rtp_port,local_video_rtp_port, local_video_pt,local_video_pt);
- if (size < 0 || size > need) {
- sprintf(buf, fmt, call->local_ip, local_audio_rtp_port, local_video_rtp_port, local_video_pt,local_video_pt);
- return buf;
- }
- else {
- return NULL;
- }
- }
- else if((call->nCallType == PADRINGUP_CALLTYPE)||(call->nCallType == PADTOPAD_CALLTYPE))
- {
- fmt = "c=IN IP4 %s\r\n"
- "m=audio %d RTP/AVP 8\r\n"
- "a=rtpmap:8 PCMA/8000\r\n"
- "a=ptime:30\r\n"
- ;
- need = _scprintf(fmt, call->local_ip, local_audio_rtp_port);
- if (size < 0 || size > need) {
- sprintf(buf, fmt, call->local_ip, local_audio_rtp_port);
- return buf;
- }
- else {
- return NULL;
- }
- }
- else if(call->nCallType == NORMAL_CALLTYPE || call->nCallType == DOUBLERECORD_CALLTYPE)//如果是可视柜台模式以及外拓版
- {
- if(eMobilePadType == call->eDeviceType)
- {
- fmt = "c=IN IP4 %s\r\n"
- "m=audio %d RTP/AVP 18\r\n"
- "a=rtpmap:18 G729/8000\r\n"
- "a=fmtp:18 annexb=no\r\n"
- "a=ptime:30\r\n"
- ;
- Dbg("pad site = CMB.FLB");
- }
- else
- {
- fmt = "c=IN IP4 %s\r\n"
- "m=audio %d RTP/AVP 8\r\n"
- "a=rtpmap:8 PCMA/8000\r\n"
- "a=ptime:30\r\n"
- ;
- Dbg("pad site = CMB.LIB");
- }
- need = _scprintf(fmt, call->local_ip, local_audio_rtp_port);
-
- if (size < 0 || size > need) {
- sprintf(buf, fmt, call->local_ip, local_audio_rtp_port);
- return buf;
- }
- else {
- return NULL;
- }
- }
- }
- else //大机
- {
- fmt =
- "c=IN IP4 %s\r\n"
- #ifdef USE_ALAW
- "m=audio %d RTP/AVP 8\r\n"
- "a=rtpmap:8 PCMA/8000\r\n"
- "a=ptime:30\r\n"
- #elif defined(USE_G729)
- "m=audio %d RTP/AVP 18\r\n"
- "a=rtpmap:18 G729/8000\r\n"
- "a=fmtp:18 annexb=no\r\n"
- "a=ptime:30\r\n"
- #endif
- //"a=rtpmap:97 telephone-event/8000\r\n"
- //"a=fmtp:97 0-15\r\n"
- #ifdef USE_H263_VIDEO
- "m=video %d RTP/AVP 34\r\n"
- "a=rtpmap:34 H263/90000\r\n"
- "a=fmtp:34 QCIF=2 MaxBR=5040\r\n"
- #endif
- //"a=inactive\r\n" //for debug only
- ;
- Dbg("pad site != CMB.FLB");
- }
-
- need = _scprintf(fmt, call->local_ip, local_audio_rtp_port);
- if (size < 0 || size > need) {
- sprintf(buf, fmt, call->local_ip, local_audio_rtp_port);
- return buf;
- } else {
- return NULL;
- }
- }
- static int new_call_id(endpoint_t *ep)
- {
- return ++ep->call_seq;
- }
- static int new_media_port(endpoint_t *ep)
- {
- ep->media_port_seq += 2;
- if (ep->media_port_seq >= ep->conf.media_stop_port) {
- ep->media_port_seq = ep->conf.media_start_port;
- }
- return ep->media_port_seq;
- }
- static void handle_invite(CONDITION_PARAMS)
- {
- // we are client only, not accept in-comming call
- nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
- }
- static void handle_reinvite(CONDITION_PARAMS)
- {
- char sdp[512];
- sip_content_type_t const *ct = NULL;
- tl_gets(tags,
- SIPTAG_CONTENT_TYPE_REF(ct),
- TAG_END());
- if (ct) {
- call_make_offer(call, sdp, sizeof(sdp));
- }
- nua_respond(nh,
- SIP_200_OK,
- TAG_IF(ct, SOATAG_USER_SDP_STR(sdp)),
- TAG_IF(ct, SOATAG_AUDIO_AUX("telephone-event")),
- TAG_END());
- }
- static void handle_r_invite(CONDITION_PARAMS)
- {
- // nothing to do
- }
- static int dir_from_attr(const sdp_media_t *m)
- {
- int dir = DIR_NONE;
- if (m) {
- if (m->m_attributes) {
- static const char *ds[] = {
- "inactive", "sendonly", "recvonly", "sendrecv"
- };
- int i;
- int n = array_size(ds);
- for (i = 0; i < n; ++i) {
- sdp_attribute_t *attr = sdp_attribute_find(m->m_attributes, ds[i]);
- if (attr) {
- dir = i;
- break;
- }
- }
- if (i >= n)
- dir = DIR_BOTH;
- } else {
- dir = DIR_BOTH;
- }
- }
- return dir;
- }
- static int ptime_from_attr(const sdp_media_t *m)
- {
- int ptime = 0; // zero for default
- if (m) {
- if (m->m_attributes) {
- sdp_attribute_t *attr = sdp_attribute_find(m->m_attributes, "ptime");
- if (attr && attr->a_value) {
- ptime = atoi(attr->a_value);
- if (ptime < 0)
- ptime = 0;
- }
- }
- }
- return ptime;
- }
- static const sdp_rtpmap_t *find_codec(const sdp_rtpmap_t *list, const char *codec)
- {
- if (!codec)
- return NULL;
- for (;list; list=list->rm_next) {
- if (!_stricmp(list->rm_encoding, codec)) {
- break;
- }
- }
- return list;
- }
- static int get_telephone_event_pt(const sdp_rtpmap_t *list)
- {
- int pt = -1;
- const sdp_rtpmap_t *rm = find_codec(list, "telephone-event");
- if (rm) {
- pt = rm->rm_pt;
- }
- return pt;
- }
- static int get_media_direction(const sdp_media_t *lm, const sdp_media_t *rm)
- {
- int media_dir = DIR_NONE;
- if (rm->m_port == 0 || lm->m_port == 0) {
- media_dir = DIR_NONE;
- } else {
- int ldir = dir_from_attr(lm);
- int rdir = dir_from_attr(rm);
- if (ldir == DIR_NONE || rdir == DIR_NONE) {
- media_dir = DIR_NONE;
- } else if (ldir == DIR_TX || rdir == DIR_RX) {
- media_dir = DIR_TX;
- } else if (ldir == DIR_RX || rdir == DIR_TX) {
- media_dir = DIR_RX;
- } else {
- media_dir = DIR_BOTH;
- }
- }
- return media_dir;
- }
- static int negotiate_audio(endpoint_call_t *call, media_desc_t *audio_desc, const sdp_media_t *lm, const sdp_media_t *rm)
- {
- memset(audio_desc, 0, sizeof(media_desc_t));
- const char *local_ip;
- const char *remote_ip;
- local_ip = lm->m_connections ? lm->m_connections->c_address : lm->m_session->sdp_connection->c_address;
- remote_ip = rm->m_connections ? rm->m_connections->c_address : rm->m_session->sdp_connection->c_address;
- audio_desc->local_ip = local_ip ? inet_addr(local_ip) : 0;
- audio_desc->local_port = lm->m_port;
- audio_desc->remote_ip = remote_ip ? inet_addr(remote_ip) : 0;
- audio_desc->remote_port = rm->m_port;
- audio_desc->local_telephone_event_pt = 97;
- audio_desc->remote_telephone_event_pt = get_telephone_event_pt(rm->m_rtpmaps);
- audio_desc->local_ptime = ptime_from_attr(lm);
- audio_desc->remote_ptime = ptime_from_attr(rm);
- int pt = -1;
- for (sdp_rtpmap_t *t = lm->m_rtpmaps; t; t = t->rm_next) {
- sdp_rtpmap_t *tt = sdp_rtpmap_find_matching(rm->m_rtpmaps, t);
- if (tt && tt->rm_pt < 96) {
- pt = tt->rm_pt;
- break;
- }
- }
- audio_desc->local_pt = audio_desc->remote_pt = pt;
- audio_desc->media_dir = get_media_direction(lm, rm);
- return 0;
- }
- static int negotiate_video(endpoint_call_t *call, media_desc_t *video_desc, const sdp_media_t *lm, const sdp_media_t *rm)
- {
- memset(video_desc, 0, sizeof(media_desc_t));
- const char *local_ip;
- const char *remote_ip;
- local_ip = lm->m_connections ? lm->m_connections->c_address : lm->m_session->sdp_connection->c_address;
- remote_ip = rm->m_connections ? rm->m_connections->c_address : rm->m_session->sdp_connection->c_address;
- video_desc->local_ip = local_ip ? inet_addr(local_ip) : 0;
- video_desc->local_port = lm->m_port;
- video_desc->remote_ip = remote_ip ? inet_addr(remote_ip) : 0;
- video_desc->remote_port = rm->m_port;
- video_desc->local_telephone_event_pt = 97;
- video_desc->remote_telephone_event_pt = get_telephone_event_pt(rm->m_rtpmaps);
- video_desc->local_ptime = ptime_from_attr(lm);
- video_desc->remote_ptime = ptime_from_attr(rm);
- int pt = -1;
- for (sdp_rtpmap_t *t = lm->m_rtpmaps; t; t = t->rm_next) {
- sdp_rtpmap_t *tt = sdp_rtpmap_find_matching(rm->m_rtpmaps, t);
- if (tt) {
- pt = tt->rm_pt;
- break;
- }
- }
- video_desc->local_pt = video_desc->remote_pt = pt;
- video_desc->media_dir = get_media_direction(lm, rm);
- return 0;
- }
- static void negotiate_sdp(endpoint_call_t *call, const sdp_session_t *local_sdp, const sdp_session_t* remote_sdp)
- {
- LOG_FUNCTION();
- const sdp_media_t *lm = local_sdp->sdp_media;
- const sdp_media_t *rm = remote_sdp->sdp_media;
- media_desc_t audio_desc = {0}, video_desc = {0};
- int rc = -1, rv = -1;
- for(; lm; lm = lm->m_next)
- {
- if (0 == lm->m_port)
- {
- continue;
- }
- const sdp_media_t *rm = remote_sdp->sdp_media;
- for (; rm; rm = rm->m_next)
- {
- if (rm->m_type == lm->m_type)
- {
- if (sdp_media_audio == rm->m_type)
- {
- rc = negotiate_audio(call, &audio_desc, lm, rm);
- }
- if (call->nCallType != NORMAL_CALLTYPE && call->nCallType != DOUBLERECORD_CALLTYPE)
- {
- if (sdp_media_video == rm->m_type)
- {
- rv = negotiate_video(call, &video_desc, lm, rm);
- }
- }
- }
- }
- }
- if (rc == 0)
- {
- unsigned int hash_code = hash_media_desc(&audio_desc);
- if (hash_code != call->last_media_desc_hash)
- {
- char str_local[128] = {0};
- char str_remote[128] = {0};
- translate_ipaddr_from_int(str_local, 128, audio_desc.local_ip);
- translate_ipaddr_from_int(str_remote, 128, audio_desc.remote_ip);
- Dbg("negotiate audio success!local audio ip=%s port=%d pt=%d,remote audio ip=%s port=%d,pt=%d",str_local,audio_desc.local_port,audio_desc.local_pt,str_remote,audio_desc.remote_port,audio_desc.remote_pt);
- endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
- call->last_media_desc_hash = hash_code;
- }
- }
- if (rv == 0)
- {
- unsigned int hash_code = hash_media_desc(&video_desc);
- if (hash_code != call->last_media_desc_hash)
- {
- char str_local[128] = {0};
- char str_remote[128] = {0};
- translate_ipaddr_from_int(str_local, 128, video_desc.local_ip);
- translate_ipaddr_from_int(str_remote, 128, video_desc.remote_ip);
- Dbg("negotiate video success!local video ip=%s port=%d pt=%d,remote video ip=%s port=%d pt=%d",str_local,video_desc.local_port,video_desc.local_pt,str_remote,video_desc.remote_port,video_desc.remote_pt);
- call->sdpvieo_desc.local_pt = video_desc.local_pt;
- call->sdpvieo_desc.local_rtp_ip = video_desc.local_ip;
- call->sdpvieo_desc.local_rtp_port = video_desc.local_port;
- call->sdpvieo_desc.remote_pt = video_desc.remote_pt;
- call->sdpvieo_desc.remote_rtp_ip = video_desc.remote_ip;
- call->sdpvieo_desc.remote_rtp_port = video_desc.remote_port;
- call->last_media_desc_hash = hash_code;
- }
- }
- else
- {
- if (call->nCallType != NORMAL_CALLTYPE && call->nCallType != DOUBLERECORD_CALLTYPE)
- {
- Dbg("negotiate video Fail!!!");
- }
- }
- }
- static void on_state(CONDITION_PARAMS)
- {
- LOG_FUNCTION();
- int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
- int state = nua_callstate_init;
- const char *replaces_str = NULL;
- const sdp_session_t *remote_sdp = NULL;
- const char *remote_sdp_str = NULL;
- const sdp_session_t *local_sdp = NULL;
- const char *local_sdp_str = NULL;
- int st;
- if (!call) {
- nua_handle_destroy(nh);
- return;
- }
- if (g_IsExternalTerminalted)
- {
- return;
- }
- tl_gets(tags,
- NUTAG_CALLSTATE_REF(state),
- NUTAG_OFFER_RECV_REF(offer_recv),
- NUTAG_ANSWER_RECV_REF(answer_recv),
- NUTAG_OFFER_SENT_REF(offer_sent),
- NUTAG_ANSWER_SENT_REF(answer_sent),
- SIPTAG_REPLACES_STR_REF(replaces_str),
- SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str),
- SOATAG_LOCAL_SDP_STR_REF(local_sdp_str),
- TAG_END());
- LOG_TRACE("state = %d, offer_recv=%d, answer_recv=%d, offer_sent=%d, answer_sent=%d",
- state, offer_recv, answer_recv, offer_sent, answer_sent);
- switch (state)
- {
- case nua_callstate_calling:
- LOG_TRACE("nua_callstate_calling, has_local_sdp : %d, has_remote_sdp : %d", !!local_sdp_str, !!remote_sdp_str);
- if (local_sdp_str) {
- sdp_parser_t *parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
- assert(call->last_sdp == NULL);
- call->last_sdp = sdp_session_dup(call->home, sdp_session(parser));
- sdp_parser_free(parser);
- }
- st = CALLING;
- call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
- break;
- case nua_callstate_proceeding:
- LOG_TRACE("nua_callstate_proceeding, status = %d, has_local_sdp: %d, has_remote_sdp : %d", status, !!local_sdp_str, !!remote_sdp_str);
- st = PROCEEDING;
- call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
- if (remote_sdp_str) {
- sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
- remote_sdp = sdp_session(parser);
- if (call->last_sdp) {
- negotiate_sdp(call, call->last_sdp, remote_sdp);
- su_free(call->home, call->last_sdp);
- call->last_sdp = NULL;
- }
- sdp_parser_free(parser);
- }
- break;
- case nua_callstate_completing:
- st = COMPLETING;
- LOG_TRACE("nua_callstate_completing, has_local_sdp : %d, has_remote_sdp : %d", !!local_sdp_str, !!remote_sdp_str);
- call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
- if (remote_sdp_str) {
- sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
- remote_sdp = sdp_session(parser);
- if (call->last_sdp) {
- negotiate_sdp(call, call->last_sdp, remote_sdp);
- su_free(call->home, call->last_sdp);
- call->last_sdp = NULL;
- }
- sdp_parser_free(parser);
- }
- break;
- case nua_callstate_completed:
- LOG_TRACE("nua_callstate_completed, has_local_sdp : %d, has_remote_sdp : %d", !!local_sdp_str, !!remote_sdp_str);
- if (remote_sdp_str) {
- if (!call->last_sdp) {
- sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
- call->last_sdp = sdp_session_dup(call->home, sdp_session(parser));
- sdp_parser_free(parser);
- }
- }
- if (local_sdp_str) {
- if (call->last_sdp) {
- sdp_parser_t *parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
- local_sdp = sdp_session(parser);
- negotiate_sdp(call, local_sdp, call->last_sdp);
- su_free(call->home, call->last_sdp);
- call->last_sdp = NULL;
- sdp_parser_free(parser);
- }
- }
- break;
- case nua_callstate_ready:
- call->connected = true;
- LOG_TRACE("nua_callstate_ready, has_local_sdp : %d, has_remote_sdp : %d.", !!local_sdp_str, !!remote_sdp_str);
- st = READY;
- call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
- if (remote_sdp_str) {
- sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
- remote_sdp = sdp_session(parser);
- if (call->last_sdp) {
- negotiate_sdp(call, call->last_sdp, remote_sdp);
- su_free(call->home, call->last_sdp);
- call->last_sdp = NULL;
- }
- sdp_parser_free(parser);
- }
- #if 0
- if (remote_sdp_str) {
- sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
- remote_sdp = sdp_session(parser);
- negotiate_sdp(call, call->last_sdp, remote_sdp);
- sdp_parser_free(parser);
- } else if (local_sdp_str) {
- sdp_parser_t *parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
- local_sdp = sdp_session(parser);
- negotiate_sdp(call, local_sdp, call->last_sdp);
- sdp_parser_free(parser);
- }
- #endif
- break;
- case nua_callstate_terminated:
- st = TERMINATED;
- LOG_TRACE("call terminated! in sofia thread!");
- {
- media_desc_t audio_desc = {0};
- audio_desc.media_dir = DIR_NONE;
- endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
- }
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- nua_handle_bind(nh, NULL);
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- nua_handle_destroy(nh);
- Dbg("%s:%d call = 0x%0x", __FUNCTION__, __LINE__, call);
- call->nh = NULL;
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- break;
- }
- }
- void Terminatedcall(endpoint_call_t *call)
- {
- int st = TERMINATED;
- g_IsExternalTerminalted = TRUE;
- Dbg("g_IsExternalTerminalted = TRUE");
- LOG_TRACE("terminated! by timeout!");
- {
- media_desc_t audio_desc = {0};
- audio_desc.media_dir = DIR_NONE;
- endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
- }
- }
-
- static void endpoint_callback(nua_event_t event,
- int status,
- char const *phrase,
- nua_t *nua,
- nua_magic_t *magic,
- nua_handle_t *nh,
- nua_hmagic_t *hmagic,
- sip_t const *sip,
- tagi_t tags[])
- {
- LOG_FUNCTION();
- switch (event)
- {
- if (!g_IsExternalTerminalted)
- {
- case nua_i_invite:
- if (hmagic == NULL) {
- handle_invite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
- } else {
- LOG_TRACE("reinvite!");
- handle_reinvite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
- }
- break;
- case nua_r_invite:
- handle_r_invite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
- break;
- case nua_i_bye:
- //.....
- LOG_TRACE("nua_i_bye");
- break;
- case nua_i_info:
- LOG_TRACE("nua_i_info");
- break;
- case nua_i_state:
- on_state(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
- break;
- case nua_i_active:
- LOG_TRACE("nua_i_active");
- break;
- case nua_i_options:
- //nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SOATAG_USER_SDP_STR(NULL), TAG_END());
- nua_respond(nh, SIP_200_OK, TAG_END());
- break;
- case nua_r_cancel:
- LOG_TRACE("nua_r_cancel");
- if (status > 300) {
- nua_bye(nh, TAG_END());
- }
- break;
- case nua_i_prack:
- LOG_TRACE("nua_i_prack");
- case nua_r_prack:
- LOG_TRACE("nua_r_prack");
- break;
- case nua_r_bye:
- //LOG_TRACE("nua_r_bye");
- if (status > 300) {
- nua_bye(nh, TAG_END());
- }
- break;
- /* and so on ... */
- default:
- if (status > 100) { /* unknown event -> print out error message */
- LOG_TRACE("unknown event %d: %03d %s.",
- event,
- status,
- phrase);
- } else {
- LOG_TRACE("unknown event %d.", event);
- }
- break;
- }
-
- }
- if (!hmagic)
- {
- nua_handle_destroy(nh);
- return;
- }
- }
- #ifdef RVC_OS_WIN
- static unsigned int __stdcall __event_thread(void* arg)
- #else
- void* __event_thread(void* arg)
- #endif
- {
- LOG_FUNCTION();
- endpoint_t *ep = (endpoint_t *)arg;
- ep->entity->GetFunction()->InitLogCurrentThread();
- #ifdef RVC_OS_WIN
- CoInitialize(NULL);
- #else
- #endif // RVC_OS_WIN
- ep->root = su_root_create(ep);
-
- ep->nua = nua_create(ep->root,
- &endpoint_callback,
- ep,
- NUTAG_URL(ep->conf.uri),
- TAG_END());
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- nua_set_params(ep->nua,
- SIPTAG_ALLOW_STR("INVITE,CANCEL,BYE,ACK,INFO,OPTIONS"),
- NUTAG_AUTOALERT(1),
- NUTAG_ALLOW("PRACK"),
- NUTAG_EARLY_MEDIA(1),
- NUTAG_SESSION_TIMER(1),
- NUTAG_AUTOANSWER(0),
- NUTAG_AUTOACK(1),
- NTATAG_SIP_T1X64(8000),
- TAG_NULL());
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- su_root_run(ep->root);
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- nua_shutdown(ep->nua);
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- ep->nua = NULL;
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- su_root_destroy(ep->root);
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- ep->root = NULL;
- Dbg("%s:%d", __FUNCTION__, __LINE__);
- #ifdef RVC_OS_WIN
- CoUninitialize();
- #else
- #endif // RVC_OS_WIN
-
- return 0;
- }
- static int __endpoint_break(void *arg)
- {
- endpoint_t *ep = (endpoint_t *)arg;
- //.....nua_shutdown
- su_root_break(ep->root);
- return 0;
- }
- #ifdef RVC_OS_WIN
- #else
- unsigned long GetTickCount()
- {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
- }
- #endif
- static endpoint_t *__endpoint_create(CEntityBase *pEntity, const endpoint_conf_t *conf,int nDev)
- {
- LOG_FUNCTION();
- endpoint_t *ep;
- ep = ZALLOC_T(endpoint_t);
- su_home_init(ep->home);
- memcpy(&ep->conf, conf, sizeof(endpoint_conf_t));
- ep->media_port_seq = (conf->media_start_port + (GetTickCount() % (conf->media_stop_port - conf->media_start_port))) & 0xfffc;
- ep->entity = pEntity;
- ep->call_seq = GetTickCount();
- ep->curr_audio_dev_type = nDev;
- INIT_LIST_HEAD(&ep->call_list);
- return ep;
- }
- static void __endpoint_destroy(endpoint_t *ep)\
- {
- su_root_destroy(ep->root);
- su_home_deinit(ep->home);
- free(ep);
- }
- static int __endpoint_start(endpoint_t *ep)
- {
- LOG_FUNCTION();
- #ifdef RVC_OS_WIN
- ep->event_thread = (HANDLE)_beginthreadex(NULL, 0, &__event_thread, ep, 0, NULL);
- if (ep->event_thread)
- {
- while (!ep->root)
- {
- DWORD dwRet = WaitForSingleObject(ep->event_thread, 1);
- if (dwRet == WAIT_OBJECT_0)
- {
- CloseHandle(ep->event_thread);
- ep->event_thread = NULL;
- break;
- }
- }
- }
- return ep->event_thread ? 0 : -1;
- #else
- int err = pthread_create(&ep->ievent_threadid, NULL, __event_thread, ep);
- if (0 == err) {
- Dbg("create event thread success, %lu.", ep->ievent_threadid);
- struct timespec ts;
- Dbg("before circle ep->root = 0x%0x", ep->root);
- while (!ep->root) {
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_nsec += 1000 * 1000;
- if (0 == pthread_timedjoin_np(ep->ievent_threadid, NULL, &ts)) {
- ep->ievent_threadid = 0;
- Dbg("__event_thread exit break");
- break;
- }
- }
- Dbg("break circle ep->root = 0x%0x", ep->root);
- }
- else {
- Dbg("create event thread failed.");
- }
- return ep->ievent_threadid > 0 ? 0 : -1;
- #endif
- }
- static void __endpoint_stop(endpoint_t *ep)
- {
- #ifdef RVC_OS_WIN
- if (ep->event_thread)
- {
- int rc;
- su_task_execute(su_root_task(ep->root), &__endpoint_break, ep, &rc);
- WaitForSingleObject(ep->event_thread, INFINITE);
- CloseHandle(ep->event_thread);
- ep->event_thread = NULL;
- }
- #else
- if (ep->ievent_threadid > 0)
- {
- int rc;
- su_task_execute(su_root_task(ep->root), &__endpoint_break, ep, &rc);
- pthread_join(ep->ievent_threadid, NULL);
- ep->ievent_threadid = 0;
- }
- #endif
- }
- int endpoint_init_lib()
- {
- return su_init();
- }
- void endpoint_deinit_lib()
- {
- su_deinit();
- }
- endpoint_t *endpoint_create(CEntityBase *pEntity, const endpoint_conf_t *conf,int nDev)
- {
- LOG_FUNCTION();
- endpoint_t *endpt;
-
- endpt = __endpoint_create(pEntity, conf,nDev);
- if (endpt) {
- int rc = __endpoint_start(endpt);
- if (rc != 0)
- {
- __endpoint_destroy(endpt);
- endpt = NULL;
- }
- }
- return endpt;
- }
- void endpoint_destroy(endpoint_t *ep)
- {
- LOG_FUNCTION();
- if (ep)
- {
- __endpoint_stop(ep);
- __endpoint_destroy(ep);
- }
- }
- int endpoint_invoke(endpoint_t *ep, int (*func)(void*), void *user_data, int *result)
- {
- return su_task_execute(su_root_task(ep->root), func, user_data, result);
- }
- void endpoint_change_audio_dev(endpoint_t *ep, int dev_type)
- {
- LOG_FUNCTION();
- if (ep->curr_audio_dev_type != dev_type) {
- ep->curr_audio_dev_type = dev_type;
- if (ep->active_call) {
- Dbg("begin invoke media change audio device!");
- endpoint_media_change_audio_dev(ep->active_call, (e_dev_type)dev_type);
- Dbg("end invoke media change audio device!");
- } else {
- Dbg("active call is null!");
- }
- } else {
- Dbg("current dev_type is the same as dev_type!");
- }
- }
- endpoint_call_t *endpoint_call_create(endpoint_t *ep, const char *remote_uri, const char*local_ip,DeviceTypeEnum nDeviceType,CallingTypeEnum nCallType,const endpoint_call_callback_t *cb)
- {
- LOG_FUNCTION();
- endpoint_call_t *call = NULL;
- su_home_t *home = NULL;
- if (!remote_uri)
- return NULL;
- home = su_home_create();
- if (!home)
- goto on_error;
- call = (endpoint_call_t*)su_home_new(sizeof(endpoint_call_t));
- if (!call)
- goto on_error;
- memset(call, 0, sizeof(endpoint_call_t));
- call->connected = 0;
- call->ep = ep;
- call->home = home;
- call->last_media_desc_hash = 0;
- call->remote_uri = su_strdup(home, remote_uri);
- memcpy(call->local_ip,local_ip,256);
- call->eDeviceType = nDeviceType;
- call->nCallType = nCallType;
- Dbg("endpoint_call_create nCallType = %d.", nCallType);
- memcpy(&call->cb, cb, sizeof(endpoint_call_callback_t));
- call->id = new_call_id(ep);
- call->local_media_port = new_media_port(ep);
- call->local_video_port = REC_COMMON_VIDEO_PORT;
- REF_COUNT_INIT(&call->ref_cnt);
- list_add_tail(&call->entry, &ep->call_list);
- ep->active_call = call;
- return call;
- on_error:
- if (home)
- su_home_unref(home);
- return call;
- }
- void endpoint_call_destroy(endpoint_call_t *call)
- {
- LOG_FUNCTION();
- endpoint_call_dec_ref(call);
- }
- int endpoint_call_start(endpoint_call_t *call)
- {
- LOG_FUNCTION();
- char sdp[512] = {0};
- if (call->nh)
- return -1;
- call->nh = nua_handle(call->ep->nua,
- call,
- SIPTAG_FROM_STR(call->ep->conf.uri),
- SIPTAG_TO_STR(call->remote_uri),
- TAG_END());
- Dbg("uri is %s.", call->ep->conf.uri);
- Dbg("call remote_uri is %s.", call->remote_uri);
-
- call_make_offer(call, sdp, -1);
- Dbg("sdp is %s", sdp);
- nua_invite(call->nh,
- //NUTAG_URL(call->remote_uri),
- SOATAG_USER_SDP_STR(sdp),
- NUTAG_SESSION_TIMER(20000),
- //SOATAG_AUDIO_AUX("telephone-event"),
- TAG_END());
- return 0;
- }
- int endpoint_call_hangup(endpoint_call_t *call)
- {
- LOG_FUNCTION();
- if (call->nh) {
- if (call->connected) {
- nua_bye(call->nh, NUTAG_SESSION_TIMER(8000),TAG_END());
- } else {
- nua_cancel(call->nh, NUTAG_SESSION_TIMER(8000),TAG_END());
- }
- }
- return 0;
- }
- int set_switch_distribute_req_buffer(char* pbuffer, size_t ulen, endpoint_distribute_call_info_t *tinfo)
- {
- int ret = 0;
- if (!tinfo){
- return ret;
- }
- int ilen = sizeof(unsigned int);
- char* pindex = pbuffer + ilen;
- memcpy(pindex, &tinfo->etype, ilen);
- pindex += ilen;
- if (tinfo->call_name){
- unsigned int callname_len = strlen(tinfo->call_name);
- memcpy(pindex, &callname_len, ilen);
- pindex += ilen;
- memcpy(pindex, tinfo->call_name, callname_len);
- pindex += callname_len;
- }
- int actlen = pindex - pbuffer;
- if (actlen < ulen)
- {
- memcpy(pbuffer, &actlen, ilen);
- ret = actlen;
- }
- return ret;
- }
- #ifndef BUFFER_SIZE
- #define BUFFER_SIZE 256
- #endif
- //int endpoint_pad_switch_interactive(endpoint_distribute_call_info_t *tinfo)
- //{
- // int ret = -1;
- // SOCKET conn = INVALID_SOCKET;
- // struct sockaddr_in addr = {0};
- // int rc = -1;
- // BOOL opt = TRUE;
- // int saccept = -1;
- // BOOL bconnect = FALSE;
- // // try connect to switch server
- // if (NULL== tinfo){
- // return ret;
- // }
- //
- // addr.sin_family = AF_INET;
- // addr.sin_port = htons(tinfo->server_port);
- // addr.sin_addr.s_addr = inet_addr(tinfo->server_ip);//strtoul(config->switch_server, NULL, 10);
- //
- // conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- // if (INVALID_SOCKET == conn){
- // return ret;
- // }
- // rc = setsockopt(conn, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
- // opt = TRUE;
- // if (rc == 0){
- // rc = setsockopt(conn, SOL_SOCKET, SO_DONTLINGER, (char*)&opt, sizeof(opt));
- // }
- //
- // if (0 != rc){
- // return ret;
- // }
- //
- // int nRet = 0;
- // u_long lRet = 1;
- // nRet = ioctlsocket(conn, FIONBIO, &lRet);
- // if (SOCKET_ERROR == nRet){
- // closesocket(conn);
- // return ret;
- // }
- //
- // saccept = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
- // if (SOCKET_ERROR == saccept){
- // fd_set fdWrite;
- // FD_ZERO(&fdWrite);
- // FD_SET(conn, &fdWrite);
- // timeval time;
- // time.tv_sec = 5;
- // time.tv_usec = 0;
- //
- // int nret = select(0, NULL, &fdWrite, NULL, &time);
- // if (SOCKET_ERROR == nret){
- // closesocket(conn);
- // return ret;
- // }
- //
- // if (!FD_ISSET(conn, &fdWrite)){
- // closesocket(conn);
- // return ret;
- // }
- // else{
- // bconnect = TRUE;
- // }
- // }
- // else{
- // bconnect = TRUE;
- // }
- //
- // if (bconnect){
- // lRet = 0;
- // nRet = ioctlsocket(conn, FIONBIO, &lRet);
- // if (SOCKET_ERROR == nRet){
- // closesocket(conn);
- // return ret;
- // }
- //
- // char req_buffer[BUFFER_SIZE] = {0};
- // int idatalen = set_switch_distribute_req_buffer(req_buffer, BUFFER_SIZE, tinfo);
- // int n = send(conn, req_buffer, idatalen, 0);
- // if (n == idatalen){
- // ret = 0;
- // }
- // }
- // closesocket(conn);
- //
- // return ret;
- //}
- int endpoint_distribute_hangup(endpoint_distribute_call_info_t *tinfo)
- {
- int ret = -1;
- if (NULL == tinfo){
- return ret;
- }
- //ret = endpoint_pad_switch_interactive(tinfo);
- Dbg("endpoint_distribute_hangup call_name=%s,server_ip=%s,server_port=%d.", tinfo->call_name,tinfo->server_ip,tinfo->server_port);
- return ret;
- }
- int endpoint_call_start_video(endpoint_call_t *call, unsigned long remote_ip, int remote_video_rtp,
- unsigned long local_ip, int local_video_rtp,
- int remote_width, int remote_height,
- int local_view_x, int local_view_y, int local_view_cx, int local_view_cy,
- int remote_view_x, int remote_view_y, int remote_view_cx, int remote_view_cy,
- int local_move, int remote_move, video_session_callback_t* cb)
- {
- char local_ip_str[128]={0};
- char remtote_ip_str[128]={0};
- LOG_FUNCTION();
- translate_ipaddr_from_int(local_ip_str, 128, local_ip);
- translate_ipaddr_from_int(remtote_ip_str, 128, remote_ip);
-
- Dbg("Assist channel video local: %s:%d, remote_ip:%s:%d", local_ip_str, local_video_rtp, remtote_ip_str, remote_video_rtp);
- if (call)
- {
- int i = 0;
- media_desc_t video_desc = {0};
- video_desc.media_dir = DIR_BOTH;
- if (call->nCallType == NORMAL_CALLTYPE || call->nCallType == DOUBLERECORD_CALLTYPE)//如果是可视柜台模式,使用协助通道的协商结果
- {
- video_desc.local_ip = local_ip;
- video_desc.local_port = local_video_rtp;
- video_desc.remote_port = remote_video_rtp;
- video_desc.remote_ip = remote_ip;
- }
- else //如果是非可视柜台模式,使用SDP协商的参数
- {
- video_desc.local_ip = call->sdpvieo_desc.local_rtp_ip;
- video_desc.local_port = call->sdpvieo_desc.local_rtp_port;
- video_desc.local_pt = call->sdpvieo_desc.local_pt;
- video_desc.remote_ip = call->sdpvieo_desc.remote_rtp_ip;
- video_desc.remote_port = call->sdpvieo_desc.remote_rtp_port;
- video_desc.remote_pt = call->sdpvieo_desc.remote_pt;
- }
- video_desc.param[i++] = local_view_x;
- video_desc.param[i++] = local_view_y;
- video_desc.param[i++] = local_view_cx;
- video_desc.param[i++] = local_view_cy;
- video_desc.param[i++] = remote_view_x;
- video_desc.param[i++] = remote_view_y;
- video_desc.param[i++] = remote_view_cx;
- video_desc.param[i++] = remote_view_cy;
- video_desc.param[i++] = remote_width;
- video_desc.param[i++] = remote_height;
- //add by clp 20190823
- video_desc.param[i++] = local_move;
- video_desc.param[i++] = remote_move;
- endpoint_media_update_video(call, &video_desc, cb);
- char str_local_ip[128]={0};
- char str_remtote_ip[128]={0};
- translate_ipaddr_from_int(str_local_ip, 128,video_desc.local_ip);
- translate_ipaddr_from_int(str_remtote_ip, 128, video_desc.remote_ip);
- Dbg("start video,local video ip=%s port=%d pt=%d,remote ip=%s port=%d pt=%d",str_local_ip,video_desc.local_port,video_desc.local_pt,str_remtote_ip,video_desc.remote_port,video_desc.remote_pt);
- return 0;
- }
- else
- {
- return Error_Param;
- }
- }
- int endpoint_call_stop_video(endpoint_call_t *call)
- {
- LOG_FUNCTION();
- if (call) {
- media_desc_t video_desc = {0};
- video_desc.media_dir = DIR_NONE;
- endpoint_media_update_video(call, &video_desc,NULL);
- return 0;
- } else {
- return Error_Param;
- }
- }
- int endpoint_call_stop_double_record_broadcast_video()
- {
- LOG_FUNCTION();
- double_record_broadcast_video_session_stop();
- return Error_Succeed;
- }
- int local_play_start_video(endpoint_call_t *call,int local_view_x, int local_view_y, int local_view_cx, int local_view_cy, int local_move, video_session_callback_t* cb)
- {
- LOG_FUNCTION();
- int rc;
- BOOL bCreateAudioObject = FALSE;
- endpoint_conf_t *ep_conf = &call->ep->conf;
- if (call->video)
- {
- video_session_destroy(call->video);
- call->video = NULL;
- }
- video_session_conf_t video_conf = {0};
- video_conf.bit_rate = 256 * 1024;
- video_conf.local_rtp_ip = 0;
- video_conf.local_rtp_port = 0;
- video_conf.local_video_view_x = local_view_x;
- video_conf.local_video_view_y = local_view_y;
- video_conf.local_video_view_cx = local_view_cx;
- video_conf.local_video_view_cy = local_view_cy;
- video_conf.local_move = local_move;
- video_conf.mtu = ep_conf->mtu;
- video_conf.video_quant = ep_conf->quant;
- video_conf.remote_rtp_ip = 0;
- video_conf.remote_rtp_port = 0;
- video_conf.remote_video_view_x = 0;
- video_conf.remote_video_view_y = 0;
- video_conf.remote_video_view_cx = 0;
- video_conf.remote_video_view_cy = 0;
- video_conf.remote_video_width = 0;
- video_conf.remote_video_height = 0;
- video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
- video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
- video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
- video_conf.ref_window_state = call->ep->conf.ref_window_state;
- video_conf.ref_active_img = call->ep->conf.ref_active_img;
- video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
- video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
- video_conf.ref_Is_showRecordArea = call->ep->conf.ref_Is_showRecordArea;
- video_conf.camera_count = call->ep->conf.camera_count;
- video_conf.screen_count = call->ep->conf.screen_count;
- video_conf.eDeviceType = call->eDeviceType;
- video_conf.video_echo_cb = cb;
- video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP|VIDEOPLAYER_FLAG_ZOOMOUTSIZE;
- video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
- rc = Local_video_session_create(&video_conf, &call->video);
- if (rc != 0)
- {
- Dbg("create video session failed! rc = %d", rc);
- return -1;
- }
- rc = video_session_start(call->video);
- if (rc != 0)
- {
- Dbg("start video session failed! rc = %d", rc);
- video_session_destroy(call->video);
- call->video = NULL;
- return -1;
- }
- return 0;
- }
- int local_remote_show_video(endpoint_call_t *call,int local_view_x, int local_view_y, int local_view_cx, int local_view_cy,int remote_view_x, int remote_view_y, int remote_view_cx, int remote_view_cy, int local_move, int remote_move, video_session_callback_t* cb)
- {
- LOG_FUNCTION();
- int rc;
- BOOL bCreateAudioObject = FALSE;
- endpoint_conf_t *ep_conf = &call->ep->conf;
- if (call->video)
- {
- video_session_destroy(call->video);
- call->video = NULL;
- }
- int remote_video_width = REC_COMMON_VIDEO_SSM_AGENT_WIDTH;
- int remote_video_height = REC_COMMON_VIDEO_SSM_AGENT_HEIGHT;
- if (eStand2sType == call->eDeviceType){
- remote_video_width = REC_COMMON_VIDEO_DSM_AGENT_WIDTH;
- remote_video_height = REC_COMMON_VIDEO_DSM_AGENT_HEIGHT;
- }
- video_session_conf_t video_conf = {0};
- video_conf.bit_rate = 256 * 1024;
- video_conf.local_rtp_ip = 0;
- video_conf.local_rtp_port = 0;
- video_conf.local_video_view_x = local_view_x;
- video_conf.local_video_view_y = local_view_y;
- video_conf.local_video_view_cx = local_view_cx;
- video_conf.local_video_view_cy = local_view_cy;
- video_conf.local_move = local_move;
- video_conf.mtu = ep_conf->mtu;
- video_conf.video_quant = ep_conf->quant;
- video_conf.remote_rtp_ip = 0;
- video_conf.remote_rtp_port = 0;
- video_conf.remote_video_view_x = remote_view_x;
- video_conf.remote_video_view_y = remote_view_y;
- video_conf.remote_video_view_cx = remote_view_cx;
- video_conf.remote_video_view_cy = remote_view_cy;
- video_conf.remote_move = remote_move;
- video_conf.remote_video_width = remote_video_width;
- video_conf.remote_video_height = remote_video_height;
- video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
- video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
- video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
- video_conf.ref_window_state = call->ep->conf.ref_window_state;
- video_conf.ref_active_img = call->ep->conf.ref_active_img;
- video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
- video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
- video_conf.camera_count = call->ep->conf.camera_count;
- video_conf.screen_count = call->ep->conf.screen_count;
- video_conf.eDeviceType = call->eDeviceType;
- video_conf.video_echo_cb = cb;
- video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP;
- video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
-
- rc = Local_video_session_create(&video_conf, &call->video, true);
- if (rc != 0){
- Dbg("create video session failed! rc = %d", rc);
- return -1;
- }
- else{
- Dbg("create video session success!");
- }
- rc = video_session_start(call->video);
- if (rc != 0){
- Dbg("start video session failed! rc = %d", rc);
- video_session_destroy(call->video);
- call->video = NULL;
- return -1;
- }
- else{
- Dbg("local remote show video success start video session %0x.", call->video);
- }
- return 0;
- }
- int local_play_stop_video(endpoint_call_t *call)
- {
- if (call) {
- media_desc_t video_desc = {0};
- video_desc.media_dir = DIR_NONE;
- endpoint_media_update_video(call, &video_desc,NULL);
- return 0;
- } else
- {
- return Error_Param;
- }
- }
- static void __endpoint_call_destroy(endpoint_call_t *call)
- {
- Dbg("endpoint call destroy! home ref:%d", su_home_refcount(call->home));
- list_del(&call->entry);
- if (call->ep->active_call == call) {
- call->ep->active_call = NULL;
- }
- su_home_unref(call->home);
- }
- int translate_ipaddr_from_int(char* strdst, unsigned ulen, unsigned long uip)
- {
- int iret = -1;
- if (NULL == strdst){
- return iret;
- }
- char* pstr_ip = inet_ntoa(__lton(uip));
- size_t ulen_ip = 0;
- if (NULL != pstr_ip){
- ulen_ip = strlen(pstr_ip);
- if (ulen_ip < ulen){
- memcpy(strdst, pstr_ip, ulen_ip);
- iret = 0;
- }
- }
- return iret;
- }
- IMPLEMENT_REF_COUNT_MT_STATIC(endpoint_call, endpoint_call_t, ref_cnt, __endpoint_call_destroy)
|