static void client_event_cb(struct pomp_ctx *ctx, enum pomp_event event, struct pomp_conn *conn, const struct pomp_msg *msg, void *userdata) { int fd, msgid; unsigned int bufsize; void *video_buffer; GstVideoFormat videoformat; unsigned int width, height; switch (event) { case POMP_EVENT_CONNECTED: ULOGI("connected to pimp user filter"); break; case POMP_EVENT_DISCONNECTED: ULOGI("disconnected from pimp user filter"); break; case POMP_EVENT_MSG: switch (msgid = pomp_msg_get_id(msg)) { case SEND_FD: pomp_msg_read(msg, "%x%u%u%u%u", &fd, &bufsize, &videoformat, &width, &height); ULOGI("received a FD from pimp: %d", fd); video_buffer = mmap(NULL, bufsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); s_app.process(video_buffer, bufsize, videoformat, width, height, s_app.priv); pomp_ctx_send(ctx, BUFFER_PROCESSING_DONE, NULL); break; default: ULOGW("received unknown message id from pimp : %d", msgid); break; } break; default: ULOGE("Unknown event: %d", event); break; } }
static void test_ctx(const struct sockaddr *addr1, uint32_t addrlen1, const struct sockaddr *addr2, uint32_t addrlen2, int isdgram, int israw, int withsockcb, int withsendcb) { int res = 0; struct test_data data; struct pomp_loop *loop = NULL; struct pomp_conn *conn = NULL; struct pomp_msg *msg = NULL; int fd = -1; uint32_t i = 0, j = 0; struct pomp_buffer *buf = NULL; memset(&data, 0, sizeof(data)); data.isdgram = isdgram; data.israw = israw; data.srv.addr = addr1; data.srv.addrlen = addrlen1; data.cli.addr = addr2; data.cli.addrlen = addrlen2; msg = pomp_msg_new(); CU_ASSERT_PTR_NOT_NULL_FATAL(msg); /* Create context */ data.srv.ctx = pomp_ctx_new(&test_event_cb_t, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(data.srv.ctx); if (israw) { res = pomp_ctx_set_raw(data.srv.ctx, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, 0); } if (withsockcb) { res = pomp_ctx_set_socket_cb(data.srv.ctx, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, 0); } if (withsendcb) { res = pomp_ctx_set_send_cb(data.srv.ctx, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, 0); } /* Create context without callback */ data.cli.ctx = pomp_ctx_new(NULL, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(data.cli.ctx); res = pomp_ctx_destroy(data.cli.ctx); CU_ASSERT_EQUAL(res, 0); /* Invalid create (NULL 3nd arg) */ data.cli.ctx = pomp_ctx_new_with_loop(NULL, &data, NULL); CU_ASSERT_PTR_NULL(data.cli.ctx); data.cli.ctx = pomp_ctx_new_with_loop(&test_event_cb_t, &data, NULL); CU_ASSERT_PTR_NULL(data.cli.ctx); /* Create 2nd context */ data.cli.ctx = pomp_ctx_new(&test_event_cb_t, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(data.cli.ctx); if (israw) { res = pomp_ctx_set_raw(data.cli.ctx, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, 0); } if (withsockcb) { res = pomp_ctx_set_socket_cb(data.cli.ctx, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, 0); } if (withsendcb) { res = pomp_ctx_set_send_cb(data.cli.ctx, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, 0); } if (!isdgram) { /* Invalid start server (NULL param) */ res = pomp_ctx_listen(NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_listen(data.srv.ctx, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); /* Start as server 1st context */ res = pomp_ctx_listen(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); /* Invalid start server (busy) */ res = pomp_ctx_listen(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EBUSY); } else { /* Invalid bind (NULL param) */ res = pomp_ctx_bind(NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_bind(data.srv.ctx, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); /* Bind 1st context */ res = pomp_ctx_bind(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); /* Invalid bind (busy) */ res = pomp_ctx_bind(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EBUSY); } if (!isdgram) { /* Invalid start client (NULL param) */ res = pomp_ctx_connect(NULL, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_connect(data.cli.ctx, NULL, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); /* Start as client 2nd context */ res = pomp_ctx_connect(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); /* Invalid start client (busy) */ res = pomp_ctx_connect(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EBUSY); } else { /* Invalid bind (NULL param) */ res = pomp_ctx_bind(NULL, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_bind(data.cli.ctx, NULL, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); /* Bind 2nd context */ res = pomp_ctx_bind(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); /* Invalid bind (busy) */ res = pomp_ctx_bind(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EBUSY); } /* Invalid set raw */ res = pomp_ctx_set_raw(NULL, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_raw(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_raw(data.srv.ctx, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, -EBUSY); /* Invalid set socket cb */ res = pomp_ctx_set_socket_cb(NULL, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_socket_cb(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_socket_cb(data.srv.ctx, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, -EBUSY); /* Invalid set send cb */ res = pomp_ctx_set_send_cb(NULL, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_send_cb(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_send_cb(data.srv.ctx, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, -EBUSY); /* Invalid get loop (NULL param) */ loop = pomp_ctx_get_loop(NULL); CU_ASSERT_PTR_NULL(loop); /* Invalid get fd (NULL param) */ fd = pomp_ctx_get_fd(NULL); CU_ASSERT_EQUAL(fd, -EINVAL); /* Get loop and fd */ loop = pomp_ctx_get_loop(data.srv.ctx); CU_ASSERT_PTR_NOT_NULL(loop); fd = pomp_ctx_get_fd(data.srv.ctx); #ifdef POMP_HAVE_LOOP_EPOLL CU_ASSERT_TRUE(fd >= 0); #else CU_ASSERT_EQUAL(fd, -ENOSYS); #endif /* Invalid process fd (NULL param) */ res = pomp_ctx_process_fd(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Keepalive settings */ if (!isdgram) { /* TODO: check that it actually does something */ res = pomp_ctx_setup_keepalive(data.srv.ctx, 0, 0, 0, 0); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_setup_keepalive(data.srv.ctx, 1, 5, 2, 1); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_setup_keepalive(NULL, 0, 0, 0, 0); CU_ASSERT_EQUAL(res, -EINVAL); } /* Run contexts (they shall connect each other) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!isdgram) { CU_ASSERT_EQUAL(data.connection, 2); /* Get remote connections */ conn = pomp_ctx_get_next_conn(data.srv.ctx, NULL); CU_ASSERT_PTR_NOT_NULL(conn); conn = pomp_ctx_get_next_conn(data.srv.ctx, conn); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_conn(data.cli.ctx); CU_ASSERT_PTR_NOT_NULL(conn); /* Invalid get remote connections */ conn = pomp_ctx_get_next_conn(data.cli.ctx, NULL); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_conn(data.srv.ctx); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_next_conn(NULL, NULL); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_conn(NULL); CU_ASSERT_PTR_NULL(conn); } /* Exchange some message */ if (!isdgram) { if (!israw) { res = pomp_ctx_send(data.srv.ctx, 1, "%s", "hello1->2"); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send(data.cli.ctx, 1, "%s", "hello2->1"); CU_ASSERT_EQUAL(res, 0); /* Invalid send (NULL param) */ res = pomp_ctx_send(NULL, 1, "%s", "hello1->2"); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_msg(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Invalid send (bad format) */ res = pomp_ctx_send(data.srv.ctx, 1, "%o", 1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_conn_send(pomp_ctx_get_conn(data.cli.ctx), 1, "%o", 1); CU_ASSERT_EQUAL(res, -EINVAL); /* Invalid send to (bad type) */ res = pomp_ctx_send_msg_to(data.cli.ctx, msg, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); } else { buf = pomp_buffer_new(32); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); memcpy(buf->data, "Hello World !!!", 15); buf->len = 15; res = pomp_ctx_send_raw_buf(data.srv.ctx, buf); data.datasent += 15; CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send_raw_buf(data.cli.ctx, buf); data.datasent += 15; CU_ASSERT_EQUAL(res, 0); /* Invalid send (NULL param) */ res = pomp_ctx_send_raw_buf(NULL, buf); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_raw_buf(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); pomp_buffer_unref(buf); buf = NULL; } } else { if (!israw) { res = pomp_msg_clear(msg); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_write(msg, 1, "%s", "hello1->2"); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send_msg_to(data.srv.ctx, msg, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_clear(msg); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_write(msg, 1, "%s", "hello2->1"); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send_msg_to(data.cli.ctx, msg, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); /* Invalid send (not connected) */ res = pomp_ctx_send_msg(data.cli.ctx, msg); CU_ASSERT_EQUAL(res, -ENOTCONN); /* Invalid send to (NULL param) */ res = pomp_ctx_send_msg_to(NULL, msg, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_msg_to(data.cli.ctx, NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_msg_to(data.cli.ctx, msg, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); } else { buf = pomp_buffer_new(32); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); memcpy(buf->data, "Hello World !!!", 15); buf->len = 15; res = pomp_ctx_send_raw_buf_to(data.srv.ctx, buf, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); data.datasent += 15; res = pomp_ctx_send_raw_buf_to(data.cli.ctx, buf, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); data.datasent += 15; /* Invalid send (not connected) */ res = pomp_ctx_send_raw_buf(data.cli.ctx, buf); CU_ASSERT_EQUAL(res, -ENOTCONN); /* Invalid send to (NULL param) */ res = pomp_ctx_send_raw_buf_to(NULL, buf, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_raw_buf_to(data.cli.ctx, NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_raw_buf_to(data.cli.ctx, buf, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); pomp_buffer_unref(buf); buf = NULL; } } /* Check no send callback directly called by the sending function. */ CU_ASSERT_EQUAL(data.sendcount, 0); /* Run contexts (they shall have answered each other) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!israw) { CU_ASSERT_EQUAL(data.msg, 4); if (withsendcb) CU_ASSERT_EQUAL(data.sendcount, 4); } else { if (data.isdgram) CU_ASSERT_EQUAL(data.buf, 2); CU_ASSERT_EQUAL(data.dataread, data.datasent); if (withsendcb) CU_ASSERT_EQUAL(data.sendcount, 2); } /* Dummy run */ res = pomp_ctx_wait_and_process(data.srv.ctx, 100); CU_ASSERT_EQUAL(res, -ETIMEDOUT); res = pomp_ctx_wait_and_process(NULL, 100); CU_ASSERT_EQUAL(res, -EINVAL); /* Wakeup */ res = pomp_ctx_wakeup(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_wait_and_process(data.srv.ctx, 100); CU_ASSERT_EQUAL(res, 0); /* Invalid wakeup (NULL param) */ res = pomp_ctx_wakeup(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Overflow server by writing on client side without running loop */ if (!isdgram) { for (i = 0; i < 1024; i++) { if (buf == NULL) buf = pomp_buffer_new(1024); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); for (j = 0; j < 1024; j++) buf->data[j] = rand() % 255; buf->len = 1024; if (!israw) { res = pomp_ctx_send(data.cli.ctx, 3, "%p%u", buf->data, 1024); CU_ASSERT_EQUAL(res, 0); } else { res = pomp_ctx_send_raw_buf(data.cli.ctx, buf); CU_ASSERT_EQUAL(res, 0); } if (buf->refcount > 1) { pomp_buffer_unref(buf); buf = NULL; } } if (buf != NULL) { pomp_buffer_unref(buf); buf = NULL; } /* Run contexts (to unlock writes) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!israw) CU_ASSERT_EQUAL(data.msg, 4 + 1024); } /* Recursive send */ if (withsendcb) { /* reset counts */ data.buf = 0; data.msg = 0; data.sendcount = 0; data.datasent = 0; data.dataread = 0; /* Enable recursive send. */ data.srv.recurs_send_enabled = 1; send_msg(&data, &data.srv, &data.cli, "srv_to_cli"); /* Check no send callback directly called by the sending function. */ CU_ASSERT_EQUAL(data.sendcount, 0); run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!israw) { CU_ASSERT_EQUAL(data.msg, 2); CU_ASSERT_EQUAL(data.sendcount, 2); } else { if (data.isdgram) CU_ASSERT_EQUAL(data.buf, 2); CU_ASSERT_EQUAL(data.dataread, data.datasent); CU_ASSERT_EQUAL(data.sendcount, 2); } /* Check client recursive send during server disconnection */ data.cli.recurs_send_enabled = 1; send_msg(&data, &data.cli, &data.srv, "cli_to_srv"); } /* Disconnect client from server */ if (!isdgram) { if (withsendcb) { /* Check recursive write during disconnection */ data.srv.recurs_send_enabled = 1; data.isdisconnecting = 1; } res = pomp_conn_disconnect(pomp_ctx_get_next_conn(data.srv.ctx, NULL)); CU_ASSERT_EQUAL(res, 0); /* Check recursive send callback by disconnection */ if (withsendcb) CU_ASSERT_EQUAL(data.sendcount, 2); } /* Run contexts (they shall disconnect each other) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); pomp_ctx_process_fd(data.cli.ctx); if (!isdgram) { CU_ASSERT_EQUAL(data.disconnection, 2); if (!israw) { /* Invalid send (client not connected) */ res = pomp_ctx_send(data.cli.ctx, 1, "%s", "hello2->1"); CU_ASSERT_EQUAL(res, -ENOTCONN); } else { /* TODO */ } } /* Invalid destroy (NULL param) */ res = pomp_ctx_destroy(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Invalid destroy (busy) */ res = pomp_ctx_destroy(data.srv.ctx); CU_ASSERT_EQUAL(res, -EBUSY); /* Stop server */ res = pomp_ctx_stop(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); /* Stop client */ res = pomp_ctx_stop(data.cli.ctx); CU_ASSERT_EQUAL(res, 0); /* Invalid stop (NULL param) */ res = pomp_ctx_stop(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Stop when already done */ res = pomp_ctx_stop(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); /* Destroy contexts */ res = pomp_ctx_destroy(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_destroy(data.cli.ctx); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_destroy(msg); CU_ASSERT_EQUAL(res, 0); }
static int send_msg(struct test_data *tdata, struct test_peer *src, struct test_peer *dst, char *msg) { int res = 0; struct pomp_msg *pmsg = NULL; struct pomp_buffer *buf = NULL; /* Exchange some message */ if (!tdata->isdgram) { if (!tdata->israw) { res = pomp_ctx_send(src->ctx, 3, "%s", msg); } else { buf = pomp_buffer_new(32); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); memcpy(buf->data, msg, strlen(msg)); buf->len = strlen(msg); res = pomp_ctx_send_raw_buf(src->ctx, buf); if (tdata->isdisconnecting && src == &tdata->cli) { /* Check failed if send after client disconnect */ CU_ASSERT_EQUAL(res, -ENOTCONN); } else { tdata->datasent += strlen(msg); CU_ASSERT_EQUAL(res, 0); } pomp_buffer_unref(buf); buf = NULL; } } else { if (!tdata->israw) { pmsg = pomp_msg_new(); res = pomp_msg_clear(pmsg); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_write(pmsg, 3, "%s", msg); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send_msg_to(src->ctx, pmsg, dst->addr, dst->addrlen); if (tdata->isdisconnecting && src == &tdata->cli) { /* Check failed if send after client disconnect */ CU_ASSERT_EQUAL(res, -ENOTCONN); } else { CU_ASSERT_EQUAL(res, 0); } res = pomp_msg_destroy(pmsg); CU_ASSERT_EQUAL(res, 0); } else { buf = pomp_buffer_new(32); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); memcpy(buf->data, msg, strlen(msg)); buf->len = strlen(msg); res = pomp_ctx_send_raw_buf_to(src->ctx, buf, dst->addr, dst->addrlen); if (tdata->isdisconnecting && src == &tdata->cli) { /* Check failed if send after client disconnect */ CU_ASSERT_EQUAL(res, -ENOTCONN); } else { tdata->datasent += strlen(msg); CU_ASSERT_EQUAL(res, 0); } pomp_buffer_unref(buf); buf = NULL; } } return res; }