blob: 62e12fabe1b3c052ce3a3e54f391aee049047c28 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <inttypes.h>
#include "utility.h"
#include "hdhomerun_tuner.h"
#include "hdhomerun_http.h"
#include "hdhomerun_dev.h"
#include "sagelog.h"
#define _MIN_(x, y) ((x) > (y) ? (y) : (x))
static int read_elemnt(char *xml, char *tag, char *buf, int size)
{
char open_tag[256], close_tag[256];
char *start, *end;
snprintf(open_tag, sizeof(open_tag), "<%s>", tag);
snprintf(close_tag, sizeof(open_tag), "</%s>", tag);
start = strstr(xml, open_tag);
if (start != NULL) {
start += strlen(open_tag);
end = strstr(start, close_tag);
if (end != NULL) {
int len = _MIN_(end - start, size);
memcpy(buf, start, len);
buf[len] = 0;
end += strlen(close_tag);
return end - xml;
}
}
return 0;
}
static void html_txt_converison(char *txt)
{
char *p;
do {
// remove &amp;
p = strstr(txt, "&amp;");
if (p)
strcpy(p + 1, p + 1 + 4);
} while (p);
}
// remove tag and trim space
static void cleanup_txt(char *txt)
{
int n = strlen(txt);
while (n > 0) {
if (txt[n] == ' ' || txt[n] == '<' || txt[n] == '\r' || txt[n] == '\n')
txt[n] = 0x0;
n--;
}
}
static int program_parser(void *context, char *buf, int bytes)
{
struct vchan_tbl_t *vt = (struct vchan_tbl_t *)context;
int pos, used_bytes;
char guide_num[16], guide_name[64];
pos = 0;
while (pos < bytes) {
used_bytes =
read_elemnt(buf + pos, "GuideNumber", guide_num, sizeof(guide_num));
if (used_bytes == 0)
break;
pos += used_bytes;
// printf( "%s ", guide_num );
used_bytes =
read_elemnt(buf + pos, "GuideName", guide_name, sizeof(guide_name));
if (used_bytes == 0)
break;
html_txt_converison(guide_name);
if (vt->channel_num >= vt->channel_size)
grow_vhcan_tbl(vt);
if (vt->channel_num < vt->channel_size) {
int i = vt->channel_num;
vt->vchan[i].guide_id = atoi(guide_num);
snprintf(vt->vchan[i].guide_name, sizeof(vt->vchan[i].guide_name),
"\"%s\"", guide_name);
vt->channel_num++;
}
pos += used_bytes;
// printf( "%s;\n", guide_name );
}
return pos;
}
static int hdhomerun_parser(void *context, char *buf, int bytes)
{
char *p;
struct hdhr_tuner_t *ht = (struct hdhr_tuner_t *)context;
p = strstr(buf, "Model:");
if (p != NULL) {
if (strlen(p + 6) < 10)
return p - buf;
if (get_string_by_name(p, "Model", ht->model, sizeof(ht->model), NULL)) {
cleanup_txt(ht->model);
}
}
if (strstr(buf, "CableCARD Menu") != NULL) {
ht->cc_tuner = 1;
}
return bytes;
}
int get_dev_model(struct hdhr_tuner_t *ht)
{
int ret = parse_http_page(ht->ip, "/", hdhomerun_parser, ht);
return ret;
}
int get_vchannel_list(struct vchan_tbl_t *vt)
{
int ret = parse_http_page(vt->ht.ip, "/lineup.xml", program_parser, vt);
return ret;
}