+/*
+ * Copyright (C) 2009, 2010 by Nils Faerber <nils.faerber@kernelconcepts.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
rb = read(rds_fd, rbuf, 3);
if (rb <= 0)
- exit(0); // just for testing
- if (rb != 3)
+ return 0;
+ if (rb != 3) {
printf("#read err rb=%d\n", rb);
+ return 0;
+ }
block = rbuf[0] | (rbuf[1] << 8);
offset = rbuf[2] & 0x07;
}
if (OutputFlags & RDS_RECEIVE_INDICATOR)
printf(".");
+
return 0;
}
GROUP_12A, GROUP_12B, GROUP_13A, GROUP_13B, GROUP_14A, GROUP_14B,
GROUP_15A, GROUP_15B, GROUP_UNKNOWN };
+void rds_radio_retuned(void)
+{
+ memset(&rds_info, 0, sizeof(rds_info));
+ rds_info.LTN = -1;
+ memset(&rds_time, 0, sizeof(rds_time));
+}
+
void rds_decode_group(unsigned short *rdsgroup)
{
static unsigned short ogrp[4];
+static unsigned char grp_decoded = 0;
+static unsigned char sname_rcvd = 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));
rds_info.ccode = (PI & 0xf000) >> 12;
rds_info.ptype = (PI & 0x0f00) >> 8;
rds_info.pref = (PI & 0x00ff);
+ sname_rcvd = 0;
if (rds_info.pref == 0) /* something is wrong here */
return;
rds_info.PI = rdsgroup[0];
float AF1=0, AF2=0;
offs = (rdsgroup[1] & 0x03);
+ if (offs == 0)
+ sname_rcvd = 0;
+ if (offs == 1 && sname_rcvd == 0)
+ sname_rcvd = 1;
+ if (offs == 2 && sname_rcvd == 1)
+ sname_rcvd = 2;
+ if (offs == 3 && sname_rcvd == 2)
+ sname_rcvd = 3;
rds_info.sname[offs*2] = ((rdsgroup[3] & 0xff00) >> 8);
rds_info.sname[(offs*2)+1] = rdsgroup[3] & 0x00ff;
- if (_rds_private.rds_sname_cb != NULL)
+ if (_rds_private.rds_sname_cb != NULL && sname_rcvd == 3) {
_rds_private.rds_sname_cb(rds_info.sname, _rds_private.rds_sname_cb_data);
+ sname_rcvd = 0;
+ }
rds_info.TA = (rdsgroup[1] & 0x10) >> 4;
rds_info.TP = (rdsgroup[1] & 0x400) >> 10;
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;
}