| #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 & |
| p = strstr(txt, "&"); |
| 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; |
| } |