summaryrefslogtreecommitdiff
path: root/mcast/client/.svn/text-base/mmi_handler.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/mmi_handler.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/mmi_handler.c.svn-base')
-rw-r--r--mcast/client/.svn/text-base/mmi_handler.c.svn-base336
1 files changed, 336 insertions, 0 deletions
diff --git a/mcast/client/.svn/text-base/mmi_handler.c.svn-base b/mcast/client/.svn/text-base/mmi_handler.c.svn-base
new file mode 100644
index 0000000..716c7f1
--- /dev/null
+++ b/mcast/client/.svn/text-base/mmi_handler.c.svn-base
@@ -0,0 +1,336 @@
+/*
+ * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de
+ *
+ * See the COPYING file for copyright information and
+ * how to reach the author.
+ *
+ * modified by Reel Multimedia, http://www.reel-multimedia.com, info@reel-multimedia.com
+ * 01042010 DL: use a single thread for reading from network layer (uses less resources)
+ *
+ */
+
+#include "headers.h"
+
+//---------------------------------------------------------------------------------------------
+void mmi_print_info (mmi_info_t * m)
+{
+ char str[INET6_ADDRSTRLEN];
+ printf ("------------------\n");
+ inet_ntop (AF_INET6, &m->ipv6, (char *) str, INET6_ADDRSTRLEN);
+ printf ("IP: %s\n", str);
+ printf ("UUID: %s\n", m->uuid);
+ printf ("Slot: %d\n", m->slot);
+
+ int i;
+ for (i = 0; i < m->caid_num; i++) {
+ caid_mcg_t *cm = m->caids + i;
+ printf ("%i.SID: %d\n", i, cm->caid);
+ inet_ntop (AF_INET6, &cm->mcg, (char *) str, INET6_ADDRSTRLEN);
+ printf ("%i.MCG: %s\n", i, str);
+ }
+ printf ("TEXT:\n===================\n %s \n===================\n", m->mmi_text);
+
+}
+
+//---------------------------------------------------------------------------------------------
+int mmi_open_menu_session (char *uuid, char *intf, int port, int cmd)
+{
+ int ret;
+ int j, sockfd;
+ struct in6_addr ipv6;
+ char iface[IFNAMSIZ];
+
+ inet_pton (AF_INET6, uuid, &ipv6);
+
+ if (!intf || !strlen (intf)) {
+ struct intnode *intn = int_find_first ();
+ if (intn) {
+ strcpy (iface, intn->name);
+ }
+ } else {
+ strncpy (iface, intf, sizeof (iface));
+ iface[sizeof (iface) - 1] = 0;
+ }
+ if (!port) {
+ port = 23013;
+ }
+
+ sockfd = socket (PF_INET6, SOCK_STREAM, 0);
+ j = 1;
+ if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, (_SOTYPE) & j, sizeof (j)) < 0) {
+ err ("setsockopt REUSEADDR\n");
+ }
+
+ j = 1;
+ if (setsockopt (sockfd, SOL_SOCKET, TCP_NODELAY, (_SOTYPE) & j, sizeof (j)) < 0) {
+ warn ("setsockopt TCP_NODELAY\n");
+ }
+
+ dbg ("Connect To: %s\n", uuid);
+
+ struct sockaddr_in6 addr;
+ memset (&addr, 0, sizeof (struct sockaddr_in6));
+
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = htons (port);
+ addr.sin6_addr = ipv6;
+ addr.sin6_scope_id = if_nametoindex (iface);
+
+ ret = connect (sockfd, (struct sockaddr *) &addr, sizeof (struct sockaddr_in6));
+ if (ret < 0) {
+ dbg ("Failed to access NetCeiver MMI support\n");
+ return -1;
+ }
+ //send init cmd
+ char buf[128];
+ memset (buf, 0, sizeof (buf));
+ dbg ("Request CAM slot %d \n", cmd);
+ sprintf (buf, "%x", cmd);
+ int n = send (sockfd, buf, strlen (buf) + 1, 0);
+ if (n < 0) {
+ dbg ("unable to sent mmi connection cmd !\n");
+ closesocket (sockfd);
+ return -1;
+ }
+ dbg ("MMI SESSION : OK\n");
+ return sockfd;
+}
+
+//---------------------------------------------------------------------------------------------
+void mmi_close_menu_session (int s)
+{
+ closesocket (s);
+}
+
+//---------------------------------------------------------------------------------------------
+int mmi_cam_reset (char *uuid, char *intf, int port, int slot)
+{
+ int cmd = (slot << 12) | 0xfff;
+ printf ("Reseting slot %d (cmd %x)...\n", slot, cmd);
+ int sock = mmi_open_menu_session (uuid, intf, port, cmd);
+ if (sock < 1) {
+ printf ("Unable to reset slot %d on netceiver %s...\n", slot, uuid);
+ }
+ closesocket (sock);
+ return 0;
+}
+//---------------------------------------------------------------------------------------------
+int mmi_cam_reinit (char *uuid, char *intf, int port, int slot)
+{
+ int cmd = (slot << 12) | 0xeee;
+ printf ("Reinitializing slot %d (cmd %x)...\n", slot, cmd);
+ int sock = mmi_open_menu_session (uuid, intf, port, cmd);
+ if (sock < 1) {
+ printf ("Unable to reset slot %d on netceiver %s...\n", slot, uuid);
+ }
+ closesocket (sock);
+ return 0;
+}
+//---------------------------------------------------------------------------------------------
+int mmi_get_menu_text (int sockfd, char *buf, int buf_len, int timeout)
+{
+ int n = -1;
+ struct pollfd p;
+ memset (buf, 0, buf_len);
+ p.fd = sockfd;
+ p.events = POLLIN;
+ if (poll (&p, 1, (timeout+999)>>10) > 0) {
+ n = recv (sockfd, buf, buf_len, 0); //MSG_DONTWAIT);
+ }
+ if (n > 0) {
+ dbg ("recv:\n%s \n", buf);
+ }
+ return n;
+}
+
+//---------------------------------------------------------------------------------------------
+int mmi_send_menu_answer (int sockfd, char *buf, int buf_len)
+{
+ dbg ("send: %s len %d \n", buf, buf_len);
+ int n;
+ n = send (sockfd, buf, buf_len, 0);
+ if (n < 0) {
+ dbg ("mmi_send_answer: error sending !\n");
+ }
+ return n;
+}
+
+//---------------------------------------------------------------------------------------------
+UDPContext *mmi_broadcast_client_init (int port, char *intf)
+{
+ UDPContext *s;
+ char mcg[1024];
+ char iface[IFNAMSIZ];
+ //FIXME: move to common
+ strcpy (mcg, "ff18:6000::");
+ if (!intf || !strlen (intf)) {
+ struct intnode *intn = int_find_first ();
+ if (intn) {
+ strcpy (iface, intn->name);
+ }
+ } else {
+ strncpy (iface, intf, sizeof (iface));
+ iface[sizeof (iface) - 1] = 0;
+ }
+ if (!port) {
+ port = 23000;
+ }
+
+ s = client_udp_open_host (mcg, port, iface);
+ if (!s) {
+ dbg ("client udp open host error !\n");
+ }
+
+ return s;
+}
+
+void mmi_broadcast_client_exit (UDPContext * s)
+{
+ udp_close (s);
+}
+
+//---------------------------------------------------------------------------------------------
+typedef struct
+{
+ xmlDocPtr doc;
+ xmlChar *str, *key;
+} xml_parser_context_t;
+
+static void clean_xml_parser_thread (void *arg)
+{
+ xml_parser_context_t *c = (xml_parser_context_t *) arg;
+ if (c->str) {
+ xmlFree (c->str);
+ }
+ if (c->key) {
+ xmlFree (c->key);
+ }
+ if (c->doc) {
+ xmlFreeDoc (c->doc);
+ }
+ dbg ("Free XML parser structures!\n");
+}
+
+//---------------------------------------------------------------------------------------------
+int mmi_get_data (xmlChar * xmlbuff, int buffersize, mmi_info_t * mmi_info)
+{
+ xml_parser_context_t c;
+ xmlNode *root_element = NULL, *cur_node = NULL;
+
+ xmlKeepBlanksDefault (0); //reomve this f. "text" nodes
+ c.doc = xmlParseMemory ((char *) xmlbuff, buffersize);
+ root_element = xmlDocGetRootElement (c.doc);
+ pthread_cleanup_push (clean_xml_parser_thread, &c);
+
+
+ if (root_element != NULL) {
+ cur_node = root_element->children;
+ if (!xmlStrcmp (cur_node->name, (xmlChar *) "Description")) {
+ root_element = cur_node->children;
+ while (root_element != NULL) {
+ c.key = NULL;
+ c.str = NULL;
+ if ((xmlStrcmp (root_element->name, (const xmlChar *) "component"))) {
+ warn ("Cannot parse XML data\n");
+ root_element = root_element->next;
+ continue;
+ }
+ cur_node = root_element->children;
+ if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "Description"))) {
+ c.str = xmlGetProp (cur_node, (unsigned char *) "about");
+ //fprintf(stdout,"\n%s:\n",c.str);
+ //fprintf(stdout,"-----------------------------------------------------------\n");
+ } else {
+ warn ("Cannot parse XML data\n");
+ root_element = root_element->next;
+ continue;
+ }
+ if (c.str && (!xmlStrcmp (c.str, (const xmlChar *) "MMIData"))) {
+ cur_node = cur_node->children;
+ while (cur_node != NULL) {
+ if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "IP"))) {
+ c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1);
+ if (c.key) {
+ dbg ("IP: %s\n", c.key);
+ inet_pton (AF_INET6, (char *) c.key, &mmi_info->ipv6);
+ xmlFree (c.key);
+ }
+ } else if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "UUID"))) {
+ c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1);
+ if (c.key) {
+ dbg ("UUID: %s\n", c.key);
+ strcpy (mmi_info->uuid, (char *) c.key);
+ xmlFree (c.key);
+ }
+ } else if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "Slot"))) {
+ c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1);
+ if (c.key) {
+ dbg ("Slot: %s\n", c.key);
+ mmi_info->slot = atoi ((char *) c.key);
+ xmlFree (c.key);
+ }
+ } else if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "TEXT"))) {
+ c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1);
+ if (c.key) {
+ dbg ("TEXT: %s\n", c.key);
+ int olen = MMI_TEXT_LENGTH, ilen = strlen ((char *) c.key);
+
+ UTF8Toisolat1 ((unsigned char *) mmi_info->mmi_text, &olen, c.key, &ilen);
+
+ xmlFree (c.key);
+ }
+ }
+ cur_node = cur_node->next;
+ }
+ } else if (c.str && (!xmlStrcmp (c.str, (const xmlChar *) "ProgramNumberIDs"))) {
+ cur_node = cur_node->children;
+ while (cur_node != NULL) {
+ if ((!xmlStrcmp (cur_node->name, (const xmlChar *) "MCG"))) {
+ c.key = xmlNodeListGetString (c.doc, cur_node->xmlChildrenNode, 1);
+ if (c.key) {
+ dbg ("MCG: %s\n", c.key);
+ struct in6_addr mcg;
+ inet_pton (AF_INET6, (char *) c.key, &mcg);
+ int sid;
+ mcg_get_id (&mcg, &sid);
+ mcg_set_id (&mcg, 0);
+ mmi_info->caids = (caid_mcg_t *) realloc (mmi_info->caids, sizeof (caid_mcg_t) * (mmi_info->caid_num + 1));
+ if (!mmi_info->caids)
+ err ("mmi_get_data: out of memory\n");
+ caid_mcg_t *cm = mmi_info->caids + mmi_info->caid_num;
+ cm->caid = sid;
+ cm->mcg = mcg;
+ mmi_info->caid_num++;
+ xmlFree (c.key);
+ }
+ }
+ cur_node = cur_node->next;
+ }
+ }
+ xmlFree (c.str);
+ root_element = root_element->next;
+ }
+ }
+ }
+
+ xmlFreeDoc (c.doc);
+ pthread_cleanup_pop (0);
+ return 1;
+}
+
+//---------------------------------------------------------------------------------------------
+int mmi_poll_for_menu_text (UDPContext * s, mmi_info_t * m, int timeout)
+{
+ char buf[8192];
+ int n = 0;
+ if (s) {
+ n = udp_read (s, (unsigned char *) buf, sizeof (buf), timeout, NULL);
+ if (n > 0) {
+ dbg ("recv:\n%s \n", buf);
+ memset (m, 0, sizeof (mmi_info_t));
+ mmi_get_data ((xmlChar *) buf, n, m);
+ }
+ }
+ return n;
+}
+//---------------------------------------------------------------------------------------------