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;
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));
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:
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;
printf("unkn. RDS group %d\n", grp_type);
break;
}
+
+ /* done with this group */
+ grp_decoded = 1;
}
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);
}
unsigned short rdsgroup[4];
int rds_fd, i;
+ rds_init();
+ tmc_init();
+
i = 1;
while (i < argc) {
if (strncmp("-all", argv[i], 4) == 0)
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);
}
}
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) {
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) {
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);
}
}
#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);
}
// 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)
{