Fix long standing hang when exiting due to blocking read in gr-pager.
[debian/gnuradio] / gr-pager / src / pager_flex_parse.cc
index 7d2b309ffc8490a29a2243fc07763e7752a5fe66..7178ba516cfa72e45d9c14e5f6ffb63f98aff905 100644 (file)
 #include <pager_flex_parse.h>
 #include <pageri_bch3221.h>
 #include <gr_io_signature.h>
+#include <ctype.h>
+#include <iostream>
 
-pager_flex_parse_sptr pager_make_flex_parse()
+pager_flex_parse_sptr pager_make_flex_parse(gr_msg_queue_sptr queue)
 {
-    return pager_flex_parse_sptr(new pager_flex_parse());
+    return pager_flex_parse_sptr(new pager_flex_parse(queue));
 }
 
-pager_flex_parse::pager_flex_parse() :
+pager_flex_parse::pager_flex_parse(gr_msg_queue_sptr queue) :
     gr_sync_block("flex_parse",
-    gr_make_io_signature(1, 1, sizeof(gr_int32)),
-    gr_make_io_signature(0, 0, 0))
+       gr_make_io_signature(1, 1, sizeof(gr_int32)),
+       gr_make_io_signature(0, 0, 0)),
+    d_queue(queue)
 {
     d_count = 0;
 }
@@ -91,7 +94,7 @@ void pager_flex_parse::parse_data()
     int voffset = (biw >> 10) & 0x3f;
     int aoffset = ((biw >> 8) & 0x03) + 1;
     
-//  printf("BIW=%08X A=%i V=%i\n", biw, aoffset, voffset);
+    //printf("BIW:%08X AW:%02i-%02i\n", biw, aoffset, voffset);
 
     // Iterate through pages and dispatch to appropriate handler
     for (int i = aoffset; i < voffset; i++) {
@@ -127,41 +130,108 @@ void pager_flex_parse::parse_data()
        if (mw1 > 87 || mw2 > 87)
            continue;                           // Invalid offsets
 
-       printf("%09i: ", d_capcode);
+       d_payload.str("");
+       d_payload << d_capcode << FIELD_DELIM << d_type << FIELD_DELIM;
 
        if (is_alphanumeric_page(d_type))
-           parse_alphanumeric(mw1, mw2-1);
+           parse_alphanumeric(mw1, mw2-1, j);
        else if (is_numeric_page(d_type))
-           parse_numeric(mw1, mw2);
+           parse_numeric(mw1, mw2, j);
        else if (is_tone_page(d_type))
            parse_tone_only();
        else
            parse_unknown(mw1, mw2);
 
-       printf("\n");
+       //std::cout << d_payload.str() << std::endl;
+       //fflush(stdout);
+
+       gr_message_sptr msg = gr_make_message_from_string(std::string(d_payload.str()));
+       d_queue->handle(msg);
     }
 }
 
-void pager_flex_parse::parse_alphanumeric(int mw1, int mw2)
+void pager_flex_parse::parse_alphanumeric(int mw1, int mw2, int j)
 {
-    printf("ALPHA");
+    int frag;
+    bool cont;
 
-    for (int i = mw1; i < mw2; i++) {
+    if (!d_laddr) {
+       frag = (d_datawords[mw1] >> 11) & 0x03;
+       cont = (d_datawords[mw1] >> 10) & 0x01;
+       mw1++;
+    }
+    else {
+       frag = (d_datawords[j+1] >> 11) & 0x03;
+       cont = (d_datawords[j+1] >> 10) & 0x01;
+       mw2--;
+    }    
+
+    d_payload << frag << FIELD_DELIM;
+    d_payload << cont << FIELD_DELIM;
+
+    for (int i = mw1; i <= mw2; i++) {
+       gr_int32 dw = d_datawords[i];
+       unsigned char ch;
+       
+       if (i > mw1 || frag != 0x03) {
+           ch = dw & 0x7F;
+           if (ch != 0x03)
+               d_payload << ch;
+       }
        
+       ch = (dw >> 7) & 0x7F;
+       if (ch != 0x03) // Fill
+           d_payload << ch;
+               
+       ch = (dw >> 14) & 0x7F;
+       if (ch != 0x03) // Fill
+           d_payload << ch;
     }
 }
 
-void pager_flex_parse::parse_numeric(int mw1, int mw2)
+void pager_flex_parse::parse_numeric(int mw1, int mw2, int j)
 {
-    printf("NUMERIC");
+    // Get first dataword from message field or from second
+    // vector word if long address
+    gr_int32 dw;
+    if (!d_laddr) {
+       dw = d_datawords[mw1];
+       mw1++;
+       mw2++;
+    }
+    else {
+       dw = d_datawords[j+1];
+    }
+
+    unsigned char digit = 0;
+    int count = 4;
+    if (d_type == FLEX_NUMBERED_NUMERIC)
+       count += 10;    // Skip 10 header bits for numbered numeric pages
+    else
+       count += 2;     // Otherwise skip 2
+    
+    for (int i = mw1; i <= mw2; i++) {
+       for (int k = 0; k < 21; k++) {
+           // Shift LSB from data word into digit
+           digit = (digit >> 1) & 0x0F;
+           if (dw & 0x01)
+               digit ^= 0x08;
+           dw >>= 1;
+           if (--count == 0) {
+               if (digit != 0x0C) // Fill
+                    d_payload << flex_bcd[digit];
+               count = 4;
+           }
+       }
+       
+       dw = d_datawords[i];
+    }
 }
 
 void pager_flex_parse::parse_tone_only()
 {
-    printf("TONE");
 }
 
 void pager_flex_parse::parse_unknown(int mw1, int mw2)
 {
-    printf("UNKNOWN");
 }