diff options
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-base | 336 |
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; +} +//--------------------------------------------------------------------------------------------- |