More decoding, some minor fixes
authorNils Faerber <nils.faerber@kernelconcepts.de>
Fri, 19 Nov 2010 12:20:34 +0000 (13:20 +0100)
committerNils Faerber <nils.faerber@kernelconcepts.de>
Fri, 19 Nov 2010 12:20:34 +0000 (13:20 +0100)
decoder/rds.c
decoder/rds_test.c
decoder/tmc.c

index 677609f..27a417c 100644 (file)
@@ -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;
 }
 
index eb9bf70..b6aceca 100644 (file)
 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);
                }
        }
index f25d277..1d52ca3 100644 (file)
@@ -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)
 {