rtptst.cpp
上传用户:hnnddl
上传日期:2007-01-06
资源大小:3580k
文件大小:11k
源码类别:

IP电话/视频会议

开发平台:

WINDOWS

  1. /*
  2.  * $Revision: 1.1 $
  3.  * $Date: 1997/08/15 15:45:39 $
  4.  */
  5. ////////////////////////////////////////////////////////////////
  6. //               Copyright (c) 1996 Lucent Technologies       //
  7. //                       All Rights Reserved                  //
  8. //                                                            //
  9. //                       THIS IS UNPUBLISHED                  //
  10. //                       PROPRIETARY SOURCE                   //
  11. //                   CODE OF Lucent Technologies              //
  12. //                       AND elemedia   //
  13. //                                                            //
  14. //           The copyright notice above does not evidence any //
  15. //          actual or intended publication of such source code//
  16. ////////////////////////////////////////////////////////////////
  17. /////////////////////////////////////////////////////////////////
  18. // File : rtptst.cpp    //
  19. //                                                             //
  20. // Test the RTP library.                                       //
  21. // Bidirectional RTP pipe.                                     //
  22. // Read from local and write into remote and vice versa..      //
  23. // Treats packets from remote side as being conformat to the   //
  24. // RTP protocol, and the local side as raw UDP packets.    //
  25. //                                                             //
  26. //    ---------------------------------------------            //
  27. //     REMOTE         RTPTST.EXE           LOCAL               //
  28. //      END                                 END                //
  29. //    ---------------------------------------------            //
  30. //      RTP ----->   Deframe RTP -----> UDP packets            //
  31. //      Packets                                                //
  32. //                                                             //
  33. //      RTP                                                    //
  34. //      Packets <------Frame RTP <-----UDP packets             //
  35. //                                                            //
  36. // History:    //
  37. //  24_Jan_1997 Created    //
  38. // 15_Aug_1997 Merged the win32 and unix versions.    //
  39. //    //
  40. /////////////////////////////////////////////////////////////////
  41. #include "stdio.h"
  42. #if (defined(WIN32))
  43. #include <windows.h>
  44. #include <winsock.h>
  45. #include <assert.h>
  46. #else
  47. #include <sys/types.h>
  48. #include <sys/socket.h>
  49. #include <netdb.h>
  50. #include <netinet/in.h>
  51. #include <arpa/inet.h>
  52. #include <thread.h>
  53. #include <unistd.h>
  54. #include <signal.h>
  55. #include <errno.h>
  56. #endif
  57. #include "rtp/rtp.h"
  58. #if (!defined(WIN32))
  59. #define SOCKET_ERROR -1
  60. #if (defined(__sun))
  61. #define INADDR_NONE 0xFFFFFFFF
  62. #endif
  63. typedef int SOCKET;
  64. #endif
  65. #define NUM_PATHS 2
  66. #define RTCP_INTERVAL 60 // rtcp activity once every 60 packets(90ms).
  67. char ip_address[2][256];
  68. unsigned short src_port[NUM_PATHS];
  69. unsigned short dst_port[NUM_PATHS];
  70. struct sockaddr_in src_addr[NUM_PATHS];
  71. struct sockaddr_in dst_addr[NUM_PATHS];
  72. SOCKET src[NUM_PATHS], dst[NUM_PATHS];
  73. SOCKET path[NUM_PATHS];
  74. SOCKET rtcp[2];
  75. struct sockaddr_in rtcp_addr[NUM_PATHS];
  76. int use_rtp = 1;
  77. void
  78. print_usage(char *appname)
  79. {
  80. printf("Usage: %s nonrtp-ip/input/output rtp-ip/input/outputn", appname);
  81. }
  82. void
  83. addr_init(struct sockaddr_in *addr, char *ip_address, 
  84. unsigned short port)
  85. {
  86. unsigned long ip;
  87. memset(addr, 0, sizeof(*addr));
  88. addr->sin_family = AF_INET;
  89. addr->sin_port = htons(port);
  90. if (ip_address)
  91. {
  92. ip = inet_addr(ip_address); 
  93. if (ip == INADDR_NONE)
  94. {
  95. struct hostent *hent_p = 
  96. gethostbyname((char *)ip_address);
  97. if(hent_p == NULL)
  98. {
  99. printf("Gethostbyname failed on %sn",ip_address);
  100. return;
  101. }
  102. ip = *(unsigned long *)(hent_p->h_addr_list[0]);
  103. }
  104. }
  105. else
  106. {
  107. ip = INADDR_ANY;
  108. }
  109. addr->sin_addr.s_addr = ip;
  110. }
  111. void 
  112. socket_error(SOCKET s, char *message)
  113. {
  114. #if (defined(WIN32))
  115. printf("socket = %d, errno = %d, %sn",
  116. s, WSAGetLastError(), message);
  117. #else
  118. printf("socket = %d, errno = %d, %sn",
  119. s, errno, message);
  120. #endif
  121. }
  122. void just_do_it()
  123. {
  124. fd_set  read_fds;
  125. char buffer[4096];
  126. char *buf = buffer;
  127. int buf_len = sizeof(buffer);
  128. int length;
  129. int i;
  130. int packets_sent_count = 0;
  131. int packets_recd_count = 0;
  132. printf("Begin...n");
  133. path[0] = dst[1];
  134. path[1] = dst[0];
  135. FD_ZERO(&read_fds);
  136. for (i=0; i<NUM_PATHS; ++i)
  137. {
  138. FD_SET(src[i],&read_fds);
  139. }
  140. if (use_rtp)
  141. {
  142. boolean frame[2];
  143. RTPSession session(ip_address[0],RTPPacket::PT_PCMU,8000);
  144. RTPPacket *framer = NULL;
  145. RTPPacket *deframer = NULL;
  146. RTCPPacket rtcp_packet(&session);
  147. int nfds = 0;
  148. deframer = new RTPPacket(&session,0);
  149. frame[0] = TRUE;
  150. frame[1] = FALSE;
  151. for (i=0;i<NUM_PATHS;++i)
  152. {
  153. if (nfds < src[i])
  154. {
  155. nfds = src[i];
  156. }
  157. }
  158. nfds++;
  159. while (1)
  160. {
  161. select(nfds, &read_fds, NULL, NULL, NULL);
  162. for (i=0;i<NUM_PATHS;++i)
  163. {
  164. if (FD_ISSET(src[i],&read_fds))
  165. {
  166. if (frame[i])
  167. {
  168. if (!framer)
  169. {
  170. length = recv(src[i],buf, buf_len,0);
  171. framer = new RTPPacket(&session,length);
  172. printf("Framer created payload len = %d, packetlen = %dn",
  173. length, framer->GetMaxPacketLength());
  174. memcpy(framer->GetPayload(), buf, length);
  175. }
  176. else
  177. {
  178. length = recv(src[i],framer->GetPayload(),
  179. framer->GetMaxPayloadLength(),0);
  180. }
  181. framer->Frame(session.GetMediaTime(),0, length);
  182. send(path[i], framer->GetPacket(),
  183. framer->GetPacketLength(),0);
  184. packets_sent_count++;
  185. }
  186. else
  187. {
  188. length = recv(src[i],buf,buf_len,0);
  189. if (length > 0)
  190. {
  191. int ret = 
  192. deframer->Deframe(buf,length, session.GetMediaTime());
  193. if (ret != 0)
  194. {
  195. printf("RTPPacket::Deframe returned %dn",ret);
  196. }
  197. send(path[i], deframer->GetPayload(),
  198. deframer->GetPayloadLength(),0);
  199. ++packets_recd_count;
  200. }
  201. }
  202. }
  203. }
  204. if (FD_ISSET(rtcp[0],&read_fds))
  205. {
  206. unsigned int ntp_sec;
  207. unsigned int ntp_frac;
  208. RTCPSenderInfo *sender_info;
  209. printf("Received rtcp packet..n");
  210. length = recv(rtcp[0], buf,buf_len,0);
  211. ntp64time(ntp_sec,ntp_frac);
  212. rtcp_packet.Deframe(buf,length, ntp_sec,
  213. ntp_frac);
  214. rtcp_packet.GetSenderInfo(sender_info);
  215. if (sender_info)
  216. {
  217. printf("Sender info..n");
  218. printf("Num packets = %dn", sender_info->sr_np);
  219. printf("Num bytes = %dn", sender_info->sr_nb);
  220. }
  221. int rr;
  222. RTCPReceptionReport *rr_list;
  223. rr = rtcp_packet.GetReceptionReports(rr_list);
  224. printf("Receiver report for %d reportsn",rr);
  225. while (rr > 0)
  226. {
  227. printf("{n"
  228. "trr_srcid = 0x%lxn"
  229. "trr_loss = %d:%dn"
  230. "trr_ehsr = %dn"
  231. "trr_dv = %dn"
  232. "trr_lsr = %dn"
  233. "trr_dlsr = %dn"
  234. "}n",
  235. rr_list[rr - 1].rr_srcid,
  236. RTCP_GET_INCREMENTAL_LOSS(rr_list[rr - 1].rr_loss),
  237. RTCP_GET_CUMULATIVE_LOSS(rr_list[rr - 1].rr_loss),
  238. rr_list[rr - 1].rr_ehsr,
  239. rr_list[rr - 1].rr_dv,
  240. rr_list[rr - 1].rr_lsr,
  241. rr_list[rr - 1].rr_dlsr);
  242. --rr;
  243. }
  244. RTPEndpointInfo *e;
  245. e = session.GetParticipant(rtcp_packet.GetSSRC());
  246. if (e)
  247. {
  248. RTPEndpointStats res;
  249. e->GetStatistics(res);
  250. printf("Endpoint stats for 0x%lxn"
  251. "{n"
  252. "tprobation = %dn"
  253. "tmisorder = %dn"
  254. "treceived = %dn"
  255. "tdelay_variance = %dn"
  256. "tpackets_sent = %dn"
  257. "toctets_sent = %dn"
  258. "}n",
  259. res.es_ssrc,
  260. res.es_probation,
  261. res.es_misorder,
  262. res.es_received,
  263. res.es_delay_variance,
  264. res.es_packets_sent,
  265. res.es_octets_sent);
  266. }
  267. }
  268. if ((packets_sent_count == RTCP_INTERVAL) || (packets_recd_count ==
  269. RTCP_INTERVAL))
  270. {
  271. unsigned int ntp_sec;
  272. unsigned int ntp_frac;
  273. //TODO
  274. // build and send an RTCP report
  275. printf("Sending rtcp packet..n");
  276. ntp64time(ntp_sec,ntp_frac);
  277. rtcp_packet.Frame(session.GetMediaTime(), ntp_sec,
  278. ntp_frac, 0,0, NULL,0);
  279. send(rtcp[1],rtcp_packet.GetPacket(),
  280. rtcp_packet.GetPacketLength(),0);
  281. if (packets_sent_count == RTCP_INTERVAL)
  282. {
  283. packets_sent_count = 0;
  284. }
  285. else
  286. {
  287. packets_recd_count = 0;
  288. }
  289. }
  290. FD_ZERO(&read_fds);
  291. for (i=0; i<NUM_PATHS; ++i)
  292. {
  293. FD_SET(src[i],&read_fds);
  294. }
  295. FD_SET(rtcp[0],&read_fds); // rtcp socket.
  296. }
  297. }
  298. else
  299. {
  300. while (1)
  301. {
  302. select(0, &read_fds, NULL, NULL, NULL);
  303. for (i=0;i<NUM_PATHS;++i)
  304. {
  305. if (FD_ISSET(src[i],&read_fds))
  306. {
  307. length = recv(src[i],buf,buf_len,0);
  308. if (length > 0)
  309. {
  310. send(path[i],buf,length,0);
  311. }
  312. }
  313. }
  314. FD_ZERO(&read_fds);
  315. for (i=0; i<NUM_PATHS; ++i)
  316. {
  317. FD_SET(src[i],&read_fds);
  318. }
  319. }
  320. }
  321. }
  322. int
  323. parse_command_line(int argc, char **argv)
  324. {
  325. int tmp1;
  326. int tmp2;
  327. if (argc < 3)
  328. {
  329. return 1;
  330. }
  331. if (sscanf(argv[1], "%[^/]%*[/]%d%*[/]%d", ip_address[0], 
  332. &tmp1, &tmp2) != 3)
  333. {
  334. return 1;
  335. }
  336. src_port[0] = tmp1;
  337. dst_port[0] = tmp2;
  338. if (sscanf(argv[2], "%[^/]%*[/]%d%*[/]%d", ip_address[1], 
  339. &tmp1, &tmp2) != 3)
  340. {
  341. return 1;
  342. }
  343. src_port[1] = tmp1;
  344. dst_port[1] = tmp2;
  345. printf("%s/%d/%dn",ip_address[0], src_port[0], dst_port[0]);
  346. printf("%s/%d/%dn",ip_address[1], src_port[1], dst_port[1]);
  347. if (argc >= 4)
  348. {
  349. if (!stricmp(argv[3],"nortp"))
  350. use_rtp = 0;
  351. else
  352. use_rtp = 1;
  353. }
  354. printf("USE_RTP = %sn",use_rtp ? "Yes" : "No");
  355. return 0;
  356. }
  357. int
  358. main (int argc, char ** argv)
  359. {
  360. #if (defined(WIN32))
  361.     WSADATA wsadata;
  362. WSAStartup(MAKEWORD(1,1), &wsadata);
  363. #endif
  364. if (parse_command_line(argc,argv))
  365. {
  366. print_usage(argv[0]);
  367. exit(1);
  368. }
  369. int i;
  370. // the sockets...
  371. src[0] = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  372. src[1] = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  373. dst[0] = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  374. dst[1] = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  375. if (src[0] == SOCKET_ERROR || dst[0] == SOCKET_ERROR ||
  376. (src[1] == SOCKET_ERROR || dst[1] == SOCKET_ERROR))
  377. {
  378. #if (defined(WIN32))
  379. printf("Socket creation failed %dn", WSAGetLastError());
  380. #else
  381. printf("Socket creation failed %dn", errno);
  382. #endif
  383. exit(0);
  384. }
  385. for (i=0;i<NUM_PATHS; ++i)
  386. {
  387. addr_init(src_addr + i, NULL, src_port[i]);
  388. addr_init(dst_addr + i, ip_address[i], dst_port[i]);
  389. printf("binding on socket = %d, ip = 0x%lx, port = %dn", src[i], 
  390. htonl(((struct sockaddr_in*)(src_addr + i))->sin_addr.s_addr),
  391. htons(((struct sockaddr_in*)(src_addr + i))->sin_port));
  392. if (bind(src[i],(struct sockaddr*)(src_addr + i),
  393. sizeof(struct sockaddr_in)) == SOCKET_ERROR)
  394. {
  395. socket_error(src[i],"bind");
  396. exit(1);
  397. }
  398. printf("connect on socket = %d, ip = 0x%x, port = %dn", dst[i], 
  399. htonl(((struct sockaddr_in*)(dst_addr + i))->sin_addr.s_addr),
  400. htons(((struct sockaddr_in*)(dst_addr + i))->sin_port));
  401. if (connect(dst[i],(struct sockaddr*)(dst_addr + i),
  402. sizeof(struct sockaddr_in)) == SOCKET_ERROR)
  403. {
  404. socket_error(dst[i],"connect");
  405. exit(1);
  406. }
  407. }
  408. rtcp[0] = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);// recv
  409. rtcp[1] = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // send
  410. addr_init(rtcp_addr + 0, NULL, src_port[1] + 1); // listen
  411. addr_init(rtcp_addr + 1, ip_address[1], dst_port[1] + 1); // send
  412. if (connect(rtcp[1],(struct sockaddr*)(rtcp_addr + 1),
  413. sizeof(struct sockaddr_in)) == SOCKET_ERROR)
  414. {
  415. socket_error(rtcp[1],"connect");
  416. exit(1);
  417. }
  418. if (bind(rtcp[0],(struct sockaddr*)(rtcp_addr + 0),
  419. sizeof(struct sockaddr_in)) == SOCKET_ERROR)
  420. {
  421. socket_error(rtcp[0],"bind");
  422. exit(1);
  423. }
  424. just_do_it();
  425. }