diff intercom/rtp.cpp @ 2:13be24d74cd2

import intercom-0.4.1
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 09:57:52 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/intercom/rtp.cpp	Fri Jun 25 09:57:52 2010 +0200
@@ -0,0 +1,199 @@
+/* rtp.cpp
+ *
+ * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). 
+ * All Rights Reserved.
+ * Author: Andre Adrian
+ *
+ * subset of Real Time Protocol Version 2 (RFC3550)
+ * handling of extension and padding is missing
+ *
+ * Version 0.3
+ */
+
+#include <stdio.h>              /* printf() */
+#include <stdlib.h>
+
+#include <sys/types.h>          /* u_long */
+#include <sys/time.h>           /* gettimeofday() */
+#include <unistd.h>             /* get..() */
+#include <time.h>               /* clock() */
+#include <sys/utsname.h>        /* uname() */
+#include <netinet/in.h>
+#include <assert.h>
+
+#include "intercomd.h"
+#include "rtp.h"
+
+/*
+ * Return random unsigned 32-bit quantity.  Use 'type' argument if
+ * you need to generate several different values in close succession.
+ * (partly from RFC 3550 A.6 Generating a Random 32-bit Identifier)
+ */
+unsigned long random32(int type)
+{
+  struct {
+    int type;
+    struct timeval tv;
+    clock_t cpu;
+    pid_t pid;
+    u_long hid;
+    uid_t uid;
+    gid_t gid;
+    struct utsname name;
+  } s;
+
+  gettimeofday(&s.tv, 0);
+  uname(&s.name);
+  s.type = type;
+  s.cpu = clock();
+  s.pid = getpid();
+  s.hid = gethostid();
+  s.uid = getuid();
+  s.gid = getgid();
+  /* also: system uptime */
+
+  unsigned long *us = (unsigned long *) &s;
+
+  /* use xor to make a (bad) random */
+  /* Note: remainder of long div of 32bit prim is better */
+  unsigned long random = 0;
+  unsigned int i;
+  for (i = 0; i < sizeof(s) / sizeof(long); ++i) {
+    random ^= *us++;
+  }
+  return random;
+}                               /* random32 */
+
+
+RTP::RTP()
+{
+  version = 2;
+  padding = 0;
+  extension = 0;
+  csrc_count = 0;
+  marker = 0;
+  payload_type = PT_PCMU;
+  ssrc = 0;
+  sequence = 0;
+  timestamp = 0;
+}
+
+void RTP::init(int payload_type_, unsigned long ssrc_)
+{
+  version = 2;
+  padding = 0;
+  extension = 0;
+  csrc_count = 0;
+  marker = 0;
+  payload_type = payload_type_;
+  ssrc = ssrc_;
+  /*  My interpretation of RFC3550 A.6: one seed is good enough */
+  sequence = random32(payload_type_);
+  timestamp = sequence;
+}
+
+void RTP::next(int frameduration)
+{
+  ++sequence;
+  timestamp += frameduration;
+}
+
+void RTP::reset_csrc()
+{
+  csrc_count = 0;
+}
+ 
+int RTP::add_csrc(unsigned long csrc_)
+{
+  return_if (csrc_count >= 15, ERROR);
+  csrc[csrc_count++] = csrc_;
+  
+  // printf("add_csrc = %08x\n", csrc_);
+  return OKAY;
+}
+
+int RTP::find_csrc(unsigned long ssrc_)
+{
+  unsigned int i;
+  
+  if (0 == csrc_count) return NO;
+  // printf("find_csrc = %08x ", ssrc_);
+  for (i = 0; i < csrc_count; ++i) {
+    // printf("%08x ", csrc[i]);
+    if (csrc[i] == ssrc_) {
+      // printf("hit\n");
+      return YES;
+    }
+  }
+  return NO;
+}
+
+int RTP::check()
+{
+  // RFC3550 A.1 RTP Data Header Validity Checks
+
+  // RTP version field must equal 2.
+  if (version != 2)
+    return -1;
+
+  // The payload type must be known
+  switch (payload_type) {
+    case PT_PCMU:
+    case PT_GSM:
+    case PT_PCMA:
+    case PT_G729:
+    case PT_iLBC:
+    case PT_EFR: 
+    case PT_G726:
+    case PT_SPX:
+      /* do nothing */
+      break;
+    default:
+      return -1;
+  }    
+
+  // The X bit must be zero if the profile does not specify that the
+  // header extension mechanism may be used.  Otherwise, the extension
+  // length field must be less than the total packet size minus the
+  // fixed header length and padding.
+  if (extension)
+    return -1;                  // hack!
+
+  // The length of the packet must be consistent with CC and payload
+  // type (if payloads have a known length).
+  // equal to SR or RR.
+  // if (csrc_count != 0)
+  //  return -1;                  // hack!
+
+  // If the P bit is set, then the last octet of the packet must
+  // contain a valid octet count, in particular, less than the total
+  // packet length minus the header size.
+  if (padding)
+    return -1;                  // hack!
+  return 0;
+}
+
+char *RTP_network_copy(char *to, RTP * from)
+{
+  unsigned long *ulfrom = (unsigned long *) from;
+  unsigned long *ulto = (unsigned long *) to;
+  int i;
+  for (i = 0; i < 3 + from->get_cc(); ++i) {
+    *ulto++ = htonl(*ulfrom++);
+  }
+  return (char *) ulto;
+}
+
+char *RTP_host_copy(RTP * to, char *from)
+{
+  unsigned long *ulfrom = (unsigned long *) from;
+  unsigned long *ulto = (unsigned long *) to;
+  int i;
+  for (i = 0; i < 3; ++i) {
+    *ulto++ = ntohl(*ulfrom++);
+  }
+  for (i = 0; i < to->get_cc(); ++i) {
+    *ulto++ = ntohl(*ulfrom++);
+  }
+  return (char *) ulfrom;
+}

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.