Home | History | Annotate | Download | only in test
      1 /*
      2  * rtp.c
      3  *
      4  * library functions for the real-time transport protocol
      5  *
      6  * David A. McGrew
      7  * Cisco Systems, Inc.
      8  */
      9 
     10 
     11 #include "rtp_priv.h"
     12 
     13 #include <stdio.h>
     14 #include <string.h>
     15 
     16 #include <sys/types.h>
     17 #ifdef HAVE_SYS_SOCKET_H
     18 # include <sys/socket.h>
     19 #endif
     20 
     21 #define PRINT_DEBUG    0    /* set to 1 to print out debugging data */
     22 #define VERBOSE_DEBUG  0    /* set to 1 to print out more data      */
     23 
     24 unsigned int
     25 rtp_sendto(rtp_sender_t sender, const void* msg, int len) {
     26   int octets_sent;
     27   err_status_t stat;
     28   int pkt_len = len + RTP_HEADER_LEN;
     29 
     30   /* marshal data */
     31   strncpy(sender->message.body, msg, len);
     32 
     33   /* update header */
     34   sender->message.header.seq = ntohs(sender->message.header.seq) + 1;
     35   sender->message.header.seq = htons(sender->message.header.seq);
     36   sender->message.header.ts = ntohl(sender->message.header.ts) + 1;
     37   sender->message.header.ts = htonl(sender->message.header.ts);
     38 
     39   /* apply srtp */
     40   stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len);
     41   if (stat) {
     42 #if PRINT_DEBUG
     43     fprintf(stderr, "error: srtp protection failed with code %d\n", stat);
     44 #endif
     45     return -1;
     46   }
     47 #if VERBOSE_DEBUG
     48   srtp_print_packet(&sender->message.header, pkt_len);
     49 #endif
     50   octets_sent = sendto(sender->socket, (void*)&sender->message,
     51 		       pkt_len, 0, (struct sockaddr *)&sender->addr,
     52 		       sizeof (struct sockaddr_in));
     53 
     54   if (octets_sent != pkt_len) {
     55 #if PRINT_DEBUG
     56     fprintf(stderr, "error: couldn't send message %s", (char *)msg);
     57     perror("");
     58 #endif
     59   }
     60 
     61   return octets_sent;
     62 }
     63 
     64 unsigned int
     65 rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) {
     66   int octets_recvd;
     67   err_status_t stat;
     68 
     69   octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message,
     70 			 *len, 0, (struct sockaddr *) NULL, 0);
     71 
     72   /* verify rtp header */
     73   if (receiver->message.header.version != 2) {
     74     *len = 0;
     75     return -1;
     76   }
     77 
     78 #if PRINT_DEBUG
     79   fprintf(stderr, "%d octets received from SSRC %u\n",
     80 	  octets_recvd, receiver->message.header.ssrc);
     81 #endif
     82 #if VERBOSE_DEBUG
     83   srtp_print_packet(&receiver->message.header, octets_recvd);
     84 #endif
     85 
     86   /* apply srtp */
     87   stat = srtp_unprotect(receiver->srtp_ctx,
     88 			&receiver->message.header, &octets_recvd);
     89   if (stat) {
     90     fprintf(stderr,
     91 	    "error: srtp unprotection failed with code %d%s\n", stat,
     92 	    stat == err_status_replay_fail ? " (replay check failed)" :
     93 	    stat == err_status_auth_fail ? " (auth check failed)" : "");
     94     return -1;
     95   }
     96   strncpy(msg, receiver->message.body, octets_recvd);
     97 
     98   return octets_recvd;
     99 }
    100 
    101 int
    102 rtp_sender_init(rtp_sender_t sender,
    103 		int socket,
    104 		struct sockaddr_in addr,
    105 		unsigned int ssrc) {
    106 
    107   /* set header values */
    108   sender->message.header.ssrc    = htonl(ssrc);
    109   sender->message.header.ts      = 0;
    110   sender->message.header.seq     = (uint16_t) rand();
    111   sender->message.header.m       = 0;
    112   sender->message.header.pt      = 0x1;
    113   sender->message.header.version = 2;
    114   sender->message.header.p       = 0;
    115   sender->message.header.x       = 0;
    116   sender->message.header.cc      = 0;
    117 
    118   /* set other stuff */
    119   sender->socket = socket;
    120   sender->addr = addr;
    121 
    122   return 0;
    123 }
    124 
    125 int
    126 rtp_receiver_init(rtp_receiver_t rcvr,
    127 		  int socket,
    128 		  struct sockaddr_in addr,
    129 		  unsigned int ssrc) {
    130 
    131   /* set header values */
    132   rcvr->message.header.ssrc    = htonl(ssrc);
    133   rcvr->message.header.ts      = 0;
    134   rcvr->message.header.seq     = 0;
    135   rcvr->message.header.m       = 0;
    136   rcvr->message.header.pt      = 0x1;
    137   rcvr->message.header.version = 2;
    138   rcvr->message.header.p       = 0;
    139   rcvr->message.header.x       = 0;
    140   rcvr->message.header.cc      = 0;
    141 
    142   /* set other stuff */
    143   rcvr->socket = socket;
    144   rcvr->addr = addr;
    145 
    146   return 0;
    147 }
    148 
    149 int
    150 rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy) {
    151   return srtp_create(&sender->srtp_ctx, policy);
    152 }
    153 
    154 int
    155 rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy) {
    156   return srtp_create(&sender->srtp_ctx, policy);
    157 }
    158 
    159 rtp_sender_t
    160 rtp_sender_alloc() {
    161   return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
    162 }
    163 
    164 rtp_receiver_t
    165 rtp_receiver_alloc() {
    166   return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
    167 }
    168