/* Copyright 2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <cdma/packet_header2.h>
namespace gr {
namespace cdma {
packet_header2::sptr
packet_header2::make(
long header_len,
const std::string &len_tag_key,
const std::string &num_tag_key,
int bits_per_byte,
int mod_type,
const std::string &mod_tag_key,
int code_type,
const std::string &code_tag_key)
{
return packet_header2::sptr(new packet_header2(header_len, len_tag_key, num_tag_key, bits_per_byte,mod_type, mod_tag_key, code_type, code_tag_key));
}
packet_header2::packet_header2(
long header_len,
const std::string &len_tag_key,
const std::string &num_tag_key,
int bits_per_byte,
int mod_type,
const std::string &mod_tag_key,
int code_type,
const std::string &code_tag_key
): gr::digital::packet_header_default(
header_len,
len_tag_key,
num_tag_key,
bits_per_byte),
d_mod_type(mod_type),
d_code_type(code_type),
d_mod_tag_key(pmt::string_to_symbol(mod_tag_key)),
d_code_tag_key(pmt::string_to_symbol(code_tag_key))
{
}
packet_header2::~packet_header2()
{
}
bool packet_header2::header_formatter(
long packet_len,
unsigned char *out,
const std::vector<tag_t> &tags
)
{
packet_len &= 0x0FFF;
d_crc_impl.reset();
d_crc_impl.process_bytes((void const *) &packet_len, 2);
d_crc_impl.process_bytes((void const *) &d_mod_type, 2);
d_crc_impl.process_bytes((void const *) &d_code_type, 2);
d_crc_impl.process_bytes((void const *) &d_header_number, 2);
unsigned char crc = d_crc_impl();
memset(out, 0x00, d_header_len);
int k = 0; // Position in out
for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) {
out[k] = (unsigned char) ((packet_len >> i) & d_mask);
}
for (int i = 0; i < 2 && k < d_header_len; i += d_bits_per_byte, k++) {
out[k] = (unsigned char) ((d_mod_type >> i) & d_mask);
}
for (int i = 0; i < 2 && k < d_header_len; i += d_bits_per_byte, k++) {
out[k] = (unsigned char) ((d_code_type >> i) & d_mask);
}
for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) {
out[k] = (unsigned char) ((d_header_number >> i) & d_mask);
}
for (int i = 0; i < 8 && k < d_header_len; i += d_bits_per_byte, k++) {
out[k] = (unsigned char) ((crc >> i) & d_mask);
}
d_header_number++;
d_header_number &= 0x0FFF;
return true;
}
bool packet_header2::header_parser(
const unsigned char *in,
std::vector<tag_t> &tags)
{
unsigned header_len = 0;
int mod_type = 0;
int code_type =0;
unsigned header_num = 0;
tag_t tag;
int k = 0; // Position in "in"
for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) {
header_len |= (((int) in[k]) & d_mask) << i;
}
tag.key = d_len_tag_key;
tag.value = pmt::from_long(header_len);
tags.push_back(tag);
if (k >= d_header_len) {
return true;
}
for (int i = 0; i < 2 && k < d_header_len; i += d_bits_per_byte, k++) {
mod_type |= (((int) in[k]) & d_mask) << i;
}
tag.key = d_mod_tag_key;
tag.value = pmt::from_long(mod_type);
tags.push_back(tag);
for (int i = 0; i < 2 && k < d_header_len; i += d_bits_per_byte, k++) {
code_type |= (((int) in[k]) & d_mask) << i;
}
tag.key = d_code_tag_key;
tag.value = pmt::from_long(code_type);
tags.push_back(tag);
if (d_num_tag_key == pmt::PMT_NIL) {
k += 12;
} else {
for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) {
header_num |= (((int) in[k]) & d_mask) << i;
}
tag.key = d_num_tag_key;
tag.value = pmt::from_long(header_num);
tags.push_back(tag);
}
if (k >= d_header_len) {
return true;
}
d_crc_impl.reset();
d_crc_impl.process_bytes((void const *) &header_len, 2);
d_crc_impl.process_bytes((void const *) &mod_type, 2);
d_crc_impl.process_bytes((void const *) &code_type, 2);
d_crc_impl.process_bytes((void const *) &header_num, 2);
unsigned char crc_calcd = d_crc_impl();
for (int i = 0; i < 8 && k < d_header_len; i += d_bits_per_byte, k++) {
if ( (((int) in[k]) & d_mask) != (((int) crc_calcd >> i) & d_mask) ) {
return false;
}
}
return true;
}
} /* namespace cdma */
} /* namespace gr */
/* -*- c++ -*- */
/* Copyright 2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_CDMA_PACKET_HEADER2_H
#define INCLUDED_CDMA_PACKET_HEADER2_H
#include <gnuradio/tags.h>
#include <cdma/api.h>
//#include <cdma/packet_header.h>
#include <gnuradio/digital/packet_header_default.h>
//#include <boost/enable_shared_from_this.hpp>
//#include <boost/crc.hpp>
namespace gr {
namespace cdma {
/*!
* \brief Default header formatter for digital packet transmission.
* \ingroup packet_operators_blk
*
* \details
* For bursty/packetized digital transmission, packets are usually prepended
* with a packet header, containing the number of bytes etc.
* This class is not a block, but a tool to create these packet header.
*
* This is a default packet header (see header_formatter()) for a description
* on the header format). To create other header, derive packet header creator
* classes from this function.
*
* gr::digital::packet_headergenerator_bb uses header generators derived from
* this class to create packet headers from data streams.
*/
class CDMA_API packet_header2 : virtual public gr::digital::packet_header_default
{
public:
typedef boost::shared_ptr<packet_header2> sptr;
packet_header2(
long header_len,
const std::string &len_tag_key="packet_len",
const std::string &num_tag_key="packet_num",
int bits_per_byte=1,
int mod_type=1,
const std::string &mod_tag_key="mod_type_tag",
int code_type=1,
const std::string &code_tag_key="code_type_tag");
~packet_header2();
void set_mod_type(int mod_type){d_mod_type = mod_type; };
void set_code_type(int code_type){d_code_type = code_type; };
//pmt::pmt_t len_tag_key() { return d_len_tag_key; };
/*!
* \brief Encodes the header information in the given tags into bits and places them into \p out
*
* Uses the following header format:
* Bits 0-11: The packet length (what was stored in the tag with key \p len_tag_key)
* Bits 12-13: The modulation type
* Bits 14-15: The coding type
* Bits 16-27: The header number (counts up everytime this function is called)
* Bit 28-35: 8-Bit CRC
* All other bits: Are set to zero
*
* If the header length is smaller than 36, bits are simply left out. For this
* reason, they always start with the LSB.
*
* However, it is recommended to stay above 36 Bits, in order to have a working
* CRC.
*/
bool header_formatter(
long packet_len,
unsigned char *out,
const std::vector<tag_t> &tags=std::vector<tag_t>()
);
/*!
* \brief Inverse function to header_formatter().
*
* Reads the bit stream in \p header and writes a corresponding tag into \p tags.
*/
bool header_parser(
const unsigned char *header,
std::vector<tag_t> &tags);
static sptr make(
long header_len,
const std::string &len_tag_key="packet_len",
const std::string &num_tag_key="packet_num",
int bits_per_byte=1,
int mod_type=1,
const std::string &mod_tag_key="mod_type_tag",
int code_type=1,
const std::string &code_tag_key="code_type_tag");
protected:
pmt::pmt_t d_mod_tag_key;
pmt::pmt_t d_code_tag_key;
int d_mod_type;
int d_code_type;
};
} // namespace cdma
} // namespace gr
#endif /* INCLUDED_CDMA_PACKET_HEADER2_H */
No comments:
Post a Comment