endpoint.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575
  1. #include "stdafx.h"
  2. #include "endpoint.h"
  3. #include <ObjBase.h>
  4. #include <sofia-sip/su.h>
  5. #include <sofia-sip/su_tag_class.h>
  6. #include <sofia-sip/nua.h>
  7. #include <sofia-sip/sip_status.h>
  8. #include <sofia-sip/sdp.h>
  9. #include <sofia-sip/sip_header.h>
  10. #include <sofia-sip/su_log.h>
  11. #include <sofia-sip/su_tagarg.h>
  12. #include <sofia-sip/su_tag_io.h>
  13. #include <sofia-sip/soa_tag.h>
  14. #include <sofia-sip/su_wait.h>
  15. #include <sofia-sip/nua_tag.h>
  16. #include "refcnt.h"
  17. #include "list.h"
  18. #include "sockutil.h"
  19. #include "hash.h"
  20. #include "SpBase.h"
  21. #include "video_session.h"
  22. #include "audio_session.h"
  23. #include "rvc_media_common.h"
  24. #include "Event.h"
  25. bool g_IsExternalTerminalted = false;
  26. // default: ptime = 20ms
  27. #define CONDITION_PARAMS \
  28. int status, \
  29. char const *phrase, \
  30. nua_t *nua, \
  31. struct endpoint_t *ep, \
  32. nua_handle_t *nh, \
  33. struct endpoint_call_t *call, \
  34. sip_t const *sip, \
  35. tagi_t tags[]
  36. // the same with rtp payload type, the same as huawei open-eye
  37. enum e_audio_rtp_pt
  38. {
  39. PCMU = 0, // 64kbps, 4.17
  40. PCMA = 8, // 64kbps, 4.11
  41. G729 = 18, // 8kbps, 3.9
  42. };
  43. enum e_video_rtp_pt
  44. {
  45. H263 = 34, // h263
  46. };
  47. enum e_media_dir
  48. {
  49. DIR_NONE = 0,
  50. DIR_TX = 1,
  51. DIR_RX = 2,
  52. DIR_BOTH = 3,
  53. };
  54. typedef struct sdpvideo_desc_t
  55. {
  56. unsigned long local_rtp_ip;
  57. int local_rtp_port;
  58. unsigned long remote_rtp_ip;
  59. int remote_rtp_port;
  60. int local_pt;
  61. int remote_pt;
  62. };
  63. typedef struct media_desc_t
  64. {
  65. unsigned long remote_ip;
  66. int remote_port;
  67. unsigned long local_ip;
  68. int local_port;
  69. int media_dir;
  70. int local_pt;
  71. int local_ptime;
  72. int remote_pt;
  73. int remote_ptime;
  74. int local_telephone_event_pt;
  75. int remote_telephone_event_pt;
  76. int param[16];
  77. }media_desc_t;
  78. // 1. how to exit
  79. struct endpoint_call_t {
  80. struct list_head entry;
  81. endpoint_call_callback_t cb;
  82. endpoint_t *ep;
  83. audio_session_t *audio;
  84. video_session_t *video;
  85. int id;
  86. su_home_t *home;
  87. nua_handle_t *nh;
  88. char *to_uri;
  89. char *from_uri;
  90. char *call_id;
  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[RVC_MAX_IP_LEN];
  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. if (call->audio) {
  157. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_AUDIO_DEVICE_SWITCH, CSimpleStringA::Format("change audio device to %s mode.", DEV_PICKUP == current_dev_type ? "pickup" : "hand free").GetData());
  158. audio_session_change_dev(call->audio, current_dev_type);
  159. }
  160. }
  161. static __inline struct in_addr __lton(unsigned long ip)
  162. {
  163. struct in_addr addr;
  164. addr.s_addr = ip;
  165. return addr;
  166. }
  167. static void endpoint_media_update_video(endpoint_call_t *call, media_desc_t *video_desc, video_session_callback_t* cb)
  168. {
  169. if (video_desc->media_dir == DIR_NONE) {
  170. if (call->video) {
  171. video_session_stop(call->video);
  172. video_session_destroy(call->video);
  173. call->video = NULL;
  174. }
  175. else{
  176. if (DOUBLERECORD_CALLTYPE == call->nCallType){
  177. double_record_broadcast_video_session_stop();
  178. }
  179. }
  180. }
  181. else
  182. {
  183. int rc;
  184. endpoint_conf_t *ep_conf = &call->ep->conf;
  185. if (!call->audio){
  186. audio_session_conf_t conf = {0};
  187. strcpy(&conf.in_dev[DEV_PICKUP][0], ep_conf->audio_pickup_in_dev);
  188. strcpy(&conf.in_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_in_dev);
  189. strcpy(&conf.out_dev[DEV_PICKUP][0], ep_conf->audio_pickup_out_dev);
  190. strcpy(&conf.out_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_out_dev);
  191. conf.agc_in[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_in_agc;
  192. conf.agc_in[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_in_agc;
  193. conf.agc_out[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_out_agc;
  194. conf.agc_out[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_out_agc;
  195. conf.ns_in[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_in_ns;
  196. conf.ns_in[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_in_ns;
  197. conf.ns_out[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_out_ns;
  198. conf.ns_out[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_out_ns;
  199. conf.aec[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_aec;
  200. conf.aec[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_aec;
  201. rc = audio_session_create(&conf, &call->audio);
  202. if (rc != 0) {
  203. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create audio session failed! rc = %d", rc);
  204. return;
  205. }
  206. }
  207. if (call->video) {
  208. video_session_destroy(call->video);
  209. call->video = NULL;
  210. }
  211. int i = 0;
  212. int local_view_x = video_desc->param[i++];
  213. int local_view_y = video_desc->param[i++];
  214. int local_view_cx = video_desc->param[i++];
  215. int local_view_cy = video_desc->param[i++];
  216. int remote_view_x = video_desc->param[i++];
  217. int remote_view_y = video_desc->param[i++];
  218. int remote_view_cx = video_desc->param[i++];
  219. int remote_view_cy = video_desc->param[i++];
  220. int remote_width = video_desc->param[i++];
  221. int remote_height = video_desc->param[i++];
  222. int local_hwd_move = video_desc->param[i++];
  223. int remote_hwd_move = video_desc->param[i++];
  224. video_session_conf_t video_conf = {0};
  225. video_conf.bit_rate = 256 * 1024;
  226. video_conf.local_rtp_ip = video_desc->local_ip;
  227. video_conf.local_rtp_port = video_desc->local_port;
  228. video_conf.local_video_view_x = local_view_x;
  229. video_conf.local_video_view_y = local_view_y;
  230. video_conf.local_video_view_cx = local_view_cx;
  231. video_conf.local_video_view_cy = local_view_cy;
  232. video_conf.mtu = ep_conf->mtu;
  233. video_conf.video_quant = ep_conf->quant;
  234. video_conf.remote_rtp_ip = video_desc->remote_ip;
  235. video_conf.remote_rtp_port = video_desc->remote_port;
  236. video_conf.remote_video_view_x = remote_view_x;
  237. video_conf.remote_video_view_y = remote_view_y;
  238. video_conf.remote_video_view_cx = remote_view_cx;
  239. video_conf.remote_video_view_cy = remote_view_cy;
  240. video_conf.remote_video_width = remote_width;
  241. video_conf.remote_video_height = remote_height;
  242. video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
  243. video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
  244. video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
  245. video_conf.ref_window_state = call->ep->conf.ref_window_state;
  246. video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
  247. //video_conf.ref_active_img = call->ep->conf.ref_active_img;
  248. //video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
  249. video_conf.ref_active_img = NULL;
  250. video_conf.ref_Is_ActiveInspect = NULL;
  251. video_conf.camera_count = call->ep->conf.camera_count;
  252. video_conf.screen_count = call->ep->conf.screen_count;
  253. video_conf.ref_Up_Fps = call->ep->conf.ref_Up_Fps;
  254. video_conf.eDeviceType = call->eDeviceType;
  255. video_conf.nCallType = call->nCallType;
  256. video_conf.local_move = local_hwd_move;
  257. video_conf.remote_move = remote_hwd_move;
  258. video_conf.video_echo_cb = cb;
  259. video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP;
  260. video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
  261. video_conf.eType = (eVideoRenderType)call->ep->conf.irendertype;
  262. video_conf.ivideotype = call->ep->conf.icaptype;
  263. //huchen modify, now we use standard h264
  264. //video_conf.local_pt = REC_COMMON_VIDEO_PT;
  265. //video_conf.remote_pt = REC_COMMON_VIDEO_PT;
  266. video_conf.local_pt = REC_COMMON_VIDEO_H264_PT;
  267. video_conf.remote_pt = REC_COMMON_VIDEO_H264_PT;
  268. rc = video_session_create(&video_conf, &call->video);
  269. if (rc != 0) {
  270. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create video session failed! rc = %d", rc);
  271. return;
  272. }
  273. rc = video_session_start(call->video);
  274. if (rc != 0) {
  275. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video session failed! rc = %d", rc);
  276. video_session_destroy(call->video);
  277. call->video = NULL;
  278. return;
  279. }
  280. }
  281. }
  282. static void endpoint_media_update_audio(endpoint_call_t *call, media_desc_t *audio_desc, int dev_type)
  283. {
  284. if (audio_desc->media_dir == DIR_NONE) {
  285. if (call->audio) {
  286. audio_session_stop(call->audio);
  287. audio_session_destroy(call->audio);
  288. call->audio = NULL;
  289. }
  290. else{
  291. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("call->audio is null.");
  292. }
  293. if (call->video) { // close video also
  294. video_session_stop(call->video);
  295. video_session_destroy(call->video);
  296. call->video = NULL;
  297. }
  298. else{
  299. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("call->video is null.");
  300. if (DOUBLERECORD_CALLTYPE == call->nCallType){
  301. double_record_broadcast_video_session_stop();
  302. }
  303. }
  304. } else {
  305. int rc;
  306. if (call->audio) {
  307. audio_session_stop(call->audio);
  308. audio_session_destroy(call->audio);
  309. call->audio = NULL;
  310. }
  311. if (!call->audio) {
  312. endpoint_conf_t *ep_conf = &call->ep->conf;
  313. audio_session_conf_t conf = {0};
  314. strcpy(&conf.in_dev[DEV_PICKUP][0], ep_conf->audio_pickup_in_dev);
  315. strcpy(&conf.in_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_in_dev);
  316. strcpy(&conf.out_dev[DEV_PICKUP][0], ep_conf->audio_pickup_out_dev);
  317. strcpy(&conf.out_dev[DEV_HANDFREE][0], ep_conf->audio_handfree_out_dev);
  318. conf.agc_in[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_in_agc;
  319. conf.agc_in[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_in_agc;
  320. conf.agc_out[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_out_agc;
  321. conf.agc_out[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_out_agc;
  322. conf.ns_in[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_in_ns;
  323. conf.ns_in[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_in_ns;
  324. conf.ns_out[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_out_ns;
  325. conf.ns_out[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_out_ns;
  326. conf.aec[DEV_PICKUP] = !!ep_conf->audio_dsp.audio_pickup_aec;
  327. conf.aec[DEV_HANDFREE] = !!ep_conf->audio_dsp.audio_handfree_aec;
  328. rc = audio_session_create(&conf, &call->audio);
  329. if (rc != 0) {
  330. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create audio session failed! rc = %d", rc);
  331. return;
  332. }
  333. }
  334. audio_session_phonemedia_conf_t phone_conf = {0};
  335. phone_conf.dir = audio_desc->media_dir;
  336. phone_conf.dev_type = (e_dev_type)dev_type;
  337. phone_conf.local_dtmf_pt = audio_desc->local_telephone_event_pt;
  338. phone_conf.local_pt = audio_desc->local_pt;
  339. phone_conf.local_ptime = audio_desc->local_ptime;
  340. phone_conf.local_rtp_ip = audio_desc->local_ip;
  341. phone_conf.local_rtp_port = audio_desc->local_port;
  342. phone_conf.remote_dtmf_pt = audio_desc->remote_telephone_event_pt;
  343. phone_conf.remote_pt = audio_desc->remote_pt;
  344. phone_conf.remote_ptime = audio_desc->remote_ptime;
  345. phone_conf.remote_rtp_ip = audio_desc->remote_ip;
  346. phone_conf.remote_rtp_port = audio_desc->remote_port;
  347. if (NULL != call){
  348. phone_conf.eCalltype = call->nCallType;
  349. phone_conf.eDeviceType = call->eDeviceType;
  350. }
  351. rc = audio_session_start_phonemedia(call->audio, &phone_conf);
  352. if (rc != 0)
  353. {
  354. LogWarn(Severity_Low, Error_Debug, ERROR_MOD_SIP_AUDIO_INITFAIL, CSimpleStringA::Format("start audio session failed! rc = %d.", rc).GetData());
  355. audio_session_destroy(call->audio);
  356. call->audio = NULL;
  357. return;
  358. }
  359. }
  360. }
  361. static unsigned int __hash_media_desc(media_desc_t *media_desc, unsigned int hash_code)
  362. {
  363. if (media_desc) {
  364. hash_code += (unsigned int)media_desc->local_ip * 33;
  365. hash_code += (unsigned int)media_desc->remote_ip * 33;
  366. hash_code += (unsigned int)media_desc->local_port * 33;
  367. hash_code += (unsigned int)media_desc->remote_port * 33;
  368. hash_code += (unsigned int)media_desc->media_dir * 33;
  369. hash_code += (unsigned int)media_desc->local_pt * 33;
  370. hash_code += (unsigned int)media_desc->local_ptime * 33;
  371. hash_code += (unsigned int)media_desc->remote_pt * 33;
  372. hash_code += (unsigned int)media_desc->remote_ptime * 33;
  373. hash_code += (unsigned int)media_desc->local_telephone_event_pt * 33;
  374. hash_code += (unsigned int)media_desc->remote_telephone_event_pt * 33;
  375. }
  376. return hash_code;
  377. }
  378. static unsigned int hash_media_desc(media_desc_t *audio)
  379. {
  380. unsigned int hash_code = 0;
  381. hash_code = __hash_media_desc(audio, hash_code);
  382. return hash_code;
  383. }
  384. #define USE_ALAW 1
  385. static const char *call_make_offer(endpoint_call_t *call, char *buf, int size)
  386. {
  387. int local_audio_rtp_port = call->local_media_port;
  388. int local_video_rtp_port = call->local_video_port;
  389. int local_video_pt = REC_COMMON_VIDEO_PT;
  390. int need;
  391. const char *fmt;
  392. {
  393. fmt =
  394. "c=IN IP4 %s\r\n"
  395. #ifdef USE_ALAW
  396. "m=audio %d RTP/AVP 8\r\n"
  397. "a=rtpmap:8 PCMA/8000\r\n"
  398. "a=ptime:30\r\n"
  399. #elif defined(USE_G729)
  400. "m=audio %d RTP/AVP 18\r\n"
  401. "a=rtpmap:18 G729/8000\r\n"
  402. "a=fmtp:18 annexb=no\r\n"
  403. "a=ptime:30\r\n"
  404. #endif
  405. //"a=rtpmap:97 telephone-event/8000\r\n"
  406. //"a=fmtp:97 0-15\r\n"
  407. #ifdef USE_H263_VIDEO
  408. "m=video %d RTP/AVP 34\r\n"
  409. "a=rtpmap:34 H263/90000\r\n"
  410. "a=fmtp:34 QCIF=2 MaxBR=5040\r\n"
  411. #endif
  412. //"a=inactive\r\n" //for debug only
  413. ;
  414. }
  415. need = _scprintf(fmt, call->local_ip, local_audio_rtp_port);
  416. if (size < 0 || size > need) {
  417. sprintf(buf, fmt, call->local_ip, local_audio_rtp_port);
  418. return buf;
  419. } else {
  420. return NULL;
  421. }
  422. }
  423. static int new_call_id(endpoint_t *ep)
  424. {
  425. return ++ep->call_seq;
  426. }
  427. int new_media_port(endpoint_t *ep)
  428. {
  429. ep->media_port_seq += 2;
  430. if (ep->media_port_seq >= ep->conf.media_stop_port) {
  431. ep->media_port_seq = ep->conf.media_start_port;
  432. }
  433. return ep->media_port_seq;
  434. }
  435. static void handle_invite(CONDITION_PARAMS)
  436. {
  437. // we are client only, not accept in-comming call
  438. nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
  439. }
  440. static void handle_reinvite(CONDITION_PARAMS)
  441. {
  442. char sdp[512] = {0};
  443. sip_content_type_t const *ct = NULL;
  444. tl_gets(tags,
  445. SIPTAG_CONTENT_TYPE_REF(ct),
  446. TAG_END());
  447. if (ct) {
  448. call_make_offer(call, sdp, sizeof(sdp));
  449. }
  450. nua_respond(nh,
  451. SIP_200_OK,
  452. TAG_IF(ct, SOATAG_USER_SDP_STR(sdp)),
  453. TAG_IF(ct, SOATAG_AUDIO_AUX("telephone-event")),
  454. TAG_END());
  455. }
  456. static void handle_r_invite(CONDITION_PARAMS)
  457. {
  458. // nothing to do
  459. }
  460. static int dir_from_attr(const sdp_media_t *m)
  461. {
  462. int dir = DIR_NONE;
  463. if (m) {
  464. if (m->m_attributes) {
  465. static const char *ds[] = {
  466. "inactive", "sendonly", "recvonly", "sendrecv"
  467. };
  468. int i;
  469. int n = array_size(ds);
  470. for (i = 0; i < n; ++i) {
  471. sdp_attribute_t *attr = sdp_attribute_find(m->m_attributes, ds[i]);
  472. if (attr) {
  473. dir = i;
  474. break;
  475. }
  476. }
  477. if (i >= n)
  478. dir = DIR_BOTH;
  479. } else {
  480. dir = DIR_BOTH;
  481. }
  482. }
  483. return dir;
  484. }
  485. static int ptime_from_attr(const sdp_media_t *m)
  486. {
  487. int ptime = 0; // zero for default
  488. if (m) {
  489. if (m->m_attributes) {
  490. sdp_attribute_t *attr = sdp_attribute_find(m->m_attributes, "ptime");
  491. if (attr && attr->a_value) {
  492. ptime = atoi(attr->a_value);
  493. if (ptime < 0)
  494. ptime = 0;
  495. }
  496. }
  497. }
  498. return ptime;
  499. }
  500. static const sdp_rtpmap_t *find_codec(const sdp_rtpmap_t *list, const char *codec)
  501. {
  502. if (!codec)
  503. return NULL;
  504. for (;list; list=list->rm_next) {
  505. if (!_stricmp(list->rm_encoding, codec)) {
  506. break;
  507. }
  508. }
  509. return list;
  510. }
  511. static int get_telephone_event_pt(const sdp_rtpmap_t *list)
  512. {
  513. int pt = -1;
  514. const sdp_rtpmap_t *rm = find_codec(list, "telephone-event");
  515. if (rm) {
  516. pt = rm->rm_pt;
  517. }
  518. return pt;
  519. }
  520. static int get_media_direction(const sdp_media_t *lm, const sdp_media_t *rm)
  521. {
  522. int media_dir = DIR_NONE;
  523. if (rm->m_port == 0 || lm->m_port == 0) {
  524. media_dir = DIR_NONE;
  525. } else {
  526. int ldir = dir_from_attr(lm);
  527. int rdir = dir_from_attr(rm);
  528. if (ldir == DIR_NONE || rdir == DIR_NONE) {
  529. media_dir = DIR_NONE;
  530. } else if (ldir == DIR_TX || rdir == DIR_RX) {
  531. media_dir = DIR_TX;
  532. } else if (ldir == DIR_RX || rdir == DIR_TX) {
  533. media_dir = DIR_RX;
  534. } else {
  535. media_dir = DIR_BOTH;
  536. }
  537. }
  538. return media_dir;
  539. }
  540. static int negotiate_audio(endpoint_call_t *call, media_desc_t *audio_desc, const sdp_media_t *lm, const sdp_media_t *rm)
  541. {
  542. memset(audio_desc, 0, sizeof(media_desc_t));
  543. const char *local_ip;
  544. const char *remote_ip;
  545. local_ip = lm->m_connections ? lm->m_connections->c_address : lm->m_session->sdp_connection->c_address;
  546. remote_ip = rm->m_connections ? rm->m_connections->c_address : rm->m_session->sdp_connection->c_address;
  547. audio_desc->local_ip = strlen(call->local_ip) ? inet_addr(call->local_ip) : 0;
  548. audio_desc->local_port = call->local_media_port;
  549. audio_desc->remote_ip = remote_ip ? inet_addr(remote_ip) : 0;
  550. audio_desc->remote_port = rm->m_port;
  551. audio_desc->local_telephone_event_pt = 97;
  552. audio_desc->remote_telephone_event_pt = get_telephone_event_pt(rm->m_rtpmaps);
  553. audio_desc->local_ptime = ptime_from_attr(lm);
  554. audio_desc->remote_ptime = ptime_from_attr(rm);
  555. int pt = -1;
  556. for (sdp_rtpmap_t *t = lm->m_rtpmaps; t; t = t->rm_next) {
  557. sdp_rtpmap_t *tt = sdp_rtpmap_find_matching(rm->m_rtpmaps, t);
  558. if (tt && tt->rm_pt < 96) {
  559. pt = tt->rm_pt;
  560. break;
  561. }
  562. }
  563. audio_desc->local_pt = audio_desc->remote_pt = pt;
  564. audio_desc->media_dir = get_media_direction(lm, rm);
  565. return 0;
  566. }
  567. static int negotiate_video(endpoint_call_t *call, media_desc_t *video_desc, const sdp_media_t *lm, const sdp_media_t *rm)
  568. {
  569. memset(video_desc, 0, sizeof(media_desc_t));
  570. const char *local_ip;
  571. const char *remote_ip;
  572. local_ip = lm->m_connections ? lm->m_connections->c_address : lm->m_session->sdp_connection->c_address;
  573. remote_ip = rm->m_connections ? rm->m_connections->c_address : rm->m_session->sdp_connection->c_address;
  574. video_desc->local_ip = strlen(call->local_ip) ? inet_addr(call->local_ip) : 0;
  575. video_desc->local_port = call->local_video_port;
  576. video_desc->remote_ip = remote_ip ? inet_addr(remote_ip) : 0;
  577. video_desc->remote_port = rm->m_port;
  578. video_desc->local_telephone_event_pt = 97;
  579. video_desc->remote_telephone_event_pt = get_telephone_event_pt(rm->m_rtpmaps);
  580. video_desc->local_ptime = ptime_from_attr(lm);
  581. video_desc->remote_ptime = ptime_from_attr(rm);
  582. int pt = -1;
  583. for (sdp_rtpmap_t *t = lm->m_rtpmaps; t; t = t->rm_next) {
  584. sdp_rtpmap_t *tt = sdp_rtpmap_find_matching(rm->m_rtpmaps, t);
  585. if (tt) {
  586. pt = tt->rm_pt;
  587. break;
  588. }
  589. }
  590. video_desc->local_pt = video_desc->remote_pt = pt;
  591. video_desc->media_dir = get_media_direction(lm, rm);
  592. return 0;
  593. }
  594. static void negotiate_sdp(endpoint_call_t *call, const sdp_session_t *local_sdp, const sdp_session_t* remote_sdp)
  595. {
  596. const sdp_media_t *lm = local_sdp->sdp_media;
  597. const sdp_media_t *rm = remote_sdp->sdp_media;
  598. media_desc_t audio_desc = {0}, video_desc = {0};
  599. int rc = -1, rv = -1;
  600. for(; lm; lm = lm->m_next)
  601. {
  602. if (0 == lm->m_port)
  603. {
  604. continue;
  605. }
  606. const sdp_media_t *rm = remote_sdp->sdp_media;
  607. for (; rm; rm = rm->m_next)
  608. {
  609. if (rm->m_type == lm->m_type)
  610. {
  611. if (sdp_media_audio == rm->m_type)
  612. {
  613. rc = negotiate_audio(call, &audio_desc, lm, rm);
  614. }
  615. if (call->nCallType != NORMAL_CALLTYPE && call->nCallType != DOUBLERECORD_CALLTYPE)
  616. {
  617. if (sdp_media_video == rm->m_type)
  618. {
  619. rv = negotiate_video(call, &video_desc, lm, rm);
  620. }
  621. }
  622. }
  623. }
  624. }
  625. if (rc == 0)
  626. {
  627. unsigned int hash_code = hash_media_desc(&audio_desc);
  628. if (hash_code != call->last_media_desc_hash)
  629. {
  630. char str_local[RVC_MAX_IP_LEN] = {0};
  631. char str_remote[RVC_MAX_IP_LEN] = {0};
  632. translate_ipaddr_from_int(str_local, RVC_MAX_IP_LEN, audio_desc.local_ip);
  633. translate_ipaddr_from_int(str_remote, RVC_MAX_IP_LEN, audio_desc.remote_ip);
  634. endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
  635. call->last_media_desc_hash = hash_code;
  636. //char strmsg[MAX_PATH] = {0};
  637. //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);
  638. //LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_CALL_AUDIO_NEGOTIATE, strmsg);
  639. }
  640. }
  641. if (rv == 0)
  642. {
  643. unsigned int hash_code = hash_media_desc(&video_desc);
  644. if (hash_code != call->last_media_desc_hash)
  645. {
  646. char str_local[128] = {0};
  647. char str_remote[128] = {0};
  648. translate_ipaddr_from_int(str_local, 128, video_desc.local_ip);
  649. translate_ipaddr_from_int(str_remote, 128, video_desc.remote_ip);
  650. call->sdpvieo_desc.local_pt = video_desc.local_pt;
  651. call->sdpvieo_desc.local_rtp_ip = video_desc.local_ip;
  652. call->sdpvieo_desc.local_rtp_port = video_desc.local_port;
  653. call->sdpvieo_desc.remote_pt = video_desc.remote_pt;
  654. call->sdpvieo_desc.remote_rtp_ip = video_desc.remote_ip;
  655. call->sdpvieo_desc.remote_rtp_port = video_desc.remote_port;
  656. call->last_media_desc_hash = hash_code;
  657. //char strmsg[MAX_PATH] = {0};
  658. //_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);
  659. //LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_CALL_VIDEO_NEGOTIATE, strmsg);
  660. }
  661. }
  662. else
  663. {
  664. if (call->nCallType != NORMAL_CALLTYPE && call->nCallType != DOUBLERECORD_CALLTYPE)
  665. {
  666. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("negotiate video Fail!!!");
  667. }
  668. }
  669. }
  670. static void on_state(CONDITION_PARAMS)
  671. {
  672. int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
  673. int state = nua_callstate_init;
  674. const char *replaces_str = NULL;
  675. const sdp_session_t *remote_sdp = NULL;
  676. const char *remote_sdp_str = NULL;
  677. const sdp_session_t *local_sdp = NULL;
  678. const char *local_sdp_str = NULL;
  679. int st;
  680. if (!call) {
  681. nua_handle_destroy(nh);
  682. return;
  683. }
  684. if (g_IsExternalTerminalted)
  685. {
  686. return;
  687. }
  688. tl_gets(tags,
  689. NUTAG_CALLSTATE_REF(state),
  690. NUTAG_OFFER_RECV_REF(offer_recv),
  691. NUTAG_ANSWER_RECV_REF(answer_recv),
  692. NUTAG_OFFER_SENT_REF(offer_sent),
  693. NUTAG_ANSWER_SENT_REF(answer_sent),
  694. SIPTAG_REPLACES_STR_REF(replaces_str),
  695. SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str),
  696. SOATAG_LOCAL_SDP_STR_REF(local_sdp_str),
  697. TAG_END());
  698. switch (state)
  699. {
  700. case nua_callstate_calling:
  701. {
  702. if (local_sdp_str) {
  703. sdp_parser_t* parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
  704. assert(call->last_sdp == NULL);
  705. call->last_sdp = sdp_session_dup(call->home, sdp_session(parser));
  706. sdp_parser_free(parser);
  707. }
  708. st = CALLING;
  709. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  710. }
  711. break;
  712. case nua_callstate_proceeding:
  713. {
  714. st = PROCEEDING;
  715. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  716. if (remote_sdp_str) {
  717. sdp_parser_t* parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  718. remote_sdp = sdp_session(parser);
  719. if (call->last_sdp) {
  720. negotiate_sdp(call, call->last_sdp, remote_sdp);
  721. su_free(call->home, call->last_sdp);
  722. call->last_sdp = NULL;
  723. }
  724. sdp_parser_free(parser);
  725. }
  726. }
  727. break;
  728. case nua_callstate_completing:
  729. {
  730. st = COMPLETING;
  731. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  732. if (remote_sdp_str) {
  733. sdp_parser_t* parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  734. remote_sdp = sdp_session(parser);
  735. if (call->last_sdp) {
  736. negotiate_sdp(call, call->last_sdp, remote_sdp);
  737. su_free(call->home, call->last_sdp);
  738. call->last_sdp = NULL;
  739. }
  740. sdp_parser_free(parser);
  741. }
  742. }
  743. break;
  744. case nua_callstate_completed:
  745. {
  746. if (remote_sdp_str) {
  747. if (!call->last_sdp) {
  748. sdp_parser_t* parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  749. call->last_sdp = sdp_session_dup(call->home, sdp_session(parser));
  750. sdp_parser_free(parser);
  751. }
  752. }
  753. if (local_sdp_str) {
  754. if (call->last_sdp) {
  755. sdp_parser_t* parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
  756. local_sdp = sdp_session(parser);
  757. negotiate_sdp(call, local_sdp, call->last_sdp);
  758. su_free(call->home, call->last_sdp);
  759. call->last_sdp = NULL;
  760. sdp_parser_free(parser);
  761. }
  762. }
  763. }
  764. break;
  765. case nua_callstate_ready:
  766. {
  767. call->connected = true;
  768. st = READY;
  769. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  770. if (remote_sdp_str) {
  771. sdp_parser_t* parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  772. remote_sdp = sdp_session(parser);
  773. if (call->last_sdp) {
  774. negotiate_sdp(call, call->last_sdp, remote_sdp);
  775. su_free(call->home, call->last_sdp);
  776. call->last_sdp = NULL;
  777. }
  778. sdp_parser_free(parser);
  779. }
  780. #if 0
  781. if (remote_sdp_str) {
  782. sdp_parser_t* parser = sdp_parse(call->home, remote_sdp_str, strlen(remote_sdp_str), -1);
  783. remote_sdp = sdp_session(parser);
  784. negotiate_sdp(call, call->last_sdp, remote_sdp);
  785. sdp_parser_free(parser);
  786. }
  787. else if (local_sdp_str) {
  788. sdp_parser_t* parser = sdp_parse(call->home, local_sdp_str, strlen(local_sdp_str), -1);
  789. local_sdp = sdp_session(parser);
  790. negotiate_sdp(call, local_sdp, call->last_sdp);
  791. sdp_parser_free(parser);
  792. }
  793. #endif
  794. }
  795. break;
  796. case nua_callstate_terminated:
  797. {
  798. st = TERMINATED;
  799. {
  800. media_desc_t audio_desc = { 0 };
  801. audio_desc.media_dir = DIR_NONE;
  802. endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
  803. }
  804. call->cb.on_call_state(st, state_desc[st], phrase, call->cb.user_data);
  805. nua_handle_bind(nh, NULL);
  806. nua_handle_destroy(nh);
  807. call->nh = NULL;
  808. }
  809. break;
  810. default:
  811. break;
  812. }
  813. }
  814. void Terminatedcall(endpoint_call_t *call)
  815. {
  816. int st = TERMINATED;
  817. g_IsExternalTerminalted = true;
  818. {
  819. media_desc_t audio_desc = {0};
  820. audio_desc.media_dir = DIR_NONE;
  821. endpoint_media_update_audio(call, &audio_desc, call->ep->curr_audio_dev_type);
  822. }
  823. }
  824. static void endpoint_callback(nua_event_t event,
  825. int status,
  826. char const *phrase,
  827. nua_t *nua,
  828. nua_magic_t *magic,
  829. nua_handle_t *nh,
  830. nua_hmagic_t *hmagic,
  831. sip_t const *sip,
  832. tagi_t tags[])
  833. {
  834. switch (event)
  835. {
  836. if (!g_IsExternalTerminalted)
  837. {
  838. case nua_i_invite:
  839. if (hmagic == NULL) {
  840. handle_invite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  841. } else {
  842. handle_reinvite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  843. }
  844. break;
  845. case nua_r_invite:
  846. handle_r_invite(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  847. break;
  848. case nua_i_bye:
  849. //.....
  850. break;
  851. case nua_i_info:
  852. break;
  853. case nua_i_state:
  854. on_state(status, phrase, nua, (endpoint_t*)magic, nh, (endpoint_call_t*)hmagic, sip, tags);
  855. break;
  856. case nua_i_active:
  857. break;
  858. case nua_i_options:
  859. //nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SOATAG_USER_SDP_STR(NULL), TAG_END());
  860. nua_respond(nh, SIP_200_OK, TAG_END());
  861. break;
  862. case nua_r_cancel:
  863. if (status > 300) {
  864. nua_bye(nh, TAG_END());
  865. }
  866. break;
  867. case nua_i_prack:
  868. case nua_r_prack:
  869. break;
  870. case nua_r_bye:
  871. //LOG_TRACE("nua_r_bye");
  872. if (status > 300) {
  873. nua_bye(nh, TAG_END());
  874. }
  875. break;
  876. /* and so on ... */
  877. default:
  878. if (status > 100) { /* unknown event -> print out error message */
  879. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unknown event %d: %03d %s.",
  880. event,
  881. status,
  882. phrase);
  883. } else {
  884. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unknown event %d.", event);
  885. }
  886. break;
  887. }
  888. }
  889. if (!hmagic)
  890. {
  891. nua_handle_destroy(nh);
  892. return;
  893. }
  894. }
  895. static unsigned int __stdcall __event_thread(void *arg)
  896. {
  897. endpoint_t *ep = (endpoint_t *)arg;
  898. ep->entity->GetFunction()->InitLogCurrentThread();
  899. CoInitialize(NULL);
  900. ep->root = su_root_create(ep);
  901. ep->nua = nua_create(ep->root,
  902. &endpoint_callback,
  903. ep,
  904. NUTAG_URL(ep->conf.uri),
  905. TAG_END());
  906. nua_set_params(ep->nua,
  907. SIPTAG_ALLOW_STR("INVITE,CANCEL,BYE,ACK,INFO,OPTIONS"),
  908. NUTAG_AUTOALERT(1),
  909. NUTAG_ALLOW("PRACK"),
  910. NUTAG_EARLY_MEDIA(1),
  911. NUTAG_SESSION_TIMER(1),
  912. NUTAG_AUTOANSWER(0),
  913. NUTAG_AUTOACK(1),
  914. NTATAG_SIP_T1X64(8000),
  915. TAG_NULL());
  916. su_root_run(ep->root);
  917. nua_shutdown(ep->nua);
  918. ep->nua = NULL;
  919. su_root_destroy(ep->root);
  920. ep->root = NULL;
  921. CoUninitialize();
  922. return 0;
  923. }
  924. static int __endpoint_break(void *arg)
  925. {
  926. endpoint_t *ep = (endpoint_t *)arg;
  927. //.....nua_shutdown
  928. su_root_break(ep->root);
  929. return 0;
  930. }
  931. static endpoint_t *__endpoint_create(CEntityBase *pEntity, const endpoint_conf_t *conf,int nDev)
  932. {
  933. endpoint_t *ep;
  934. ep = ZALLOC_T(endpoint_t);
  935. su_home_init(ep->home);
  936. memcpy(&ep->conf, conf, sizeof(endpoint_conf_t));
  937. ep->media_port_seq = (conf->media_start_port + (GetTickCount() % (conf->media_stop_port - conf->media_start_port))) & 0xfffc;
  938. ep->entity = pEntity;
  939. ep->call_seq = GetTickCount();
  940. ep->curr_audio_dev_type = nDev;
  941. INIT_LIST_HEAD(&ep->call_list);
  942. return ep;
  943. }
  944. static void __endpoint_destroy(endpoint_t *ep)
  945. {
  946. su_root_destroy(ep->root);
  947. su_home_deinit(ep->home);
  948. free(ep);
  949. }
  950. static int __endpoint_start(endpoint_t *ep)
  951. {
  952. ep->event_thread = (HANDLE)_beginthreadex(NULL, 0, &__event_thread, ep, 0, NULL);
  953. if (ep->event_thread)
  954. {
  955. while (!ep->root)
  956. {
  957. DWORD dwRet = WaitForSingleObject(ep->event_thread, 1);
  958. if (dwRet == WAIT_OBJECT_0)
  959. {
  960. CloseHandle(ep->event_thread);
  961. ep->event_thread = NULL;
  962. break;
  963. }
  964. }
  965. }
  966. return ep->event_thread ? 0 : -1;
  967. }
  968. static void __endpoint_stop(endpoint_t *ep)
  969. {
  970. if (ep->event_thread)
  971. {
  972. int rc;
  973. su_task_execute(su_root_task(ep->root), &__endpoint_break, ep, &rc);
  974. WaitForSingleObject(ep->event_thread, INFINITE);
  975. CloseHandle(ep->event_thread);
  976. ep->event_thread = NULL;
  977. }
  978. }
  979. static void rvc_sofia_logger(void* stream, char const* fmt, va_list ap) {
  980. if (!fmt)
  981. return;
  982. char line[255];
  983. vsnprintf(line, sizeof(line), fmt, ap);
  984. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("rvc_sofia_logger : %s", line);
  985. }
  986. int endpoint_init_lib()
  987. {
  988. int result = su_init();
  989. //su_log_set_level(NULL, 9);
  990. //su_log_redirect(NULL, rvc_sofia_logger, NULL);
  991. return result;
  992. }
  993. void endpoint_deinit_lib()
  994. {
  995. su_deinit();
  996. }
  997. endpoint_t *endpoint_create(CEntityBase *pEntity, const endpoint_conf_t *conf,int nDev)
  998. {
  999. endpoint_t *endpt;
  1000. endpt = __endpoint_create(pEntity, conf,nDev);
  1001. if (endpt) {
  1002. int rc = __endpoint_start(endpt);
  1003. if (rc != 0)
  1004. {
  1005. __endpoint_destroy(endpt);
  1006. endpt = NULL;
  1007. }
  1008. }
  1009. return endpt;
  1010. }
  1011. void endpoint_destroy(endpoint_t *ep)
  1012. {
  1013. if (ep)
  1014. {
  1015. __endpoint_stop(ep);
  1016. __endpoint_destroy(ep);
  1017. }
  1018. }
  1019. int endpoint_invoke(endpoint_t *ep, int (*func)(void*), void *user_data, int *result)
  1020. {
  1021. if (ep){
  1022. return su_task_execute(su_root_task(ep->root), func, user_data, result);
  1023. }
  1024. else
  1025. {
  1026. *result = Error_Param;
  1027. return -1;
  1028. }
  1029. }
  1030. void endpoint_change_audio_dev(endpoint_t *ep, int dev_type)
  1031. {
  1032. if (ep){
  1033. if (ep->curr_audio_dev_type != dev_type) {
  1034. ep->curr_audio_dev_type = dev_type;
  1035. if (ep->active_call) {
  1036. endpoint_media_change_audio_dev(ep->active_call, (e_dev_type)dev_type);
  1037. } else {
  1038. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("active call is null!");
  1039. }
  1040. }
  1041. }
  1042. }
  1043. endpoint_call_t *endpoint_call_create(endpoint_t *ep, const endpoint_call_params_t* pcallparam, const endpoint_call_callback_t *cb)
  1044. {
  1045. endpoint_call_t *call = NULL;
  1046. su_home_t *home = NULL;
  1047. if (!pcallparam || !pcallparam->to_uri){
  1048. return NULL;
  1049. }
  1050. home = su_home_create();
  1051. if (!home){
  1052. goto on_error;
  1053. }
  1054. call = (endpoint_call_t*)su_home_new(sizeof(endpoint_call_t));
  1055. if (!call){
  1056. goto on_error;
  1057. }
  1058. memset(call, 0, sizeof(endpoint_call_t));
  1059. call->connected = 0;
  1060. call->ep = ep;
  1061. call->home = home;
  1062. call->last_media_desc_hash = 0;
  1063. call->to_uri = su_strdup(home, pcallparam->to_uri);
  1064. if (pcallparam->from_uri != NULL){
  1065. call->from_uri = su_strdup(home, pcallparam->from_uri);
  1066. }
  1067. if (pcallparam->call_id != NULL){
  1068. call->call_id = su_strdup(home, pcallparam->call_id);
  1069. }
  1070. if (NULL != pcallparam->local_ip){
  1071. _snprintf(call->local_ip, RVC_MAX_IP_LEN, "%s", pcallparam->local_ip);
  1072. }
  1073. call->eDeviceType = pcallparam->nDeviceType;
  1074. call->nCallType = pcallparam->nCallType;
  1075. memcpy(&call->cb, cb, sizeof(endpoint_call_callback_t));
  1076. call->id = new_call_id(ep);
  1077. call->local_media_port = pcallparam->ilocal_audio_port;
  1078. call->local_video_port = pcallparam->ilocal_video_port;
  1079. REF_COUNT_INIT(&call->ref_cnt);
  1080. list_add_tail(&call->entry, &ep->call_list);
  1081. ep->active_call = call;
  1082. return call;
  1083. on_error:
  1084. if (home)
  1085. su_home_unref(home);
  1086. return call;
  1087. }
  1088. void endpoint_call_destroy(endpoint_call_t *call)
  1089. {
  1090. endpoint_call_dec_ref(call);
  1091. }
  1092. int endpoint_call_start(endpoint_call_t *call)
  1093. {
  1094. char sdp[512] = {0};
  1095. if (call->nh)
  1096. return -1;
  1097. if (call->from_uri != NULL && call->call_id != NULL){
  1098. call->nh = nua_handle(call->ep->nua,
  1099. call,
  1100. SIPTAG_CALL_ID_STR(call->call_id),
  1101. SIPTAG_FROM_STR(call->from_uri),
  1102. SIPTAG_TO_STR(call->to_uri),
  1103. TAG_END());
  1104. } else if (call->from_uri != NULL){
  1105. call->nh = nua_handle(call->ep->nua,
  1106. call,
  1107. SIPTAG_FROM_STR(call->from_uri),
  1108. SIPTAG_TO_STR(call->to_uri),
  1109. TAG_END());
  1110. }else if (call->call_id != NULL){
  1111. call->nh = nua_handle(call->ep->nua,
  1112. call,
  1113. SIPTAG_FROM_STR(call->ep->conf.uri),
  1114. SIPTAG_CALL_ID_STR(call->call_id),
  1115. SIPTAG_TO_STR(call->to_uri),
  1116. TAG_END());
  1117. }else{
  1118. call->nh = nua_handle(call->ep->nua,
  1119. call,
  1120. SIPTAG_FROM_STR(call->ep->conf.uri),
  1121. SIPTAG_TO_STR(call->to_uri),
  1122. TAG_END());
  1123. }
  1124. call_make_offer(call, sdp, -1);
  1125. if (0 == strlen(sdp)){
  1126. LogWarn(Severity_Middle, Error_Debug, EVENT_MOD_SIP_INVALID_SDP, "invalid sdp.");
  1127. }
  1128. nua_invite(call->nh,
  1129. //NUTAG_URL(call->remote_uri),
  1130. SOATAG_USER_SDP_STR(sdp),
  1131. NUTAG_SESSION_TIMER(20000),
  1132. //SOATAG_AUDIO_AUX("telephone-event"),
  1133. TAG_END());
  1134. return 0;
  1135. }
  1136. int endpoint_call_hangup(endpoint_call_t *call)
  1137. {
  1138. if (call->nh) {
  1139. if (call->connected) {
  1140. nua_bye(call->nh, NUTAG_SESSION_TIMER(8000),TAG_END());
  1141. } else {
  1142. nua_cancel(call->nh, NUTAG_SESSION_TIMER(8000),TAG_END());
  1143. }
  1144. }
  1145. return 0;
  1146. }
  1147. int endpoint_call_start_video(endpoint_call_t *call, unsigned long remote_ip, int remote_video_rtp,
  1148. unsigned long local_ip, int local_video_rtp,
  1149. int remote_width, int remote_height,
  1150. int local_view_x, int local_view_y, int local_view_cx, int local_view_cy,
  1151. int remote_view_x, int remote_view_y, int remote_view_cx, int remote_view_cy,
  1152. int local_move, int remote_move, video_session_callback_t* cb)
  1153. {
  1154. char local_ip_str[RVC_MAX_IP_LEN]={0};
  1155. char remtote_ip_str[RVC_MAX_IP_LEN]={0};
  1156. translate_ipaddr_from_int(local_ip_str, RVC_MAX_IP_LEN, local_ip);
  1157. translate_ipaddr_from_int(remtote_ip_str, RVC_MAX_IP_LEN, remote_ip);
  1158. if (call)
  1159. {
  1160. int i = 0;
  1161. media_desc_t video_desc = {0};
  1162. video_desc.media_dir = DIR_BOTH;
  1163. if (call->nCallType == NORMAL_CALLTYPE || call->nCallType == DOUBLERECORD_CALLTYPE)//如果是可视柜台模式,使用协助通道的协商结果
  1164. {
  1165. video_desc.local_ip = local_ip;
  1166. video_desc.local_port = local_video_rtp;
  1167. video_desc.remote_port = remote_video_rtp;
  1168. video_desc.remote_ip = remote_ip;
  1169. }
  1170. else //如果是非可视柜台模式,使用SDP协商的参数
  1171. {
  1172. video_desc.local_ip = call->sdpvieo_desc.local_rtp_ip;
  1173. video_desc.local_port = call->sdpvieo_desc.local_rtp_port;
  1174. video_desc.local_pt = call->sdpvieo_desc.local_pt;
  1175. video_desc.remote_ip = call->sdpvieo_desc.remote_rtp_ip;
  1176. video_desc.remote_port = call->sdpvieo_desc.remote_rtp_port;
  1177. video_desc.remote_pt = call->sdpvieo_desc.remote_pt;
  1178. }
  1179. video_desc.param[i++] = local_view_x;
  1180. video_desc.param[i++] = local_view_y;
  1181. video_desc.param[i++] = local_view_cx;
  1182. video_desc.param[i++] = local_view_cy;
  1183. video_desc.param[i++] = remote_view_x;
  1184. video_desc.param[i++] = remote_view_y;
  1185. video_desc.param[i++] = remote_view_cx;
  1186. video_desc.param[i++] = remote_view_cy;
  1187. video_desc.param[i++] = remote_width;
  1188. video_desc.param[i++] = remote_height;
  1189. //add by clp 20190823
  1190. video_desc.param[i++] = local_move;
  1191. video_desc.param[i++] = remote_move;
  1192. endpoint_media_update_video(call, &video_desc, cb);
  1193. char str_local_ip[RVC_MAX_IP_LEN]={0};
  1194. char str_remtote_ip[RVC_MAX_IP_LEN]={0};
  1195. translate_ipaddr_from_int(str_local_ip, RVC_MAX_IP_LEN,video_desc.local_ip);
  1196. translate_ipaddr_from_int(str_remtote_ip, RVC_MAX_IP_LEN, video_desc.remote_ip);
  1197. return 0;
  1198. }
  1199. else
  1200. {
  1201. return Error_Param;
  1202. }
  1203. }
  1204. int endpoint_call_stop_video(endpoint_call_t *call)
  1205. {
  1206. if (call) {
  1207. media_desc_t video_desc = {0};
  1208. video_desc.media_dir = DIR_NONE;
  1209. endpoint_media_update_video(call, &video_desc,NULL);
  1210. return 0;
  1211. } else {
  1212. return Error_Param;
  1213. }
  1214. }
  1215. int endpoint_call_stop_double_record_broadcast_video()
  1216. {
  1217. double_record_broadcast_video_session_stop();
  1218. return Error_Succeed;
  1219. }
  1220. 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)
  1221. {
  1222. int rc;
  1223. endpoint_conf_t *ep_conf = &call->ep->conf;
  1224. if (call->video)
  1225. {
  1226. video_session_destroy(call->video);
  1227. call->video = NULL;
  1228. }
  1229. video_session_conf_t video_conf = {0};
  1230. video_conf.bit_rate = 256 * 1024;
  1231. video_conf.local_rtp_ip = 0;
  1232. video_conf.local_rtp_port = 0;
  1233. video_conf.local_video_view_x = local_view_x;
  1234. video_conf.local_video_view_y = local_view_y;
  1235. video_conf.local_video_view_cx = local_view_cx;
  1236. video_conf.local_video_view_cy = local_view_cy;
  1237. video_conf.local_move = local_move;
  1238. video_conf.mtu = ep_conf->mtu;
  1239. video_conf.video_quant = ep_conf->quant;
  1240. video_conf.remote_rtp_ip = 0;
  1241. video_conf.remote_rtp_port = 0;
  1242. video_conf.remote_video_view_x = 0;
  1243. video_conf.remote_video_view_y = 0;
  1244. video_conf.remote_video_view_cx = 0;
  1245. video_conf.remote_video_view_cy = 0;
  1246. video_conf.remote_video_width = 0;
  1247. video_conf.remote_video_height = 0;
  1248. video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
  1249. video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
  1250. video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
  1251. video_conf.ref_window_state = call->ep->conf.ref_window_state;
  1252. video_conf.ref_active_img = call->ep->conf.ref_active_img;
  1253. video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
  1254. video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
  1255. video_conf.ref_Is_showRecordArea = call->ep->conf.ref_Is_showRecordArea;
  1256. video_conf.camera_count = call->ep->conf.camera_count;
  1257. video_conf.screen_count = call->ep->conf.screen_count;
  1258. video_conf.eDeviceType = call->eDeviceType;
  1259. video_conf.video_echo_cb = cb;
  1260. video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP|VIDEOPLAYER_FLAG_ZOOMOUTSIZE;
  1261. video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
  1262. video_conf.eType = (eVideoRenderType)call->ep->conf.irendertype;
  1263. video_conf.ivideotype = call->ep->conf.icaptype;
  1264. rc = Local_video_session_create(&video_conf, &call->video);
  1265. if (rc != 0)
  1266. {
  1267. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create video session failed! rc = %d", rc);
  1268. return -1;
  1269. }
  1270. rc = video_session_start(call->video);
  1271. if (rc != 0)
  1272. {
  1273. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video session failed! rc = %d", rc);
  1274. video_session_destroy(call->video);
  1275. call->video = NULL;
  1276. return -1;
  1277. }
  1278. return 0;
  1279. }
  1280. 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)
  1281. {
  1282. int rc;
  1283. endpoint_conf_t *ep_conf = &call->ep->conf;
  1284. if (call->video)
  1285. {
  1286. video_session_destroy(call->video);
  1287. call->video = NULL;
  1288. }
  1289. int remote_video_width = REC_COMMON_VIDEO_SSM_AGENT_WIDTH;
  1290. int remote_video_height = REC_COMMON_VIDEO_SSM_AGENT_HEIGHT;
  1291. if (eStand2sType == call->eDeviceType){
  1292. remote_video_width = REC_COMMON_VIDEO_DSM_AGENT_WIDTH;
  1293. remote_video_height = REC_COMMON_VIDEO_DSM_AGENT_HEIGHT;
  1294. }
  1295. video_session_conf_t video_conf = {0};
  1296. video_conf.bit_rate = 256 * 1024;
  1297. video_conf.local_rtp_ip = 0;
  1298. video_conf.local_rtp_port = 0;
  1299. video_conf.local_video_view_x = local_view_x;
  1300. video_conf.local_video_view_y = local_view_y;
  1301. video_conf.local_video_view_cx = local_view_cx;
  1302. video_conf.local_video_view_cy = local_view_cy;
  1303. video_conf.local_move = local_move;
  1304. video_conf.mtu = ep_conf->mtu;
  1305. video_conf.video_quant = ep_conf->quant;
  1306. video_conf.remote_rtp_ip = 0;
  1307. video_conf.remote_rtp_port = 0;
  1308. video_conf.remote_video_view_x = remote_view_x;
  1309. video_conf.remote_video_view_y = remote_view_y;
  1310. video_conf.remote_video_view_cx = remote_view_cx;
  1311. video_conf.remote_video_view_cy = remote_view_cy;
  1312. video_conf.remote_move = remote_move;
  1313. video_conf.remote_video_width = remote_video_width;
  1314. video_conf.remote_video_height = remote_video_height;
  1315. video_conf.ref_active_camera = call->ep->conf.ref_active_camera;
  1316. video_conf.ref_camera_switch = call->ep->conf.ref_camera_switch;
  1317. video_conf.ref_camera_state = call->ep->conf.ref_camera_state;
  1318. video_conf.ref_window_state = call->ep->conf.ref_window_state;
  1319. video_conf.ref_active_img = call->ep->conf.ref_active_img;
  1320. video_conf.ref_Is_ActiveInspect = call->ep->conf.ref_Is_ActiveInspect;
  1321. video_conf.ref_Is_showPersonArea = call->ep->conf.ref_Is_showPersonArea;
  1322. video_conf.camera_count = call->ep->conf.camera_count;
  1323. video_conf.screen_count = call->ep->conf.screen_count;
  1324. video_conf.eDeviceType = call->eDeviceType;
  1325. video_conf.video_echo_cb = cb;
  1326. video_conf.ilocal_wind_flags = VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP;
  1327. video_conf.iremote_wind_flags = VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP;
  1328. video_conf.eType = (eVideoRenderType)call->ep->conf.irendertype;
  1329. video_conf.ivideotype = call->ep->conf.icaptype;
  1330. rc = Local_video_session_create(&video_conf, &call->video, true);
  1331. if (rc != 0){
  1332. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create video session failed! rc = %d", rc);
  1333. return -1;
  1334. }
  1335. rc = video_session_start(call->video);
  1336. if (rc != 0){
  1337. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video session failed! rc = %d", rc);
  1338. video_session_destroy(call->video);
  1339. call->video = NULL;
  1340. return -1;
  1341. }
  1342. return 0;
  1343. }
  1344. int local_play_stop_video(endpoint_call_t *call)
  1345. {
  1346. if (call) {
  1347. media_desc_t video_desc = {0};
  1348. video_desc.media_dir = DIR_NONE;
  1349. endpoint_media_update_video(call, &video_desc,NULL);
  1350. return 0;
  1351. } else
  1352. {
  1353. return Error_Param;
  1354. }
  1355. }
  1356. static void __endpoint_call_destroy(endpoint_call_t *call)
  1357. {
  1358. list_del(&call->entry);
  1359. if (call->ep && call->ep->active_call == call) {
  1360. call->ep->active_call = NULL;
  1361. }
  1362. su_home_unref(call->home);
  1363. }
  1364. int translate_ipaddr_from_int(char* strdst, size_t ulen, unsigned long uip)
  1365. {
  1366. int iret = -1;
  1367. if (NULL == strdst){
  1368. return iret;
  1369. }
  1370. char* pstr_ip = inet_ntoa(__lton(uip));
  1371. size_t ulen_ip = 0;
  1372. if (NULL != pstr_ip){
  1373. ulen_ip = strlen(pstr_ip);
  1374. if (ulen_ip < ulen){
  1375. memcpy(strdst, pstr_ip, ulen_ip);
  1376. iret = 0;
  1377. }
  1378. }
  1379. return iret;
  1380. }
  1381. IMPLEMENT_REF_COUNT_MT_STATIC(endpoint_call, endpoint_call_t, ref_cnt, __endpoint_call_destroy)