Merge branch 'master' of ssh://box.fiane.intra/var/lib/git/libucore
This commit is contained in:
+119
-3
@@ -17,57 +17,173 @@ enum UC_MBUF_FLAGS {
|
||||
};
|
||||
|
||||
struct MBuf {
|
||||
/** prev/next pointer, user can use this for a linked list*/
|
||||
struct MBuf *prev;
|
||||
struct MBuf *next;
|
||||
/** Pointers the user can use to remember spots in
|
||||
* the data. (these must either be NULL pointers or point into
|
||||
* something in the buffer*/
|
||||
uint8_t *p1;
|
||||
uint8_t *p2;
|
||||
uint8_t *p3;
|
||||
uint8_t *p4;
|
||||
/**Arbitary pointer user can associate with the mbuf*/
|
||||
void *cookie;
|
||||
|
||||
uint32_t flags;
|
||||
/** Total no of bytes from bufstart*/
|
||||
uint32_t allocated;
|
||||
/** Start of the buffer*/
|
||||
uint8_t *bufstart;
|
||||
/** Start of the data in the buffer*/
|
||||
uint8_t *head;
|
||||
/** End of the buffer (one byte past the data) */
|
||||
uint8_t *tail;
|
||||
/** Internal data, if we allocate it inline */
|
||||
uint8_t inline_data[0];
|
||||
};
|
||||
|
||||
/* Conventions:
|
||||
/**
|
||||
* Concept:
|
||||
* <--------- allocated ----------->
|
||||
* <--- len -->
|
||||
* +--------------------------------+
|
||||
* |Headroom| Data |Tailroom |
|
||||
* +--------------------------------+
|
||||
* ^ ^ ^
|
||||
* | | |
|
||||
* | | tail
|
||||
* | head
|
||||
* bufstart
|
||||
*
|
||||
* Initially when empty, head == tail, and the length is 0.
|
||||
* Data is added to the tail.
|
||||
*
|
||||
* If head == bufstart, there is no headroom
|
||||
* if tail points one past the allocated space, there is no
|
||||
* tailroom (the buffer is full)
|
||||
*
|
||||
* Conventions:
|
||||
* push - prepend data to the buffer (in the head room part)
|
||||
* (move head to the left)
|
||||
* pull - remove data from the beginning of the message.
|
||||
* (move head to the right)
|
||||
* put - Add data to the buffer.
|
||||
* (move tail to the right)
|
||||
*/
|
||||
|
||||
/** Allocate an mbuf with a length and headroom,
|
||||
* the buffer will have the flag UC_MBUF_FL_MALLOC
|
||||
* The total length of the buffer will be length+headroom
|
||||
*
|
||||
* @param len the initial length of the mbuf
|
||||
* @param the initial headroom of the mbuf
|
||||
* @return NULL if the allocation fails
|
||||
*/
|
||||
struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom);
|
||||
|
||||
/** As uc_mbuf_new_hr, but without any headroom*/
|
||||
#define uc_mbuf_new(len) uc_mbuf_new_hr((len), 0)
|
||||
|
||||
|
||||
/** Allocate an mbuf with a length and headroom,
|
||||
* the buffer will have the flag UC_MBUF_FL_MALLOC_INLINE
|
||||
* The total length of the buffer will be length+headroom
|
||||
*
|
||||
* @param len the initial length of the mbuf
|
||||
* @param the initial headroom of the mbuf
|
||||
* @return NULL if the allocation fails
|
||||
*/
|
||||
struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom);
|
||||
|
||||
/** As uc_mbuf_new_inline_hr, but without any headroom*/
|
||||
#define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0)
|
||||
|
||||
/** @param mbuf the mbuf to free. (passing NULL is a no-op)*/
|
||||
void uc_mbuf_free(struct MBuf *mbuf);
|
||||
|
||||
/** Create a new mbuf, with a copy of the data from the given
|
||||
* mbuf. The new mbuf will have the same headroom as the old one,
|
||||
* but no tailroom.
|
||||
*
|
||||
* @param mbuf mbuf to copy
|
||||
*/
|
||||
struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf);
|
||||
|
||||
/** Initialize an mbuf. This function is mostly used internally,
|
||||
* but can be used to e.g. create an mbuf based on a local array
|
||||
* (in which case UC_MBUF_FL_STATIC must be set), or other data
|
||||
* whose memory is already allocated.
|
||||
*
|
||||
* The whole buffer must have len + headroom available data
|
||||
*
|
||||
* @param mbuf to initialise
|
||||
* @param buf start of the buffer
|
||||
* @param len length of the buffer (not including the headroom)
|
||||
* @param headroom the headroom in the buffer
|
||||
* @param flags The appropriate UC_MBUF_FLAGS
|
||||
*/
|
||||
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags);
|
||||
void uc_mbuf_zero(struct MBuf *mbuf);
|
||||
void uc_mbuf_reset(struct MBuf *mbuf);
|
||||
|
||||
/** Zero out all the data in this mbuf, including the headroom
|
||||
*
|
||||
* @param mbuf mbuf to zero out
|
||||
*/
|
||||
void uc_mbuf_zero(struct MBuf *mbuf);
|
||||
|
||||
/**
|
||||
* @return the length of the data in this mbuf
|
||||
*/
|
||||
static UC_INLINE uint32_t uc_mbuf_len(struct MBuf *mbuf)
|
||||
{
|
||||
return (uint32_t)(mbuf->tail - mbuf->head);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the length of the tailroom in this mbuf
|
||||
*/
|
||||
static UC_INLINE uint32_t uc_mbuf_tailroom(struct MBuf *mbuf)
|
||||
{
|
||||
return mbuf->allocated - (uint32_t)(mbuf->tail - mbuf->bufstart);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the length of the headroom in this mbuf
|
||||
*/
|
||||
static inline uint32_t uc_mbuf_headroom(struct MBuf *mbuf)
|
||||
{
|
||||
return (uint32_t)(mbuf->head - mbuf->bufstart);
|
||||
}
|
||||
|
||||
|
||||
/** Append data data to this buffer
|
||||
* The returned pointer points at the end of the current
|
||||
* data in the buffer, advancing the tail be size bytes .
|
||||
* You need to insert the size bytes at in the returned pointer.
|
||||
*
|
||||
* @param size bytes to put in the buffer
|
||||
* @return NULL if the mbuf does not have room for the given size
|
||||
*/
|
||||
uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size);
|
||||
|
||||
/** Prepend data to the buffer. The buffer needs to have enough
|
||||
* headroom to allow this.
|
||||
* The returned pointer points size bytes in front if the current
|
||||
* data in the buffer, retreating the head pointer by size butes
|
||||
* You need to insert the size bytes in the returned pointer.
|
||||
*
|
||||
* @oaram size bytes to prepend to the buffer
|
||||
* @return NULL if the mbuf does not have enough headroom
|
||||
*/
|
||||
uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size);
|
||||
|
||||
/** Remove data from the buffer ("read" data from it)
|
||||
* The returned pointer is the beginning of the data in the
|
||||
* buffer, advancing the head by size bytes.
|
||||
*
|
||||
* @param size number of bytes to pull
|
||||
* @return NULL if the buffer does not have at least size bytes
|
||||
**/
|
||||
uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size);
|
||||
|
||||
#undef UC_INLINE
|
||||
|
||||
@@ -87,6 +87,18 @@ void uc_strv_clear(struct UCStrv *strv);
|
||||
*/
|
||||
void uc_strv_destroy(struct UCStrv *strv);
|
||||
|
||||
/**
|
||||
* Append all the elments from b to a
|
||||
* If copy is 1, the appended elements will be copied when appended
|
||||
*
|
||||
* @param a destination UCStrv
|
||||
* @param b source UCStrv
|
||||
* @param copy 1 for making a copy of the string when appending it
|
||||
* 0 to just append the same pointer in b to a
|
||||
* @return 0 on success, != 0 if appending/allocation fails
|
||||
*/
|
||||
int uc_strv_append_all(struct UCStrv *a, struct UCStrv *b, int copy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -46,14 +46,14 @@
|
||||
//a 'zap' member inside a struct foo.
|
||||
//give us the struct foo*:
|
||||
//struct foo *f = CONTAINER_OF(p, struct foo, zap);
|
||||
#define CONTAINER_OF(ptr, type, member) ({ \
|
||||
#define UC_CONTAINER_OF(ptr, type, member) ({ \
|
||||
typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)((void *)(unsigned char *)__mptr - offsetof(type, member) ); })
|
||||
|
||||
//the void* cast is to suppress alignment warnings
|
||||
|
||||
//Same as CONTAINER_OF, but for a const pointer to avoid gcc warnings..
|
||||
#define CONST_CONTAINER_OF(ptr, type, member) ({ \
|
||||
//Same as UC_CONTAINER_OF, but for a const pointer to avoid gcc warnings..
|
||||
#define UC_CONST_CONTAINER_OF(ptr, type, member) ({ \
|
||||
const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
||||
(const type *)((const void *)(const unsigned char *)__mptr - offsetof(const type, member) ); })
|
||||
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ static void uc_cached_clock_now(struct UCoreClock *uclock,
|
||||
struct timeval *tv)
|
||||
{
|
||||
struct UCoreCachedClock *cached_clock;
|
||||
cached_clock = CONTAINER_OF(uclock, struct UCoreCachedClock, clock),
|
||||
cached_clock = UC_CONTAINER_OF(uclock, struct UCoreCachedClock, clock),
|
||||
|
||||
*tv = cached_clock->cache;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ void uc_cached_clock_update(struct UCoreCachedClock *uclock)
|
||||
static void uc_settable_clock_now(struct UCoreClock *uclock, struct timeval *tv)
|
||||
{
|
||||
struct UCoreSettableClock *cached_clock;
|
||||
cached_clock = CONTAINER_OF(uclock, struct UCoreSettableClock, clock),
|
||||
cached_clock = UC_CONTAINER_OF(uclock, struct UCoreSettableClock, clock),
|
||||
|
||||
*tv = cached_clock->now;
|
||||
}
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ again:
|
||||
|
||||
event_cnt = iomux_timers_run(mux_); //process timers
|
||||
|
||||
if (rc == 0) //Just the timeout
|
||||
if (rc == 0) //no fd's were ready, no more work to do
|
||||
return event_cnt;
|
||||
|
||||
for (i = 0; i < rc; i++) {
|
||||
|
||||
+2
-2
@@ -157,10 +157,10 @@ again:
|
||||
|
||||
event_cnt = iomux_timers_run(mux_); //fire the timers
|
||||
|
||||
if (rc == 0) //Just the timeout
|
||||
if (rc == 0) //no fd's were ready, no more work to do
|
||||
return event_cnt;
|
||||
|
||||
for (i = 0; rc >= 0 && i < mux->num_descriptors; i++) {
|
||||
for (i = 0; rc > 0 && i < mux->num_descriptors; i++) {
|
||||
unsigned int events = 0;
|
||||
|
||||
if (mux->descriptors[i] == NULL) { //callback might have deleted it
|
||||
|
||||
@@ -86,11 +86,13 @@ struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom)
|
||||
|
||||
void uc_mbuf_free(struct MBuf *mbuf)
|
||||
{
|
||||
if (mbuf != NULL) {
|
||||
if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_BUF))
|
||||
free(mbuf->bufstart);
|
||||
|
||||
if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_INLINE))
|
||||
free(mbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void uc_mbuf_zero(struct MBuf *mbuf)
|
||||
|
||||
+27
-2
@@ -29,7 +29,8 @@ int uc_strv_expand(struct UCStrv *strv)
|
||||
int rc = 0;
|
||||
|
||||
if (strv->cnt >= strv->allocated) {
|
||||
rc = uc_strv_grow(strv, 1);
|
||||
//make some extra room
|
||||
rc = uc_strv_grow(strv, 4);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -81,7 +82,6 @@ int uc_strv_null_terminate(struct UCStrv *strv)
|
||||
}
|
||||
|
||||
strv->strings[strv->cnt] = NULL;
|
||||
strv->cnt++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -105,3 +105,28 @@ void uc_strv_destroy(struct UCStrv *strv)
|
||||
strv->strings = NULL;
|
||||
}
|
||||
|
||||
int uc_strv_append_all(struct UCStrv *a, struct UCStrv *b, int copy)
|
||||
{
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
rc = uc_strv_grow(a, a->allocated + b->cnt);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < b->cnt; i++) {
|
||||
if (copy) {
|
||||
rc = uc_strv_append(a, b->strings[i]);
|
||||
} else {
|
||||
rc = uc_strv_append_nocopy(a, b->strings[i]);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+17
-7
@@ -57,7 +57,9 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, long max_elements)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int uc_thread_queue_tryadd(struct uc_threadqueue *queue, const struct timespec *timeout, struct uc_threadmsg *msg)
|
||||
int uc_thread_queue_tryadd(struct uc_threadqueue *queue,
|
||||
const struct timespec *timeout,
|
||||
struct uc_threadmsg *msg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct timespec abstimeout;
|
||||
@@ -81,7 +83,8 @@ int uc_thread_queue_tryadd(struct uc_threadqueue *queue, const struct timespec *
|
||||
if(timeout->tv_sec == 0 && timeout->tv_nsec == 0) {
|
||||
rc = ETIMEDOUT;
|
||||
} else {
|
||||
rc = pthread_cond_timedwait(&queue->write_cond, &queue->mutex, &abstimeout);
|
||||
rc = pthread_cond_timedwait(&queue->write_cond, &queue->mutex,
|
||||
&abstimeout);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -127,7 +130,9 @@ int uc_thread_queue_tryadd(struct uc_threadqueue *queue, const struct timespec *
|
||||
|
||||
}
|
||||
|
||||
int uc_thread_queue_tryget(struct uc_threadqueue *queue, const struct timespec *timeout, struct uc_threadmsg **msg)
|
||||
int uc_thread_queue_tryget(struct uc_threadqueue *queue,
|
||||
const struct timespec *timeout,
|
||||
struct uc_threadmsg **msg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct timespec abstimeout;
|
||||
@@ -153,7 +158,8 @@ int uc_thread_queue_tryget(struct uc_threadqueue *queue, const struct timespec *
|
||||
if(timeout->tv_sec == 0 && timeout->tv_nsec == 0) {
|
||||
rc = ETIMEDOUT;
|
||||
} else {
|
||||
rc = pthread_cond_timedwait(&queue->read_cond, &queue->mutex, &abstimeout);
|
||||
rc = pthread_cond_timedwait(&queue->read_cond, &queue->mutex,
|
||||
&abstimeout);
|
||||
}
|
||||
} else {
|
||||
pthread_cond_wait(&queue->read_cond, &queue->mutex);
|
||||
@@ -192,17 +198,20 @@ int uc_thread_queue_tryget(struct uc_threadqueue *queue, const struct timespec *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uc_thread_queue_walk_unlocked(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func)
|
||||
static void uc_thread_queue_walk_unlocked(struct uc_threadqueue *queue,
|
||||
uc_thread_queue_walk_func walk_func)
|
||||
{
|
||||
struct uc_threadmsg *p;
|
||||
struct uc_threadmsg *next;
|
||||
|
||||
for(p = queue->first; p; p = next) {
|
||||
next = p->next;
|
||||
walk_func(p);
|
||||
}
|
||||
}
|
||||
|
||||
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func)
|
||||
int uc_thread_queue_walk(struct uc_threadqueue *queue,
|
||||
uc_thread_queue_walk_func walk_func)
|
||||
{
|
||||
if (queue == NULL || !walk_func) {
|
||||
return EINVAL;
|
||||
@@ -217,7 +226,8 @@ int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func)
|
||||
int uc_thread_queue_destroy(struct uc_threadqueue *queue,
|
||||
uc_thread_queue_walk_func free_func)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@
|
||||
|
||||
static int timers_cmp(const RBNode *a_, const RBNode *b_)
|
||||
{
|
||||
const struct UCTimer *a = CONST_CONTAINER_OF(a_, struct UCTimer, rb_node);
|
||||
const struct UCTimer *b = CONST_CONTAINER_OF(b_, struct UCTimer, rb_node);
|
||||
const struct UCTimer *a = UC_CONST_CONTAINER_OF(a_, struct UCTimer, rb_node);
|
||||
const struct UCTimer *b = UC_CONST_CONTAINER_OF(b_, struct UCTimer, rb_node);
|
||||
|
||||
if (timercmp(&a->timeout, &b->timeout, <)) {
|
||||
return -1;
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ortp/ortp.h>
|
||||
#include <ucore/iomux.h>
|
||||
#include <ucore/utils.h>
|
||||
#include <ucore/string.h>
|
||||
|
||||
|
||||
struct IOMux *mux;
|
||||
|
||||
#define errx(x, ...) do { fprintf(stderr, x, __VA_ARGS__); exit(1); } while(0)
|
||||
|
||||
struct RTPSender {
|
||||
FILE *file;
|
||||
char remote_ip[48];
|
||||
uint16_t remote_port;
|
||||
struct UCTimer timer;
|
||||
uint32_t ts;
|
||||
struct timespec last_ts;
|
||||
RtpSession *rtp_sess;
|
||||
RtpProfile *rtp_profile;
|
||||
int accum_diff;
|
||||
uint8_t frame[160];
|
||||
};
|
||||
|
||||
|
||||
//returns microsec
|
||||
int diffts(const struct timespec *a, struct timespec *b)
|
||||
{
|
||||
struct timespec diff;
|
||||
diff.tv_sec = b->tv_sec - a->tv_sec;
|
||||
diff.tv_nsec = b->tv_nsec - a->tv_nsec;
|
||||
if (diff.tv_nsec < 0) {
|
||||
diff.tv_sec--;
|
||||
diff.tv_nsec += 1000000000;
|
||||
}
|
||||
|
||||
|
||||
return (int) (diff.tv_sec * 1000 + (diff.tv_nsec + 500)/1000);
|
||||
}
|
||||
|
||||
void timer_cb(struct UCTimers *timers, struct UCTimer *timer)
|
||||
{
|
||||
struct RTPSender *s = UC_CONTAINER_OF(timer, struct RTPSender, timer);
|
||||
int rc;
|
||||
ssize_t r;
|
||||
struct timespec ts;
|
||||
int diff;
|
||||
int adjust;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
rc = rtp_session_send_with_ts(s->rtp_sess,s->frame, sizeof s->frame, s->ts);
|
||||
if(rc < sizeof s->frame) {
|
||||
printf("Error, short send of %d bytes\n", rc);
|
||||
}
|
||||
s->ts += 160;
|
||||
|
||||
r = fread(s->frame,1, sizeof s->frame, s->file);
|
||||
if (r <= 0) {
|
||||
rtp_session_bye(s->rtp_sess, "Finished");
|
||||
return;
|
||||
}
|
||||
|
||||
diff = diffts(&s->last_ts, &ts);
|
||||
diff -= 20000;
|
||||
|
||||
s->accum_diff += diff;
|
||||
|
||||
if (s->accum_diff > 500)
|
||||
adjust = -1000;
|
||||
else if (s->accum_diff < -500)
|
||||
adjust = 1000;
|
||||
else
|
||||
adjust = s->accum_diff;
|
||||
|
||||
if (s->accum_diff >= 20000 || s->accum_diff <= -20000) {
|
||||
s->ts += 160;
|
||||
printf("Skew ! accum_diff %d\n", s->accum_diff);
|
||||
s->accum_diff -= 20000;
|
||||
}
|
||||
|
||||
|
||||
uc_timers_add(iomux_get_timers(mux), &s->timer, 0, 20 * 1000 + adjust);
|
||||
|
||||
s->last_ts = ts;
|
||||
}
|
||||
|
||||
void init_sender(FILE* file, const char *remote_ip, uint16_t remote_port)
|
||||
{
|
||||
struct RTPSender *s = calloc(1, sizeof *s);
|
||||
|
||||
RtpSession *rtp_sess = rtp_session_new(RTP_SESSION_SENDONLY);
|
||||
RtpProfile *rtp_prof = rtp_profile_new("pcmu8000");
|
||||
rtp_profile_set_payload(rtp_prof, 0, &payload_type_pcmu8000);
|
||||
rtp_session_set_profile(rtp_sess, rtp_prof);
|
||||
//rtp_session_set_local_addr("192.168.1.55", 0);
|
||||
rtp_session_set_remote_addr(rtp_sess, remote_ip, remote_port);
|
||||
rtp_session_set_blocking_mode(rtp_sess, FALSE);
|
||||
|
||||
s->file = file;
|
||||
strcpy(s->remote_ip, remote_ip);
|
||||
s->remote_port = remote_port;
|
||||
s->rtp_sess = rtp_sess;
|
||||
s->rtp_profile = rtp_prof;
|
||||
s->timer.callback = timer_cb;
|
||||
clock_gettime(CLOCK_MONOTONIC, &s->last_ts);
|
||||
uc_timers_add(iomux_get_timers(mux), &s->timer, 0, 20000);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mux = iomux_create(IOMUX_TYPE_DEFAULT);
|
||||
|
||||
FILE *file;
|
||||
if(argc != 4) {
|
||||
puts("Specify a file name, remote IP and remote port");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strcmp(argv[1], "-") == 0) {
|
||||
file = stdin;
|
||||
} else {
|
||||
file = fopen(argv[1], "rb");
|
||||
if(file == NULL) {
|
||||
perror("Cannot open file");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
ortp_init();
|
||||
ortp_set_log_level_mask(ORTP_DEBUG| ORTP_MESSAGE| ORTP_WARNING| ORTP_ERROR|ORTP_FATAL);
|
||||
init_sender(file ,argv[2], atoi(argv[3]));
|
||||
|
||||
iomux_run(mux);
|
||||
|
||||
|
||||
fclose(file);
|
||||
ortp_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//compile:
|
||||
// gcc -Wall -g -O `pkg-config --cflags --libs ortp` ortp-send-simple.c
|
||||
@@ -25,7 +25,7 @@ START_TEST (test_container_of)
|
||||
};
|
||||
|
||||
struct Inner *innerp = &outer.inner;
|
||||
struct Outer *outerp = CONTAINER_OF(innerp, struct Outer, inner);
|
||||
struct Outer *outerp = UC_CONTAINER_OF(innerp, struct Outer, inner);
|
||||
|
||||
fail_if(outerp != &outer);
|
||||
|
||||
|
||||
+3
-3
@@ -33,9 +33,7 @@ static suite_func suites[] = {
|
||||
read_file_suite,
|
||||
pack_suite,
|
||||
logging_suite,
|
||||
threadqueue_suite,
|
||||
buffer_suite,
|
||||
clock_suite,
|
||||
seq_suite,
|
||||
sat_math_suite,
|
||||
timers_suite,
|
||||
@@ -43,7 +41,9 @@ static suite_func suites[] = {
|
||||
human_bytesz_suite,
|
||||
dbuf_suite,
|
||||
sprintb_suite,
|
||||
strv_suite
|
||||
strv_suite,
|
||||
clock_suite,
|
||||
threadqueue_suite
|
||||
};
|
||||
|
||||
int
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <check.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ucore/strvec.h>
|
||||
|
||||
|
||||
@@ -67,12 +68,61 @@ START_TEST (test_strv_null_terminate)
|
||||
|
||||
rc = uc_strv_null_terminate(&strv);
|
||||
fail_if(rc != 0);
|
||||
fail_if(strv.cnt != 1); //shouldn't increase .cnt
|
||||
fail_if(strv.strings[strv.cnt] != NULL);
|
||||
|
||||
uc_strv_destroy(&strv);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_strv_append_all_copy)
|
||||
struct UCStrv src;
|
||||
struct UCStrv dst;
|
||||
int rc;
|
||||
|
||||
uc_strv_init(&src);
|
||||
uc_strv_init(&dst);
|
||||
|
||||
uc_strv_append(&dst, "string1");
|
||||
uc_strv_append(&src, "string2");
|
||||
uc_strv_append(&src, "string3");
|
||||
|
||||
rc = uc_strv_append_all(&dst, &src, 1);
|
||||
fail_if(rc != 0);
|
||||
fail_if(dst.cnt != 3);
|
||||
ck_assert_str_eq("string1", dst.strings[0]);
|
||||
ck_assert_str_eq("string2", dst.strings[1]);
|
||||
ck_assert_str_eq("string3", dst.strings[2]);
|
||||
|
||||
uc_strv_destroy(&src);
|
||||
uc_strv_destroy(&dst);
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_strv_append_all_nocopy)
|
||||
struct UCStrv src;
|
||||
struct UCStrv dst;
|
||||
int rc;
|
||||
|
||||
uc_strv_init(&src);
|
||||
uc_strv_init(&dst);
|
||||
|
||||
uc_strv_append(&dst, "string1");
|
||||
uc_strv_append(&src, "string2");
|
||||
uc_strv_append(&src, "string3");
|
||||
|
||||
rc = uc_strv_append_all(&dst, &src, 0);
|
||||
fail_if(rc != 0);
|
||||
fail_if(dst.cnt != 3);
|
||||
ck_assert_str_eq("string1", dst.strings[0]);
|
||||
ck_assert_str_eq("string2", dst.strings[1]);
|
||||
ck_assert_str_eq("string3", dst.strings[2]);
|
||||
|
||||
uc_strv_destroy(&dst);
|
||||
free(src.strings);
|
||||
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite *strv_suite(void)
|
||||
{
|
||||
@@ -83,6 +133,8 @@ Suite *strv_suite(void)
|
||||
tcase_add_test(tc, test_strv_clear);
|
||||
tcase_add_test(tc, test_strv_nocopy);
|
||||
tcase_add_test(tc, test_strv_null_terminate);
|
||||
tcase_add_test(tc, test_strv_append_all_copy);
|
||||
tcase_add_test(tc, test_strv_append_all_nocopy);
|
||||
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
||||
+16
-22
@@ -164,37 +164,31 @@ START_TEST (test_timers_add_remove)
|
||||
struct UCoreSettableClock clk;
|
||||
struct TimerTest tt;
|
||||
struct UCTimers timers;
|
||||
struct UCTimer timer1;
|
||||
struct UCTimer timer2;
|
||||
struct UCTimer timer3;
|
||||
struct UCTimer timer4;
|
||||
struct UCTimer timer[1023];
|
||||
struct timeval first;
|
||||
size_t i;
|
||||
int toggle = 5;
|
||||
|
||||
common_init(&clk, &tt, &timers, &timer1);
|
||||
memset(&timer2, 0, sizeof timer2);
|
||||
memset(&timer3, 0, sizeof timer2);
|
||||
memset(&timer4, 0, sizeof timer2);
|
||||
common_init(&clk, &tt, &timers, &timer[0]);
|
||||
memset(&timer, 0, sizeof timer);
|
||||
for (i = 0; i < sizeof timer/sizeof timer[0]; i++) {
|
||||
timer[i].callback = timer_test_cb_add;
|
||||
|
||||
timer1.callback = timer_test_cb_add;
|
||||
timer2.callback = timer_test_cb_add;
|
||||
timer3.callback = timer_test_cb_add;
|
||||
timer4.callback = timer_test_cb_add;
|
||||
|
||||
uc_timers_add(&timers, &timer1, 10, 0);
|
||||
uc_timers_add(&timers, &timer2, 5 , 0);
|
||||
uc_timers_add(&timers, &timer3, 15, 1);
|
||||
uc_timers_add(&timers, &timer4, 15, 1);
|
||||
uc_timers_add(&timers, &timer[i], toggle + i , 0);
|
||||
if (i > 5) //just to add timeouts non-ascending order
|
||||
toggle = 5 - toggle;
|
||||
}
|
||||
|
||||
fail_if(uc_timers_first(&timers, &first) != 0);
|
||||
fail_if(first.tv_sec != TEST_TIMER_START + 5);
|
||||
fail_if(first.tv_usec != 0);
|
||||
|
||||
fail_if(uc_timers_count(&timers) != 4);
|
||||
fail_if(uc_timers_count(&timers) != sizeof timer/sizeof timer[0]);
|
||||
|
||||
for (i = 0; i < sizeof timer/sizeof timer[0]; i++) {
|
||||
uc_timers_remove(&timers, &timer[i]);
|
||||
}
|
||||
|
||||
uc_timers_remove(&timers, &timer1);
|
||||
uc_timers_remove(&timers, &timer2);
|
||||
uc_timers_remove(&timers, &timer3);
|
||||
uc_timers_remove(&timers, &timer4);
|
||||
|
||||
fail_if(uc_timers_count(&timers) != 0);
|
||||
fail_if(uc_timers_first(&timers, &first) == 0);
|
||||
|
||||
@@ -70,7 +70,7 @@ void peer_do_state(struct HBPeer *peer, enum PeerEvent event);
|
||||
|
||||
void peer_timer_cb(struct UCTimers *timers, struct UCTimer *timer)
|
||||
{
|
||||
struct HBPeer *peer = CONTAINER_OF(timer, struct HBPeer, timer);
|
||||
struct HBPeer *peer = UC_CONTAINER_OF(timer, struct HBPeer, timer);
|
||||
struct HBContext *ctx = timer->cookie_ptr;
|
||||
time_t now;
|
||||
|
||||
@@ -181,7 +181,7 @@ void peer_received(struct HBPeer *peer)
|
||||
|
||||
void hb_read(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
||||
{
|
||||
struct HBContext *ctx = CONTAINER_OF(fd, struct HBContext, sock_fd);
|
||||
struct HBContext *ctx = UC_CONTAINER_OF(fd, struct HBContext, sock_fd);
|
||||
ssize_t rc;
|
||||
struct sockaddr_in peer_addr;
|
||||
socklen_t peer_len = sizeof peer_addr;
|
||||
|
||||
Reference in New Issue
Block a user