endpoint.cpp 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874
  1. #ifdef RVC_OS_WIN
  2. #include "stdafx.h"
  3. #else
  4. #endif
  5. #include "endpoint.h"
  6. #include <sofia-sip/su.h>
  7. #include <sofia-sip/su_tag_class.h>
  8. #include <sofia-sip/nua.h>
  9. #include <sofia-sip/sip_status.h>
  10. #include <sofia-sip/sdp.h>
  11. #include <sofia-sip/sip_header.h>
  12. #include <sofia-sip/su_log.h>
  13. #include <sofia-sip/su_tagarg.h>
  14. #include <sofia-sip/su_tag_io.h>
  15. #include <sofia-sip/soa_tag.h>
  16. #include <sofia-sip/su_wait.h>
  17. #include <sofia-sip/nua_tag.h>
  18. #include "refcnt.h"
  19. #include "list.h"
  20. #include "sockutil.h"
  21. #include "hash.h"
  22. #include "SpBase.h"
  23. #include "video_session.h"
  24. #include "audio_session.h"
  25. #include "rec_common.h"
  26. #include "Event.h"
  27. BOOL g_IsExternalTerminalted = FALSE;
  28. // default: ptime = 20ms
  29. #define CONDITION_PARAMS \
  30. int status, \
  31. char const *phrase, \
  32. nua_t *nua, \
  33. struct endpoint_t *ep, \
  34. nua_handle_t *nh, \
  35. struct endpoint_call_t *call, \
  36. sip_t const *sip, \
  37. tagi_t tags[]
  38. // the same with rtp payload type, the same as huawei open-eye
  39. enum e_audio_rtp_pt
  40. {
  41. PCMU = 0, // 64kbps, 4.17
  42. PCMA = 8, // 64kbps, 4.11
  43. G729 = 18, // 8kbps, 3.9
  44. };
  45. enum e_video_rtp_pt
  46. {
  47. H263 = 34, // h263
  48. };
  49. enum e_media_dir
  50. {
  51. DIR_NONE = 0,
  52. DIR_TX = 1,
  53. DIR_RX = 2,
  54. DIR_BOTH = 3,
  55. };
  56. typedef struct sdpvideo_desc_t
  57. {
  58. unsigned long local_rtp_ip;
  59. int local_rtp_port;
  60. unsigned long remote_rtp_ip;
  61. int remote_rtp_port;
  62. int local_pt;
  63. int remote_pt;
  64. };
  65. typedef struct media_desc_t
  66. {
  67. unsigned long remote_ip;
  68. int remote_port;
  69. unsigned long local_ip;
  70. int local_port;
  71. int media_dir;
  72. int local_pt;
  73. int local_ptime;
  74. int remote_pt;
  75. int remote_ptime;
  76. int local_telephone_event_pt;
  77. int remote_telephone_event_pt;
  78. int param[16];
  79. }media_desc_t;
  80. // 1. how to exit
  81. struct endpoint_call_t {
  82. struct list_head entry;
  83. endpoint_call_callback_t cb;
  84. endpoint_t *ep;
  85. audio_session_t *audio;
  86. video_session_t *video;
  87. int id;
  88. su_home_t *home;
  89. nua_handle_t *nh;
  90. char *remote_uri;
  91. sdp_session_t *last_sdp;
  92. int connected;
  93. int local_media_port;
  94. int local_video_port;
  95. unsigned int last_media_desc_hash;
  96. char local_ip[256];
  97. DeviceTypeEnum eDeviceType;
  98. CallingTypeEnum nCallType;
  99. sdpvideo_desc_t sdpvieo_desc;
  100. DECLARE_REF_COUNT_MEMBER(ref_cnt);
  101. };
  102. DECLARE_REF_COUNT_STATIC(endpoint_call, endpoint_call_t)
  103. struct endpoint_t {
  104. su_home_t home[1];
  105. su_root_t *root;
  106. nua_t *nua;
  107. endpoint_call_t *active_call;
  108. #ifdef RVC_OS_WIN
  109. HANDLE event_thread;;
  110. #else
  111. pthread_t ievent_threadid;
  112. #endif
  113. int call_seq;
  114. int media_port_seq;
  115. CEntityBase *entity;
  116. struct list_head call_list;
  117. endpoint_conf_t conf;
  118. int curr_audio_dev_type; // handfree or pickup
  119. };
  120. static const char *state_desc[] = {
  121. "STATE::INIT",
  122. "STATE::CALLING",
  123. "STATE::PROCEEDING",
  124. "STATE::COMPLETING",
  125. "STATE::READY",
  126. "STATE::TERMINATING",
  127. "STATE::TERMINATED",
  128. };
  129. static const char* call_type_table[] = {
  130. "NORMAL_CALLTYPE",
  131. "PADRINGUP_CALLTYPE",
  132. "PADTOPAD_CALLTYPE",
  133. "MOBILETOPAD_CALLTYPE",
  134. "DOUBLERECORD_CALLTYPE"
  135. };
  136. #ifndef VIDEOPLAYER_FLAG_DOUBLESIZE
  137. #define VIDEOPLAYER_FLAG_DOUBLESIZE 0x01
  138. #endif
  139. #ifndef VIDEOPLAYER_FLAG_NOTIMER
  140. #define VIDEOPLAYER_FLAG_NOTIMER 0x02
  141. #endif
  142. #ifndef VIDEOPLAYER_FLAG_PUSH
  143. #define VIDEOPLAYER_FLAG_PUSH 0x04
  144. #endif
  145. #ifndef VIDEOPLAYER_FLAG_PULL
  146. #define VIDEOPLAYER_FLAG_PULL 0x08
  147. #endif
  148. #ifndef VIDEOPLAYER_FLAG_CHECKTOP
  149. #define VIDEOPLAYER_FLAG_CHECKTOP 0x10
  150. #endif
  151. #ifndef VIDEOPLAYER_FLAG_ZOOMOUTSIZE
  152. #define VIDEOPLAYER_FLAG_ZOOMOUTSIZE 0x100
  153. #endif
  154. static void endpoint_media_change_audio_dev(endpoint_call_t *call, e_dev_type current_dev_type)
  155. {
  156. LOG_FUNCTION();
  157. if (call->audio) {
  158. Dbg("begin audio_session_change_dev %d", current_dev_type);
  159. audio_session_change_dev(call->audio, current_dev_type);
  160. Dbg("end audio_session_change_dev");
  161. }
  162. }
  163. static __inline struct in_addr __lton(unsigned long ip)
  164. {
  165. struct in_addr addr;
  166. addr.s_addr = ip;
  167. return addr;
  168. }
  169. static void endpoint_media_update_video(endpoint_call_t *call, media_desc_t *video_desc, video_session_callback_t* cb)
  170. {
  171. LOG_FUNCTION();
  172. if (video_desc->media_dir == DIR_NONE)
  173. {
  174. if (call->video)
  175. {
  176. video_session_stop(call->video);
  177. video_session_destroy(call->video);
  178. call->video = NULL;
  179. }
  180. else
  181. {
  182. if (DOUBLERECORD_CALLTYPE == call->nCallType)
  183. {
  184. double_record_broadcast_video_session_stop();
  185. }
  186. }
  187. }
  188. else
  189. {
  190. int rc;
  191. BOOL bCreateAudioObject = FALSE;
  192. endpoint_conf_t *ep_conf = &call->ep->conf;
  193. if (!call->audio)
  194. {
  195. audio_session_conf_t conf = {0};
  196. strcpy(&conf.in_dev[DEV_PICKUP][0], ep_conf->audio_pickup_in_dev);
  197. strcpy(&conf.in_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_in_dev);
  198. strcpy(&conf.out_dev[DEV_PICKUP][0], ep_conf->audio_pickup_out_dev);
  199. strcpy(&conf.out_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_out_dev);
  200. conf.agc_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_agc;
  201. conf.agc_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_agc;
  202. conf.agc_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_agc;
  203. conf.agc_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_agc;
  204. conf.ns_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_ns;
  205. conf.ns_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_ns;
  206. conf.ns_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_ns;
  207. conf.ns_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_ns;
  208. conf.aec[DEV_PICKUP] = !!ep_conf->audio_pickup_aec;
  209. conf.aec[DEV_HANDFREE] = !!ep_conf->audio_handfree_aec;
  210. rc = audio_session_create(&conf, &call->audio);
  211. if (rc != 0)
  212. {
  213. Dbg("create audio session failed! rc = %d", rc);
  214. return;
  215. }
  216. bCreateAudioObject = TRUE;
  217. }
  218. audio_session_remote_recording_conf_t remote_conf = {0};
  219. remote_conf.local_rtp_ip = video_desc->local_ip;
  220. remote_conf.local_rtp_port = video_desc->local_port+2;
  221. remote_conf.ptime = REC_COMMON_AUDIO_FRAME_PTIME; // for remote recording
  222. remote_conf.remote_rtp_ip = video_desc->remote_ip;
  223. remote_conf.remote_rtp_port = video_desc->remote_port+2;
  224. rc = audio_session_start_remote_recording(call->audio, &remote_conf);
  225. if (rc != 0)
  226. {
  227. Dbg("audio_session_start_remote_recording failed! rc = %d", rc);
  228. if (bCreateAudioObject)
  229. {
  230. audio_session_destroy(call->audio);
  231. call->audio = NULL;
  232. }
  233. //return;
  234. }
  235. if (call->video) {
  236. video_session_destroy(call->video);
  237. call->video = NULL;
  238. }
  239. int i = 0;
  240. int local_view_x = video_desc->param[i++];
  241. int local_view_y = video_desc->param[i++];
  242. int local_view_cx = video_desc->param[i++];
  243. int local_view_cy = video_desc->param[i++];
  244. int remote_view_x = video_desc->param[i++];
  245. int remote_view_y = video_desc->param[i++];
  246. int remote_view_cx = video_desc->param[i++];
  247. int remote_view_cy = video_desc->param[i++];
  248. int remote_width = video_desc->param[i++];
  249. int remote_height = video_desc->param[i++];
  250. //add by clp 20190823
  251. int local_hwd_move = video_desc->param[i++];
  252. int remote_hwd_move = video_desc->param[i++];
  253. video_session_conf_t video_conf = {0};
  254. if (eMobilePadType == call->eDeviceType)
  255. {
  256. video_conf.bit_rate = 150 * 1024;
  257. }
  258. else
  259. {
  260. video_conf.bit_rate = 256 * 1024;
  261. }
  262. video_conf.local_rtp_ip = video_desc->local_ip;
  263. video_conf.local_rtp_port = video_desc->local_port;
  264. video_conf.local_video_view_x = local_view_x;
  265. video_conf.local_video_view_y = local_view_y;
  266. video_conf.local_video_view_cx = local_view_cx;
  267. video_conf.local_video_view_cy = local_view_cy;
  268. video_conf.mtu = ep_conf->mtu;
  269. video_conf.video_quant = ep_conf->quant;
  270. video_conf.remote_rtp_ip = video_desc->remote_ip;
  271. video_conf.remote_rtp_port = video_desc->remote_port;
  272. video_conf.remote_video_view_x = remote_view_x;
  273. video_conf.remote_video_view_y = remote_view_y;
  274. video_conf.remote_video_view_cx = remote_view_cx;
  275. video_conf.remote_video_view_cy = remote_view_cy;
  276. video_conf.remote_video_width = remote_width;
  277. video_conf.remote_video_height = remote_height;
  278. video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
  279. video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
  280. video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
  281. video_conf.ref_window_state = call->ep->conf.ref_window_state;
  282. video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
  283. //video_conf.ref_active_img = call->ep->conf.ref_active_img;
  284. //video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
  285. video_conf.ref_active_img = NULL;
  286. video_conf.ref_Is_ActiveInspect = NULL;
  287. video_conf.camera_count = call->ep->conf.camera_count;
  288. video_conf.screen_count = call->ep->conf.screen_count;
  289. video_conf.ref_Up_Fps = call->ep->conf.ref_Up_Fps;
  290. video_conf.eDeviceType = call->eDeviceType;
  291. video_conf.nCallType = call->nCallType;
  292. video_conf.local_move = local_hwd_move;
  293. video_conf.remote_move = remote_hwd_move;
  294. video_conf.video_echo_cb = cb;
  295. video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP;
  296. video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
  297. if (video_conf.nCallType == MOBILETOPAD_CALLTYPE ) //如果与手机连接使用标准H264
  298. {
  299. video_conf.local_pt = video_desc->local_pt;
  300. video_conf.remote_pt = video_desc->remote_pt;
  301. }
  302. else //如果与pad连接或者常规连接模式使用H264+
  303. {
  304. //huchen modify, now we use standard h264
  305. //video_conf.local_pt = REC_COMMON_VIDEO_PT;
  306. //video_conf.remote_pt = REC_COMMON_VIDEO_PT;
  307. video_conf.local_pt = REC_COMMON_VIDEO_H264_PT;
  308. video_conf.remote_pt = REC_COMMON_VIDEO_H264_PT;
  309. }
  310. rc = video_session_create(&video_conf, &call->video);
  311. if (rc != 0) {
  312. Dbg("create video session failed! rc = %d", rc);
  313. return;
  314. }
  315. else{
  316. Dbg("make remote call session addr is %0x.",call->video);
  317. }
  318. rc = video_session_start(call->video);
  319. if (rc != 0) {
  320. Dbg("start video session failed! rc = %d", rc);
  321. video_session_destroy(call->video);
  322. call->video = NULL;
  323. return;
  324. }
  325. else{
  326. Dbg("endpoint media update video, video session start suc, and session is %0x.", call->video);
  327. }
  328. }
  329. }
  330. static void endpoint_media_update_audio(endpoint_call_t *call, media_desc_t *audio_desc, int dev_type)
  331. {
  332. LOG_FUNCTION();
  333. LOG_TRACE("audio dir:%d", audio_desc->media_dir);
  334. if (audio_desc->media_dir == DIR_NONE) {
  335. if (call->audio) {
  336. LOG_TRACE("stop audio...");
  337. audio_session_stop(call->audio);
  338. audio_session_destroy(call->audio);
  339. call->audio = NULL;
  340. LOG_TRACE("stop audio ok!");
  341. }
  342. else{
  343. LOG_TRACE("call->audio is null.");
  344. }
  345. if (call->video) { // close video also
  346. LOG_TRACE("stop video...");
  347. video_session_stop(call->video);
  348. video_session_destroy(call->video);
  349. call->video = NULL;
  350. LOG_TRACE("stop video ok!");
  351. }
  352. else{
  353. LOG_TRACE("call->video is null.");
  354. }
  355. } else {
  356. int rc;
  357. if (call->audio) {
  358. LOG_TRACE("stop audio...");
  359. audio_session_stop(call->audio);
  360. audio_session_destroy(call->audio);
  361. call->audio = NULL;
  362. LOG_TRACE("stop audio ok!");
  363. }
  364. if (!call->audio) {
  365. endpoint_conf_t *ep_conf = &call->ep->conf;
  366. audio_session_conf_t conf = {0};
  367. strcpy(&conf.in_dev[DEV_PICKUP][0], ep_conf->audio_pickup_in_dev);
  368. strcpy(&conf.in_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_in_dev);
  369. strcpy(&conf.out_dev[DEV_PICKUP][0], ep_conf->audio_pickup_out_dev);
  370. strcpy(&conf.out_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_out_dev);
  371. conf.agc_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_agc;
  372. conf.agc_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_agc;
  373. conf.agc_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_agc;
  374. conf.agc_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_agc;
  375. conf.ns_in[DEV_PICKUP] = !!ep_conf->audio_pickup_in_ns;
  376. conf.ns_in[DEV_HANDFREE] = !!ep_conf->audio_handfree_in_ns;
  377. conf.ns_out[DEV_PICKUP] = !!ep_conf->audio_pickup_out_ns;
  378. conf.ns_out[DEV_HANDFREE] = !!ep_conf->audio_handfree_out_ns;
  379. conf.aec[DEV_PICKUP] = !!ep_conf->audio_pickup_aec;
  380. conf.aec[DEV_HANDFREE] = !!ep_conf->audio_handfree_aec;
  381. rc = audio_session_create(&conf, &call->audio);
  382. if (rc != 0) {
  383. Dbg("create audio session failed! rc = %d", rc);
  384. return;
  385. }
  386. }
  387. audio_session_phonemedia_conf_t phone_conf = {0};
  388. phone_conf.dir = audio_desc->media_dir;
  389. phone_conf.dev_type = (e_dev_type)dev_type;
  390. phone_conf.local_dtmf_pt = audio_desc->local_telephone_event_pt;
  391. phone_conf.local_pt = audio_desc->local_pt;
  392. phone_conf.local_ptime = audio_desc->local_ptime;
  393. phone_conf.local_rtp_ip = audio_desc->local_ip;
  394. phone_conf.local_rtp_port = audio_desc->local_port;
  395. phone_conf.remote_dtmf_pt = audio_desc->remote_telephone_event_pt;
  396. phone_conf.remote_pt = audio_desc->remote_pt;
  397. phone_conf.remote_ptime = audio_desc->remote_ptime;
  398. phone_conf.remote_rtp_ip = audio_desc->remote_ip;
  399. phone_conf.remote_rtp_port = audio_desc->remote_port;
  400. if (NULL != call){
  401. phone_conf.eCalltype = call->nCallType;
  402. phone_conf.eDeviceType = call->eDeviceType;
  403. }
  404. rc = audio_session_start_phonemedia(call->audio, &phone_conf);
  405. if (rc != 0) {
  406. Dbg("start audio session failed! rc = %d", rc);
  407. LogError(Severity_High,Error_DevMedia,ERROR_MOD_SIP_AUDIO_INITFAIL,"audio initialize fail");
  408. audio_session_destroy(call->audio);
  409. call->audio = NULL;
  410. return;
  411. }
  412. else {
  413. Dbg("start audio session success!");
  414. }
  415. }
  416. }
  417. static unsigned int __hash_media_desc(media_desc_t *media_desc, unsigned int hash_code)
  418. {
  419. if (media_desc) {
  420. hash_code += (unsigned int)media_desc->local_ip * 33;
  421. hash_code += (unsigned int)media_desc->remote_ip * 33;
  422. hash_code += (unsigned int)media_desc->local_port * 33;
  423. hash_code += (unsigned int)media_desc->remote_port * 33;
  424. hash_code += (unsigned int)media_desc->media_dir * 33;
  425. hash_code += (unsigned int)media_desc->local_pt * 33;
  426. hash_code += (unsigned int)media_desc->local_ptime * 33;
  427. hash_code += (unsigned int)media_desc->remote_pt * 33;
  428. hash_code += (unsigned int)media_desc->remote_ptime * 33;
  429. hash_code += (unsigned int)media_desc->local_telephone_event_pt * 33;
  430. hash_code += (unsigned int)media_desc->remote_telephone_event_pt * 33;
  431. }
  432. return hash_code;
  433. }
  434. static unsigned int hash_media_desc(media_desc_t *audio)
  435. {
  436. unsigned int hash_code = 0;
  437. hash_code = __hash_media_desc(audio, hash_code);
  438. return hash_code;
  439. }
  440. #define USE_ALAW 1
  441. static const char *call_make_offer(endpoint_call_t *call, char *buf, int size)
  442. {
  443. int local_audio_rtp_port = call->local_media_port;
  444. int local_video_rtp_port = call->local_video_port;
  445. int local_video_pt = REC_COMMON_VIDEO_PT;
  446. int need;
  447. const char *fmt;
  448. Dbg("make call offer,device type is %s, Call Type is %s", Device_Type_Table[call->eDeviceType], call_type_table[call->nCallType]);
  449. if ((eMobilePadType == call->eDeviceType) || (ePadtype == call->eDeviceType)||(eDesk2SType == call->eDeviceType)||(eDesk1SType==call->eDeviceType)||(eDesk2SIntegratedType==call->eDeviceType)) //pad
  450. {
  451. if (call->nCallType == MOBILETOPAD_CALLTYPE) //如果跟手机对接
  452. {
  453. local_video_pt = REC_COMMON_VIDEO_H264_PT;
  454. fmt = "c=IN IP4 %s\r\n"
  455. "m=audio %d RTP/AVP 8\r\n"
  456. "a=rtpmap:8 PCMA/8000\r\n"
  457. "a=ptime:30\r\n"
  458. "m=video %d RTP/AVP %d\r\n"
  459. "a=rtpmap:%d H264/90000\r\n";
  460. need = _scprintf(fmt, call->local_ip, local_audio_rtp_port,local_video_rtp_port, local_video_pt,local_video_pt);
  461. if (size < 0 || size > need) {
  462. sprintf(buf, fmt, call->local_ip, local_audio_rtp_port, local_video_rtp_port, local_video_pt,local_video_pt);
  463. return buf;
  464. }
  465. else {
  466. return NULL;
  467. }
  468. }
  469. else if((call->nCallType == PADRINGUP_CALLTYPE)||(call->nCallType == PADTOPAD_CALLTYPE))
  470. {
  471. fmt = "c=IN IP4 %s\r\n"
  472. "m=audio %d RTP/AVP 8\r\n"
  473. "a=rtpmap:8 PCMA/8000\r\n"
  474. "a=ptime:30\r\n"
  475. ;
  476. need = _scprintf(fmt, call->local_ip, local_audio_rtp_port);
  477. if (size < 0 || size > need) {
  478. sprintf(buf, fmt, call->local_ip, local_audio_rtp_port);
  479. return buf;
  480. }
  481. else {
  482. return NULL;
  483. }
  484. }
  485. else if(call->nCallType == NORMAL_CALLTYPE || call->nCallType == DOUBLERECORD_CALLTYPE)//如果是可视柜台模式以及外拓版
  486. {
  487. if(eMobilePadType == call->eDeviceType)
  488. {
  489. fmt = "c=IN IP4 %s\r\n"
  490. "m=audio %d RTP/AVP 18\r\n"
  491. "a=rtpmap:18 G729/8000\r\n"
  492. "a=fmtp:18 annexb=no\r\n"
  493. "a=ptime:30\r\n"
  494. ;
  495. Dbg("pad site = CMB.FLB");
  496. }
  497. else
  498. {
  499. fmt = "c=IN IP4 %s\r\n"
  500. "m=audio %d RTP/AVP 8\r\n"
  501. "a=rtpmap:8 PCMA/8000\r\n"
  502. "a=ptime:30\r\n"
  503. ;
  504. Dbg("pad site = CMB.LIB");
  505. }
  506. need = _scprintf(fmt, call->local_ip, local_audio_rtp_port);
  507. if (size < 0 || size > need) {
  508. sprintf(buf, fmt, call->local_ip, local_audio_rtp_port);
  509. return buf;
  510. }
  511. else {
  512. return NULL;
  513. }
  514. }
  515. }
  516. else //大机
  517. {
  518. fmt =
  519. "c=IN IP4 %s\r\n"
  520. #ifdef USE_ALAW
  521. "m=audio %d RTP/AVP 8\r\n"
  522. "a=rtpmap:8 PCMA/8000\r\n"
  523. "a=ptime:30\r\n"
  524. #elif defined(USE_G729)
  525. "m=audio %d RTP/AVP 18\r\n"
  526. "a=rtpmap:18 G729/8000\r\n"
  527. "a=fmtp:18 annexb=no\r\n"
  528. "a=ptime:30\r\n"
  529. #endif
  530. //"a=rtpmap:97 telephone-event/8000\r\n"
  531. //"a=fmtp:97 0-15\r\n"
  532. #ifdef USE_H263_VIDEO
  533. "m=video %d RTP/AVP 34\r\n"
  534. "a=rtpmap:34 H263/90000\r\n"
  535. "a=fmtp:34 QCIF=2 MaxBR=5040\r\n"
  536. #endif
  537. //"a=inactive\r\n" //for debug only
  538. ;
  539. Dbg("pad site != CMB.FLB");
  540. }
  541. need = _scprintf(fmt, call->local_ip, local_audio_rtp_port);
  542. if (size < 0 || size > need) {
  543. sprintf(buf, fmt, call->local_ip, local_audio_rtp_port);
  544. return buf;
  545. } else {
  546. return NULL;
  547. }
  548. }
  549. static int new_call_id(endpoint_t *ep)
  550. {
  551. return ++ep->call_seq;
  552. }
  553. static int new_media_port(endpoint_t *ep)
  554. {
  555. ep->media_port_seq += 2;
  556. if (ep->media_port_seq >= ep->conf.media_stop_port) {
  557. ep->media_port_seq = ep->conf.media_start_port;
  558. }
  559. return ep->media_port_seq;
  560. }
  561. static void handle_invite(CONDITION_PARAMS)
  562. {
  563. // we are client only, not accept in-comming call
  564. nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
  565. }
  566. static void handle_reinvite(CONDITION_PARAMS)
  567. {
  568. char sdp[512];
  569. sip_content_type_t const *ct = NULL;
  570. tl_gets(tags,
  571. SIPTAG_CONTENT_TYPE_REF(ct),
  572. TAG_END());
  573. if (ct) {
  574. call_make_offer(call, sdp, sizeof(sdp));
  575. }
  576. nua_respond(nh,
  577. SIP_200_OK,
  578. TAG_IF(ct, SOATAG_USER_SDP_STR(sdp)),
  579. TAG_IF(ct, SOATAG_AUDIO_AUX("telephone-event")),
  580. TAG_END());
  581. }
  582. static void handle_r_invite(CONDITION_PARAMS)
  583. {
  584. // nothing to do
  585. }
  586. static int dir_from_attr(const sdp_media_t *m)
  587. {
  588. int dir = DIR_NONE;
  589. if (m) {
  590. if (m->m_attributes) {
  591. static const char *ds[] = {
  592. "inactive", "sendonly", "recvonly", "sendrecv"
  593. };
  594. int i;
  595. int n = array_size(ds);
  596. for (i = 0; i < n; ++i) {
  597. sdp_attribute_t *attr = sdp_attribute_find(m->m_attributes, ds[i]);
  598. if (attr) {
  599. dir = i;
  600. break;
  601. }
  602. }
  603. if (i >= n)
  604. dir = DIR_BOTH;
  605. } else {
  606. dir = DIR_BOTH;
  607. }
  608. }
  609. return dir;
  610. }
  611. static int ptime_from_attr(const sdp_media_t *m)
  612. {
  613. int ptime = 0; // zero for default
  614. if (m) {
  615. if (m->m_attributes) {
  616. sdp_attribute_t *attr = sdp_attribute_find(m->m_attributes, "ptime");
  617. if (attr && attr->a_value) {
  618. ptime = atoi(attr->a_value);
  619. if (ptime < 0)
  620. ptime = 0;
  621. }
  622. }
  623. }
  624. return ptime;
  625. }
  626. static const sdp_rtpmap_t *find_codec(const sdp_rtpmap_t *list, const char *codec)
  627. {
  628. if (!codec)
  629. return NULL;
  630. for (;list; list=list->rm_next) {
  631. if (!_stricmp(list->rm_encoding, codec)) {
  632. break;
  633. }
  634. }
  635. return list;
  636. }
  637. static int get_telephone_event_pt(const sdp_rtpmap_t *list)
  638. {
  639. int pt = -1;
  640. const sdp_rtpmap_t *rm = find_codec(list, "telephone-event");
  641. if (rm) {
  642. pt = rm->rm_pt;
  643. }
  644. return pt;
  645. }
  646. static int get_media_direction(const sdp_media_t *lm, const sdp_media_t *rm)
  647. {
  648. int media_dir = DIR_NONE;
  649. if (rm->m_port == 0 || lm->m_port == 0) {
  650. media_dir = DIR_NONE;
  651. } else {
  652. int ldir = dir_from_attr(lm);
  653. int rdir = dir_from_attr(rm);
  654. if (ldir == DIR_NONE || rdir == DIR_NONE) {
  655. media_dir = DIR_NONE;
  656. } else if (ldir == DIR_TX || rdir == DIR_RX) {
  657. media_dir = DIR_TX;
  658. } else if (ldir == DIR_RX || rdir == DIR_TX) {
  659. media_dir = DIR_RX;
  660. } else {
  661. media_dir = DIR_BOTH;
  662. }
  663. }
  664. return media_dir;
  665. }
  666. static int negotiate_audio(endpoint_call_t *call, media_desc_t *audio_desc, const sdp_media_t *lm, const sdp_media_t *rm)
  667. {
  668. memset(audio_desc, 0, sizeof(media_desc_t));
  669. const char *local_ip;
  670. const char *remote_ip;
  671. local_ip = lm->m_connections ? lm->m_connections->c_address : lm->m_session->sdp_connection->c_address;
  672. remote_ip = rm->m_connections ? rm->m_connections->c_address : rm->m_session->sdp_connection->c_address;
  673. audio_desc->local_ip = local_ip ? inet_addr(local_ip) : 0;
  674. audio_desc->local_port = lm->m_port;
  675. audio_desc->remote_ip = remote_ip ? inet_addr(remote_ip) : 0;
  676. audio_desc->remote_port = rm->m_port;
  677. audio_desc->local_telephone_event_pt = 97;
  678. audio_desc->remote_telephone_event_pt = get_telephone_event_pt(rm->m_rtpmaps);
  679. audio_desc->local_ptime = ptime_from_attr(lm);
  680. audio_desc->remote_ptime = ptime_from_attr(rm);
  681. int pt = -1;
  682. for (sdp_rtpmap_t *t = lm->m_rtpmaps; t; t = t->rm_next) {
  683. sdp_rtpmap_t *tt = sdp_rtpmap_find_matching(rm->m_rtpmaps, t);
  684. if (tt && tt->rm_pt < 96) {
  685. pt = tt->rm_pt;
  686. break;
  687. }
  688. }
  689. audio_desc->local_pt = audio_desc->remote_pt = pt;
  690. audio_desc->media_dir = get_media_direction(lm, rm);
  691. return 0;
  692. }
  693. static int negotiate_video(endpoint_call_t *call, media_desc_t *video_desc, const sdp_media_t *lm, const sdp_media_t *rm)
  694. {
  695. memset(video_desc, 0, sizeof(media_desc_t));
  696. const char *local_ip;
  697. const char *remote_ip;
  698. local_ip = lm->m_connections ? lm->m_connections->c_address : lm->m_session->sdp_connection->c_address;
  699. remote_ip = rm->m_connections ? rm->m_connections->c_address : rm->m_session->sdp_connection->c_address;
  700. video_desc->local_ip = local_ip ? inet_addr(local_ip) : 0;
  701. video_desc->local_port = lm->m_port;
  702. video_desc->remote_ip = remote_ip ? inet_addr(remote_ip) : 0;
  703. video_desc->remote_port = rm->m_port;
  704. video_desc->local_telephone_event_pt = 97;
  705. video_desc->remote_telephone_event_pt = get_telephone_event_pt(rm->m_rtpmaps);
  706. video_desc->local_ptime = ptime_from_attr(lm);
  707. video_desc->remote_ptime = ptime_from_attr(rm);
  708. int pt = -1;
  709. for (sdp_rtpmap_t *t = lm->m_rtpmaps; t; t = t->rm_next) {
  710. sdp_rtpmap_t *tt = sdp_rtpmap_find_matching(rm->m_rtpmaps, t);
  711. if (tt) {
  712. pt = tt->rm_pt;
  713. break;
  714. }
  715. }
  716. video_desc->local_pt = video_desc->remote_pt = pt;
  717. video_desc->media_dir = get_media_direction(lm, rm);
  718. return 0;
  719. }
  720. static void negotiate_sdp(endpoint_call_t *call, const sdp_session_t *local_sdp, const sdp_session_t* remote_sdp)
  721. {
  722. LOG_FUNCTION();
  723. const sdp_media_t *lm = local_sdp->sdp_media;
  724. const sdp_media_t *rm = remote_sdp->sdp_media;
  725. media_desc_t audio_desc = {0}, video_desc = {0};
  726. int rc = -1, rv = -1;
  727. for(; lm; lm = lm->m_next)
  728. {
  729. if (0 == lm->m_port)
  730. {
  731. continue;
  732. }
  733. const sdp_media_t *rm = remote_sdp->sdp_media;
  734. for (; rm; rm = rm->m_next)
  735. {
  736. if (rm->m_type == lm->m_type)
  737. {
  738. if (sdp_media_audio == rm->m_type)
  739. {
  740. rc = negotiate_audio(call, &audio_desc, lm, rm);
  741. }
  742. if (call->nCallType != NORMAL_CALLTYPE && call->nCallType != DOUBLERECORD_CALLTYPE)
  743. {
  744. if (sdp_media_video == rm->m_type)
  745. {
  746. rv = negotiate_video(call, &video_desc, lm, rm);
  747. }
  748. }
  749. }
  750. }
  751. }
  752. if (rc == 0)
  753. {
  754. unsigned int hash_code = hash_media_desc(&audio_desc);
  755. if (hash_code != call->last_media_desc_hash)
  756. {
  757. char str_local[128] = {0};
  758. char str_remote[128] = {0};
  759. translate_ipaddr_from_int(str_local, 128, audio_desc.local_ip);
  760. translate_ipaddr_from_int(str_remote, 128, audio_desc.remote_ip);
  761. 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);
  762. endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
  763. call->last_media_desc_hash = hash_code;
  764. }
  765. }
  766. if (rv == 0)
  767. {
  768. unsigned int hash_code = hash_media_desc(&video_desc);
  769. if (hash_code != call->last_media_desc_hash)
  770. {
  771. char str_local[128] = {0};
  772. char str_remote[128] = {0};
  773. translate_ipaddr_from_int(str_local, 128, video_desc.local_ip);
  774. translate_ipaddr_from_int(str_remote, 128, video_desc.remote_ip);
  775. 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);
  776. call->sdpvieo_desc.local_pt = video_desc.local_pt;
  777. call->sdpvieo_desc.local_rtp_ip = video_desc.local_ip;
  778. call->sdpvieo_desc.local_rtp_port = video_desc.local_port;
  779. call->sdpvieo_desc.remote_pt = video_desc.remote_pt;
  780. call->sdpvieo_desc.remote_rtp_ip = video_desc.remote_ip;
  781. call->sdpvieo_desc.remote_rtp_port = video_desc.remote_port;
  782. call->last_media_desc_hash = hash_code;
  783. }
  784. }
  785. else
  786. {
  787. if (call->nCallType != NORMAL_CALLTYPE && call->nCallType != DOUBLERECORD_CALLTYPE)
  788. {
  789. Dbg("negotiate video Fail!!!");
  790. }
  791. }
  792. }
  793. static void on_state(CONDITION_PARAMS)
  794. {
  795. LOG_FUNCTION();
  796. int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
  797. int state = nua_callstate_init;
  798. const char *replaces_str = NULL;
  799. const sdp_session_t *remote_sdp = NULL;
  800. const char *remote_sdp_str = NULL;
  801. const sdp_session_t *local_sdp = NULL;
  802. const char *local_sdp_str = NULL;
  803. int st;
  804. if (!call) {
  805. nua_handle_destroy(nh);
  806. return;
  807. }
  808. if (g_IsExternalTerminalted)
  809. {
  810. return;
  811. }
  812. tl_gets(tags,
  813. NUTAG_CALLSTATE_REF(state),
  814. NUTAG_OFFER_RECV_REF(offer_recv),
  815. NUTAG_ANSWER_RECV_REF(answer_recv),
  816. NUTAG_OFFER_SENT_REF(offer_sent),
  817. NUTAG_ANSWER_SENT_REF(answer_sent),
  818. SIPTAG_REPLACES_STR_REF(replaces_str),
  819. SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str),
  820. SOATAG_LOCAL_SDP_STR_REF(local_sdp_str),
  821. TAG_END());
  822. LOG_TRACE("state = %d, offer_recv=%d, answer_recv=%d, offer_sent=%d, answer_sent=%d",
  823. state, offer_recv, answer_recv, offer_sent, answer_sent);
  824. switch (state)
  825. {
  826. case nua_callstate_calling:
  827. LOG_TRACE("nua_callstate_calling, has_local_sdp : %d, has_remote_sdp : %d", !!local_sdp_str, !!remote_sdp_str);
  828. if (local_sdp_str) {
  829. sdp_parser_t *parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
  830. assert(call->last_sdp == NULL);
  831. call->last_sdp = sdp_session_dup(call->home, sdp_session(parser));
  832. sdp_parser_free(parser);
  833. }
  834. st = CALLING;
  835. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  836. break;
  837. case nua_callstate_proceeding:
  838. LOG_TRACE("nua_callstate_proceeding, status = %d, has_local_sdp: %d, has_remote_sdp : %d", status, !!local_sdp_str, !!remote_sdp_str);
  839. st = PROCEEDING;
  840. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  841. if (remote_sdp_str) {
  842. sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  843. remote_sdp = sdp_session(parser);
  844. if (call->last_sdp) {
  845. negotiate_sdp(call, call->last_sdp, remote_sdp);
  846. su_free(call->home, call->last_sdp);
  847. call->last_sdp = NULL;
  848. }
  849. sdp_parser_free(parser);
  850. }
  851. break;
  852. case nua_callstate_completing:
  853. st = COMPLETING;
  854. LOG_TRACE("nua_callstate_completing, has_local_sdp : %d, has_remote_sdp : %d", !!local_sdp_str, !!remote_sdp_str);
  855. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  856. if (remote_sdp_str) {
  857. sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  858. remote_sdp = sdp_session(parser);
  859. if (call->last_sdp) {
  860. negotiate_sdp(call, call->last_sdp, remote_sdp);
  861. su_free(call->home, call->last_sdp);
  862. call->last_sdp = NULL;
  863. }
  864. sdp_parser_free(parser);
  865. }
  866. break;
  867. case nua_callstate_completed:
  868. LOG_TRACE("nua_callstate_completed, has_local_sdp : %d, has_remote_sdp : %d", !!local_sdp_str, !!remote_sdp_str);
  869. if (remote_sdp_str) {
  870. if (!call->last_sdp) {
  871. sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  872. call->last_sdp = sdp_session_dup(call->home, sdp_session(parser));
  873. sdp_parser_free(parser);
  874. }
  875. }
  876. if (local_sdp_str) {
  877. if (call->last_sdp) {
  878. sdp_parser_t *parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
  879. local_sdp = sdp_session(parser);
  880. negotiate_sdp(call, local_sdp, call->last_sdp);
  881. su_free(call->home, call->last_sdp);
  882. call->last_sdp = NULL;
  883. sdp_parser_free(parser);
  884. }
  885. }
  886. break;
  887. case nua_callstate_ready:
  888. call->connected = true;
  889. LOG_TRACE("nua_callstate_ready, has_local_sdp : %d, has_remote_sdp : %d.", !!local_sdp_str, !!remote_sdp_str);
  890. st = READY;
  891. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  892. if (remote_sdp_str) {
  893. sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  894. remote_sdp = sdp_session(parser);
  895. if (call->last_sdp) {
  896. negotiate_sdp(call, call->last_sdp, remote_sdp);
  897. su_free(call->home, call->last_sdp);
  898. call->last_sdp = NULL;
  899. }
  900. sdp_parser_free(parser);
  901. }
  902. #if 0
  903. if (remote_sdp_str) {
  904. sdp_parser_t *parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  905. remote_sdp = sdp_session(parser);
  906. negotiate_sdp(call, call->last_sdp, remote_sdp);
  907. sdp_parser_free(parser);
  908. } else if (local_sdp_str) {
  909. sdp_parser_t *parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
  910. local_sdp = sdp_session(parser);
  911. negotiate_sdp(call, local_sdp, call->last_sdp);
  912. sdp_parser_free(parser);
  913. }
  914. #endif
  915. break;
  916. case nua_callstate_terminated:
  917. st = TERMINATED;
  918. LOG_TRACE("call terminated! in sofia thread!");
  919. {
  920. media_desc_t audio_desc = {0};
  921. audio_desc.media_dir = DIR_NONE;
  922. endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
  923. }
  924. Dbg("%s:%d", __FUNCTION__, __LINE__);
  925. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  926. Dbg("%s:%d", __FUNCTION__, __LINE__);
  927. nua_handle_bind(nh, NULL);
  928. Dbg("%s:%d", __FUNCTION__, __LINE__);
  929. nua_handle_destroy(nh);
  930. Dbg("%s:%d call = 0x%0x", __FUNCTION__, __LINE__, call);
  931. call->nh = NULL;
  932. Dbg("%s:%d", __FUNCTION__, __LINE__);
  933. break;
  934. }
  935. }
  936. void Terminatedcall(endpoint_call_t *call)
  937. {
  938. int st = TERMINATED;
  939. g_IsExternalTerminalted = TRUE;
  940. Dbg("g_IsExternalTerminalted = TRUE");
  941. LOG_TRACE("terminated! by timeout!");
  942. {
  943. media_desc_t audio_desc = {0};
  944. audio_desc.media_dir = DIR_NONE;
  945. endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
  946. }
  947. }
  948. static void endpoint_callback(nua_event_t event,
  949. int status,
  950. char const *phrase,
  951. nua_t *nua,
  952. nua_magic_t *magic,
  953. nua_handle_t *nh,
  954. nua_hmagic_t *hmagic,
  955. sip_t const *sip,
  956. tagi_t tags[])
  957. {
  958. LOG_FUNCTION();
  959. switch (event)
  960. {
  961. if (!g_IsExternalTerminalted)
  962. {
  963. case nua_i_invite:
  964. if (hmagic == NULL) {
  965. handle_invite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  966. } else {
  967. LOG_TRACE("reinvite!");
  968. handle_reinvite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  969. }
  970. break;
  971. case nua_r_invite:
  972. handle_r_invite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  973. break;
  974. case nua_i_bye:
  975. //.....
  976. LOG_TRACE("nua_i_bye");
  977. break;
  978. case nua_i_info:
  979. LOG_TRACE("nua_i_info");
  980. break;
  981. case nua_i_state:
  982. on_state(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  983. break;
  984. case nua_i_active:
  985. LOG_TRACE("nua_i_active");
  986. break;
  987. case nua_i_options:
  988. //nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SOATAG_USER_SDP_STR(NULL), TAG_END());
  989. nua_respond(nh, SIP_200_OK, TAG_END());
  990. break;
  991. case nua_r_cancel:
  992. LOG_TRACE("nua_r_cancel");
  993. if (status > 300) {
  994. nua_bye(nh, TAG_END());
  995. }
  996. break;
  997. case nua_i_prack:
  998. LOG_TRACE("nua_i_prack");
  999. case nua_r_prack:
  1000. LOG_TRACE("nua_r_prack");
  1001. break;
  1002. case nua_r_bye:
  1003. //LOG_TRACE("nua_r_bye");
  1004. if (status > 300) {
  1005. nua_bye(nh, TAG_END());
  1006. }
  1007. break;
  1008. /* and so on ... */
  1009. default:
  1010. if (status > 100) { /* unknown event -> print out error message */
  1011. LOG_TRACE("unknown event %d: %03d %s.",
  1012. event,
  1013. status,
  1014. phrase);
  1015. } else {
  1016. LOG_TRACE("unknown event %d.", event);
  1017. }
  1018. break;
  1019. }
  1020. }
  1021. if (!hmagic)
  1022. {
  1023. nua_handle_destroy(nh);
  1024. return;
  1025. }
  1026. }
  1027. #ifdef RVC_OS_WIN
  1028. static unsigned int __stdcall __event_thread(void* arg)
  1029. #else
  1030. void* __event_thread(void* arg)
  1031. #endif
  1032. {
  1033. LOG_FUNCTION();
  1034. endpoint_t *ep = (endpoint_t *)arg;
  1035. ep->entity->GetFunction()->InitLogCurrentThread();
  1036. #ifdef RVC_OS_WIN
  1037. CoInitialize(NULL);
  1038. #else
  1039. #endif // RVC_OS_WIN
  1040. ep->root = su_root_create(ep);
  1041. ep->nua = nua_create(ep->root,
  1042. &endpoint_callback,
  1043. ep,
  1044. NUTAG_URL(ep->conf.uri),
  1045. TAG_END());
  1046. Dbg("%s:%d", __FUNCTION__, __LINE__);
  1047. nua_set_params(ep->nua,
  1048. SIPTAG_ALLOW_STR("INVITE,CANCEL,BYE,ACK,INFO,OPTIONS"),
  1049. NUTAG_AUTOALERT(1),
  1050. NUTAG_ALLOW("PRACK"),
  1051. NUTAG_EARLY_MEDIA(1),
  1052. NUTAG_SESSION_TIMER(1),
  1053. NUTAG_AUTOANSWER(0),
  1054. NUTAG_AUTOACK(1),
  1055. NTATAG_SIP_T1X64(8000),
  1056. TAG_NULL());
  1057. Dbg("%s:%d", __FUNCTION__, __LINE__);
  1058. su_root_run(ep->root);
  1059. Dbg("%s:%d", __FUNCTION__, __LINE__);
  1060. nua_shutdown(ep->nua);
  1061. Dbg("%s:%d", __FUNCTION__, __LINE__);
  1062. ep->nua = NULL;
  1063. Dbg("%s:%d", __FUNCTION__, __LINE__);
  1064. su_root_destroy(ep->root);
  1065. Dbg("%s:%d", __FUNCTION__, __LINE__);
  1066. ep->root = NULL;
  1067. Dbg("%s:%d", __FUNCTION__, __LINE__);
  1068. #ifdef RVC_OS_WIN
  1069. CoUninitialize();
  1070. #else
  1071. #endif // RVC_OS_WIN
  1072. return 0;
  1073. }
  1074. static int __endpoint_break(void *arg)
  1075. {
  1076. endpoint_t *ep = (endpoint_t *)arg;
  1077. //.....nua_shutdown
  1078. su_root_break(ep->root);
  1079. return 0;
  1080. }
  1081. #ifdef RVC_OS_WIN
  1082. #else
  1083. unsigned long GetTickCount()
  1084. {
  1085. struct timespec ts;
  1086. clock_gettime(CLOCK_MONOTONIC, &ts);
  1087. return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
  1088. }
  1089. #endif
  1090. static endpoint_t *__endpoint_create(CEntityBase *pEntity, const endpoint_conf_t *conf,int nDev)
  1091. {
  1092. LOG_FUNCTION();
  1093. endpoint_t *ep;
  1094. ep = ZALLOC_T(endpoint_t);
  1095. su_home_init(ep->home);
  1096. memcpy(&ep->conf, conf, sizeof(endpoint_conf_t));
  1097. ep->media_port_seq = (conf->media_start_port + (GetTickCount() % (conf->media_stop_port - conf->media_start_port))) & 0xfffc;
  1098. ep->entity = pEntity;
  1099. ep->call_seq = GetTickCount();
  1100. ep->curr_audio_dev_type = nDev;
  1101. INIT_LIST_HEAD(&ep->call_list);
  1102. return ep;
  1103. }
  1104. static void __endpoint_destroy(endpoint_t *ep)\
  1105. {
  1106. su_root_destroy(ep->root);
  1107. su_home_deinit(ep->home);
  1108. free(ep);
  1109. }
  1110. static int __endpoint_start(endpoint_t *ep)
  1111. {
  1112. LOG_FUNCTION();
  1113. #ifdef RVC_OS_WIN
  1114. ep->event_thread = (HANDLE)_beginthreadex(NULL, 0, &__event_thread, ep, 0, NULL);
  1115. if (ep->event_thread)
  1116. {
  1117. while (!ep->root)
  1118. {
  1119. DWORD dwRet = WaitForSingleObject(ep->event_thread, 1);
  1120. if (dwRet == WAIT_OBJECT_0)
  1121. {
  1122. CloseHandle(ep->event_thread);
  1123. ep->event_thread = NULL;
  1124. break;
  1125. }
  1126. }
  1127. }
  1128. return ep->event_thread ? 0 : -1;
  1129. #else
  1130. int err = pthread_create(&ep->ievent_threadid, NULL, __event_thread, ep);
  1131. if (0 == err) {
  1132. Dbg("create event thread success, %lu.", ep->ievent_threadid);
  1133. struct timespec ts;
  1134. Dbg("before circle ep->root = 0x%0x", ep->root);
  1135. while (!ep->root) {
  1136. clock_gettime(CLOCK_REALTIME, &ts);
  1137. ts.tv_nsec += 1000 * 1000;
  1138. if (0 == pthread_timedjoin_np(ep->ievent_threadid, NULL, &ts)) {
  1139. ep->ievent_threadid = 0;
  1140. Dbg("__event_thread exit break");
  1141. break;
  1142. }
  1143. }
  1144. Dbg("break circle ep->root = 0x%0x", ep->root);
  1145. }
  1146. else {
  1147. Dbg("create event thread failed.");
  1148. }
  1149. return ep->ievent_threadid > 0 ? 0 : -1;
  1150. #endif
  1151. }
  1152. static void __endpoint_stop(endpoint_t *ep)
  1153. {
  1154. #ifdef RVC_OS_WIN
  1155. if (ep->event_thread)
  1156. {
  1157. int rc;
  1158. su_task_execute(su_root_task(ep->root), &__endpoint_break, ep, &rc);
  1159. WaitForSingleObject(ep->event_thread, INFINITE);
  1160. CloseHandle(ep->event_thread);
  1161. ep->event_thread = NULL;
  1162. }
  1163. #else
  1164. if (ep->ievent_threadid > 0)
  1165. {
  1166. int rc;
  1167. su_task_execute(su_root_task(ep->root), &__endpoint_break, ep, &rc);
  1168. pthread_join(ep->ievent_threadid, NULL);
  1169. ep->ievent_threadid = 0;
  1170. }
  1171. #endif
  1172. }
  1173. int endpoint_init_lib()
  1174. {
  1175. return su_init();
  1176. }
  1177. void endpoint_deinit_lib()
  1178. {
  1179. su_deinit();
  1180. }
  1181. endpoint_t *endpoint_create(CEntityBase *pEntity, const endpoint_conf_t *conf,int nDev)
  1182. {
  1183. LOG_FUNCTION();
  1184. endpoint_t *endpt;
  1185. endpt = __endpoint_create(pEntity, conf,nDev);
  1186. if (endpt) {
  1187. int rc = __endpoint_start(endpt);
  1188. if (rc != 0)
  1189. {
  1190. __endpoint_destroy(endpt);
  1191. endpt = NULL;
  1192. }
  1193. }
  1194. return endpt;
  1195. }
  1196. void endpoint_destroy(endpoint_t *ep)
  1197. {
  1198. LOG_FUNCTION();
  1199. if (ep)
  1200. {
  1201. __endpoint_stop(ep);
  1202. __endpoint_destroy(ep);
  1203. }
  1204. }
  1205. int endpoint_invoke(endpoint_t *ep, int (*func)(void*), void *user_data, int *result)
  1206. {
  1207. return su_task_execute(su_root_task(ep->root), func, user_data, result);
  1208. }
  1209. void endpoint_change_audio_dev(endpoint_t *ep, int dev_type)
  1210. {
  1211. LOG_FUNCTION();
  1212. if (ep->curr_audio_dev_type != dev_type) {
  1213. ep->curr_audio_dev_type = dev_type;
  1214. if (ep->active_call) {
  1215. Dbg("begin invoke media change audio device!");
  1216. endpoint_media_change_audio_dev(ep->active_call, (e_dev_type)dev_type);
  1217. Dbg("end invoke media change audio device!");
  1218. } else {
  1219. Dbg("active call is null!");
  1220. }
  1221. } else {
  1222. Dbg("current dev_type is the same as dev_type!");
  1223. }
  1224. }
  1225. 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)
  1226. {
  1227. LOG_FUNCTION();
  1228. endpoint_call_t *call = NULL;
  1229. su_home_t *home = NULL;
  1230. if (!remote_uri)
  1231. return NULL;
  1232. home = su_home_create();
  1233. if (!home)
  1234. goto on_error;
  1235. call = (endpoint_call_t*)su_home_new(sizeof(endpoint_call_t));
  1236. if (!call)
  1237. goto on_error;
  1238. memset(call, 0, sizeof(endpoint_call_t));
  1239. call->connected = 0;
  1240. call->ep = ep;
  1241. call->home = home;
  1242. call->last_media_desc_hash = 0;
  1243. call->remote_uri = su_strdup(home, remote_uri);
  1244. memcpy(call->local_ip,local_ip,256);
  1245. call->eDeviceType = nDeviceType;
  1246. call->nCallType = nCallType;
  1247. Dbg("endpoint_call_create nCallType = %d.", nCallType);
  1248. memcpy(&call->cb, cb, sizeof(endpoint_call_callback_t));
  1249. call->id = new_call_id(ep);
  1250. call->local_media_port = new_media_port(ep);
  1251. call->local_video_port = REC_COMMON_VIDEO_PORT;
  1252. REF_COUNT_INIT(&call->ref_cnt);
  1253. list_add_tail(&call->entry, &ep->call_list);
  1254. ep->active_call = call;
  1255. return call;
  1256. on_error:
  1257. if (home)
  1258. su_home_unref(home);
  1259. return call;
  1260. }
  1261. void endpoint_call_destroy(endpoint_call_t *call)
  1262. {
  1263. LOG_FUNCTION();
  1264. endpoint_call_dec_ref(call);
  1265. }
  1266. int endpoint_call_start(endpoint_call_t *call)
  1267. {
  1268. LOG_FUNCTION();
  1269. char sdp[512] = {0};
  1270. if (call->nh)
  1271. return -1;
  1272. call->nh = nua_handle(call->ep->nua,
  1273. call,
  1274. SIPTAG_FROM_STR(call->ep->conf.uri),
  1275. SIPTAG_TO_STR(call->remote_uri),
  1276. TAG_END());
  1277. Dbg("uri is %s.", call->ep->conf.uri);
  1278. Dbg("call remote_uri is %s.", call->remote_uri);
  1279. call_make_offer(call, sdp, -1);
  1280. Dbg("sdp is %s", sdp);
  1281. nua_invite(call->nh,
  1282. //NUTAG_URL(call->remote_uri),
  1283. SOATAG_USER_SDP_STR(sdp),
  1284. NUTAG_SESSION_TIMER(20000),
  1285. //SOATAG_AUDIO_AUX("telephone-event"),
  1286. TAG_END());
  1287. return 0;
  1288. }
  1289. int endpoint_call_hangup(endpoint_call_t *call)
  1290. {
  1291. LOG_FUNCTION();
  1292. if (call->nh) {
  1293. if (call->connected) {
  1294. nua_bye(call->nh, NUTAG_SESSION_TIMER(8000),TAG_END());
  1295. } else {
  1296. nua_cancel(call->nh, NUTAG_SESSION_TIMER(8000),TAG_END());
  1297. }
  1298. }
  1299. return 0;
  1300. }
  1301. int set_switch_distribute_req_buffer(char* pbuffer, size_t ulen, endpoint_distribute_call_info_t *tinfo)
  1302. {
  1303. int ret = 0;
  1304. if (!tinfo){
  1305. return ret;
  1306. }
  1307. int ilen = sizeof(unsigned int);
  1308. char* pindex = pbuffer + ilen;
  1309. memcpy(pindex, &tinfo->etype, ilen);
  1310. pindex += ilen;
  1311. if (tinfo->call_name){
  1312. unsigned int callname_len = strlen(tinfo->call_name);
  1313. memcpy(pindex, &callname_len, ilen);
  1314. pindex += ilen;
  1315. memcpy(pindex, tinfo->call_name, callname_len);
  1316. pindex += callname_len;
  1317. }
  1318. int actlen = pindex - pbuffer;
  1319. if (actlen < ulen)
  1320. {
  1321. memcpy(pbuffer, &actlen, ilen);
  1322. ret = actlen;
  1323. }
  1324. return ret;
  1325. }
  1326. #ifndef BUFFER_SIZE
  1327. #define BUFFER_SIZE 256
  1328. #endif
  1329. //int endpoint_pad_switch_interactive(endpoint_distribute_call_info_t *tinfo)
  1330. //{
  1331. // int ret = -1;
  1332. // SOCKET conn = INVALID_SOCKET;
  1333. // struct sockaddr_in addr = {0};
  1334. // int rc = -1;
  1335. // BOOL opt = TRUE;
  1336. // int saccept = -1;
  1337. // BOOL bconnect = FALSE;
  1338. // // try connect to switch server
  1339. // if (NULL== tinfo){
  1340. // return ret;
  1341. // }
  1342. //
  1343. // addr.sin_family = AF_INET;
  1344. // addr.sin_port = htons(tinfo->server_port);
  1345. // addr.sin_addr.s_addr = inet_addr(tinfo->server_ip);//strtoul(config->switch_server, NULL, 10);
  1346. //
  1347. // conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  1348. // if (INVALID_SOCKET == conn){
  1349. // return ret;
  1350. // }
  1351. // rc = setsockopt(conn, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
  1352. // opt = TRUE;
  1353. // if (rc == 0){
  1354. // rc = setsockopt(conn, SOL_SOCKET, SO_DONTLINGER, (char*)&opt, sizeof(opt));
  1355. // }
  1356. //
  1357. // if (0 != rc){
  1358. // return ret;
  1359. // }
  1360. //
  1361. // int nRet = 0;
  1362. // u_long lRet = 1;
  1363. // nRet = ioctlsocket(conn, FIONBIO, &lRet);
  1364. // if (SOCKET_ERROR == nRet){
  1365. // closesocket(conn);
  1366. // return ret;
  1367. // }
  1368. //
  1369. // saccept = connect(conn, (struct sockaddr*)&addr, sizeof(addr));
  1370. // if (SOCKET_ERROR == saccept){
  1371. // fd_set fdWrite;
  1372. // FD_ZERO(&fdWrite);
  1373. // FD_SET(conn, &fdWrite);
  1374. // timeval time;
  1375. // time.tv_sec = 5;
  1376. // time.tv_usec = 0;
  1377. //
  1378. // int nret = select(0, NULL, &fdWrite, NULL, &time);
  1379. // if (SOCKET_ERROR == nret){
  1380. // closesocket(conn);
  1381. // return ret;
  1382. // }
  1383. //
  1384. // if (!FD_ISSET(conn, &fdWrite)){
  1385. // closesocket(conn);
  1386. // return ret;
  1387. // }
  1388. // else{
  1389. // bconnect = TRUE;
  1390. // }
  1391. // }
  1392. // else{
  1393. // bconnect = TRUE;
  1394. // }
  1395. //
  1396. // if (bconnect){
  1397. // lRet = 0;
  1398. // nRet = ioctlsocket(conn, FIONBIO, &lRet);
  1399. // if (SOCKET_ERROR == nRet){
  1400. // closesocket(conn);
  1401. // return ret;
  1402. // }
  1403. //
  1404. // char req_buffer[BUFFER_SIZE] = {0};
  1405. // int idatalen = set_switch_distribute_req_buffer(req_buffer, BUFFER_SIZE, tinfo);
  1406. // int n = send(conn, req_buffer, idatalen, 0);
  1407. // if (n == idatalen){
  1408. // ret = 0;
  1409. // }
  1410. // }
  1411. // closesocket(conn);
  1412. //
  1413. // return ret;
  1414. //}
  1415. int endpoint_distribute_hangup(endpoint_distribute_call_info_t *tinfo)
  1416. {
  1417. int ret = -1;
  1418. if (NULL == tinfo){
  1419. return ret;
  1420. }
  1421. //ret = endpoint_pad_switch_interactive(tinfo);
  1422. Dbg("endpoint_distribute_hangup call_name=%s,server_ip=%s,server_port=%d.", tinfo->call_name,tinfo->server_ip,tinfo->server_port);
  1423. return ret;
  1424. }
  1425. int endpoint_call_start_video(endpoint_call_t *call, unsigned long remote_ip, int remote_video_rtp,
  1426. unsigned long local_ip, int local_video_rtp,
  1427. int remote_width, int remote_height,
  1428. int local_view_x, int local_view_y, int local_view_cx, int local_view_cy,
  1429. int remote_view_x, int remote_view_y, int remote_view_cx, int remote_view_cy,
  1430. int local_move, int remote_move, video_session_callback_t* cb)
  1431. {
  1432. char local_ip_str[128]={0};
  1433. char remtote_ip_str[128]={0};
  1434. LOG_FUNCTION();
  1435. translate_ipaddr_from_int(local_ip_str, 128, local_ip);
  1436. translate_ipaddr_from_int(remtote_ip_str, 128, remote_ip);
  1437. Dbg("Assist channel video local: %s:%d, remote_ip:%s:%d", local_ip_str, local_video_rtp, remtote_ip_str, remote_video_rtp);
  1438. if (call)
  1439. {
  1440. int i = 0;
  1441. media_desc_t video_desc = {0};
  1442. video_desc.media_dir = DIR_BOTH;
  1443. if (call->nCallType == NORMAL_CALLTYPE || call->nCallType == DOUBLERECORD_CALLTYPE)//如果是可视柜台模式,使用协助通道的协商结果
  1444. {
  1445. video_desc.local_ip = local_ip;
  1446. video_desc.local_port = local_video_rtp;
  1447. video_desc.remote_port = remote_video_rtp;
  1448. video_desc.remote_ip = remote_ip;
  1449. }
  1450. else //如果是非可视柜台模式,使用SDP协商的参数
  1451. {
  1452. video_desc.local_ip = call->sdpvieo_desc.local_rtp_ip;
  1453. video_desc.local_port = call->sdpvieo_desc.local_rtp_port;
  1454. video_desc.local_pt = call->sdpvieo_desc.local_pt;
  1455. video_desc.remote_ip = call->sdpvieo_desc.remote_rtp_ip;
  1456. video_desc.remote_port = call->sdpvieo_desc.remote_rtp_port;
  1457. video_desc.remote_pt = call->sdpvieo_desc.remote_pt;
  1458. }
  1459. video_desc.param[i++] = local_view_x;
  1460. video_desc.param[i++] = local_view_y;
  1461. video_desc.param[i++] = local_view_cx;
  1462. video_desc.param[i++] = local_view_cy;
  1463. video_desc.param[i++] = remote_view_x;
  1464. video_desc.param[i++] = remote_view_y;
  1465. video_desc.param[i++] = remote_view_cx;
  1466. video_desc.param[i++] = remote_view_cy;
  1467. video_desc.param[i++] = remote_width;
  1468. video_desc.param[i++] = remote_height;
  1469. //add by clp 20190823
  1470. video_desc.param[i++] = local_move;
  1471. video_desc.param[i++] = remote_move;
  1472. endpoint_media_update_video(call, &video_desc, cb);
  1473. char str_local_ip[128]={0};
  1474. char str_remtote_ip[128]={0};
  1475. translate_ipaddr_from_int(str_local_ip, 128,video_desc.local_ip);
  1476. translate_ipaddr_from_int(str_remtote_ip, 128, video_desc.remote_ip);
  1477. 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);
  1478. return 0;
  1479. }
  1480. else
  1481. {
  1482. return Error_Param;
  1483. }
  1484. }
  1485. int endpoint_call_stop_video(endpoint_call_t *call)
  1486. {
  1487. LOG_FUNCTION();
  1488. if (call) {
  1489. media_desc_t video_desc = {0};
  1490. video_desc.media_dir = DIR_NONE;
  1491. endpoint_media_update_video(call, &video_desc,NULL);
  1492. return 0;
  1493. } else {
  1494. return Error_Param;
  1495. }
  1496. }
  1497. int endpoint_call_stop_double_record_broadcast_video()
  1498. {
  1499. LOG_FUNCTION();
  1500. double_record_broadcast_video_session_stop();
  1501. return Error_Succeed;
  1502. }
  1503. 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)
  1504. {
  1505. LOG_FUNCTION();
  1506. int rc;
  1507. BOOL bCreateAudioObject = FALSE;
  1508. endpoint_conf_t *ep_conf = &call->ep->conf;
  1509. if (call->video)
  1510. {
  1511. video_session_destroy(call->video);
  1512. call->video = NULL;
  1513. }
  1514. video_session_conf_t video_conf = {0};
  1515. video_conf.bit_rate = 256 * 1024;
  1516. video_conf.local_rtp_ip = 0;
  1517. video_conf.local_rtp_port = 0;
  1518. video_conf.local_video_view_x = local_view_x;
  1519. video_conf.local_video_view_y = local_view_y;
  1520. video_conf.local_video_view_cx = local_view_cx;
  1521. video_conf.local_video_view_cy = local_view_cy;
  1522. video_conf.local_move = local_move;
  1523. video_conf.mtu = ep_conf->mtu;
  1524. video_conf.video_quant = ep_conf->quant;
  1525. video_conf.remote_rtp_ip = 0;
  1526. video_conf.remote_rtp_port = 0;
  1527. video_conf.remote_video_view_x = 0;
  1528. video_conf.remote_video_view_y = 0;
  1529. video_conf.remote_video_view_cx = 0;
  1530. video_conf.remote_video_view_cy = 0;
  1531. video_conf.remote_video_width = 0;
  1532. video_conf.remote_video_height = 0;
  1533. video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
  1534. video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
  1535. video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
  1536. video_conf.ref_window_state = call->ep->conf.ref_window_state;
  1537. video_conf.ref_active_img = call->ep->conf.ref_active_img;
  1538. video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
  1539. video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
  1540. video_conf.ref_Is_showRecordArea = call->ep->conf.ref_Is_showRecordArea;
  1541. video_conf.camera_count = call->ep->conf.camera_count;
  1542. video_conf.screen_count = call->ep->conf.screen_count;
  1543. video_conf.eDeviceType = call->eDeviceType;
  1544. video_conf.video_echo_cb = cb;
  1545. video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP|VIDEOPLAYER_FLAG_ZOOMOUTSIZE;
  1546. video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
  1547. rc = Local_video_session_create(&video_conf, &call->video);
  1548. if (rc != 0)
  1549. {
  1550. Dbg("create video session failed! rc = %d", rc);
  1551. return -1;
  1552. }
  1553. rc = video_session_start(call->video);
  1554. if (rc != 0)
  1555. {
  1556. Dbg("start video session failed! rc = %d", rc);
  1557. video_session_destroy(call->video);
  1558. call->video = NULL;
  1559. return -1;
  1560. }
  1561. return 0;
  1562. }
  1563. 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)
  1564. {
  1565. LOG_FUNCTION();
  1566. int rc;
  1567. BOOL bCreateAudioObject = FALSE;
  1568. endpoint_conf_t *ep_conf = &call->ep->conf;
  1569. if (call->video)
  1570. {
  1571. video_session_destroy(call->video);
  1572. call->video = NULL;
  1573. }
  1574. int remote_video_width = REC_COMMON_VIDEO_SSM_AGENT_WIDTH;
  1575. int remote_video_height = REC_COMMON_VIDEO_SSM_AGENT_HEIGHT;
  1576. if (eStand2sType == call->eDeviceType){
  1577. remote_video_width = REC_COMMON_VIDEO_DSM_AGENT_WIDTH;
  1578. remote_video_height = REC_COMMON_VIDEO_DSM_AGENT_HEIGHT;
  1579. }
  1580. video_session_conf_t video_conf = {0};
  1581. video_conf.bit_rate = 256 * 1024;
  1582. video_conf.local_rtp_ip = 0;
  1583. video_conf.local_rtp_port = 0;
  1584. video_conf.local_video_view_x = local_view_x;
  1585. video_conf.local_video_view_y = local_view_y;
  1586. video_conf.local_video_view_cx = local_view_cx;
  1587. video_conf.local_video_view_cy = local_view_cy;
  1588. video_conf.local_move = local_move;
  1589. video_conf.mtu = ep_conf->mtu;
  1590. video_conf.video_quant = ep_conf->quant;
  1591. video_conf.remote_rtp_ip = 0;
  1592. video_conf.remote_rtp_port = 0;
  1593. video_conf.remote_video_view_x = remote_view_x;
  1594. video_conf.remote_video_view_y = remote_view_y;
  1595. video_conf.remote_video_view_cx = remote_view_cx;
  1596. video_conf.remote_video_view_cy = remote_view_cy;
  1597. video_conf.remote_move = remote_move;
  1598. video_conf.remote_video_width = remote_video_width;
  1599. video_conf.remote_video_height = remote_video_height;
  1600. video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
  1601. video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
  1602. video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
  1603. video_conf.ref_window_state = call->ep->conf.ref_window_state;
  1604. video_conf.ref_active_img = call->ep->conf.ref_active_img;
  1605. video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
  1606. video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
  1607. video_conf.camera_count = call->ep->conf.camera_count;
  1608. video_conf.screen_count = call->ep->conf.screen_count;
  1609. video_conf.eDeviceType = call->eDeviceType;
  1610. video_conf.video_echo_cb = cb;
  1611. video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP;
  1612. video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
  1613. rc = Local_video_session_create(&video_conf, &call->video, true);
  1614. if (rc != 0){
  1615. Dbg("create video session failed! rc = %d", rc);
  1616. return -1;
  1617. }
  1618. else{
  1619. Dbg("create video session success!");
  1620. }
  1621. rc = video_session_start(call->video);
  1622. if (rc != 0){
  1623. Dbg("start video session failed! rc = %d", rc);
  1624. video_session_destroy(call->video);
  1625. call->video = NULL;
  1626. return -1;
  1627. }
  1628. else{
  1629. Dbg("local remote show video success start video session %0x.", call->video);
  1630. }
  1631. return 0;
  1632. }
  1633. int local_play_stop_video(endpoint_call_t *call)
  1634. {
  1635. if (call) {
  1636. media_desc_t video_desc = {0};
  1637. video_desc.media_dir = DIR_NONE;
  1638. endpoint_media_update_video(call, &video_desc,NULL);
  1639. return 0;
  1640. } else
  1641. {
  1642. return Error_Param;
  1643. }
  1644. }
  1645. static void __endpoint_call_destroy(endpoint_call_t *call)
  1646. {
  1647. Dbg("endpoint call destroy! home ref:%d", su_home_refcount(call->home));
  1648. list_del(&call->entry);
  1649. if (call->ep->active_call == call) {
  1650. call->ep->active_call = NULL;
  1651. }
  1652. su_home_unref(call->home);
  1653. }
  1654. int translate_ipaddr_from_int(char* strdst, unsigned ulen, unsigned long uip)
  1655. {
  1656. int iret = -1;
  1657. if (NULL == strdst){
  1658. return iret;
  1659. }
  1660. char* pstr_ip = inet_ntoa(__lton(uip));
  1661. size_t ulen_ip = 0;
  1662. if (NULL != pstr_ip){
  1663. ulen_ip = strlen(pstr_ip);
  1664. if (ulen_ip < ulen){
  1665. memcpy(strdst, pstr_ip, ulen_ip);
  1666. iret = 0;
  1667. }
  1668. }
  1669. return iret;
  1670. }
  1671. IMPLEMENT_REF_COUNT_MT_STATIC(endpoint_call, endpoint_call_t, ref_cnt, __endpoint_call_destroy)