diff options
-rw-r--r-- | HISTORY | 5 | ||||
-rw-r--r-- | LIESMICH.bitte | 15 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | radio.c | 21 | ||||
-rw-r--r-- | radioaudio.c | 745 | ||||
-rw-r--r-- | radioaudio.h | 3 | ||||
-rw-r--r-- | radiocheck.c | 6 | ||||
-rw-r--r-- | radiotextosd.c | 2 | ||||
-rw-r--r-- | radiotools.c | 1659 | ||||
-rw-r--r-- | radiotools.h | 1 | ||||
-rw-r--r-- | rdsreceiver.c | 45 | ||||
-rw-r--r-- | rtpluslist.c | 3 | ||||
-rw-r--r-- | rtplusosd.c | 2 |
13 files changed, 402 insertions, 2107 deletions
@@ -1,5 +1,10 @@ VDR Plugin 'radio' Revision History ----------------------------------- +2018-07-15: Version 1.xx + Ulrich Eckhardt <uli-vdr@uli-eckhardt.de> +- Better CRC check (should help on Harmony FM). +- Code cleanups. + 2018-02-23: Version 1.1.0 Ulrich Eckhardt <uli-vdr@uli-eckhardt.de> - Enhancements for osd2web by Jörg Wendel diff --git a/LIESMICH.bitte b/LIESMICH.bitte index 9a7508d..d5ed83e 100644 --- a/LIESMICH.bitte +++ b/LIESMICH.bitte @@ -1,3 +1,18 @@ +Written by: Lars Tegeler <email@host.dom>, + Uwe Hanke <egal @at egal-vdr dot de> + +Alte aber nicht mehr erreichbare homepages: + www.math.uni-paderborn.de/~tegeler/vdr + www.egal-vdr.de/plugins + +Aktueller Maintainer: + Ulrich Eckhardt <vdr@uli-eckhardt.de> +Aktuelle Homepage: + http://www.vdr-wiki.de/wiki/index.php/Radio-plugin +Aktuellste Version: + https://projects.vdr-developer.org/git/vdr-plugin-radio.git/ + + Plugin radio for vdr >= 1.7.37 MPEG-Standbilder als Beispiele beigefügt (siehe SubDir ../config/mpgestill), @@ -7,6 +7,8 @@ Project's old but now unavailable homepages: www.math.uni-paderborn.de/~tegeler/vdr www.egal-vdr.de/plugins +Current Maintainer: + Ulrich Eckhardt <vdr@uli-eckhardt.de> Project's Homepage: http://www.vdr-wiki.de/wiki/index.php/Radio-plugin Latest version available at: @@ -61,7 +61,7 @@ int S_RtMsgItems = 0; int S_RassText = 1; int S_ExtInfo = 0; uint32_t rt_color[9]; -int S_Verbose = 1; +int S_Verbose = 0; int S_Encrypted = 0; // Radiotext char RT_Text[5][RT_MEL]; @@ -187,37 +187,38 @@ bool cPluginRadio::ProcessArgs(int argc, char *argv[]) while ((c = getopt_long(argc, argv, "f:d:l:r:e:v:", long_options, NULL)) != -1) { switch (c) { case 'f': - printf("vdr-radio: arg files-dir = %s\n", optarg); + isyslog("vdr-radio: arg files-dir = %s", optarg); ConfigDir = strdup(optarg); ConfigDirParam = true; break; case 'd': - printf("vdr-radio: arg data-dir = %s\n", optarg); + isyslog("vdr-radio: arg data-dir = %s", optarg); DataDir = strdup(optarg); DataDirParam = true; break; case 'l': - printf("vdr-radio: arg live-mpeg = %s\n", optarg); + isyslog("vdr-radio: arg live-mpeg = %s", optarg); LiveFile = strdup(optarg); LiveFileParam = true; break; case 'r': - printf("vdr-radio: arg replay-mpeg = %s\n", optarg); + isyslog("vdr-radio: arg replay-mpeg = %s", optarg); ReplayFile = strdup(optarg); ReplayFileParam = true; break; case 'v': - printf("vdr-radio: arg verbose = %s\n", optarg); - if (isnumber(optarg)) + isyslog("vdr-radio: arg verbose = %s", optarg); + if (isnumber(optarg)) { S_Verbose = atoi(optarg); + } break; case 'e': - printf("vdr-radio: arg encrypted = %s\n", optarg); + isyslog("vdr-radio: arg encrypted = %s", optarg); if (isnumber(optarg)) S_Encrypted = atoi(optarg); break; default: - printf("vdr-radio: arg char = %c\n", c); + isyslog("vdr-radio: arg char = %c\n", c); return false; } } @@ -228,7 +229,7 @@ bool cPluginRadio::ProcessArgs(int argc, char *argv[]) bool cPluginRadio::Start(void) { // Start any background activities the plugin shall perform. - printf("vdr-radio: Radio-Plugin Backgr.Image/RDS-Text starts...\n"); + isyslog("vdr-radio: Radio-Plugin Backgr.Image/RDS-Text starts...\n"); radioImage = new cRadioImage; if (!radioImage) diff --git a/radioaudio.c b/radioaudio.c index ed931b5..8a7a51c 100644 --- a/radioaudio.c +++ b/radioaudio.c @@ -82,6 +82,17 @@ void radioStatusMsg(void) { // --- cRadioAudio ------------------------------------------------------------- +bool cRadioAudio::CrcOk(uchar *data) { + // crc16-check + int msglen = data[4] + 4; + unsigned short crc16 = crc16_ccitt(data, msglen, true); + unsigned short exp = (data[msglen+1] << 8) + data[msglen + 2]; + if ((crc16 != exp) && ((S_Verbose & 0x0f) >= 1)) { + printf("Wrong CRC # calc = %04x <> transmit = %04x Len %d\n", crc16, exp, msglen); + } + return (crc16 == exp); +} + cRadioAudio::cRadioAudio() : cAudio(), enabled(false), first_packets(0), audiopid(0), bratefound( false), rdsdevice(NULL), bitrate(NULL) { @@ -188,7 +199,8 @@ void cRadioAudio::RadiotextCheckPES(const uchar *data, int len) { printf("(End)\n\n"); } - for (int i = offset - 3, val; i > offset - 3 - rdsl; i--) { // <-- data reverse, from end to start + int val; + for (int i = offset - 3; i > offset - 3 - rdsl; i--) { // <-- data reverse, from end to start val = data[i]; if (val == 0xfe) { // Start @@ -196,7 +208,7 @@ void cRadioAudio::RadiotextCheckPES(const uchar *data, int len) { rt_start = true; rt_bstuff = false; if ((S_Verbose & 0x0f) >= 2) { - printf("\nRDS-Start: "); + printf("\nradioaudio: RDS-Start: "); } } @@ -246,14 +258,14 @@ void cRadioAudio::RadiotextCheckPES(const uchar *data, int len) { default: rt_start = false; if ((S_Verbose & 0x0f) >= 2) { - printf("[RDS-MEC '%02x' not used -> End]\n", + printf("radioaudio: [RDS-MEC '%02x' not used -> End]\n", val); } } } if (index >= mframel) { // max. rdslength, garbage ? if ((S_Verbose & 0x0f) >= 1) { - printf("RDS-Error(PES): too long, garbage ?\n"); + printf("radioaudio: RDS-Error(PES): too long, garbage ?\n"); } rt_start = false; } @@ -261,45 +273,31 @@ void cRadioAudio::RadiotextCheckPES(const uchar *data, int len) { if (rt_start && val == 0xff) { // End if ((S_Verbose & 0x0f) >= 2) { - printf("(RDS-End)\n"); + printf("radioaudio: (RDS-End)\n"); } rt_start = false; if (index < 9) { // min. rdslength, garbage ? if ((S_Verbose & 0x0f) >= 1) { - printf("RDS-Error(PES): too short -> garbage ?\n"); + printf("radioaudio: RDS-Error(PES): too short -> garbage ?\n"); } } else { // crc16-check - unsigned short crc16 = crc16_ccitt(mtext, index - 3, - true); - if (crc16 - != (mtext[index - 2] << 8) + mtext[index - 1]) { + + if (!CrcOk(mtext)) { if ((S_Verbose & 0x0f) >= 1) { - printf( - "RDS-Error(PES): wrong CRC # calc = %04x <> transmit = %02x%02x\n", - crc16, mtext[index - 2], - mtext[index - 1]); + printf("radioaudio: RDS-Error(PES): wrong\n"); } } else { switch (mec) { case 0x0a: - RadiotextDecode(mtext, index); // Radiotext + RadiotextDecode(mtext); // Radiotext break; case 0x46: switch ((mtext[7] << 8) + mtext[8]) { // ODA-ID case 0x4bd7: - RadioAudio->RadiotextDecode(mtext, index); // RT+ - break; - case 0x0d45: - case 0xcd46: - if ((S_Verbose & 0x20) > 0) { - unsigned char tmc[6]; // TMC Alert-C - int i; - for (i = 9; i <= (index - 3); i++) - tmc[i - 9] = mtext[i]; - tmc_parser(tmc, i - 8); - } + RadioAudio->RadiotextDecode(mtext); // RT+ break; + default: if ((S_Verbose & 0x0f) >= 2) { printf( @@ -324,16 +322,6 @@ void cRadioAudio::RadiotextCheckPES(const uchar *data, int len) { case 0xda: RassDecode(mtext, index); // Rass break; - case 0x30: - if ((S_Verbose & 0x20) > 0) { // TMC Alert-C - unsigned char tmc[6]; - int i; - for (i = 7; i <= (index - 3); i++) { - tmc[i - 7] = mtext[i]; - } - tmc_parser(tmc, i - 6); - } - break; } } } @@ -359,7 +347,7 @@ void cRadioAudio::RadiotextCheckTS(const uchar *data, int len) { } if ((S_Verbose & 0x02) == 0x02) { - printf("\nTS-Data(%d):\n", len); + printf("\nradioaudio: TS-Data(%d):\n", len); int cnt = 0; for (int a = 0; a < len; a++) { printf("%02x ", data[a]); @@ -432,7 +420,7 @@ void cRadioAudio::RadiotextCheckTS(const uchar *data, int len) { rt_bstuff = 0; mec = 0; if ((S_Verbose & 0x0f) >= 2) { - printf("\nRDS-Start: "); + printf("\nradioaudio: RDS-Start: "); } } @@ -475,7 +463,6 @@ void cRadioAudio::RadiotextCheckTS(const uchar *data, int len) { case 0xda: // Rass case 0x07: // PTY case 0x3e: // PTYN - case 0x30: // TMC case 0x02: mec = val; // PS RdsLogo = true; @@ -497,7 +484,17 @@ void cRadioAudio::RadiotextCheckTS(const uchar *data, int len) { if (rt_start == 1 && val == 0xff) { // End if ((S_Verbose & 0x0f) >= 2) { - printf("(RDS-End)\n"); + printf("(%02x RDS-End)\n", mec); + if ((mec == 0x02)||(mec == 0x0a)) { + for (i=5; i<index;i++) { + printf("%02x ", mtext[i]); + } + + for (i=9; i<index-2;i++) { + printf("%c", mtext[i]); + } + printf("\n\n"); + } } rt_start = 0; if (index < 9) { // min. rdslength, garbage ? @@ -505,33 +502,19 @@ void cRadioAudio::RadiotextCheckTS(const uchar *data, int len) { printf("RDS-Error(TS): too short -> garbage ?\n"); } } else { - // crc16-check - unsigned short crc16 = crc16_ccitt(mtext, index - 3, 1); - if (crc16 != (mtext[index - 2] << 8) + mtext[index - 1]) { + if (!CrcOk(mtext)) { if ((S_Verbose & 0x0f) >= 1) { - printf( - "RDS-Error(TS): wrong CRC # calc = %04x <> transmit = %02x%02x\n", - crc16, mtext[index - 2], mtext[index - 1]); + printf("radioaudio: RDS-Error(TS): wrong CRC\n"); } } else { switch (mec) { case 0x0a: - RadiotextDecode(mtext, index); // Radiotext + RadiotextDecode(mtext); // Radiotext break; case 0x46: switch ((mtext[7] << 8) + mtext[8]) { // ODA-ID case 0x4bd7: - RadiotextDecode(mtext, index); // RT+ - break; - case 0x0d45: - case 0xcd46: - if ((S_Verbose & 0x20) > 0) { - unsigned char tmc[6]; // TMC Alert-C - int i; - for (i = 9; i <= (index - 3); i++) - tmc[i - 9] = mtext[i]; - tmc_parser(tmc, i - 8); - } + RadiotextDecode(mtext); // RT+ break; default: if ((S_Verbose & 0x0f) >= 2) { @@ -557,15 +540,6 @@ void cRadioAudio::RadiotextCheckTS(const uchar *data, int len) { case 0xda: RassDecode(mtext, index); // Rass break; - case 0x30: - if ((S_Verbose & 0x20) > 0) { // TMC Alert-C - unsigned char tmc[6]; - int i; - for (i = 7; i <= (index - 3); i++) { - tmc[i - 7] = mtext[i]; - } - tmc_parser(tmc, i - 6); - } } } } @@ -573,7 +547,7 @@ void cRadioAudio::RadiotextCheckTS(const uchar *data, int len) { } } -void cRadioAudio::RadiotextDecode(unsigned char *mtext, int len) { +void cRadioAudio::RadiotextDecode(unsigned char *mtext) { static bool rtp_itoggle = false; static int rtp_idiffs = 0; static cTimeMs rtp_itime; @@ -582,358 +556,347 @@ void cRadioAudio::RadiotextDecode(unsigned char *mtext, int len) { // byte 1+2 = ADD (10bit SiteAdress + 6bit EncoderAdress) // byte 3 = SQC (Sequence Counter 0x00 = not used) int leninfo = mtext[4]; // byte 4 = MFL (Message Field Length) - if (len >= leninfo + 7) { // check complete length + // byte 5 = MEC (Message Element Code, 0x0a for RT, 0x46 for RTplus) - if (mtext[5] == 0x0a) { - // byte 6+7 = DSN+PSN (DataSetNumber+ProgramServiceNumber, - // ignore here, always 0x00 ?) - // byte 8 = MEL (MessageElementLength, max. 64+1 byte @ RT) - if (mtext[8] == 0 || mtext[8] > RT_MEL || mtext[8] > leninfo - 4) { + if (mtext[5] == 0x0a) { + // byte 6+7 = DSN+PSN (DataSetNumber+ProgramServiceNumber, + // ignore here, always 0x00 ?) + // byte 8 = MEL (MessageElementLength, max. 64+1 byte @ RT) + if (mtext[8] == 0 || mtext[8] > RT_MEL || mtext[8] > leninfo - 4) { + if ((S_Verbose & 0x0f) >= 1) { + printf("RT-Error: Length=0 or not correct (MFL= %d, MEL= %d)\n", + mtext[4], mtext[8]); + } + return; + } + // byte 9 = RT-Status bitcodet (0=AB-flagcontrol, 1-4=Transmission-Number, 5+6=Buffer-Config, + // ignored, always 0x01 ?) + char temptext[RT_MEL]; + memset(temptext, 0x20, RT_MEL - 1); + for (int i = 1, ii = 0; i < mtext[8]; i++) { + char c = mtext[9 + i]; + if ((c >= 0x20) && (c <= 0xfe)) { + // additional rds-character, see RBDS-Standard, Annex E + temptext[ii++] = (c >= 0x80) ? rds_addchar[c - 0x80] : c; + } + } + memcpy(plustext, temptext, RT_MEL - 1); + rds_entitychar(temptext); + // check repeats + bool repeat = false; + for (int ind = 0; ind < S_RtOsdRows; ind++) { + if (memcmp(RT_Text[ind], temptext, RT_MEL - 1) == 0) { + repeat = true; if ((S_Verbose & 0x0f) >= 1) { - printf("RT-Error: Length=0 or not correct (MFL= %d, MEL= %d)\n", - mtext[4], mtext[8]); + printf("RText-Rep[%d]: %s\n", ind, RT_Text[ind]); } - return; } - // byte 9 = RT-Status bitcodet (0=AB-flagcontrol, 1-4=Transmission-Number, 5+6=Buffer-Config, - // ignored, always 0x01 ?) - char temptext[RT_MEL]; - memset(temptext, 0x20, RT_MEL - 1); - for (int i = 1, ii = 0; i < mtext[8]; i++) { - if (mtext[9 + i] <= 0xfe) { - // additional rds-character, see RBDS-Standard, Annex E - temptext[ii++] = - (mtext[9 + i] >= 0x80) ? - rds_addchar[mtext[9 + i] - 0x80] : - mtext[9 + i]; - } + } + if (!repeat) { + memcpy(RT_Text[RT_Index], temptext, RT_MEL - 1); + // +Memory + char *temp; + asprintf(&temp, "%s", RT_Text[RT_Index]); + if (++rtp_content.rt_Index >= 2 * MAX_RTPC) { + rtp_content.rt_Index = 0; } - memcpy(plustext, temptext, RT_MEL - 1); - rds_entitychar(temptext); - // check repeats - bool repeat = false; - for (int ind = 0; ind < S_RtOsdRows; ind++) { - if (memcmp(RT_Text[ind], temptext, RT_MEL - 1) == 0) { - repeat = true; - if ((S_Verbose & 0x0f) >= 1) { - printf("RText-Rep[%d]: %s\n", ind, RT_Text[ind]); - } - } + asprintf(&rtp_content.radiotext[rtp_content.rt_Index], "%s", + rtrim(temp)); + free(temp); + if ((S_Verbose & 0x0f) >= 1) { + printf("Radiotext[%d]: %s\n", RT_Index, RT_Text[RT_Index]); } - if (!repeat) { - memcpy(RT_Text[RT_Index], temptext, RT_MEL - 1); - // +Memory - char *temp; - asprintf(&temp, "%s", RT_Text[RT_Index]); - if (++rtp_content.rt_Index >= 2 * MAX_RTPC) { - rtp_content.rt_Index = 0; - } - asprintf(&rtp_content.radiotext[rtp_content.rt_Index], "%s", - rtrim(temp)); - free(temp); - if ((S_Verbose & 0x0f) >= 1) { - printf("Radiotext[%d]: %s\n", RT_Index, RT_Text[RT_Index]); - } - RT_Index += 1; - if (RT_Index >= S_RtOsdRows) { - RT_Index = 0; - } + RT_Index += 1; + if (RT_Index >= S_RtOsdRows) { + RT_Index = 0; } - RTP_TToggle = 0x03; // Bit 0/1 = Title/Artist - RT_MsgShow = true; - (RT_Info > 0) ? : RT_Info = 1; - radioStatusMsg(); } + RTP_TToggle = 0x03; // Bit 0/1 = Title/Artist + RT_MsgShow = true; + (RT_Info > 0) ? : RT_Info = 1; + radioStatusMsg(); + } - else if (RTP_TToggle > 0 && mtext[5] == 0x46 && S_RtFunc >= 2) { // RTplus tags V2.1, only if RT - if (mtext[6] > leninfo - 2 || mtext[6] != 8) { // byte 6 = MEL, only 8 byte for 2 tags + else if (RTP_TToggle > 0 && mtext[5] == 0x46 && S_RtFunc >= 2) { // RTplus tags V2.1, only if RT + if (mtext[6] > leninfo - 2 || mtext[6] != 8) { // byte 6 = MEL, only 8 byte for 2 tags + if ((S_Verbose & 0x0f) >= 1) { + printf("RTp-Error: Length not correct (MEL= %d)\n", + mtext[6]); + } + return; + } + uint rtp_typ[2], rtp_start[2], rtp_len[2]; + // byte 7+8 = ApplicationID, always 0x4bd7 + // byte 9 = Applicationgroup Typecode / PTY ? + // bit 10#4 = Item Togglebit + // bit 10#3 = Item Runningbit + // Tag1: bit 10#2..11#5 = Contenttype, 11#4..12#7 = Startmarker, 12#6..12#1 = Length + rtp_typ[0] = (0x38 & mtext[10] << 3) | mtext[11] >> 5; + rtp_start[0] = (0x3e & mtext[11] << 1) | mtext[12] >> 7; + rtp_len[0] = 0x3f & mtext[12] >> 1; + // Tag2: bit 12#0..13#3 = Contenttype, 13#2..14#5 = Startmarker, 14#4..14#0 = Length(5bit) + rtp_typ[1] = (0x20 & mtext[12] << 5) | mtext[13] >> 3; + rtp_start[1] = (0x38 & mtext[13] << 3) | mtext[14] >> 5; + rtp_len[1] = 0x1f & mtext[14]; + if ((S_Verbose & 0x0f) >= 2) { + printf( + "RTplus (tag=Typ/Start/Len): Toggle/Run = %d/%d, tag#1 = %d/%d/%d, tag#2 = %d/%d/%d\n", + (mtext[10] & 0x10) > 0, (mtext[10] & 0x08) > 0, + rtp_typ[0], rtp_start[0], rtp_len[0], rtp_typ[1], + rtp_start[1], rtp_len[1]); + } + // save info + for (int i = 0; i < 2; i++) { + if (rtp_start[i] + rtp_len[i] + 1 >= RT_MEL) { // length-error if ((S_Verbose & 0x0f) >= 1) { - printf("RTp-Error: Length not correct (MEL= %d)\n", - mtext[6]); + printf( + "RTp-Error (tag#%d = Typ/Start/Len): %d/%d/%d (Start+Length > 'RT-MEL' !)\n", + i + 1, rtp_typ[i], rtp_start[i], rtp_len[i]); } - return; } - uint rtp_typ[2], rtp_start[2], rtp_len[2]; - // byte 7+8 = ApplicationID, always 0x4bd7 - // byte 9 = Applicationgroup Typecode / PTY ? - // bit 10#4 = Item Togglebit - // bit 10#3 = Item Runningbit - // Tag1: bit 10#2..11#5 = Contenttype, 11#4..12#7 = Startmarker, 12#6..12#1 = Length - rtp_typ[0] = (0x38 & mtext[10] << 3) | mtext[11] >> 5; - rtp_start[0] = (0x3e & mtext[11] << 1) | mtext[12] >> 7; - rtp_len[0] = 0x3f & mtext[12] >> 1; - // Tag2: bit 12#0..13#3 = Contenttype, 13#2..14#5 = Startmarker, 14#4..14#0 = Length(5bit) - rtp_typ[1] = (0x20 & mtext[12] << 5) | mtext[13] >> 3; - rtp_start[1] = (0x38 & mtext[13] << 3) | mtext[14] >> 5; - rtp_len[1] = 0x1f & mtext[14]; - if ((S_Verbose & 0x0f) >= 2) { - printf( - "RTplus (tag=Typ/Start/Len): Toggle/Run = %d/%d, tag#1 = %d/%d/%d, tag#2 = %d/%d/%d\n", - (mtext[10] & 0x10) > 0, (mtext[10] & 0x08) > 0, - rtp_typ[0], rtp_start[0], rtp_len[0], rtp_typ[1], - rtp_start[1], rtp_len[1]); - } - // save info - for (int i = 0; i < 2; i++) { - if (rtp_start[i] + rtp_len[i] + 1 >= RT_MEL) { // length-error - if ((S_Verbose & 0x0f) >= 1) { - printf( - "RTp-Error (tag#%d = Typ/Start/Len): %d/%d/%d (Start+Length > 'RT-MEL' !)\n", - i + 1, rtp_typ[i], rtp_start[i], rtp_len[i]); - } - } - else { - char temptext[RT_MEL]; - memset(temptext, 0x20, RT_MEL - 1); - memmove(temptext, plustext + rtp_start[i], rtp_len[i] + 1); - rds_entitychar(temptext); - // +Memory - memset(rtp_content.temptext, 0x20, RT_MEL - 1); - memcpy(rtp_content.temptext, temptext, RT_MEL - 1); - switch (rtp_typ[i]) { - case 1: // Item-Title - if ((mtext[10] & 0x08) > 0 - && (RTP_TToggle & 0x01) == 0x01) { - RTP_TToggle -= 0x01; - RT_Info = 2; - if (memcmp(RTP_Title, temptext, RT_MEL - 1) != 0 - || (mtext[10] & 0x10) != RTP_ItemToggle) { - memcpy(RTP_Title, temptext, RT_MEL - 1); - if (RT_PlusShow && rtp_itime.Elapsed() > 1000) { - rtp_idiffs = (int) rtp_itime.Elapsed() - / 1000; - } - if (!rtp_content.item_New) { - RTP_Starttime = time(NULL); - rtp_itime.Set(0); - sprintf(RTP_Artist, "---"); - if (++rtp_content.item_Index >= MAX_RTPC) { - rtp_content.item_Index = 0; - } - rtp_content.item_Start[rtp_content.item_Index] = - time(NULL); // todo: replay-mode - rtp_content.item_Artist[rtp_content.item_Index] = - NULL; - } - rtp_content.item_New = - (!rtp_content.item_New) ? true : false; - if (rtp_content.item_Index >= 0) { - asprintf( - &rtp_content.item_Title[rtp_content.item_Index], - "%s", rtrim(rtp_content.temptext)); + else { + char temptext[RT_MEL]; + memset(temptext, 0x20, RT_MEL - 1); + memmove(temptext, plustext + rtp_start[i], rtp_len[i] + 1); + rds_entitychar(temptext); + // +Memory + memset(rtp_content.temptext, 0x20, RT_MEL - 1); + memcpy(rtp_content.temptext, temptext, RT_MEL - 1); + switch (rtp_typ[i]) { + case 1: // Item-Title + if ((mtext[10] & 0x08) > 0 + && (RTP_TToggle & 0x01) == 0x01) { + RTP_TToggle -= 0x01; + RT_Info = 2; + if (memcmp(RTP_Title, temptext, RT_MEL - 1) != 0 + || (mtext[10] & 0x10) != RTP_ItemToggle) { + memcpy(RTP_Title, temptext, RT_MEL - 1); + if (RT_PlusShow && rtp_itime.Elapsed() > 1000) { + rtp_idiffs = (int) rtp_itime.Elapsed() + / 1000; + } + if (!rtp_content.item_New) { + RTP_Starttime = time(NULL); + rtp_itime.Set(0); + sprintf(RTP_Artist, "---"); + if (++rtp_content.item_Index >= MAX_RTPC) { + rtp_content.item_Index = 0; } - RT_PlusShow = RT_MsgShow = rtp_itoggle = true; + rtp_content.item_Start[rtp_content.item_Index] = + time(NULL); // todo: replay-mode + rtp_content.item_Artist[rtp_content.item_Index] = + NULL; } + rtp_content.item_New = + (!rtp_content.item_New) ? true : false; + if (rtp_content.item_Index >= 0) { + asprintf( + &rtp_content.item_Title[rtp_content.item_Index], + "%s", rtrim(rtp_content.temptext)); + } + RT_PlusShow = RT_MsgShow = rtp_itoggle = true; } - break; - case 4: // Item-Artist - if ((mtext[10] & 0x08) > 0 - && (RTP_TToggle & 0x02) == 0x02) { - RTP_TToggle -= 0x02; - RT_Info = 2; - if (memcmp(RTP_Artist, temptext, RT_MEL - 1) != 0 - || (mtext[10] & 0x10) != RTP_ItemToggle) { - memcpy(RTP_Artist, temptext, RT_MEL - 1); - if (RT_PlusShow && rtp_itime.Elapsed() > 1000) { - rtp_idiffs = (int) rtp_itime.Elapsed() - / 1000; - } - if (!rtp_content.item_New) { - RTP_Starttime = time(NULL); - rtp_itime.Set(0); - sprintf(RTP_Title, "---"); - if (++rtp_content.item_Index >= MAX_RTPC) { - rtp_content.item_Index = 0; - } - rtp_content.item_Start[rtp_content.item_Index] = - time(NULL); // todo: replay-mode - rtp_content.item_Title[rtp_content.item_Index] = - NULL; - } - rtp_content.item_New = - (!rtp_content.item_New) ? true : false; - if (rtp_content.item_Index >= 0) { - asprintf( - &rtp_content.item_Artist[rtp_content.item_Index], - "%s", rtrim(rtp_content.temptext)); + } + break; + case 4: // Item-Artist + if ((mtext[10] & 0x08) > 0 + && (RTP_TToggle & 0x02) == 0x02) { + RTP_TToggle -= 0x02; + RT_Info = 2; + if (memcmp(RTP_Artist, temptext, RT_MEL - 1) != 0 + || (mtext[10] & 0x10) != RTP_ItemToggle) { + memcpy(RTP_Artist, temptext, RT_MEL - 1); + if (RT_PlusShow && rtp_itime.Elapsed() > 1000) { + rtp_idiffs = (int) rtp_itime.Elapsed() + / 1000; + } + if (!rtp_content.item_New) { + RTP_Starttime = time(NULL); + rtp_itime.Set(0); + sprintf(RTP_Title, "---"); + if (++rtp_content.item_Index >= MAX_RTPC) { + rtp_content.item_Index = 0; } - RT_PlusShow = RT_MsgShow = rtp_itoggle = true; + rtp_content.item_Start[rtp_content.item_Index] = + time(NULL); // todo: replay-mode + rtp_content.item_Title[rtp_content.item_Index] = + NULL; } + rtp_content.item_New = + (!rtp_content.item_New) ? true : false; + if (rtp_content.item_Index >= 0) { + asprintf( + &rtp_content.item_Artist[rtp_content.item_Index], + "%s", rtrim(rtp_content.temptext)); + } + RT_PlusShow = RT_MsgShow = rtp_itoggle = true; } - break; - case 12: // Info_News - asprintf(&rtp_content.info_News, "%s", - rtrim(rtp_content.temptext)); - break; - case 13: // Info_NewsLocal - asprintf(&rtp_content.info_NewsLocal, "%s", - rtrim(rtp_content.temptext)); - break; - case 14: // Info_Stockmarket - if (++rtp_content.info_StockIndex >= MAX_RTPC) { - rtp_content.info_StockIndex = 0; - } - asprintf( - &rtp_content.info_Stock[rtp_content.info_StockIndex], - "%s", rtrim(rtp_content.temptext)); - break; - case 15: // Info_Sport - if (++rtp_content.info_SportIndex >= MAX_RTPC) { - rtp_content.info_SportIndex = 0; - } - asprintf( - &rtp_content.info_Sport[rtp_content.info_SportIndex], - "%s", rtrim(rtp_content.temptext)); - break; - case 16: // Info_Lottery - if (++rtp_content.info_LotteryIndex >= MAX_RTPC) { - rtp_content.info_LotteryIndex = 0; - } - asprintf( - &rtp_content.info_Lottery[rtp_content.info_LotteryIndex], - "%s", rtrim(rtp_content.temptext)); - break; - case 24: // Info_DateTime - asprintf(&rtp_content.info_DateTime, "%s", - rtrim(rtp_content.temptext)); - break; - case 25: // Info_Weather - if (++rtp_content.info_WeatherIndex >= MAX_RTPC) { - rtp_content.info_WeatherIndex = 0; - } - asprintf( - &rtp_content.info_Weather[rtp_content.info_WeatherIndex], - "%s", rtrim(rtp_content.temptext)); - break; - case 26: // Info_Traffic - asprintf(&rtp_content.info_Traffic, "%s", - rtrim(rtp_content.temptext)); - break; - case 27: // Info_Alarm - asprintf(&rtp_content.info_Alarm, "%s", - rtrim(rtp_content.temptext)); - break; - case 28: // Info_Advert - asprintf(&rtp_content.info_Advert, "%s", - rtrim(rtp_content.temptext)); - break; - case 29: // Info_Url - asprintf(&rtp_content.info_Url, "%s", - rtrim(rtp_content.temptext)); - break; - case 30: // Info_Other - if (++rtp_content.info_OtherIndex >= MAX_RTPC) { - rtp_content.info_OtherIndex = 0; - } - asprintf( - &rtp_content.info_Other[rtp_content.info_OtherIndex], - "%s", rtrim(rtp_content.temptext)); - break; - case 31: // Programme_Stationname.Short - asprintf(&rtp_content.prog_StatShort, "%s", - rtrim(rtp_content.temptext)); - break; - case 32: // Programme_Stationname.Long - asprintf(&rtp_content.prog_Station, "%s", - rtrim(rtp_content.temptext)); - break; - case 33: // Programme_Now - asprintf(&rtp_content.prog_Now, "%s", - rtrim(rtp_content.temptext)); - break; - case 34: // Programme_Next - asprintf(&rtp_content.prog_Next, "%s", - rtrim(rtp_content.temptext)); - break; - case 35: // Programme_Part - asprintf(&rtp_content.prog_Part, "%s", - rtrim(rtp_content.temptext)); - break; - case 36: // Programme_Host - asprintf(&rtp_content.prog_Host, "%s", - rtrim(rtp_content.temptext)); - break; - case 37: // Programme_EditorialStaff - asprintf(&rtp_content.prog_EditStaff, "%s", - rtrim(rtp_content.temptext)); - break; - case 39: // Programme_Homepage - asprintf(&rtp_content.prog_Homepage, "%s", - rtrim(rtp_content.temptext)); - break; - case 41: // Phone_Hotline - asprintf(&rtp_content.phone_Hotline, "%s", - rtrim(rtp_content.temptext)); - break; - case 42: // Phone_Studio - asprintf(&rtp_content.phone_Studio, "%s", - rtrim(rtp_content.temptext)); - break; - case 44: // SMS_Studio - asprintf(&rtp_content.sms_Studio, "%s", - rtrim(rtp_content.temptext)); - break; - case 46: // Email_Hotline - asprintf(&rtp_content.email_Hotline, "%s", - rtrim(rtp_content.temptext)); - break; - case 47: // Email_Studio - asprintf(&rtp_content.email_Studio, "%s", - rtrim(rtp_content.temptext)); - break; } + break; + case 12: // Info_News + asprintf(&rtp_content.info_News, "%s", + rtrim(rtp_content.temptext)); + break; + case 13: // Info_NewsLocal + asprintf(&rtp_content.info_NewsLocal, "%s", + rtrim(rtp_content.temptext)); + break; + case 14: // Info_Stockmarket + if (++rtp_content.info_StockIndex >= MAX_RTPC) { + rtp_content.info_StockIndex = 0; + } + asprintf( + &rtp_content.info_Stock[rtp_content.info_StockIndex], + "%s", rtrim(rtp_content.temptext)); + break; + case 15: // Info_Sport + if (++rtp_content.info_SportIndex >= MAX_RTPC) { + rtp_content.info_SportIndex = 0; + } + asprintf( + &rtp_content.info_Sport[rtp_content.info_SportIndex], + "%s", rtrim(rtp_content.temptext)); + break; + case 16: // Info_Lottery + if (++rtp_content.info_LotteryIndex >= MAX_RTPC) { + rtp_content.info_LotteryIndex = 0; + } + asprintf( + &rtp_content.info_Lottery[rtp_content.info_LotteryIndex], + "%s", rtrim(rtp_content.temptext)); + break; + case 24: // Info_DateTime + asprintf(&rtp_content.info_DateTime, "%s", + rtrim(rtp_content.temptext)); + break; + case 25: // Info_Weather + if (++rtp_content.info_WeatherIndex >= MAX_RTPC) { + rtp_content.info_WeatherIndex = 0; + } + asprintf( + &rtp_content.info_Weather[rtp_content.info_WeatherIndex], + "%s", rtrim(rtp_content.temptext)); + break; + case 26: // Info_Traffic + asprintf(&rtp_content.info_Traffic, "%s", + rtrim(rtp_content.temptext)); + break; + case 27: // Info_Alarm + asprintf(&rtp_content.info_Alarm, "%s", + rtrim(rtp_content.temptext)); + break; + case 28: // Info_Advert + asprintf(&rtp_content.info_Advert, "%s", + rtrim(rtp_content.temptext)); + break; + case 29: // Info_Url + asprintf(&rtp_content.info_Url, "%s", + rtrim(rtp_content.temptext)); + break; + case 30: // Info_Other + if (++rtp_content.info_OtherIndex >= MAX_RTPC) { + rtp_content.info_OtherIndex = 0; + } + asprintf( + &rtp_content.info_Other[rtp_content.info_OtherIndex], + "%s", rtrim(rtp_content.temptext)); + break; + case 31: // Programme_Stationname.Short + asprintf(&rtp_content.prog_StatShort, "%s", + rtrim(rtp_content.temptext)); + break; + case 32: // Programme_Stationname.Long + asprintf(&rtp_content.prog_Station, "%s", + rtrim(rtp_content.temptext)); + break; + case 33: // Programme_Now + asprintf(&rtp_content.prog_Now, "%s", + rtrim(rtp_content.temptext)); + break; + case 34: // Programme_Next + asprintf(&rtp_content.prog_Next, "%s", + rtrim(rtp_content.temptext)); + break; + case 35: // Programme_Part + asprintf(&rtp_content.prog_Part, "%s", + rtrim(rtp_content.temptext)); + break; + case 36: // Programme_Host + asprintf(&rtp_content.prog_Host, "%s", + rtrim(rtp_content.temptext)); + break; + case 37: // Programme_EditorialStaff + asprintf(&rtp_content.prog_EditStaff, "%s", + rtrim(rtp_content.temptext)); + break; + case 39: // Programme_Homepage + asprintf(&rtp_content.prog_Homepage, "%s", + rtrim(rtp_content.temptext)); + break; + case 41: // Phone_Hotline + asprintf(&rtp_content.phone_Hotline, "%s", + rtrim(rtp_content.temptext)); + break; + case 42: // Phone_Studio + asprintf(&rtp_content.phone_Studio, "%s", + rtrim(rtp_content.temptext)); + break; + case 44: // SMS_Studio + asprintf(&rtp_content.sms_Studio, "%s", + rtrim(rtp_content.temptext)); + break; + case 46: // Email_Hotline + asprintf(&rtp_content.email_Hotline, "%s", + rtrim(rtp_content.temptext)); + break; + case 47: // Email_Studio + asprintf(&rtp_content.email_Studio, "%s", + rtrim(rtp_content.temptext)); + break; } } + } - // Title-end @ no Item-Running' - if ((mtext[10] & 0x08) == 0) { - sprintf(RTP_Title, "---"); - sprintf(RTP_Artist, "---"); - if (RT_PlusShow) { - RT_PlusShow = false; - rtp_itoggle = true; - rtp_idiffs = (int) rtp_itime.Elapsed() / 1000; - RTP_Starttime = time(NULL); - } - RT_MsgShow = (RT_Info > 0); - rtp_content.item_New = false; + // Title-end @ no Item-Running' + if ((mtext[10] & 0x08) == 0) { + sprintf(RTP_Title, "---"); + sprintf(RTP_Artist, "---"); + if (RT_PlusShow) { + RT_PlusShow = false; + rtp_itoggle = true; + rtp_idiffs = (int) rtp_itime.Elapsed() / 1000; + RTP_Starttime = time(NULL); } + RT_MsgShow = (RT_Info > 0); + rtp_content.item_New = false; + } - if (rtp_itoggle) { - if ((S_Verbose & 0x0f) >= 1) { - struct tm tm_store; - struct tm *ts = localtime_r(&RTP_Starttime, &tm_store); - if (rtp_idiffs > 0) { - printf( - " StartTime : %02d:%02d:%02d (last Title elapsed = %d s)\n", - ts->tm_hour, ts->tm_min, ts->tm_sec, - rtp_idiffs); - } - else { - printf(" StartTime : %02d:%02d:%02d\n", ts->tm_hour, - ts->tm_min, ts->tm_sec); - } - printf(" RTp-Title : %s\n RTp-Artist: %s\n", RTP_Title, - RTP_Artist); + if (rtp_itoggle) { + if ((S_Verbose & 0x0f) >= 1) { + struct tm tm_store; + struct tm *ts = localtime_r(&RTP_Starttime, &tm_store); + if (rtp_idiffs > 0) { + printf( + " StartTime : %02d:%02d:%02d (last Title elapsed = %d s)\n", + ts->tm_hour, ts->tm_min, ts->tm_sec, + rtp_idiffs); } - RTP_ItemToggle = mtext[10] & 0x10; - rtp_itoggle = false; - rtp_idiffs = 0; - radioStatusMsg(); - AudioRecorderService(); + else { + printf(" StartTime : %02d:%02d:%02d\n", ts->tm_hour, + ts->tm_min, ts->tm_sec); + } + printf(" RTp-Title : %s\n RTp-Artist: %s\n", RTP_Title, + RTP_Artist); } - - RTP_TToggle = 0; + RTP_ItemToggle = mtext[10] & 0x10; + rtp_itoggle = false; + rtp_idiffs = 0; + radioStatusMsg(); + AudioRecorderService(); } - } - else { - if ((S_Verbose & 0x0f) >= 1) { - printf( - "RDS-Error: [RTDecode] Length not correct (MFL= %d, len= %d)\n", - mtext[4], len); - } + RTP_TToggle = 0; } } diff --git a/radioaudio.h b/radioaudio.h index b3797ba..56cb573 100644 --- a/radioaudio.h +++ b/radioaudio.h @@ -73,6 +73,7 @@ private: void RadiotextCheckTS(const uchar *Data, int Length); void AudioRecorderService(void); void RassDecode(uchar *Data, int Length); + bool CrcOk(uchar *data); protected: virtual void Play(const uchar *Data, int Length, uchar Id); virtual void PlayTs(const uchar *Data, int Length); @@ -84,7 +85,7 @@ public: char *bitrate; void EnableRadioTextProcessing(const char *Titel, int apid, bool replay = false); void DisableRadioTextProcessing(); - void RadiotextDecode(uchar *Data, int Length); + void RadiotextDecode(uchar *Data); void RDS_PsPtynDecode(bool PTYN, uchar *Data, int Length); }; diff --git a/radiocheck.c b/radiocheck.c index 79b39cb..5f09bbb 100644 --- a/radiocheck.c +++ b/radiocheck.c @@ -150,14 +150,10 @@ void cRadioCheck::Action(void) // temp. OSD-CloseTimeout (RT_OsdTOTemp > 0) ? RT_OsdTOTemp -= 2 : RT_OsdTOTemp = 0; // in sec like this cycletime -// TODO -esyslog("%s %d cOsd::IsOpen %d Skins.IsOpen %d", __FILE__, __LINE__, - cOsd::IsOpen(), Skins.IsOpen()); // Radiotext-Autodisplay if ((S_RtDispl == 2) && (RT_Info >= 0) && !RT_OsdTO && (RT_OsdTOTemp == 0) && RT_ReOpen && !Skins.IsOpen() && !cOsd::IsOpen()) { -esyslog("CallPlugin(radio)"); // TODO cRemote::CallPlugin("radio"); } } @@ -167,5 +163,3 @@ esyslog("CallPlugin(radio)"); // TODO } } - - diff --git a/radiotextosd.c b/radiotextosd.c index 31ab563..fc1ba81 100644 --- a/radiotextosd.c +++ b/radiotextosd.c @@ -93,8 +93,6 @@ cRadioTextOsd::cRadioTextOsd() : LastKey = kNone; fheight = 0; bheight = 0; -// TODO -dsyslog("%s %d cRadioTextOsd::cRadioTextOsd", __FILE__, __LINE__); } cRadioTextOsd::~cRadioTextOsd() { diff --git a/radiotools.c b/radiotools.c index e67e985..edccd2d 100644 --- a/radiotools.c +++ b/radiotools.c @@ -249,1665 +249,6 @@ char *audiobitrate(const unsigned char *data) return temp; } -/* ----------------------------------------------------------------------------------------------------------- */ - -const char *tmc_duration[8] = { - "none", - "15 minutes", - "30 minutes", - "1 hour", - "2 hours", - "3 hours", - "4 hours", - "all day", -}; - -const char *tmc_direction[2] = { "+", "-" }; - -const char *tmc_event[2048] = { - "---", // 0 - "traffic problem", - "queuing traffic (with average speeds Q). Danger of stationary traffic", - "..", "..", "..", "..", "..", "..", "..", "..", // 10 - "overheight warning system triggered", - "(Q) accident(s), traffic being directed around accident area", - "..", "..", "..", - "closed, rescue and recovery work in progress", - "..", "..", "..", - "service area overcrowded, drive to another service area", // 20 - "..", - "service area, fuel station closed", - "service area, restaurant closed", - "bridge closed", - "tunnel closed", - "bridge blocked", - "tunnel blocked", - "road closed intermittently", - "..", "..", // 30 - "..", "..", "..", "..", "..", - "fuel station reopened", - "restaurant reopened", - "..", "..", - "smog alert ended", // 40 - "(Q) overtaking lane(s) closed", - "(Q) overtaking lane(s) blocked", - "..", "..", "..", "..", "..", "..", "..", "..", // 50 - "roadworks, (Q) overtaking lane(s) closed", - "(Q sets of) roadworks on the hard shoulder", - "(Q sets of) roadworks in the emergency lane", - "..", - "traffic problem expected", - "traffic congestion expected", - "normal traffic expected", - "..", "..", "..", // 60 - "(Q) object(s) on roadway {something that does not neccessarily block the road}", - "(Q) burst pipe(s)", - "(Q) object(s) on the road. Danger", - "burst pipe. Danger", - "..", "..", "..", "..", "..", - "traffic congestion, average speed of ?? km/h", // 70 - "traffic congestion, average speed of ?? km/h", - "traffic congestion, average speed of ?? km/h", - "traffic congestion, average speed of ?? km/h", - "traffic congestion, average speed of ?? km/h", - "traffic congestion, average speed of ?? km/h", - "traffic congestion, average speed of ?? km/h", - "..", "..", "..", "..", // 80 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 90 - "delays (Q) for cars", - "..", "..", "..", "..", "..", "..", "..", "..", "..", // 100 - "stationary traffic", - "stationary traffic for 1 km", - "stationary traffic for 2 km", - "stationary traffic for 4 km", - "stationary traffic for 6 km", - "stationary traffic for 10 km", - "stationary traffic expected", - "queuing traffic (with average speeds Q)", - "queuing traffic for 1 km (with average speeds Q)", - "queuing traffic for 2 km (with average speeds Q)", // 110 - "queuing traffic for 4 km (with average speeds Q)", - "queuing traffic for 6 km (with average speeds Q)", - "queuing traffic for 10 km (with average speeds Q)", - "queuing traffic expected", - "slow traffic (with average speeds Q)", - "slow traffic for 1 km (with average speeds Q)", - "slow traffic for 2 km (with average speeds Q)", - "slow traffic for 4 km (with average speeds Q)", - "slow traffic for 6 km (with average speeds Q)", - "slow traffic for 10 km (with average speeds Q)", // 120 - "slow traffic expected", - "heavy traffic (with average speeds Q)", - "heavy traffic expected", - "traffic flowing freely (with average speeds Q)", - "traffic building up (with average speeds Q)", - "no problems to report", - "traffic congestion cleared", - "message cancelled", - "stationary traffic for 3 km", - "danger of stationary traffic", // 130 - "queuing traffic for 3 km (with average speeds Q)", - "danger of queuing traffic (with average speeds Q)", - "long queues (with average speeds Q)", - "slow traffic for 3 km (with average speeds Q)", - "traffic easing", - "traffic congestion (with average speeds Q)", - "traffic lighter than normal (with average speeds Q)", - "queuing traffic (with average speeds Q). Approach with care", - "queuing traffic around a bend in the road", - "queuing traffic over the crest of a hill", // 140 - "all accidents cleared, no problems to report", - "traffic heavier than normal (with average speeds Q)", - "traffic very much heavier than normal (with average speeds Q)", - "..", "..", "..", "..", "..", "..", "..", // 150 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 160 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 170 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 180 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 190 - "..", "..", "..", "..", "..", "..", "..", "..", "..", - "multi vehicle pile up. Delays (Q)", // 200 - "(Q) accident(s)", - "(Q) serious accident(s)", - "multi-vehicle accident (involving Q vehicles)", - "accident involving (a/Q) heavy lorr(y/ies)", - "(Q) accident(s) involving hazardous materials", - "(Q) fuel spillage accident(s)", - "(Q) chemical spillage accident(s)", - "vehicles slowing to look at (Q) accident(s)", - "(Q) accident(s) in the opposing lanes", - "(Q) shed load(s)", // 210 - "(Q) broken down vehicle(s)", - "(Q) broken down heavy lorr(y/ies)", - "(Q) vehicle fire(s)", - "(Q) incident(s)", - "(Q) accident(s). Stationary traffic", - "(Q) accident(s). Stationary traffic for 1 km", - "(Q) accident(s). Stationary traffic for 2 km", - "(Q) accident(s). Stationary traffic for 4 km", - "(Q) accident(s). Stationary traffic for 6 km", - "(Q) accident(s). Stationary traffic for 10 km", // 220 - "(Q) accident(s). Danger of stationary traffic", - "(Q) accident(s). Queuing traffic", - "(Q) accident(s). Queuing traffic for 1 km", - "(Q) accident(s). Queuing traffic for 2 km", - "(Q) accident(s). Queuing traffic for 4 km", - "(Q) accident(s). Queuing traffic for 6 km", - "(Q) accident(s). Queuing traffic for 10 km", - "(Q) accident(s). Danger of queuing traffic", - "(Q) accident(s). Slow traffic", - "(Q) accident(s). Slow traffic for 1 km", // 230 - "(Q) accident(s). Slow traffic for 2 km", - "(Q) accident(s). Slow traffic for 4 km", - "(Q) accident(s). Slow traffic for 6 km", - "(Q) accident(s). Slow traffic for 10 km", - "(Q) accident(s). Slow traffic expected", - "(Q) accident(s). Heavy traffic", - "(Q) accident(s). Heavy traffic expected", - "(Q) accident(s). Traffic flowing freely", - "(Q) accident(s). Traffic building up", - "road closed due to (Q) accident(s)", // 240 - "(Q) accident(s). Right lane blocked", - "(Q) accident(s). Centre lane blocked", - "(Q) accident(s). Left lane blocked", - "(Q) accident(s). Hard shoulder blocked", - "(Q) accident(s). Two lanes blocked", - "(Q) accident(s). Three lanes blocked", - "accident. Delays (Q)", - "accident. Delays (Q) expected", - "accident. Long delays (Q)", - "vehicles slowing to look at (Q) accident(s). Stationary traffic", // 250 - "vehicles slowing to look at (Q) accident(s). Stationary traffic for 1 km", - "vehicles slowing to look at (Q) accident(s). Stationary traffic for 2 km", - "vehicles slowing to look at (Q) accident(s). Stationary traffic for 4 km", - "vehicles slowing to look at (Q) accident(s). Stationary traffic for 6 km", - "vehicles slowing to look at (Q) accident(s). Stationary traffic for 10 km", - "vehicles slowing to look at (Q) accident(s). Danger of stationary traffic", - "vehicles slowing to look at (Q) accident(s). Queuing traffic", - "vehicles slowing to look at (Q) accident(s). Queuing traffic for 1 km", - "vehicles slowing to look at (Q) accident(s). Queuing traffic for 2 km", - "vehicles slowing to look at (Q) accident(s). Queuing traffic for 4 km", // 260 - "vehicles slowing to look at (Q) accident(s). Queuing traffic for 6 km", - "vehicles slowing to look at (Q) accident(s). Queuing traffic for 10 km", - "vehicles slowing to look at (Q) accident(s). Danger of queuing traffic", - "vehicles slowing to look at (Q) accident(s). Slow traffic", - "vehicles slowing to look at (Q) accident(s). Slow traffic for 1 km", - "vehicles slowing to look at (Q) accident(s). Slow traffic for 2 km", - "vehicles slowing to look at (Q) accident(s). Slow traffic for 4 km", - "vehicles slowing to look at (Q) accident(s). Slow traffic for 6 km", - "vehicles slowing to look at (Q) accident(s). Slow traffic for 10 km", - "vehicles slowing to look at (Q) accident(s). Slow traffic expected", // 270 - "vehicles slowing to look at (Q) accident(s). Heavy traffic", - "vehicles slowing to look at (Q) accident(s). Heavy traffic expected", - "..", - "vehicles slowing to look at (Q) accident(s). Traffic building up", - "vehicles slowing to look at accident. Delays (Q)", - "vehicles slowing to look at accident. Delays (Q) expected", - "vehicles slowing to look at accident. Long delays (Q)", - "(Q) shed load(s). Stationary traffic", - "(Q) shed load(s). Stationary traffic for 1 km", - "(Q) shed load(s). Stationary traffic for 2 km", // 280 - "(Q) shed load(s). Stationary traffic for 4 km", - "(Q) shed load(s). Stationary traffic for 6 km", - "(Q) shed load(s). Stationary traffic for 10 km", - "(Q) shed load(s). Danger of stationary traffic", - "(Q) shed load(s). Queuing traffic", - "(Q) shed load(s). Queuing traffic for 1 km", - "(Q) shed load(s). Queuing traffic for 2 km", - "(Q) shed load(s). Queuing traffic for 4 km", - "(Q) shed load(s). Queuing traffic for 6 km", - "(Q) shed load(s). Queuing traffic for 10 km", // 290 - "(Q) shed load(s). Danger of queuing traffic", - "(Q) shed load(s). Slow traffic", - "(Q) shed load(s). Slow traffic for 1 km", - "(Q) shed load(s). Slow traffic for 2 km", - "(Q) shed load(s). Slow traffic for 4 km", - "(Q) shed load(s). Slow traffic for 6 km", - "(Q) shed load(s). Slow traffic for 10 km", - "(Q) shed load(s). Slow traffic expected", - "(Q) shed load(s). Heavy traffic", - "(Q) shed load(s). Heavy traffic expected", // 300 - "(Q) shed load(s). Traffic flowing freely", - "(Q) shed load(s). Traffic building up", - "blocked by (Q) shed load(s)", - "(Q) shed load(s). Right lane blocked", - "(Q) shed load(s). Centre lane blocked", - "(Q) shed load(s). Left lane blocked", - "(Q) shed load(s). Hard shoulder blocked", - "(Q) shed load(s). Two lanes blocked", - "(Q) shed load(s). Three lanes blocked", - "shed load. Delays (Q)", // 310 - "shed load. Delays (Q) expected", - "shed load. Long delays (Q)", - "(Q) broken down vehicle(s). Stationary traffic", - "(Q) broken down vehicle(s). Danger of stationary traffic", - "(Q) broken down vehicle(s). Queuing traffic", - "(Q) broken down vehicle(s). Danger of queuing traffic", - "(Q) broken down vehicle(s). Slow traffic", - "(Q) broken down vehicle(s). Slow traffic expected", - "(Q) broken down vehicle(s). Heavy traffic", - "(Q) broken down vehicle(s). Heavy traffic expected", // 320 - "(Q) broken down vehicle(s). Traffic flowing freely", - "(Q) broken down vehicle(s).Traffic building up", - "blocked by (Q) broken down vehicle(s).", - "(Q) broken down vehicle(s). Right lane blocked", - "(Q) broken down vehicle(s). Centre lane blocked", - "(Q) broken down vehicle(s). Left lane blocked", - "(Q) broken down vehicle(s). Hard shoulder blocked", - "(Q) broken down vehicle(s). Two lanes blocked", - "(Q) broken down vehicle(s). Three lanes blocked", - "broken down vehicle. Delays (Q)", // 330 - "broken down vehicle. Delays (Q) expected", - "broken down vehicle. Long delays (Q)", - "accident cleared", - "message cancelled", - "accident involving (a/Q) bus(es)", - "(Q) oil spillage accident(s)", - "(Q) overturned vehicle(s)", - "(Q) overturned heavy lorr(y/ies)", - "(Q) jackknifed trailer(s)", - "(Q) jackknifed caravan(s)", // 340 - "(Q) jackknifed articulated lorr(y/ies)", - "(Q) vehicle(s) spun around", - "(Q) earlier accident(s)", - "accident investigation work", - "(Q) secondary accident(s)", - "(Q) broken down bus(es)", - "(Q) overheight vehicle(s)", - "(Q) accident(s). Stationary traffic for 3 km", - "(Q) accident(s). Queuing traffic for 3 km", - "(Q) accident(s). Slow traffic for 3 km", // 350 - "(Q) accident(s) in roadworks area", - "vehicles slowing to look at (Q) accident(s). Stationary traffic for 3 km", - "vehicles slowing to look at (Q) accident(s). Queuing traffic for 3 km", - "vehicles slowing to look at (Q) accident(s). Slow traffic for 3 km", - "vehicles slowing to look at (Q) accident(s). Danger", - "(Q) shed load(s). Stationary traffic for 3 km", - "(Q) shed load(s). Queuing traffic for 3 km", - "(Q) shed load(s). Slow traffic for 3 km", - "(Q) shed load(s). Danger", - "(Q) overturned vehicle(s). Stationary traffic", // 360 - "(Q) overturned vehicle(s). Danger of stationary traffic", - "(Q) overturned vehicle(s). Queuing traffic", - "(Q) overturned vehicle(s). Danger of queuing traffic", - "(Q) overturned vehicle(s). Slow traffic", - "(Q) overturned vehicle(s). Slow traffic expected", - "(Q) overturned vehicle(s). Heavy traffic", - "(Q) overturned vehicle(s). Heavy traffic expected", - "(Q) overturned vehicle(s). Traffic building up", - "blocked by (Q) overturned vehicle(s)", - "(Q) overturned vehicle(s). Right lane blocked", // 370 - "(Q) overturned vehicle(s). Centre lane blocked", - "(Q) overturned vehicle(s). Left lane blocked", - "(Q) overturned vehicle(s). Two lanes blocked", - "(Q) overturned vehicle(s). Three lanes blocked", - "overturned vehicle. Delays (Q)", - "overturned vehicle. Delays (Q) expected", - "overturned vehicle. Long delays (Q)", - "(Q) overturned vehicle(s). Danger", - "Stationary traffic due to (Q) earlier accident(s)", - "Danger of stationary traffic due to (Q) earlier accident(s)", // 380 - "Queuing traffic due to (Q) earlier accident(s)", - "Danger of queuing traffic due to (Q) earlier accident(s)", - "Slow traffic due to (Q) earlier accident(s)", - "..", - "Heavy traffic due to (Q) earlier accident(s)", - "..", - "Traffic building up due to (Q) earlier accident(s)", - "Delays (Q) due to earlier accident", - "..", - "Long delays (Q) due to earlier accident", // 390 - "accident investigation work. Danger", - "(Q) secondary accident(s). Danger", - "(Q) broken down vehicle(s). Danger", - "(Q) broken down heavy lorr(y/ies). Danger", - "road cleared", - "incident cleared", - "rescue and recovery work in progress", - "..", - "message cancelled", - "..", // 400 - "closed", - "blocked", - "closed for heavy vehicles (over Q)", - "no through traffic for heavy lorries (over Q)", - "no through traffic", - "(Q th) entry slip road closed", - "(Q th) exit slip road closed", - "slip roads closed", - "slip road restrictions", - "closed ahead. Stationary traffic", // 410 - "closed ahead. Stationary traffic for 1 km", - "closed ahead. Stationary traffic for 2 km", - "closed ahead. Stationary traffic for 4 km", - "closed ahead. Stationary traffic for 6 km", - "closed ahead. Stationary traffic for 10 km", - "closed ahead. Danger of stationary traffic", - "closed ahead. Queuing traffic", - "closed ahead. Queuing traffic for 1 km", - "closed ahead. Queuing traffic for 2 km", - "closed ahead. Queuing traffic for 4 km", // 420 - "closed ahead. Queuing traffic for 6 km", - "closed ahead. Queuing traffic for 10 km", - "closed ahead. Danger of queuing traffic", - "closed ahead. Slow traffic", - "closed ahead. Slow traffic for 1 km", - "closed ahead. Slow traffic for 2 km", - "closed ahead. Slow traffic for 4 km", - "closed ahead. Slow traffic for 6 km", - "closed ahead. Slow traffic for 10 km", - "closed ahead. Slow traffic expected", // 430 - "closed ahead. Heavy traffic", - "closed ahead. Heavy traffic expected", - "closed ahead. Traffic flowing freely", - "closed ahead. Traffic building up", - "closed ahead. Delays (Q)", - "closed ahead. Delays (Q) expected", - "closed ahead. Long delays (Q)", - "blocked ahead. Stationary traffic", - "blocked ahead. Stationary traffic for 1 km", - "blocked ahead. Stationary traffic for 2 km", // 440 - "blocked ahead. Stationary traffic for 4 km", - "blocked ahead. Stationary traffic for 6 km", - "blocked ahead. Stationary traffic for 10 km", - "blocked ahead. Danger of stationary traffic", - "blocked ahead. Queuing traffic", - "blocked ahead. Queuing traffic for 1 km", - "blocked ahead. Queuing traffic for 2 km", - "blocked ahead. Queuing traffic for 4 km", - "blocked ahead. Queuing traffic for 6 km", - "blocked ahead. Queuing traffic for 10 km", // 450 - "blocked ahead. Danger of queuing traffic", - "blocked ahead. Slow traffic", - "blocked ahead. Slow traffic for 1 km", - "blocked ahead. Slow traffic for 2 km", - "blocked ahead. Slow traffic for 4 km", - "blocked ahead. Slow traffic for 6 km", - "blocked ahead. Slow traffic for 10 km", - "blocked ahead. Slow traffic expected", - "blocked ahead. Heavy traffic", - "blocked ahead. Heavy traffic expected", // 460 - "blocked ahead. Traffic flowing freely", - "blocked ahead. Traffic building up", - "blocked ahead. Delays (Q)", - "blocked ahead. Delays (Q) expected", - "blocked ahead. Long delays (Q)", - "slip roads reopened", - "reopened", - "message cancelled", - "closed ahead", - "blocked ahead", // 470 - "(Q) entry slip road(s) closed", - "(Q th) entry slip road blocked", - "entry blocked", - "(Q) exit slip road(s) closed", - "(Q th) exit slip road blocked", - "exit blocked", - "slip roads blocked", - "connecting carriageway closed", - "parallel carriageway closed", - "right-hand parallel carriageway closed", // 480 - "left-hand parallel carriageway closed", - "express lanes closed", - "through traffic lanes closed", - "local lanes closed", - "connecting carriageway blocked", - "parallel carriageway blocked", - "right-hand parallel carriageway blocked", - "left-hand parallel carriageway blocked", - "express lanes blocked", - "through traffic lanes blocked", // 490 - "local lanes blocked", - "no motor vehicles", - "restrictions", - "closed for heavy lorries (over Q)", - "closed ahead. Stationary traffic for 3 km", - "closed ahead. Queuing traffic for 3 km", - "closed ahead. Slow traffic for 3 km", - "blocked ahead. Stationary traffic for 3 km", - "blocked ahead. Queuing traffic for 3 km", - "(Q) lane(s) closed", // 500 - "(Q) right lane(s) closed", - "(Q) centre lane(s) closed", - "(Q) left lane(s) closed", - "hard shoulder closed", - "two lanes closed", - "three lanes closed", - "(Q) right lane(s) blocked", - "(Q) centre lane(s) blocked", - "(Q) left lane(s) blocked", - "hard shoulder blocked", // 510 - "two lanes blocked", - "three lanes blocked", - "single alternate line traffic", - "carriageway reduced (from Q lanes) to one lane", - "carriageway reduced (from Q lanes) to two lanes", - "carriageway reduced (from Q lanes) to three lanes", - "contraflow", - "narrow lanes", - "contraflow with narrow lanes", - "(Q) lane(s) blocked", // 520 - "(Q) lanes closed. Stationary traffic", - "(Q) lanes closed. Stationary traffic for 1 km", - "(Q) lanes closed. Stationary traffic for 2 km", - "(Q) lanes closed. Stationary traffic for 4 km", - "(Q) lanes closed. Stationary traffic for 6 km", - "(Q) lanes closed. Stationary traffic for 10 km", - "(Q) lanes closed. Danger of stationary traffic", - "(Q) lanes closed. Queuing traffic", - "(Q) lanes closed. Queuing traffic for 1 km", - "(Q) lanes closed. Queuing traffic for 2 km", // 530 - "(Q) lanes closed. Queuing traffic for 4 km", - "(Q) lanes closed. Queuing traffic for 6 km", - "(Q) lanes closed. Queuing traffic for 10 km", - "(Q) lanes closed. Danger of queuing traffic", - "(Q) lanes closed. Slow traffic", - "(Q) lanes closed. Slow traffic for 1 km", - "(Q) lanes closed. Slow traffic for 2 km", - "(Q) lanes closed. Slow traffic for 4 km", - "(Q) lanes closed. Slow traffic for 6 km", - "(Q) lanes closed. Slow traffic for 10 km", // 540 - "(Q) lanes closed. Slow traffic expected", - "(Q) lanes closed. Heavy traffic", - "(Q) lanes closed. Heavy traffic expected", - "(Q)lanes closed. Traffic flowing freely", - "(Q)lanes closed. Traffic building up", - "carriageway reduced (from Q lanes) to one lane. Stationary traffic", - "carriageway reduced (from Q lanes) to one lane. Danger of stationary traffic", - "carriageway reduced (from Q lanes) to one lane. Queuing traffic", - "carriageway reduced (from Q lanes) to one lane. Danger of queuing traffic", - "carriageway reduced (from Q lanes) to one lane. Slow traffic", // 550 - "carriageway reduced (from Q lanes) to one lane. Slow traffic expected", - "carriageway reduced (from Q lanes) to one lane. Heavy traffic", - "carriageway reduced (from Q lanes) to one lane. Heavy traffic expected", - "carriageway reduced (from Q lanes) to one lane. Traffic flowing freely", - "carriageway reduced (from Q lanes) to one lane. Traffic building up", - "carriageway reduced (from Q lanes) to two lanes. Stationary traffic", - "carriageway reduced (from Q lanes) to two lanes. Danger of stationary traffic", - "carriageway reduced (from Q lanes) to two lanes. Queuing traffic", - "carriageway reduced (from Q lanes) to two lanes. Danger of queuing traffic", - "carriageway reduced (from Q lanes) to two lanes. Slow traffic", // 560 - "carriageway reduced (from Q lanes) to two lanes. Slow traffic expected", - "carriageway reduced (from Q lanes) to two lanes. Heavy traffic", - "carriageway reduced (from Q lanes) to two lanes. Heavy traffic expected", - "carriageway reduced (from Q lanes) to two lanes. Traffic flowing freely", - "carriageway reduced (from Q lanes) to two lanes. Traffic building up", - "carriageway reduced (from Q lanes) to three lanes. Stationary traffic", - "carriageway reduced (from Q lanes) to three lanes. Danger of stationary traffic", - "carriageway reduced (from Q lanes) to three lanes. Queuing traffic", - "carriageway reduced (from Q lanes) to three lanes. Danger of queuing traffic", - "carriageway reduced (from Q lanes) to three lanes. Slow traffic", // 570 - "carriageway reduced (from Q lanes) to three lanes. Slow traffic expected", - "carriageway reduced (from Q lanes) to three lanes. Heavy traffic", - "carriageway reduced (from Q lanes) to three lanes. Heavy traffic expected", - "carriageway reduced (from Q lanes) to three lanes. Traffic flowing freely", - "carriageway reduced (from Q lanes) to three lanes. Traffic building up", - "contraflow. Stationary traffic", - "contraflow. Stationary traffic for 1 km", - "contraflow. Stationary traffic for 2 km", - "contraflow. Stationary traffic for 4 km", - "contraflow. Stationary traffic for 6 km", // 580 - "contraflow. Stationary traffic for 10 km", - "contraflow. Danger of stationary traffic", - "contraflow. Queuing traffic", - "contraflow. Queuing traffic for 1 km", - "contraflow. Queuing traffic for 2 km", - "contraflow. Queuing traffic for 4 km", - "contraflow. Queuing traffic for 6 km", - "contraflow. Queuing traffic for 10 km", - "contraflow. Danger of queuing traffic", - "contraflow. Slow traffic", // 590 - "contraflow. Slow traffic for 1 km", - "contraflow. Slow traffic for 2 km", - "contraflow. Slow traffic for 4 km", - "contraflow. Slow traffic for 6 km", - "contraflow. Slow traffic for 10 km", - "contraflow. Slow traffic expected", - "contraflow. Heavy traffic", - "contraflow. Heavy traffic expected", - "contraflow. Traffic flowing freely", - "contraflow. Traffic building up", // 600 - "contraflow. Carriageway reduced (from Q lanes) to one lane", - "contraflow. Carriageway reduced (from Q lanes) to two lanes", - "contraflow. Carriageway reduced (from Q lanes) to three lanes", - "narrow lanes. Stationary traffic", - "narrow lanes. Danger of stationary traffic", - "narrow lanes. Queuing traffic", - "narrow lanes. Danger of queuing traffic", - "narrow lanes. Slow traffic", - "narrow lanes. Slow traffic expected", - "narrow lanes. Heavy traffic", // 610 - "narrow lanes. Heavy traffic expected", - "narrow lanes. Traffic flowing freely", - "narrow lanes. Traffic building up", - "contraflow with narrow lanes. Stationary traffic", - "contraflow with narrow lanes. Stationary traffic. Danger of stationary traffic", - "contraflow with narrow lanes. Queuing traffic", - "contraflow with narrow lanes. Danger of queuing traffic", - "contraflow with narrow lanes. Slow traffic", - "contraflow with narrow lanes. Slow traffic expected", - "contraflow with narrow lanes. Heavy traffic", // 620 - "contraflow with narrow lanes. Heavy traffic expected", - "contraflow with narrow lanes. Traffic flowing freely", - "contraflow with narrow lanes. Traffic building up", - "lane closures removed", - "message cancelled", - "blocked ahead. Slow traffic for 3 km", - "no motor vehicles without catalytic converters", - "no motor vehicles with even-numbered registration plates", - "no motor vehicles with odd-numbered registration plates", - "open", // 630 - "road cleared", - "entry reopened", - "exit reopened", - "all carriageways reopened", - "motor vehicle restrictions lifted", - "traffic restrictions lifted {reopened for all traffic}", - "emergency lane closed", - "turning lane closed", - "crawler lane closed", - "slow vehicle lane closed", // 640 - "one lane closed", - "emergency lane blocked", - "turning lane blocked", - "crawler lane blocked", - "slow vehicle lane blocked", - "one lane blocked", - "(Q person) carpool lane in operation", - "(Q person) carpool lane closed", - "(Q person) carpool lane blocked", - "carpool restrictions changed (to Q persons per vehicle)", // 650 - "(Q) lanes closed. Stationary traffic for 3 km", - "(Q) lanes closed. Queuing traffic for 3 km", - "(Q) lanes closed. Slow traffic for 3 km", - "contraflow. Stationary traffic for 3 km", - "contraflow. Queuing traffic for 3 km", - "contraflow. Slow traffic for 3 km", - "lane blockages cleared", - "contraflow removed", - "(Q person) carpool restrictions lifted", - "lane restrictions lifted", // 660 - "use of hard shoulder allowed", - "normal lane regulations restored", - "all carriageways cleared", - "..", "..", "..", "..", "..", "..", "..", // 670 - "bus lane available for carpools (with at least Q occupants)", - "message cancelled", - "message cancelled", - "..", "..", - "bus lane blocked", - "..", - "heavy vehicle lane closed", - "heavy vehicle lane blocked", - "reopened for through traffic", // 680 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 690 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 700 - "(Q sets of) roadworks", - "(Q sets of) major roadworks", - "(Q sets of) maintenance work", - "(Q sections of) resurfacing work", - "(Q sets of) central reservation work", - "(Q sets of) road marking work", - "bridge maintenance work (at Q bridges)", - "(Q sets of) temporary traffic lights", - "(Q sections of) blasting work", - "(Q sets of) roadworks. Stationary traffic", // 710 - "(Q sets of) roadworks. Stationary traffic for 1 km", - "(Q sets of) roadworks. Stationary traffic for 2 km", - "(Q sets of) roadworks. Stationary traffic for 4 km", - "(Q sets of) roadworks. Stationary traffic for 6 km", - "(Q sets of) roadworks. Stationary traffic for 10 km", - "(Q sets of) roadworks. Danger of stationary traffic", - "(Q sets of) roadworks. Queuing traffic", - "(Q sets of) roadworks. Queuing traffic for 1 km", - "(Q sets of) roadworks. Queuing traffic for 2 km", - "(Q sets of) roadworks. Queuing traffic for 4 km", // 720 - "(Q sets of) roadworks. Queuing traffic for 6 km", - "(Q sets of) roadworks. Queuing traffic for 10 km", - "(Q sets of) roadworks. Danger of queuing traffic", - "(Q sets of) roadworks. Slow traffic", - "(Q sets of) roadworks. Slow traffic for 1 km", - "(Q sets of) roadworks. Slow traffic for 2 km", - "(Q sets of) roadworks. Slow traffic for 4 km", - "(Q sets of) roadworks. Slow traffic for 6 km", - "(Q sets of) roadworks. Slow traffic for 10 km", - "(Q sets of) roadworks. Slow traffic expected", // 730 - "(Q sets of) roadworks. Heavy traffic", - "(Q sets of) roadworks. Heavy traffic expected", - "(Q sets of) roadworks. Traffic flowing freely", - "(Q sets of) roadworks. Traffic building up", - "closed due to (Q sets of) roadworks", - "(Q sets of) roadworks. Right lane closed", - "(Q sets of) roadworks. Centre lane closed", - "(Q sets of) roadworks. Left lane closed", - "(Q sets of) roadworks. Hard shoulder closed", - "(Q sets of) roadworks. Two lanes closed", // 740 - "(Q sets of) roadworks. Three lanes closed", - "(Q sets of) roadworks. Single alternate line traffic", - "roadworks. Carriageway reduced (from Q lanes) to one lane", - "roadworks. Carriageway reduced (from Q lanes) to two lanes", - "roadworks. Carriageway reduced (from Q lanes) to three lanes", - "(Q sets of) roadworks. Contraflow", - "roadworks. Delays (Q)", - "roadworks. Delays (Q) expected", - "roadworks. Long delays (Q)", - "(Q sections of) resurfacing work. Stationary traffic", // 750 - "(Q sections of) resurfacing work. Stationary traffic for 1 km", - "(Q sections of) resurfacing work. Stationary traffic for 2 km", - "(Q sections of) resurfacing work. Stationary traffic for 4 km", - "(Q sections of) resurfacing work. Stationary traffic for 6 km", - "(Q sections of) resurfacing work. Stationary traffic for 10 km", - "(Q sections of) resurfacing work. Danger of stationary traffic", - "(Q sections of) resurfacing work. Queuing traffic", - "(Q sections of) resurfacing work. Queuing traffic for 1 km", - "(Q sections of) resurfacing work. Queuing traffic for 2 km", - "(Q sections of) resurfacing work. Queuing traffic for 4 km", // 760 - "(Q sections of) resurfacing work. Queuing traffic for 6 km", - "(Q sections of) resurfacing work. Queuing traffic for 10 km", - "(Q sections of) resurfacing work. Danger of queuing traffic", - "(Q sections of) resurfacing work. Slow traffic", - "(Q sections of) resurfacing work. Slow traffic for 1 km", - "(Q sections of) resurfacing work. Slow traffic for 2 km", - "(Q sections of) resurfacing work. Slow traffic for 4 km", - "(Q sections of) resurfacing work. Slow traffic for 6 km", - "(Q sections of) resurfacing work. Slow traffic for 10 km", - "(Q sections of) resurfacing work. Slow traffic expected", // 770 - "(Q sections of) resurfacing work. Heavy traffic", - "(Q sections of) resurfacing work. Heavy traffic expected", - "(Q sections of) resurfacing work. Traffic flowing freely", - "(Q sections of) resurfacing work. Traffic building up", - "(Q sections of) resurfacing work. Single alternate line traffic", - "resurfacing work. Carriageway reduced (from Q lanes) to one lane", - "resurfacing work. Carriageway reduced (from Q lanes) to two lanes", - "resurfacing work. Carriageway reduced (from Q lanes) to three lanes", - "(Q sections of) resurfacing work. Contraflow", - "resurfacing work. Delays (Q)", // 780 - "resurfacing work. Delays (Q) expected", - "resurfacing work. Long delays (Q)", - "(Q sets of) road marking work. Stationary traffic", - "(Q sets of) road marking work. Danger of stationary traffic", - "(Q sets of) road marking work. Queuing traffic", - "(Q sets of) road marking work. Danger of queuing traffic", - "(Q sets of) road marking work. Slow traffic", - "(Q sets of) road marking work. Slow traffic expected", - "(Q sets of) road marking work. Heavy traffic", - "(Q sets of) road marking work. Heavy traffic expected", // 790 - "(Q sets of) road marking work. Traffic flowing freely", - "(Q sets of) road marking work. Traffic building up", - "(Q sets of) road marking work. Right lane closed", - "(Q sets of) road marking work. Centre lane closed", - "(Q sets of) road marking work. Left lane closed", - "(Q sets of) road marking work. Hard shoulder closed", - "(Q sets of) road marking work. Two lanes closed", - "(Q sets of) road marking work. Three lanes closed", - "closed for bridge demolition work (at Q bridges)", - "roadworks cleared", // 800 - "message cancelled", - "(Q sets of) long-term roadworks", - "(Q sets of) construction work", - "(Q sets of) slow moving maintenance vehicles", - "bridge demolition work (at Q bridges)", - "(Q sets of) water main work", - "(Q sets of) gas main work", - "(Q sets of) work on buried cables", - "(Q sets of) work on buried services", - "new roadworks layout", // 810 - "new road layout", - "(Q sets of) roadworks. Stationary traffic for 3 km", - "(Q sets of) roadworks. Queuing traffic for 3 km", - "(Q sets of) roadworks. Slow traffic for 3 km", - "(Q sets of) roadworks during the day time", - "(Q sets of) roadworks during off-peak periods", - "(Q sets of) roadworks during the night", - "(Q sections of) resurfacing work. Stationary traffic for 3 km", - "(Q sections of) resurfacing work. Queuing traffic for 3 km", - "(Q sections of) resurfacing work. Slow traffic for 3 km", // 820 - "(Q sets of) resurfacing work during the day time", - "(Q sets of) resurfacing work during off-peak periods", - "(Q sets of) resurfacing work during the night", - "(Q sets of) road marking work. Danger", - "(Q sets of) slow moving maintenance vehicles. Stationary traffic", - "(Q sets of) slow moving maintenance vehicles. Danger of stationary traffic", - "(Q sets of) slow moving maintenance vehicles. Queuing traffic", - "(Q sets of) slow moving maintenance vehicles. Danger of queuing traffic", - "(Q sets of) slow moving maintenance vehicles. Slow traffic", - "(Q sets of) slow moving maintenance vehicles. Slow traffic expected", // 830 - "(Q sets of) slow moving maintenance vehicles. Heavy traffic", - "(Q sets of) slow moving maintenance vehicles. Heavy traffic expected", - "(Q sets of) slow moving maintenance vehicles. Traffic flowing freely", - "(Q sets of) slow moving maintenance vehicles. Traffic building up", - "(Q sets of) slow moving maintenance vehicles. Right lane closed", - "(Q sets of) slow moving maintenance vehicles. Centre lane closed", - "(Q sets of) slow moving maintenance vehicles. Left lane closed", - "(Q sets of) slow moving maintenance vehicles. Two lanes closed", - "(Q sets of) slow moving maintenance vehicles. Three lanes closed", - "water main work. Delays (Q)", // 840 - "water main work. Delays (Q) expected", - "water main work. Long delays (Q)", - "gas main work. Delays (Q)", - "gas main work. Delays (Q) expected", - "gas main work. Long delays (Q)", - "work on buried cables. Delays (Q)", - "work on buried cables. Delays (Q) expected", - "work on buried cables. Long delays (Q)", - "work on buried services. Delays (Q)", - "work on buried services. Delays (Q) expected", // 850 - "work on buried services. Long delays (Q)", - "construction traffic merging", - "roadwork clearance in progress", - "maintenance work cleared", - "road layout unchanged", - "construction traffic merging. Danger", - "..", "..", "..", "..", // 860 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 870 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 880 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 890 - "..", "..", "..", "..", "..", "..", "..", - "obstruction warning withdrawn", - "clearance work in progress, road free again", - "flooding expected", // 900 - "(Q) obstruction(s) on roadway {something that does block the road or part of", - "(Q) obstructions on the road. Danger", - "spillage on the road", - "storm damage", - "(Q) fallen trees", - "(Q) fallen trees. Danger", - "flooding", - "flooding. Danger", - "flash floods", - "danger of flash floods", // 910 - "avalanches", - "avalanche risk", - "rockfalls", - "landslips", - "earthquake damage", - "road surface in poor condition", - "subsidence", - "(Q) collapsed sewer(s)", - "burst water main", - "gas leak", // 920 - "serious fire", - "animals on roadway", - "animals on the road. Danger", - "clearance work", - "blocked by storm damage", - "blocked by (Q) fallen trees", - "(Q) fallen tree(s). Passable with care", - "flooding. Stationary traffic", - "flooding. Danger of stationary traffic", - "flooding. Queuing traffic", // 930 - "flooding. Danger of queuing traffic", - "flooding. Slow traffic", - "flooding. Slow traffic expected", - "flooding. Heavy traffic", - "flooding. Heavy traffic expected", - "flooding. Traffic flowing freely", - "flooding. Traffic building up", - "closed due to flooding", - "flooding. Delays (Q)", - "flooding. Delays (Q) expected", // 940 - "flooding. Long delays (Q)", - "flooding. Passable with care", - "closed due to avalanches", - "avalanches. Passable with care (above Q hundred metres)", - "closed due to rockfalls", - "rockfalls. Passable with care", - "road closed due to landslips", - "landslips. Passable with care", - "closed due to subsidence", - "subsidence. Single alternate line traffic", // 950 - "subsidence. Carriageway reduced (from Q lanes) to one lane", - "subsidence. Carriageway reduced (from Q lanes) to two lanes", - "subsidence. Carriageway reduced (from Q lanes) to three lanes", - "subsidence. Contraflow in operation", - "subsidence. Passable with care", - "closed due to sewer collapse", - "road closed due to burst water main", - "burst water main. Delays (Q)", - "burst water main. Delays (Q) expected", - "burst water main. Long delays (Q)", // 960 - "closed due to gas leak", - "gas leak. Delays (Q)", - "gas leak. Delays (Q) expected", - "gas leak. Long delays (Q)", - "closed due to serious fire", - "serious fire. Delays (Q)", - "serious fire. Delays (Q) expected", - "serious fire. Long delays (Q)", - "closed for clearance work", - "road free again", // 970 - "message cancelled", - "storm damage expected", - "fallen power cables", - "sewer overflow", - "ice build-up", - "mud slide", - "grass fire", - "air crash", - "rail crash", - "blocked by (Q) obstruction(s) on the road", // 980 - "(Q) obstructions on the road. Passable with care", - "blocked due to spillage on roadway", - "spillage on the road. Passable with care", - "spillage on the road. Danger", - "storm damage. Passable with care", - "storm damage. Danger", - "blocked by fallen power cables", - "fallen power cables. Passable with care", - "fallen power cables. Danger", - "sewer overflow. Danger", // 990 - "flash floods. Danger", - "avalanches. Danger", - "closed due to avalanche risk", - "avalanche risk. Danger", - "closed due to ice build-up", - "ice build-up. Passable with care (above Q hundred metres)", - "ice build-up. Single alternate traffic", - "rockfalls. Danger", - "landslips. Danger", - "earthquake damage. Danger", // 1000 - "hazardous driving conditions (above Q hundred metres)", - "danger of aquaplaning", - "slippery road (above Q hundred metres)", - "mud on road", - "leaves on road", - "ice (above Q hundred metres)", - "danger of ice (above Q hundred metres)", - "black ice (above Q hundred metres)", - "freezing rain (above Q hundred metres)", - "wet and icy roads (above Q hundred metres)", // 1010 - "slush (above Q hundred metres)", - "snow on the road (above Q hundred metres)", - "packed snow (above Q hundred metres)", - "fresh snow (above Q hundred metres)", - "deep snow (above Q hundred metres)", - "snow drifts (above Q hundred metres)", - "slippery due to spillage on roadway", - "slippery road (above Q hundred metres) due to snow", - "slippery road (above Q hundred metres) due to frost", - "road blocked by snow (above Q hundred metres)", // 1020 - "snow on the road. Carriageway reduced (from Q lanes) to one lane", - "snow on the road. Carriageway reduced (from Q lanes) to two lanes", - "snow on the road. Carriageway reduced (from Q lanes) to three lanes", - "conditions of road surface improved", - "message cancelled", - "subsidence. Danger", - "sewer collapse. Delays (Q)", - "sewer collapse. Delays (Q) expected", - "sewer collapse. Long delays (Q)", - "sewer collapse. Danger", // 1030 - "burst water main. Danger", - "gas leak. Danger", - "serious fire. Danger", - "clearance work. Danger", - "impassable (above Q hundred metres)", - "almost impassable (above Q hundred metres)", - "extremely hazardous driving conditions (above Q hundred metres)", - "difficult driving conditions (above Q hundred metres)", - "passable with care (up to Q hundred metres)", - "passable (up to Q hundred metres)", // 1040 - "surface water hazard", - "loose sand on road", - "loose chippings", - "oil on road", - "petrol on road", - "icy patches (above Q hundred metres)", - "danger of icy patches (above Q hundred metres)", - "danger of black ice (above Q hundred metres)", - "..", "..", // 1050 - "..", "..", "..", - "slippery due to loose sand on roadway", - "mud on road. Danger", - "loose chippings. Danger", - "oil on road. Danger", - "petrol on road. Danger", - "road surface in poor condition. Danger", - "icy patches (above Q hundred metres) on bridges", // 1060 - "danger of icy patches (above Q hundred metres) on bridges", - "icy patches (above Q hundred metres) on bridges, in shaded areas and on s", - "impassable for heavy vehicles (over Q)", - "impassable (above Q hundred metres) for vehicles with trailers", - "driving conditions improved", - "rescue and recovery work in progress. Danger", - "large animals on roadway", - "herds of animals on roadway", - "skid hazard reduced", - "snow cleared", // 1070 - "..", "..", - "extremely hazardous driving conditions expected (above Q hundred meters", - "freezing rain expected (above Q hundred metres)", - "danger of road being blocked by snow (above Q hundred metres)", - "..", "..", "..", - "temperature falling rapidly (to Q)", - "extreme heat (up to Q)", // 1080 - "extreme cold (of Q)", - "less extreme temperatures", - "current temperature (Q)", - "..", "..", "..", "..", "..", "..", "..", // 1090 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1100 - "heavy snowfall (Q)", - "heavy snowfall (Q). Visibility reduced to < ?? m", - "heavy snowfall (Q). Visibility reduced to < ?? m", - "snowfall (Q)", - "snowfall (Q). Visibility reduced to < ?? m", - "hail (visibility reduced to Q)", - "sleet (visibility reduced to Q)", - "thunderstorms (visibility reduced to Q)", - "heavy rain (Q)", - "heavy rain (Q). Visibility reduced to < ?? m", // 1110 - "heavy rain (Q). Visibility reduced to < ?? m", - "rain (Q)", - "rain (Q). Visibility reduced to < ?? m", - "showers (visibility reduced to Q)", - "heavy frost", - "frost", - "..", "..", "..", "..", // 1120 - "..", "..", "..", "..", "..", - "weather situation improved", - "message cancelled", - "winter storm (visibility reduced to Q)", - "..", - "blizzard (visibility reduced to Q)", // 1130 - "..", - "damaging hail (visibility reduced to Q)", - "..", - "heavy snowfall. Visibility reduced (to Q)", - "snowfall. Visibility reduced (to Q)", - "heavy rain. Visibility reduced (to Q)", - "rain. Visibility reduced (to Q)", - "..", "..", "..", // 1140 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1150 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1160 - "..", "..", "..", "..", "..", "..", "..", "..", "..", - "heavy snowfall (Q) expected", // 1170 - "heavy rain (Q) expected", - "weather expected to improve", - "blizzard (with visibility reduced to Q) expected", - "damaging hail (with visibility reduced to Q) expected", - "reduced visibility (to Q) expected", - "freezing fog expected (with visibility reduced to Q). Danger of slippery roads", - "dense fog (with visibility reduced to Q) expected", - "patchy fog (with visibility reduced to Q) expected", - "visibility expected to improve", - "adverse weather warning withdrawn", // 1180 - "..", "..", "..", "..", "..", "..", "..", "..", "..", - "severe smog", // 1190 - "severe exhaust pollution", - "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1200 - "tornadoes", - "hurricane force winds (Q)", - "gales (Q)", - "storm force winds (Q)", - "strong winds (Q)", - "..", "..", "..", - "gusty winds (Q)", - "crosswinds (Q)", // 1210 - "strong winds (Q) affecting high-sided vehicles", - "closed for high-sided vehicles due to strong winds (Q)", - "strong winds easing", - "message cancelled", - "restrictions for high-sided vehicles lifted", - "..", - "tornado warning ended", - "..", "..", "..", // 1220 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1230 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1240 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1250 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1260 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1270 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1280 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1290 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1300 - "dense fog (visibility reduced to Q)", - "dense fog. Visibility reduced to < ?? m", - "dense fog. Visibility reduced to < ?? m", - "fog (visibility reduced to Q)", - "fog. Visibility reduced to < ?? m", - "..", - "patchy fog (visibility reduced to Q)", - "freezing fog (visibility reduced to Q)", - "smoke hazard (visibility reduced to Q)", - "blowing dust (visibility reduced to Q)", // 1310 - "..", - "snowfall and fog (visibility reduced to Q)", - "visibility improved", - "message cancelled", - "..", "..", "..", - "visibility reduced (to Q)", - "visibility reduced to < ?? m", - "visibility reduced to < ?? m", // 1320 - "visibility reduced to < ?? m", - "white out (visibility reduced to Q)", - "blowing snow (visibility reduced to Q)", - "spray hazard (visibility reduced to Q)", - "low sun glare", - "sandstorms (visibility reduced to Q)", - "..", "..", "..", "..", // 1330 - "..", - "smog alert", - "..", "..", "..", "..", - "freezing fog (visibility reduced to Q). Slippery roads", - "no motor vehicles due to smog alert", - "..", - "swarms of insects (visibility reduced to Q)", // 1340 - "..", "..", "..", "..", - "fog clearing", - "fog forecast withdrawn", - "..", "..", "..", "..", // 1350 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1360 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1370 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1380 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1390 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1400 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1410 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1420 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1430 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1440 - "..", "..", "..", "..", "..", "..", "..", "..", "..", - "international sports meeting", // 1450 - "match", - "tournament", - "athletics meeting", - "ball game", - "boxing tournament", - "bull fight", - "cricket match", - "cycle race", - "football match", - "golf tournament", // 1460 - "marathon", - "race meeting", - "rugby match", - "show jumping", - "tennis tournament", - "water sports meeting", - "winter sports meeting", - "funfair", - "trade fair", - "procession", // 1470 - "sightseers obstructing access", - "people on roadway", - "children on roadway", - "cyclists on roadway", - "strike", - "security incident", - "police checkpoint", - "terrorist incident", - "gunfire on roadway, danger", - "civil emergency", // 1480 - "air raid, danger", - "people on roadway. Danger", - "children on roadway. Danger", - "cyclists on roadway. Danger", - "closed due to security incident", - "security incident. Delays (Q)", - "security incident. Delays (Q) expected", - "security incident. Long delays (Q)", - "police checkpoint. Delays (Q)", - "police checkpoint. Delays (Q) expected", // 1490 - "police checkpoint. Long delays (Q)", - "security alert withdrawn", - "sports traffic cleared", - "evacuation", - "evacuation. Heavy traffic", - "traffic disruption cleared", - "..", "..", "..", "..", // 1500 - "major event", - "sports event meeting", - "show", - "festival", - "exhibition", - "fair", - "market", - "ceremonial event", - "state occasion", - "parade", // 1510 - "crowd", - "march", - "demonstration", - "public disturbance", - "security alert", - "bomb alert", - "major event. Stationary traffic", - "major event. Danger of stationary traffic", - "major event. Queuing traffic", - "major event. Danger of queuing traffic", // 1520 - "major event. Slow traffic", - "major event. Slow traffic expected", - "major event. Heavy traffic", - "major event. Heavy traffic expected", - "major event. Traffic flowing freely", - "major event. Traffic building up", - "closed due to major event", - "major event. Delays (Q)", - "major event. Delays (Q) expected", - "major event. Long delays (Q)", // 1530 - "sports meeting. Stationary traffic", - "sports meeting. Danger of stationary traffic", - "sports meeting. Queuing traffic", - "sports meeting. Danger of queuing traffic", - "sports meeting. Slow traffic", - "sports meeting. Slow traffic expected", - "sports meeting. Heavy traffic", - "sports meeting. Heavy traffic expected", - "sports meeting. Traffic flowing freely", - "sports meeting. Traffic building up", // 1540 - "closed due to sports meeting", - "sports meeting. Delays (Q)", - "sports meeting. Delays (Q) expected", - "sports meeting. Long delays (Q)", - "fair. Stationary traffic", - "fair. Danger of stationary traffic", - "fair. Queuing traffic", - "fair. Danger of queuing traffic", - "fair. Slow traffic", - "fair. Slow traffic expected", // 1550 - "fair. Heavy traffic", - "fair. Heavy traffic expected", - "fair. Traffic flowing freely", - "fair. Traffic building up", - "closed due to fair", - "fair. Delays (Q)", - "fair. Delays (Q) expected", - "fair. Long delays (Q)", - "closed due to parade", - "parade. Delays (Q)", // 1560 - "parade. Delays (Q) expected", - "parade. Long delays (Q)", - "closed due to strike", - "strike. Delays (Q)", - "strike. Delays (Q) expected", - "strike. Long delays (Q)", - "closed due to demonstration", - "demonstration. Delays (Q)", - "demonstration. Delays (Q) expected", - "demonstration. Long delays (Q)", // 1570 - "security alert. Stationary traffic", - "security alert. Danger of stationary traffic", - "security alert. Queuing traffic", - "security alert. Danger of queuing traffic", - "security alert. Slow traffic", - "security alert. Slow traffic expected", - "security alert. Heavy traffic", - "security alert. Heavy traffic expected", - "security alert. Traffic building up", - "closed due to security alert", // 1580 - "security alert. Delays (Q)", - "security alert. Delays (Q) expected", - "security alert. Long delays (Q)", - "traffic has returned to normal", - "message cancelled", - "security alert. Traffic flowing freely", - "air raid warning cancelled", - "civil emergency cancelled", - "message cancelled", - "several major events", // 1590 - "information about major event no longer valid", - "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1600 - "delays (Q)", - "delays up to ?? minutes", - "delays up to ?? minutes", - "delays up to one hour", - "delays up to two hours", - "delays of several hours", - "delays (Q) expected", - "long delays (Q)", - "delays (Q) for heavy vehicles", - "delays up to ?? minutes for heavy lorr(y/ies)", // 1610 - "delays up to ?? minutes for heavy lorr(y/ies)", - "delays up to one hour for heavy lorr(y/ies)", - "delays up to two hours for heavy lorr(y/ies)", - "delays of several hours for heavy lorr(y/ies)", - "service suspended (until Q)", - "(Q) service withdrawn", - "(Q) service(s) fully booked", - "(Q) service(s) fully booked for heavy vehicles", - "normal services resumed", - "message cancelled", // 1620 - "delays up to ?? minutes", - "delays up to ?? minutes", - "delays up to ?? minutes", - "delays up to ?? minutes", - "delays up to ?? minutes", - "delays up to ?? minutes", - "delays up to ?? minutes", - "delays up to three hours", - "delays up to four hours", - "delays up to five hours", // 1630 - "very long delays (Q)", - "delays of uncertain duration", - "delayed until further notice", - "cancellations", - "park and ride service not operating (until Q)", - "special public transport services operating (until Q)", - "normal services not operating (until Q)", - "rail services not operating (until Q)", - "bus services not operating (until Q)", - "shuttle service operating (until Q)", // 1640 - "free shuttle service operating (until Q)", - "delays (Q) for heavy lorr(y/ies)", - "delays (Q) for buses", - "(Q) service(s) fully booked for heavy lorr(y/ies)", - "(Q) service(s) fully booked for buses", - "next departure (Q) for heavy lorr(y/ies)", - "next departure (Q) for buses", - "delays cleared", - "rapid transit service not operating (until Q)", - "delays (Q) possible", // 1650 - "underground service not operating (until Q)", - "cancellations expected", - "long delays expected", - "very long delays expected", - "all services fully booked (until Q)", - "next arrival (Q)", - "rail services irregular. Delays (Q)", - "bus services irregular. Delays (Q)", - "underground services irregular", - "normal public transport services resumed", // 1660 - "ferry service not operating (until Q)", - "park and ride trip time (Q)", - "delay expected to be cleared", - "..", "..", "..", "..", "..", "..", "..", // 1670 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1680 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1690 - "..", "..", "..", "..", - "current trip time (Q)", - "expected trip time (Q)", - "..", "..", "..", - "(Q) slow moving maintenance vehicle(s)", // 1700 - "(Q) vehicle(s) on wrong carriageway", - "dangerous vehicle warning cleared", - "message cancelled", - "(Q) reckless driver(s)", - "(Q) prohibited vehicle(s) on the roadway", - "(Q) emergency vehicles", - "(Q) high-speed emergency vehicles", - "high-speed chase (involving Q vehicles)", - "spillage occurring from moving vehicle", - "objects falling from moving vehicle", // 1710 - "emergency vehicle warning cleared", - "road cleared", - "..", "..", "..", "..", "..", "..", "..", - "rail services irregular", // 1720 - "public transport services not operating", - "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1730 - "(Q) abnormal load(s), danger", - "(Q) wide load(s), danger", - "(Q) long load(s), danger", - "(Q) slow vehicle(s), danger", - "(Q) track-laying vehicle(s), danger", - "(Q) vehicle(s) carrying hazardous materials. Danger", - "(Q) convoy(s), danger", - "(Q) military convoy(s), danger", - "(Q) overheight load(s), danger", - "abnormal load causing slow traffic. Delays (Q)", // 1740 - "convoy causing slow traffic. Delays (Q)", - "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1750 - "(Q) abnormal load(s)", - "(Q) wide load(s)", - "(Q) long load(s)", - "(Q) slow vehicle(s)", - "(Q) convoy(s)", - "abnormal load. Delays (Q)", - "abnormal load. Delays (Q) expected", - "abnormal load. Long delays (Q)", - "convoy causing delays (Q)", - "convoy. Delays (Q) expected", // 1760 - "convoy causing long delays (Q)", - "exceptional load warning cleared", - "message cancelled", - "(Q) track-laying vehicle(s)", - "(Q) vehicle(s) carrying hazardous materials", - "(Q) military convoy(s)", - "(Q) abnormal load(s). No overtaking", - "Vehicles carrying hazardous materials have to stop at next safe place!", - "hazardous load warning cleared", - "convoy cleared", // 1770 - "warning cleared", - "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1780 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1790 - "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", // 1800 - "lane control signs not working", - "emergency telephones not working", - "emergency telephone number not working", - "(Q sets of) traffic lights not working", - "(Q sets of) traffic lights working incorrectly", - "level crossing failure", - "(Q sets of) traffic lights not working. Stationary traffic", - "(Q sets of) traffic lights not working. Danger of stationary traffic", - "(Q sets of) traffic lights not working. Queuing traffic", - "(Q sets of) traffic lights not working. Danger of queuing traffic", // 1810 - "(Q sets of) traffic lights not working. Slow traffic", - "(Q sets of) traffic lights not working. Slow traffic expected", - "(Q sets of) traffic lights not working. Heavy traffic", - "(Q sets of) traffic lights not working. Heavy traffic expected", - "(Q sets of) traffic lights not working. Traffic flowing freely", - "(Q sets of) traffic lights not working. Traffic building up", - "traffic lights not working. Delays (Q)", - "traffic lights not working. Delays (Q) expected", - "traffic lights not working. Long delays (Q)", - "level crossing failure. Stationary traffic", // 1820 - "level crossing failure. Danger of stationary traffic", - "level crossing failure. Queuing traffic", - "level crossing failure. Danger of queuing traffic", - "level crossing failure. Slow traffic", - "level crossing failure. Slow traffic expected", - "level crossing failure. Heavy traffic", - "level crossing failure. Heavy traffic expected", - "level crossing failure. Traffic flowing freely", - "level crossing failure. Traffic building up", - "level crossing failure. Delays (Q)", // 1830 - "level crossing failure. Delays (Q) expected", - "level crossing failure. Long delays (Q)", - "electronic signs repaired", - "emergency call facilities restored", - "traffic signals repaired", - "level crossing now working normally", - "message cancelled", - "lane control signs working incorrectly", - "lane control signs operating", - "variable message signs not working", // 1840 - "variable message signs working incorrectly", - "variable message signs operating", - "(Q sets of) ramp control signals not working", - "(Q sets of) ramp control signals working incorrectly", - "(Q sets of) temporary traffic lights not working", - "(Q sets of) temporary traffic lights working incorrectly", - "traffic signal control computer not working", - "traffic signal timings changed", - "tunnel ventilation not working", - "lane control signs not working. Danger", // 1850 - "temporary width limit (Q)", - "temporary width limit lifted", - "..", - "traffic regulations have been changed", - "less than parking spaces available", - "no parking information available (until Q)", - "message cancelled", - "..", "..", "..", // 1860 - "temporary height limit (Q)", - "temporary height limit lifted", - "..", - "lane control signs working incorrectly. Danger", - "emergency telephones out of order. Extra police patrols in operation", - "emergency telephones out of order. In emergency, wait for police patrol", - "(Q sets of) traffic lights not working. Danger", - "traffic lights working incorrectly. Delays (Q)", - "traffic lights working incorrectly. Delays (Q) expected", - "traffic lights working incorrectly. Long delays (Q)", // 1870 - "temporary axle load limit (Q)", - "temporary gross weight limit (Q)", - "temporary gross weight limit lifted", - "temporary axle weight limit lifted", - "(Q sets of) traffic lights working incorrectly. Danger", - "temporary traffic lights not working. Delays (Q)", - "temporary traffic lights not working. Delays (Q) expected", - "temporary traffic lights not working. Long delays (Q)", - "(Q sets of) temporary traffic lights not working. Danger", - "traffic signal control computer not working. Delays (Q)", // 1880 - "temporary length limit (Q)", - "temporary length limit lifted", - "message cancelled", - "traffic signal control computer not working. Delays (Q) expected", - "traffic signal control computer not working. Long delays (Q)", - "normal parking restrictions lifted", - "special parking restrictions in force", - "10% full", - "20% full", - "30% full", // 1890 - "40% full", - "50% full", - "60% full", - "70% full", - "80% full", - "90% full", - "less than ?? parking spaces available", - "less than ?? parking spaces available", - "less than ?? parking spaces available", - "less than ?? parking spaces available", // 1900 - "next departure (Q)", - "next departure (Q) for heavy vehicles", - "car park (Q) full", - "all car parks (Q) full", - "less than (Q) car parking spaces available", - "park and ride service operating (until Q)", - "(null event)", - "switch your car radio (to Q)", - "alarm call: important new information on this frequency follows now in normal", - "alarm set: new information will be broadcast between these times in normal", // 1910 - "message cancelled", - "..", - "switch your car radio (to Q)", - "no information available (until Q)", - "this message is for test purposes only (number Q), please ignore", - "no information available (until Q) due to technical problems", - "..", - "full", - "..", - "only a few parking spaces available", // 1920 - "(Q) parking spaces available", - "expect car park to be full", - "expect no parking spaces available", - "multi story car parks full", - "no problems to report with park and ride services", - "no parking spaces available", - "no parking (until Q)", - "special parking restrictions lifted", - "urgent information will be given (at Q) on normal programme broadcasts", - "this TMC-service is not active (until Q)", // 1930 - "detailed information will be given (at Q) on normal programme broadcasts", - "detailed information is provided by another TMC service", - "..", - "no park and ride information available (until Q)", - "..", "..", "..", - "park and ride information service resumed", - "..", - "additional regional information is provided by another TMC service", // 1940 - "additional local information is provided by another TMC service", - "additional public transport information is provided by another TMC service", - "national traffic information is provided by another TMC service", - "this service provides major road information", - "this service provides regional travel information", - "this service provides local travel information", - "no detailed regional information provided by this service", - "no detailed local information provided by this service", - "no cross-border information provided by this service", - "information restricted to this area", // 1950 - "no new traffic information available (until Q)", - "no public transport information available", - "this TMC-service is being suspended (at Q)", - "active TMC-service will resume (at Q)", - "reference to audio programmes no longer valid", - "reference to other TMC services no longer valid", - "previous announcement about this or other TMC services no longer valid", - "..", "..", "..", // 1960 - "allow emergency vehicles to pass in the carpool lane", - "carpool lane available for all vehicles", - "police directing traffic via the carpool lane", - "..", "..", "..", "..", "..", "..", "..", // 1970 - "police directing traffic", - "buslane available for all vehicles", - "police directing traffic via the buslane", - "allow emergency vehicles to pass", - "..", "..", - "allow emergency vehicles to pass in the heavy vehicle lane", - "heavy vehicle lane available for all vehicles", - "police directing traffic via the heavy vehicle lane", - "..", // 1980 - "..", - "buslane closed", - "..", "..", "..", "..", "..", "..", "..", "..", // 1990 - "..", "..", "..", "..", "..", "..", "..", "..", "..", - "closed due to smog alert (until Q)", // 2000 - "..", "..", "..", "..", "..", - "closed for vehicles with less than three occupants {not valid for lorries}", - "closed for vehicles with only one occupant {not valid for lorries}", - "..", "..", "..", // 2010 - "..", "..", - "service area busy", - "..", "..", "..", "..", "..", "..", "..", // 2020 - "service not operating, substitute service available", - "public transport strike", - "..", "..", "..", "..", "..", - "message cancelled", - "message cancelled", - "message cancelled", // 2030 - "..", "..", - "message cancelled", - "message cancelled", - "message cancelled", - "..", "..", - "message cancelled", - "message cancelled", - "message cancelled", // 2040 - "..", "..", "..", "..", "..", "..", - "(null message)", // last = 2047 -}; - -const char *tmc_mglabel[16] = { - "Duration", - "Control code", - "Length", - "Speed limit", - "Quantifier", - "Quantifier", - "Info code", - "Start time", - "Stop time", - "Event", - "Diversion", - "Location", - "unknown", - "Location", - "NOP", - "unknown", -}; -int tmc_mgsize[16] = { 3, 3, 5, 5, 5, 8, 8, 8, 8, 11, 16, 16, 16, 16, 0, 0 }; - -// TMC, Alert-C Coding -void tmc_parser(unsigned char *data, int len) { - static char lastdata[6]; - - if (len < 6) { - printf("TMC Length only '%d' bytes (<6).\n", len); - return; - } - - if (memcmp(data, lastdata, 6) == 0) { - printf("TMC Repeating.\n"); - return; - } - memcpy(lastdata, data, 6); - - // Buffer = data[0], todo or not :D - - // check Encrypted-Service, TMC Pro ? - if ((data[1] & 0x1f) == 0x00) { // Type+DP = '00000' - printf("TMC Encrypted Service detected, TMC-Pro?\n"); - return; - } - - int type = (data[1] & 0x18) >> 3; // Type = User-,TuningInformation & Multi-,Singlegroup Message - int dp = data[1] & 0x07; // Duration+Persistance or Continuity Index - int da = (data[2] & 0x80) >> 7; // DiversionAdvice or GroupIndicator - int di = (data[2] & 0x40) >> 6; // Direction (-/+) or 2.GroupIndicator - int ex = (data[2] & 0x38) >> 3; // Extent - int ev = (data[2] & 0x07) << 8 | data[3]; // Event - int lo = data[4] << 8 | data[5]; // Location - - switch (type) { - case 0: // Multigroup-Message - printf("TMC Multi-Group Message, "); - if (da == 1) { - printf("First:\n"); - printf(" CI: '%d', Direction: %s, Extent: '%d'\n", dp, - tmc_direction[di], ex); - printf(" Event: '%d' = %s\n", ev, tmc_event[ev]); - printf(" Location: '%d' > LT not available yet :-(\n", lo); - } - else { - int gsi = (data[2] & 0x30) >> 4; // GroupSequenceIdentifier - printf("Subsequent:\n"); - printf( - " CI: '%d', 2.GI: '%d', GSI: '%d', Block_0x: '%02x%02x%02x%02x'\n", - dp, di, gsi, data[2] & 0xf, data[3], data[4], data[5]); - if (di == 0) { - printf(" SecondGroupIndicator = 0 -> todo, exit here.\n\n"); - return; - } - unsigned int block = (data[2] & 0x0f) << 24 | data[3] << 16 - | data[4] << 8 | data[5]; - int lc = 1; - int rbits = 28; - while (rbits > 0) { - int lb = block >> (rbits - 4); - rbits -= 4; - if (lb <= 0) - return; - block = block & ((unsigned long int) (pow(2, rbits)) - 1); - rbits -= tmc_mgsize[lb]; - int val = block >> (rbits); - printf(" #%d: Label '%02d' = %s", lc, lb, tmc_mglabel[lb]); - if (val > 0) { - switch (lb) { - case 0: - printf(", Value '%d' min.?\n", val); - break; - case 2: - printf(", Value '%d' km?\n", val); - break; - case 3: - printf(", Value '%d' km/h?\n", val); - break; - case 9: - printf(", Value '%d' = %s\n", val, tmc_event[val]); - break; - case 11: - case 13: - printf(", Value '%d' > LT not available yet :-(\n", - val); - break; - case 14: - case 15: - printf(" ---\n"); - break; - default: - printf(", Value '%d'\n", val); - } - } - else { - if (block > 0) { - printf(", rest block_0x '%04x'\n", (int) block); - } - else { - printf(", ...\n"); - } - } - block = block & ((unsigned int) (pow(2, rbits)) - 1); - lc++; - } - } - break; - case 1: // Singlegroup-Message - printf("TMC Single-Group Message:\n"); - printf(" Duration: %s, Diversion: '%d', Direction: %s, Extent: '%d'\n", - tmc_duration[dp], da, tmc_direction[di], ex); - printf(" Event: '%d' = %s\n", ev, tmc_event[ev]); - printf(" Location: '%d' > LT not available yet :-(\n", lo); - break; - case 2: - case 3: // System,Tuning - printf("TMC Tuning/System Information:\n"); - switch (data[1] & 0x0f) { - case 9: - printf(" LTN: '%d', MGS: '%d', SID: '%d' %04x.\n", data[2] >> 2, - (data[2] & 0x03) << 2 | data[3] >> 6, data[3] & 0x3f, lo); - break; - default: - printf(" todo, exit.\n"); - } - } -} - const char* ptynr2string(int nr) { switch (nr) { // Source: http://www.ebu.ch/trev_255-beale.pdf diff --git a/radiotools.h b/radiotools.h index 1bf042e..8acd311 100644 --- a/radiotools.h +++ b/radiotools.h @@ -15,7 +15,6 @@ char *rds_entitychar(char *text); char *xhtml2text(char *text); char *rtrim(char *text); char *audiobitrate(const unsigned char *data); -void tmc_parser(unsigned char *data, int len); // Alert-c const char* ptynr2string(int nr); #endif //__RADIO_TOOLS_H diff --git a/rdsreceiver.c b/rdsreceiver.c index 63bbeac..42b8320 100644 --- a/rdsreceiver.c +++ b/rdsreceiver.c @@ -29,7 +29,7 @@ void cRDSReceiver::Receive(const uchar *Data, int Length) #else void cRDSReceiver::Receive(uchar *Data, int Length) #endif - { +{ const int mframel = 263; // max. 255(MSG)+4(ADD/SQC/MFL)+2(CRC)+2(Start/Stop) of RDS-data static unsigned char mtext[mframel + 1]; static int index; @@ -42,10 +42,10 @@ void cRDSReceiver::Receive(const uchar *Data, int Length) } int offset; - if (Data[1] & 0x40) { // 1.TS-Frame, payload-unit-start - offset = (Data[3] & 0x20) ? Data[4] + 11 : 10; // Header + ADFL + 6 byte: PES-Startcode, -StreamID, -PacketLength - if (Data[offset - 3] == 0xbd) { // StreamID = Private stream 1 (for rds) - offset += 3; // 3 byte: Extension + Headerlength + if (Data[1] & 0x40) { // 1.TS-Frame, payload-unit-start + offset = (Data[3] & 0x20) ? Data[4] + 11 : 10; // Header + ADFL + 6 byte: PES-Startcode, -StreamID, -PacketLength + if (Data[offset - 3] == 0xbd) { // StreamID = Private stream 1 (for rds) + offset += 3; // 3 byte: Extension + Headerlength offset += Data[offset - 1]; } else { return; @@ -81,7 +81,7 @@ void cRDSReceiver::Receive(const uchar *Data, int Length) rt_bstuff = false; mec = 0; if ((S_Verbose & 0x0f) >= 2) { - printf("\nRDS-Start: "); + printf("\nrdsreceiver: RDS-Start: "); } } @@ -137,19 +137,19 @@ void cRDSReceiver::Receive(const uchar *Data, int Length) if (index >= mframel) { // max. rdslength, garbage ? rt_start = false; if ((S_Verbose & 0x0f) >= 2) { - printf("(RDS-Error: too long, garbage ?)\n"); + printf("rdsreceiver: (RDS-Error: too long %d, garbage ?)\n", index); } } } - if (rt_start && val == 0xff) { // End + if (rt_start && (val == 0xff)) { // End rt_start = false; if ((S_Verbose & 0x0f) >= 2) { printf("(RDS-End)\n"); } if (index < 9) { // min. rdslength, garbage ? if ((S_Verbose & 0x0f) >= 1) { - printf("RDS-Error: too short -> garbage ?\n"); + printf("rdsreceiver: RDS-Error: too short -> garbage ?\n"); } } else { // crc16-check @@ -157,29 +157,18 @@ void cRDSReceiver::Receive(const uchar *Data, int Length) if (crc16 != (mtext[index - 2] << 8) + mtext[index - 1]) { if ((S_Verbose & 0x0f) >= 1) { printf( - "RDS-Error: wrong CRC # calc = %04x <> transmit = %02x%02x\n", + "rdsreceiver: RDS-Error: wrong CRC # calc = %04x <> transmit = %02x%02x\n", crc16, mtext[index - 2], mtext[index - 1]); } } else { switch (mec) { case 0x0a: - RadioAudio->RadiotextDecode(mtext, index); // Radiotext + RadioAudio->RadiotextDecode(mtext); // Radiotext break; case 0x46: switch ((mtext[7] << 8) + mtext[8]) { // ODA-ID case 0x4bd7: - RadioAudio->RadiotextDecode(mtext, index); // RT+ - break; - case 0x0d45: - case 0xcd46: - if ((S_Verbose & 0x20) > 0) { - unsigned char tmc[6]; // TMC Alert-C - int i; - for (i = 9; i <= (index - 3); i++) { - tmc[i - 9] = mtext[i]; - } - tmc_parser(tmc, i - 8); - } + RadioAudio->RadiotextDecode(mtext); // RT+ break; default: if ((S_Verbose & 0x0f) >= 2) { @@ -202,16 +191,6 @@ void cRDSReceiver::Receive(const uchar *Data, int Length) case 0x02: RadioAudio->RDS_PsPtynDecode(false, mtext, index); // PS break; - case 0x30: - if ((S_Verbose & 0x20) > 0) { // TMC Alert-C - unsigned char tmc[6]; - int i; - for (i = 7; i <= (index - 3); i++) { - tmc[i - 7] = mtext[i]; - } - tmc_parser(tmc, i - 6); - } - break; } } } diff --git a/rtpluslist.c b/rtpluslist.c index d7f4728..ca592d0 100644 --- a/rtpluslist.c +++ b/rtpluslist.c @@ -32,8 +32,7 @@ void cRTplusList::Load(void) { struct tm *ts, tm_store; int ind, lfd = 0; char ctitle[80]; - // TODO - dsyslog("%s %d cRTplusList::Load", __FILE__, __LINE__); + ts = localtime_r(&rtp_content.start, &tm_store); switch (typ) { case 0: diff --git a/rtplusosd.c b/rtplusosd.c index 61d2ed3..4e72a7e 100644 --- a/rtplusosd.c +++ b/rtplusosd.c @@ -30,8 +30,6 @@ cRTplusOsd::cRTplusOsd(void) : Load(); Display(); -// TODO -dsyslog("%s %d cRTplusOsd::cRTplusOsd ", __FILE__, __LINE__); } cRTplusOsd::~cRTplusOsd() { |