summaryrefslogtreecommitdiff
path: root/mcast/client/.svn/text-base/api_server.c.svn-base
diff options
context:
space:
mode:
authorLars Heer <l.heer@gmx.de>2013-09-18 05:50:03 +0200
committerLars Heer <l.heer@gmx.de>2013-09-18 05:50:03 +0200
commitccf6e0f9c6b0481ed13e0f4794e3fbead750f385 (patch)
treeed86efb54f7ee41edfba5c89ca519b5fd10aa0d5 /mcast/client/.svn/text-base/api_server.c.svn-base
downloadvdr-plugin-mcli-ccf6e0f9c6b0481ed13e0f4794e3fbead750f385.tar.gz
vdr-plugin-mcli-ccf6e0f9c6b0481ed13e0f4794e3fbead750f385.tar.bz2
added vdr-plugin-mcli-0.0.1+svn20120927
Diffstat (limited to 'mcast/client/.svn/text-base/api_server.c.svn-base')
-rw-r--r--mcast/client/.svn/text-base/api_server.c.svn-base397
1 files changed, 397 insertions, 0 deletions
diff --git a/mcast/client/.svn/text-base/api_server.c.svn-base b/mcast/client/.svn/text-base/api_server.c.svn-base
new file mode 100644
index 0000000..c3d7617
--- /dev/null
+++ b/mcast/client/.svn/text-base/api_server.c.svn-base
@@ -0,0 +1,397 @@
+/*
+ * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de
+ *
+ * See the COPYING file for copyright information and
+ * how to reach the author.
+ *
+ */
+
+#include "headers.h"
+
+#if defined(API_SOCK) || defined(API_SHM) || defined (API_WIN)
+
+static int process_cmd (api_cmd_t * api_cmd, tra_info_t * trl, netceiver_info_list_t * nci)
+{
+ if(api_cmd->magic != MCLI_MAGIC || api_cmd->version != MCLI_VERSION) {
+ api_cmd->magic = MCLI_MAGIC;
+ api_cmd->version = MCLI_VERSION;
+ api_cmd->state = API_RESPONSE;
+ return 0;
+ }
+ if (api_cmd->state != API_REQUEST) {
+ return 0;
+ }
+
+ switch (api_cmd->cmd) {
+ case API_GET_NC_NUM:
+ api_cmd->parm[API_PARM_NC_NUM] = nci->nci_num;
+ api_cmd->state = API_RESPONSE;
+ break;
+
+ case API_GET_NC_INFO:
+ if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) {
+ api_cmd->u.nc_info = nci->nci[api_cmd->parm[API_PARM_NC_NUM]];
+ api_cmd->state = API_RESPONSE;
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ break;
+ case API_GET_TUNER_INFO:
+ if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) {
+ if (api_cmd->parm[API_PARM_TUNER_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].tuner_num) {
+ api_cmd->u.tuner_info = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].tuner[api_cmd->parm[API_PARM_TUNER_NUM]];
+ api_cmd->state = API_RESPONSE;
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ break;
+ case API_GET_SAT_LIST_INFO:
+ if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) {
+ if (api_cmd->parm[API_PARM_SAT_LIST_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list_num) {
+ api_cmd->u.sat_list = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]];
+ api_cmd->state = API_RESPONSE;
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ break;
+ case API_GET_SAT_INFO:
+ if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) {
+ if (api_cmd->parm[API_PARM_SAT_LIST_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list_num) {
+ if (api_cmd->parm[API_PARM_SAT_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat_num) {
+ api_cmd->u.sat_info = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat[api_cmd->parm[API_PARM_SAT_NUM]];
+ api_cmd->state = API_RESPONSE;
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ break;
+
+ case API_GET_SAT_COMP_INFO:
+ if (api_cmd->parm[API_PARM_NC_NUM] < nci->nci_num) {
+ if (api_cmd->parm[API_PARM_SAT_LIST_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list_num) {
+ if (api_cmd->parm[API_PARM_SAT_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat_num) {
+ if (api_cmd->parm[API_PARM_SAT_COMP_NUM] < nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat[api_cmd->parm[API_PARM_SAT_NUM]].comp_num) {
+ api_cmd->u.sat_comp = nci->nci[api_cmd->parm[API_PARM_NC_NUM]].sat_list[api_cmd->parm[API_PARM_SAT_LIST_NUM]].sat[api_cmd->parm[API_PARM_SAT_NUM]].comp[api_cmd->parm[API_PARM_SAT_COMP_NUM]];
+ api_cmd->state = API_RESPONSE;
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ break;
+ case API_GET_TRA_NUM:
+ api_cmd->parm[API_PARM_TRA_NUM] = trl->tra_num;
+ api_cmd->state = API_RESPONSE;
+ break;
+ case API_GET_TRA_INFO:
+ if (api_cmd->parm[API_PARM_TRA_NUM] < trl->tra_num) {
+ api_cmd->u.tra = trl->tra[api_cmd->parm[API_PARM_TRA_NUM]];
+ api_cmd->state = API_RESPONSE;
+ } else {
+ api_cmd->state = API_ERROR;
+ }
+ break;
+ default:
+ api_cmd->state = API_ERROR;
+ }
+ return 1;
+}
+#endif
+#ifdef API_SOCK
+typedef struct
+{
+ pthread_t thread;
+ int fd;
+ struct sockaddr_un addr;
+ socklen_t len;
+ int run;
+} sock_t;
+
+static void *sock_cmd_loop (void *p)
+{
+ sock_t *s = (sock_t *) p;
+ api_cmd_t sock_cmd;
+ int n;
+ netceiver_info_list_t *nc_list=nc_get_list();
+ tra_info_t *tra_list=tra_get_list();
+
+ dbg ("new api client connected\n");
+ s->run = 1;
+ while (s->run){
+ n = recv (s->fd, &sock_cmd, sizeof (api_cmd_t), 0);
+ if (n == sizeof (api_cmd_t)) {
+ nc_lock_list();
+ process_cmd (&sock_cmd, tra_list, nc_list);
+ nc_unlock_list();
+ send (s->fd, &sock_cmd, sizeof (api_cmd_t), 0);
+ } else {
+ sock_cmd.magic = MCLI_MAGIC;
+ sock_cmd.version = MCLI_VERSION;
+ sock_cmd.state = API_RESPONSE;
+ send (s->fd, &sock_cmd, sizeof (api_cmd_t), 0);
+ break;
+ }
+ pthread_testcancel();
+ }
+
+ close (s->fd);
+ pthread_detach (s->thread);
+ free (s);
+ return NULL;
+}
+
+static void *sock_cmd_listen_loop (void *p)
+{
+ sock_t tmp;
+ sock_t *s = (sock_t *) p;
+ dbg ("sock api listen loop started\n");
+ s->run = 1;
+
+ while (s->run) {
+ tmp.len = sizeof (struct sockaddr_un);
+ tmp.fd = accept (s->fd, (struct sockaddr*)&tmp.addr, &tmp.len);
+ if (tmp.fd >= 0) {
+ sock_t *as = (sock_t *) malloc (sizeof (sock_t));
+ if (as == NULL) {
+ err ("Cannot get memory for socket\n");
+ }
+ *as=tmp;
+ as->run = 0;
+ pthread_create (&as->thread, NULL, sock_cmd_loop, as);
+ } else {
+ break;
+ }
+ pthread_testcancel();
+ }
+ pthread_detach (s->thread);
+ return NULL;
+}
+
+static sock_t s;
+int api_sock_init (const char *cmd_sock_path)
+{
+ s.addr.sun_family = AF_UNIX;
+ strcpy (s.addr.sun_path, cmd_sock_path);
+ s.len = sizeof(struct sockaddr_un); //strlen (cmd_sock_path) + sizeof (s.addr.sun_family);
+
+ if ((s.fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ warn ("Cannot get socket %d\n", errno);
+ return -1;
+ }
+ unlink (cmd_sock_path);
+ if (bind (s.fd, (struct sockaddr*)&s.addr, s.len) < 0) {
+ warn ("Cannot bind control socket\n");
+ return -1;
+ }
+ if (chmod(cmd_sock_path, S_IRWXU|S_IRWXG|S_IRWXO)) {
+ warn ("Cannot chmod 777 socket %s\n", cmd_sock_path);
+ }
+ if (listen (s.fd, 5) < 0) {
+ warn ("Cannot listen on socket\n");
+ return -1;
+ }
+ return pthread_create (&s.thread, NULL, sock_cmd_listen_loop, &s);
+}
+
+void api_sock_exit (void)
+{
+ //FIXME memory leak on exit in context structres
+ s.run=0;
+ close(s.fd);
+
+ if(pthread_exist(s.thread) && !pthread_cancel (s.thread)) {
+ pthread_join (s.thread, NULL);
+ }
+}
+#endif
+#ifdef API_SHM
+static api_cmd_t *api_cmd = NULL;
+static pthread_t api_cmd_loop_thread;
+
+static void *api_cmd_loop (void *p)
+{
+ netceiver_info_list_t *nc_list=nc_get_list();
+ tra_info_t *tra_list=tra_get_list();
+ while (1) {
+ nc_lock_list();
+ process_cmd (api_cmd, tra_list, nc_list);
+ nc_unlock_list();
+ usleep (1);
+ pthread_testcancel();
+ }
+
+ return NULL;
+}
+
+int api_shm_init (void)
+{
+ int fd = shm_open (API_SHM_NAMESPACE, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ warn ("Cannot get a shared memory handle\n");
+ return -1;
+ }
+ if (ftruncate (fd, sizeof (api_cmd_t)) == -1) {
+ err ("Cannot truncate shared memory\n");
+ }
+ api_cmd = mmap (NULL, sizeof (api_cmd_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (api_cmd == MAP_FAILED) {
+ err ("MMap of shared memory region failed\n");
+ }
+ close (fd);
+
+ memset (api_cmd, 0, sizeof (api_cmd_t));
+
+ pthread_create (&api_cmd_loop_thread, NULL, api_cmd_loop, NULL);
+ return 0;
+}
+
+void api_shm_exit (void)
+{
+ if(pthread_exist(api_cmd_loop_thread) && !pthread_cancel (api_cmd_loop_thread)) {
+ pthread_join (api_cmd_loop_thread, NULL);
+ }
+ shm_unlink (API_SHM_NAMESPACE);
+}
+#endif
+#ifdef API_WIN
+
+void *api_cmd_loop(void *lpvParam)
+{
+ netceiver_info_list_t *nc_list=nc_get_list();
+ tra_info_t *tra_list=tra_get_list();
+ api_cmd_t sock_cmd;
+ DWORD cbBytesRead, cbWritten;
+ BOOL fSuccess;
+ HANDLE hPipe;
+
+ hPipe = (HANDLE) lpvParam;
+
+ while (1) {
+ fSuccess = ReadFile(
+ hPipe, // handle to pipe
+ &sock_cmd, // buffer to receive data
+ sizeof(sock_cmd), // size of buffer
+ &cbBytesRead, // number of bytes read
+ NULL); // not overlapped I/O
+
+ if (! fSuccess || cbBytesRead == 0) {
+ break;
+ }
+
+ if (cbBytesRead == sizeof (api_cmd_t)) {
+ nc_lock_list();
+ process_cmd (&sock_cmd, tra_list, nc_list);
+ nc_unlock_list();
+
+ fSuccess = WriteFile(
+ hPipe, // handle to pipe
+ &sock_cmd, // buffer to write from
+ sizeof(sock_cmd), // number of bytes to write
+ &cbWritten, // number of bytes written
+ NULL); // not overlapped I/O
+
+ if (! fSuccess || sizeof(sock_cmd) != cbWritten) {
+ break;
+ }
+ } else {
+ sock_cmd.magic = MCLI_MAGIC;
+ sock_cmd.version = MCLI_VERSION;
+ sock_cmd.state = API_RESPONSE;
+ fSuccess = WriteFile(
+ hPipe, // handle to pipe
+ &sock_cmd, // buffer to write from
+ sizeof(sock_cmd), // number of bytes to write
+ &cbWritten, // number of bytes written
+ NULL); // not overlapped I/O
+
+ if (! fSuccess || sizeof(sock_cmd) != cbWritten) {
+ break;
+ }
+ break;
+ }
+ }
+
+ FlushFileBuffers(hPipe);
+ DisconnectNamedPipe(hPipe);
+ CloseHandle(hPipe);
+
+ return NULL;
+}
+
+#define BUFSIZE 2048
+void *api_listen_loop(void *p)
+{
+ BOOL fConnected;
+ pthread_t api_cmd_loop_thread;
+ HANDLE hPipe;
+ LPTSTR lpszPipename=(LPTSTR)p;
+
+ while(1) {
+ hPipe = CreateNamedPipe(
+ lpszPipename, // pipe name
+ PIPE_ACCESS_DUPLEX, // read/write access
+ PIPE_TYPE_MESSAGE | // message type pipe
+ PIPE_READMODE_MESSAGE | // message-read mode
+ PIPE_WAIT, // blocking mode
+ PIPE_UNLIMITED_INSTANCES, // max. instances
+ BUFSIZE, // output buffer size
+ BUFSIZE, // input buffer size
+ 0, // client time-out
+ NULL); // default security attribute
+
+ if (hPipe == INVALID_HANDLE_VALUE) {
+ err ("CreatePipe failed");
+ return NULL;
+ }
+ pthread_testcancel();
+ fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
+
+ if (fConnected) {
+ if(pthread_create(&api_cmd_loop_thread, NULL, api_cmd_loop, hPipe)) {
+ err ("CreateThread failed");
+ return NULL;
+ } else {
+ pthread_detach(api_cmd_loop_thread);
+ }
+ }
+ else {
+ CloseHandle(hPipe);
+ }
+ }
+ return NULL;
+}
+
+pthread_t api_listen_loop_thread;
+
+int api_init (LPTSTR cmd_pipe_path)
+{
+ return pthread_create (&api_listen_loop_thread, NULL, api_listen_loop, cmd_pipe_path);
+}
+
+void api_exit (void)
+{
+ if(pthread_exist(api_listen_loop_thread) && !pthread_cancel (api_listen_loop_thread)) {
+ TerminateThread(pthread_getw32threadhandle_np(api_listen_loop_thread),0);
+ pthread_join (api_listen_loop_thread, NULL);
+ }
+}
+
+#endif