From 676e37ddd2faa27593615e47d42a50446bf10fac Mon Sep 17 00:00:00 2001 From: Nils Faerber Date: Fri, 19 Nov 2010 13:20:34 +0100 Subject: [PATCH] More decoding, some minor fixes --- decoder/rds.c | 51 +++++++++++++++++++++++++++++++++-------- decoder/rds_test.c | 57 +++++++++++++++++++++++++--------------------- decoder/tmc.c | 21 ++++++++++++----- 3 files changed, 87 insertions(+), 42 deletions(-) diff --git a/decoder/rds.c b/decoder/rds.c index 677609f..27a417c 100644 --- a/decoder/rds.c +++ b/decoder/rds.c @@ -138,6 +138,7 @@ enum RDSGroupType { GROUP_0A=0, GROUP_0B, GROUP_1A, GROUP_1B, GROUP_2A, GROUP_2B void rds_decode_group(unsigned short *rdsgroup) { static unsigned short ogrp[4]; +static unsigned char grp_decoded = 0; unsigned char grp_type = (rdsgroup[1] >> 11); unsigned char offs; static unsigned char otextAB = 0, newtext = 0; @@ -147,15 +148,19 @@ int local_time_off = 0; int day_code = 0; int year_, mon_, K; - if (ogrp[0] == rdsgroup[0] && ogrp[1] == rdsgroup[1] && ogrp[2] == rdsgroup[2] && ogrp[3] == rdsgroup[3]) - return; - else { + /* we want to wait for at least two identical group transmits */ + if (ogrp[0] != rdsgroup[0] || ogrp[1] != rdsgroup[1] || ogrp[2] != rdsgroup[2] || ogrp[3] != rdsgroup[3]) { ogrp[0] = rdsgroup[0]; ogrp[1] = rdsgroup[1]; ogrp[2] = rdsgroup[2]; ogrp[3] = rdsgroup[3]; //printf("grp: 0x%04x 0x%04x 0x%04x 0x%04x\n", rdsgroup[0], rdsgroup[1], rdsgroup[2], rdsgroup[3]); + grp_decoded = 0; + return; } + if (grp_decoded) + return; + if (rds_info.PI != PI) { /* station change? */ memset(&rds_info, 0, sizeof(rds_info)); @@ -338,6 +343,16 @@ int year_, mon_, K; printf("urban "); printf("\n"); } + } else if (rds_info.AID == 0x4bd7) { + if (OutputFlags & RDS_OUTPUT_RDSINFO) { + printf("RT+\nG2 = 0x%04x\n", rdsgroup[2]); + printf("template = 0x%02x\n", (rdsgroup[2] & 0x00ff)); + printf("SCB = 0x%02x\n", (rdsgroup[2] & 0x0f00)>>8); + printf("CB = 0x%02x\n", (rdsgroup[2] & 0x1000)>>12); + printf("rfu = 0x%02x\n", (rdsgroup[2] & 0xe000)>>13); + } + } else { + printf("3A AID=0x%04x\n", rds_info.AID); } break; case GROUP_3B: @@ -431,27 +446,40 @@ int year_, mon_, K; if (OutputFlags & RDS_OUTPUT_UNKNGRP) printf("GRP10B\n"); break; - case GROUP_11A: + case GROUP_11A: /* Open Data Application ODA */ if (OutputFlags & RDS_OUTPUT_UNKNGRP) - printf("GRP11A\n"); + printf("GRP11A ODA: #1=0x%02x #2=0x%04x #3=0x%04x\n", rdsgroup[1] & 0x1f, rdsgroup[2], rdsgroup[3]); + + /* we previously got an RT+ identifier, try RT+ decoding */ + if (rds_info.AID == 0x4bd7) { + printf("RT+\ntoggle: %s\n", (rdsgroup[1] & 0x10) ? "yes" : "no"); + printf("item running : %s\n", (rdsgroup[1] & 0x08) ? "yes" : "no"); + printf("content type 1 : %d\n", (rdsgroup[1] & 0x07) << 3 | (rdsgroup[2] & 0x0e00) >> 13); + printf("start marker 1 : %d\n", (rdsgroup[2] & 0x1f80) >> 7); + printf("length marker 1: %d\n", (rdsgroup[2] & 0x007e) >> 1); + printf("content type 2 : %d\n", (rdsgroup[1] & 0x01) << 4); + printf("start marker 2 : %d\n", (rdsgroup[2] & 0x07e0) >> 5); + printf("length marker 2: %d\n", (rdsgroup[2] & 0x001f)); + } break; - case GROUP_11B: + case GROUP_11B: /* Open Data Application ODA */ if (OutputFlags & RDS_OUTPUT_UNKNGRP) printf("GRP11B\n"); + printf("11B ODA: #1=0x%02x PI=0x%04x #3=0x%04x\n", rdsgroup[1] & 0x1f, rdsgroup[2], rdsgroup[3]); break; - case GROUP_12A: + case GROUP_12A: /* Open Data Application ODA */ if (OutputFlags & RDS_OUTPUT_UNKNGRP) printf("GRP12A\n"); break; - case GROUP_12B: + case GROUP_12B: /* Open Data Application ODA */ if (OutputFlags & RDS_OUTPUT_UNKNGRP) printf("GRP12B\n"); break; - case GROUP_13A: + case GROUP_13A: /* Open Data Application ODA or paging */ if (OutputFlags & RDS_OUTPUT_UNKNGRP) printf("GRP13A\n"); break; - case GROUP_13B: + case GROUP_13B: /* Open Data Application ODA */ if (OutputFlags & RDS_OUTPUT_UNKNGRP) printf("GRP13B\n"); break; @@ -504,5 +532,8 @@ int year_, mon_, K; printf("unkn. RDS group %d\n", grp_type); break; } + + /* done with this group */ + grp_decoded = 1; } diff --git a/decoder/rds_test.c b/decoder/rds_test.c index eb9bf70..b6aceca 100644 --- a/decoder/rds_test.c +++ b/decoder/rds_test.c @@ -25,22 +25,22 @@ sqlite3 *lcl_db; int OutputFlags; -void test_rds_PI_cb(unsigned short PI, unsigned char ccode, unsigned char ptype, unsigned char pref) +void test_rds_PI_cb(unsigned short PI, unsigned char ccode, unsigned char ptype, unsigned char pref, void *udata) { printf("New PI=%d ccode=%X ptype=%X '%s' '%s' pref=%d\n", PI, ccode, ptype, ptype_stext[ptype], ptype_ltext[ptype], pref); } -void test_rds_radiotext_cb(char *radio_text) +void test_rds_radiotext_cb(char *radio_text, void *udata) { printf("New RT: '%s'\n", radio_text); } -void test_rds_date_time_cb(struct tm *rds_time) +void test_rds_date_time_cb(struct tm *rds_time, void *udata) { printf("RDS date/time: %s", asctime(rds_time)); } -void test_rds_sname_cb(char *sname) +void test_rds_sname_cb(char *sname, void *udata) { printf("RDS sname='%s'\n", sname); } @@ -67,6 +67,9 @@ char rdevname[PATH_MAX] = "/dev/radio0"; unsigned short rdsgroup[4]; int rds_fd, i; + rds_init(); + tmc_init(); + i = 1; while (i < argc) { if (strncmp("-all", argv[i], 4) == 0) @@ -76,45 +79,47 @@ int rds_fd, i; if (strncmp("-rd", argv[i], 3) == 0) if (argc > i) strcpy(rdevname, argv[++i]); - if (strncmp("-rt", argv[i], 3) == 0) - OutputFlags |= RDS_OUTPUT_RADIO_TEXT; - if (strncmp("-ri", argv[i], 3) == 0) - OutputFlags |= RDS_OUTPUT_STATION_ID; - if (strncmp("-tmc", argv[i], 4) == 0) - OutputFlags |= RDS_OUTPUT_TMC; + if (strncmp("-rt", argv[i], 3) == 0) { + // OutputFlags |= RDS_OUTPUT_RADIO_TEXT; + rds_set_radiotext_cb(test_rds_radiotext_cb, NULL); + } + if (strncmp("-ri", argv[i], 3) == 0) { + // OutputFlags |= RDS_OUTPUT_STATION_ID; + rds_set_sname_cb(test_rds_sname_cb, NULL); + } + if (strncmp("-tmc", argv[i], 4) == 0) { + // OutputFlags |= RDS_OUTPUT_TMC; + tmc_set_msg_cb(test_tmc_msg_cb, NULL); + } if (strncmp("-eon", argv[i], 4) == 0) OutputFlags |= RDS_OUTPUT_EON; - if (strncmp("-dt", argv[i], 3) == 0) - OutputFlags |= RDS_OUTPUT_DATETIME; + if (strncmp("-dt", argv[i], 3) == 0) { + // OutputFlags |= RDS_OUTPUT_DATETIME; + rds_set_date_time_cb(test_rds_date_time_cb, NULL); + } if (strncmp("-ug", argv[i], 3) == 0) OutputFlags |= RDS_OUTPUT_UNKNGRP; - if (strncmp("-pi", argv[i], 3) == 0) - OutputFlags |= RDS_RECEIVE_INDICATOR; + if (strncmp("-pi", argv[i], 3) == 0) { + // OutputFlags |= RDS_RECEIVE_INDICATOR; + rds_set_PI_cb(test_rds_PI_cb, NULL); + } i++; } + if (!(rds_fd = open_radio(rdevname))) { perror("open radio:"); return -1; } + if (sqlite3_open("lcl.db", &lcl_db) != SQLITE_OK) { - perror("open radio:"); + perror("open LCL database:"); close(rds_fd); return -1; } - rds_init(); - tmc_init(); - - //rds_set_PI_cb(test_rds_PI_cb); - //rds_set_radiotext_cb(test_rds_radiotext_cb); - //rds_set_date_time_cb(test_rds_date_time_cb); - //rds_set_sname_cb(test_rds_sname_cb); - - tmc_set_msg_cb(test_tmc_msg_cb, NULL); - while (1) { if (rds_receive_group(rds_fd, rdsgroup)) { - // group complete, start decode + /* group complete, start decode */ rds_decode_group(rdsgroup); } } diff --git a/decoder/tmc.c b/decoder/tmc.c index f25d277..1d52ca3 100644 --- a/decoder/tmc.c +++ b/decoder/tmc.c @@ -76,9 +76,12 @@ char type_str2[128]=""; char typechr; int typenr, subtype; + //fprintf(stderr, "mCI=%d CI=%d\n", cur_tmc_msg.CI, CI); if (CI != cur_tmc_msg.CI || CI == -1) { - //printf("GF evt=%d loc=%d ext=%d CI=%d dir=%d", event, location, extent, CI, direction); - //printf("ev=%d ", event); +#ifdef DEBUG + printf("GF evt=%d loc=%d ext=%d CI=%d dir=%d", event, location, extent, CI, direction); + printf("ev=%d ", event); +#endif snprintf(sql, 256, "select ROADNUMBER,FIRST_NAME,NEGATIVE_OFFSET,POSITIVE_OFFSET,LINEAR_REFERENCE,TYPE,SUBTYPE from lcl where LOCATIONCODE=%d", location); sqlite3_prepare(lcl_db, sql, 256, &ppstmt, NULL); if (sqlite3_step(ppstmt) != SQLITE_ROW) { @@ -96,7 +99,9 @@ int typenr, subtype; subtype = sqlite3_column_int(ppstmt, 6); typechr = type_str1[0]; typenr = atoi(&type_str1[1]); - // printf(" type=%c %d stype=%d\n", typechr, typenr, subtype); +#ifdef DEBUG + printf(" type=%c %d stype=%d\n", typechr, typenr, subtype); +#endif snprintf(sql, 256, "select SNATDESC from lcl_supc where CLASS='%c' AND TCD=%d AND STCD=%d", typechr, typenr, subtype); sqlite3_prepare(lcl_db, sql, 256, &ppstmt, NULL); if (sqlite3_step(ppstmt) != SQLITE_ROW) { @@ -190,12 +195,15 @@ int typenr, subtype; if (location == 64777) { tmc_msg_ptr += sprintf(tmc_msg_ptr, "%s\n", evt_str); } else { - if (extent) + if (extent) { +#ifdef DEBUG + printf("dir=%d\n", direction); +#endif if (direction) tmc_msg_ptr += sprintf(tmc_msg_ptr, "zwischen %s %s und %s %s\n%s\n", type_str1, fst_name, type_str2, last_name, evt_str); else tmc_msg_ptr += sprintf(tmc_msg_ptr, "zwischen %s %s und %s %s\n%s\n", type_str2, last_name, type_str1, fst_name, evt_str); - else + } else tmc_msg_ptr += sprintf(tmc_msg_ptr, "in Höhe %s %s\n%s\n", type_str1, fst_name, evt_str); } } @@ -407,6 +415,7 @@ unsigned char ext_buf[256]; #endif } else { strncpy(evt_str, (char *)sqlite3_column_text(ppstmt, 0), 255); + // printf("(L)='%s'\n", evt_str); if (strlen(lofrstr) != 0 && strstr(evt_str,"(L)")!=NULL) { replace_str(evt_str, "(L)", lofrstr); } @@ -505,7 +514,7 @@ unsigned char CI = rdsgroup[1] & 0x07; // printf(" 0x%04x 0x%04x\n", rdsgroup[2], rdsgroup[3]); } -enum TMCtype { TMC_GROUP=0, TMC_SINGLE, TMC_SYSTEM, TMC_TUNING }; +// enum TMCtype { TMC_GROUP=0, TMC_SINGLE, TMC_SYSTEM, TMC_TUNING }; void decode_tmc(unsigned short *rdsgroup) { -- 2.39.2