endpoint.cpp 43 KB

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