| |
| #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 *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; |
| } |
| |