blob: fa4366ac6da45b22baf4230c3d82a78c2e4cc316 [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 *line, *nl, *p;
struct hdhr_tuner_t *ht = (struct hdhr_tuner_t *)context;
line = buf;
while ((nl = strchr(line, '\n')) != NULL) {
// replace \r\n with \0
*nl = '\0';
if (nl > line && *(nl - 1) == '\r') {
*(nl - 1) = '\0';
}
// process line
printf("hdhr:parse:[%s]\n", line);
p = strstr(line, "Model:");
if (p) {
if (get_string_by_name(p, "Model", ht->model, sizeof(ht->model), NULL)) {
cleanup_txt(ht->model);
p = strstr(ht->model, "-CC");
if (p) {
ht->cc_tuner = 1;
}
p = strstr(ht->model, "HDTC");
if (p) {
ht->transcode_tuner = 1;
}
}
}
p = strstr(line, "Firmware:");
if (p) {
if (get_string_by_name(p, "Firmware", ht->firmware, sizeof(ht->firmware), NULL)) {
cleanup_txt(ht->firmware);
}
}
line = nl + 1;
}
return (line - buf);
}
int get_dev_model_and_fw(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;
}