diff options
Diffstat (limited to 'src/lrtp.cc')
| -rw-r--r-- | src/lrtp.cc | 134 | 
1 files changed, 94 insertions, 40 deletions
| diff --git a/src/lrtp.cc b/src/lrtp.cc index b627c95..71854f0 100644 --- a/src/lrtp.cc +++ b/src/lrtp.cc @@ -45,9 +45,21 @@  extern "C" {  #endif +#define MAGIC 0x726c7074 + +// Check if 'h' is a valid smtl handle and report/return error if not. +#define CHECK_HANDLE(h)                         \ +  do {                                          \ +    if(!h || h->magic != MAGIC) {               \ +      return LRTP_MISSING_HANDLE;               \ +    }                                           \ +  } while(0) +  typedef std::map<csrc_t, lrtp_profile_t *> profile_map_t;  struct lrtp_t { +  unsigned int magic; +    SRTP *srtp;    csrc_t ssrc;    unsigned short seq; @@ -55,7 +67,7 @@ struct lrtp_t {    csrc_t next_csrc; // for frame iterator (see get_next_frame) -  std::list<outputframe_t *> framelist; +  oframelist_t framelist;  };  typedef struct { @@ -74,35 +86,71 @@ static const profile_class_t registered_profiles[] = {  };  EXPORT -struct lrtp_t *lrtp_init(const char *key, unsigned int ssrc) +struct lrtp_t *lrtp_init(enum lrtp_status_t *status, +                         const char *key, unsigned int ssrc)  { -  struct lrtp_t *lrtp = new struct lrtp_t; +  if(status == NULL) return NULL; -  lrtp->srtp = new SRTP(key, ssrc); +  struct lrtp_t *lrtp = new (std::nothrow) struct lrtp_t; +  if(!lrtp) { +    *status = LRTP_OUT_OF_MEMORY; +    return NULL; +  } + +  try { +    lrtp->srtp = new SRTP(key, ssrc); +  } catch(enum lrtp_status_t s) { +    *status = s; +    delete lrtp; +    return NULL; +  } +      lrtp->ssrc = ssrc;    lrtp->seq = 0; +  lrtp->magic = MAGIC; +    return lrtp;  }  EXPORT -void lrtp_close(struct lrtp_t *lrtp) +enum lrtp_status_t lrtp_close(struct lrtp_t *lrtp)  { -  delete lrtp->srtp; -  delete lrtp; +  CHECK_HANDLE(lrtp); + +  enum lrtp_status_t status = LRTP_OK; + +  try { +    if(lrtp->srtp) delete lrtp->srtp; +    lrtp->srtp = NULL; +  } catch(enum lrtp_status_t s) { +    status = s; +  } + +  lrtp->magic = 0; + +  try { +    delete lrtp; +  } catch(enum lrtp_status_t s) { +    status = s; +  } + +  return status;  }  EXPORT -int lrtp_create_profile(struct lrtp_t *lrtp, -                        lrtp_profile_id_t profile_id, -                        unsigned int csrc, ...) +enum lrtp_status_t lrtp_create_profile(struct lrtp_t *lrtp, +                                       lrtp_profile_id_t profile_id, +                                       unsigned int csrc, ...)  { +  CHECK_HANDLE(lrtp); +    struct lrtp_profile_t *profile = NULL;    if(lrtp->profiles.find(csrc) != lrtp->profiles.end()) {      // TODO: CSRC already active      printf("ERROR: CSRC already active\n"); -    return 1; +    return LRTP_CSRC_ALREADY_ACTIVE;    }    va_list ap; @@ -122,7 +170,7 @@ int lrtp_create_profile(struct lrtp_t *lrtp,    if(!profile) {      printf("ERROR: Could not find profile [%d]\n", profile_id); -    return 1; +    return LRTP_MISSING_PROFILE;    }    profile->id = profile_id; @@ -131,32 +179,34 @@ int lrtp_create_profile(struct lrtp_t *lrtp,    lrtp->profiles[csrc] = profile; -  return 0; +  return LRTP_OK;  }  EXPORT -void lrtp_destroy_profile(struct lrtp_t *lrtp, unsigned int csrc) +enum lrtp_status_t lrtp_destroy_profile(struct lrtp_t *lrtp, unsigned int csrc)  { +  CHECK_HANDLE(lrtp); +    if(lrtp->profiles.find(csrc) == lrtp->profiles.end()) { -    // TODO: CSRC not found -    printf("ERROR: CSRC not found\n"); -    return; +    return LRTP_MISSING_CSRC;    }    struct lrtp_profile_t *profile = lrtp->profiles[csrc];    profile->destroy(profile);    lrtp->profiles.erase(csrc); + +  return LRTP_OK;  }  EXPORT -int lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc, -                       char *data, size_t size, -                       unsigned long int timestamp) +enum lrtp_status_t lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc, +                                      char *data, size_t size, +                                      unsigned long int timestamp)  { +  CHECK_HANDLE(lrtp); +    if(lrtp->profiles.find(csrc) == lrtp->profiles.end()) { -    // TODO: CSRC not found -    printf("ERROR: CSRC not found\n"); -    return 1; +    return LRTP_MISSING_CSRC;    }    struct lrtp_profile_t *profile = lrtp->profiles[csrc]; @@ -171,7 +221,7 @@ int lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc,    profile->framelist.push_back(frame); -  return 0; +  return LRTP_OK;  }  // Assume we have at least one csrc in the list @@ -219,6 +269,8 @@ static lrtp_profile_t *get_next_profile(struct lrtp_t *lrtp)  EXPORT  int lrtp_pack(struct lrtp_t *lrtp, char *packet, size_t maxsize)  { +  CHECK_HANDLE(lrtp); +    //if(!profile) return PACK_MISSING_PROFILE;    // TODO: Check profile magic word @@ -271,6 +323,8 @@ int lrtp_dequeue_frame(struct lrtp_t *lrtp,                         char *frame, size_t maxsize,                         unsigned int *csrc, unsigned int *ts)  { +  CHECK_HANDLE(lrtp); +    if(lrtp->framelist.size() == 0) return 0;    outputframe_t *f = lrtp->framelist.front(); @@ -297,11 +351,10 @@ int lrtp_dequeue_frame(struct lrtp_t *lrtp,  }  EXPORT -int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size) +enum lrtp_status_t lrtp_unpack(struct lrtp_t *lrtp, +                               const char *packet, size_t size)  { -  if(!lrtp) return -UNPACK_MISSING_HANDLE; - -  // TODO: Check lrtp magic word +  CHECK_HANDLE(lrtp);    char *pkg = (char*)malloc(size);    memcpy(pkg, packet, size); @@ -309,12 +362,11 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)    int ret = 0;  #ifndef SKIP_SRTP -  ret = lrtp->srtp->decrypt(pkg, size); - -  if(ret < 0) { -    printf("lrtp_unpack::decrypt error: %d\n", ret); +  try { +    ret = lrtp->srtp->decrypt(pkg, size); +  } catch(enum lrtp_status_t s) {      free(pkg); -    return -1; +    return s;    }    size = ret; @@ -325,11 +377,11 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)    std::list<csrc_t> csrcs = rtp.getCSrcs();    if(csrcs.size() == 0) {      free(pkg); -    return -UNPACK_MISSING_CSRC; +    return LRTP_MISSING_CSRC;    }    if(csrcs.size() > 1) {      free(pkg); -    return -UNPACK_TOO_MANY_CSRCS; +    return LRTP_TOO_MANY_CSRCS;    }    csrc_t csrc = *csrcs.begin(); @@ -337,22 +389,22 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)    struct lrtp_profile_t *profile = NULL;    if(lrtp->profiles.find(csrc) == lrtp->profiles.end()) {      free(pkg); -    return -UNPACK_MISSING_PROFILE; +    return LRTP_MISSING_PROFILE;    }    profile = lrtp->profiles[csrc]; -  std::list<outputframe_t*> framelist; +  oframelist_t framelist;    ret = profile->unpack(profile, rtp, framelist);    if(ret < 0) {      printf("lrtp_unpack::Profile unpack failed: %d\n", ret);      free(pkg); -    return -1; +    return (enum lrtp_status_t)ret;    }    // Make sure all frames in the list have the correct csrc. -  std::list<outputframe_t*>::iterator fi = framelist.begin(); +  oframelist_t::iterator fi = framelist.begin();    while(fi != framelist.end()) {      (*fi)->csrc = csrc;      fi++; @@ -362,9 +414,11 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)    free(pkg); -  return ret; +  return LRTP_OK;  } +// NOTE: lrtp_strerror implemented in error.cc +  #ifdef __cplusplus  }  #endif | 
