endpoint.cpp 50 KB

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