message, msg_queue, msg_handler

This commit is contained in:
Max 2022-09-20 15:00:31 -04:00
parent dc90a85c02
commit f010f3f5dc
9 changed files with 714 additions and 0 deletions

View File

@ -0,0 +1,82 @@
/* -*- c++ -*- */
/*
* Copyright 2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef INCLUDED_OP25_MESSAGE_H
#define INCLUDED_OP25_MESSAGE_H
#include <op25/api.h>
#include <gnuradio/types.h>
#include <string>
namespace gr {
namespace op25 {
/*!
* \brief Message class.
*
* \ingroup misc
* The ideas and method names for adjustable message length were
* lifted from the click modular router "Packet" class.
*/
class OP25_API message
{
public:
typedef std::shared_ptr<message> sptr;
private:
sptr d_next; // link field for msg queue
long d_type; // type of the message
double d_arg1; // optional arg1
double d_arg2; // optional arg2
std::vector<unsigned char> d_buf;
unsigned char* d_msg_start; // where the msg starts
unsigned char* d_msg_end; // one beyond end of msg
message(long type, double arg1, double arg2, size_t length);
friend class msg_queue;
unsigned char* buf_data() { return d_buf.data(); }
size_t buf_len() const { return d_buf.size(); }
public:
/*!
* \brief public constructor for message
*/
static sptr make(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
static sptr make_from_string(const std::string s,
long type = 0,
double arg1 = 0,
double arg2 = 0);
~message();
long type() const { return d_type; }
double arg1() const { return d_arg1; }
double arg2() const { return d_arg2; }
void set_type(long type) { d_type = type; }
void set_arg1(double arg1) { d_arg1 = arg1; }
void set_arg2(double arg2) { d_arg2 = arg2; }
unsigned char* msg() const { return d_msg_start; }
size_t length() const { return d_msg_end - d_msg_start; }
std::string to_string() const;
};
OP25_API long message_ncurrently_allocated();
} /* namespace op25 */
} /* namespace gr */
#endif /* INCLUDED_OP25_MESSAGE_H */

View File

@ -0,0 +1,39 @@
/* -*- c++ -*- */
/*
* Copyright 2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef INCLUDED_OP25_MSG_HANDLER_H
#define INCLUDED_OP25_MSG_HANDLER_H
#include <op25/api.h>
#include <op25/message.h>
namespace gr {
namespace op25 {
class msg_handler;
typedef std::shared_ptr<msg_handler> msg_handler_sptr;
/*!
* \brief abstract class of message handlers
* \ingroup base
*/
class OP25_API msg_handler
{
public:
virtual ~msg_handler();
//! handle \p msg
virtual void handle(message::sptr msg) = 0;
};
} /* namespace op25 */
} /* namespace gr */
#endif /* INCLUDED_OP25_MSG_HANDLER_H */

View File

@ -0,0 +1,85 @@
/* -*- c++ -*- */
/*
* Copyright 2005,2009 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef INCLUDED_OP25_MSG_QUEUE_H
#define INCLUDED_OP25_MSG_QUEUE_H
#include <op25/api.h>
#include <op25/msg_handler.h>
#include <gnuradio/thread/thread.h>
namespace gr {
namespace op25 {
/*!
* \brief thread-safe message queue
* \ingroup misc
*/
class OP25_API msg_queue : public msg_handler
{
gr::thread::mutex d_mutex;
gr::thread::condition_variable d_not_empty;
gr::thread::condition_variable d_not_full;
message::sptr d_head;
message::sptr d_tail;
unsigned int d_count; // # of messages in queue.
unsigned int d_limit; // max # of messages in queue. 0 -> unbounded
public:
typedef std::shared_ptr<msg_queue> sptr;
static sptr make(unsigned int limit = 0);
msg_queue(unsigned int limit);
~msg_queue() override;
//! Generic msg_handler method: insert the message.
void handle(message::sptr msg) override { insert_tail(msg); }
/*!
* \brief Insert message at tail of queue.
* \param msg message
*
* Block if queue if full.
*/
void insert_tail(message::sptr msg);
/*!
* \brief Delete message from head of queue and return it.
* Block if no message is available.
*/
message::sptr delete_head();
/*!
* \brief If there's a message in the q, delete it and return it.
* If no message is available, return 0.
*/
message::sptr delete_head_nowait();
//! Delete all messages from the queue
void flush();
//! is the queue empty?
bool empty_p() const { return d_count == 0; }
//! is the queue full?
bool full_p() const { return d_limit != 0 && d_count >= d_limit; }
//! return number of messages in queue
unsigned int count() const { return d_count; }
//! return limit on number of message in queue. 0 -> unbounded
unsigned int limit() const { return d_limit; }
};
} /* namespace op25 */
} /* namespace gr */
#endif /* INCLUDED_OP25_MSG_QUEUE_H */

View File

@ -0,0 +1,63 @@
/* -*- c++ -*- */
/*
* Copyright 2005 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/message.h>
#include <cassert>
#include <cstring>
namespace gr {
namespace op25 {
static long s_ncurrently_allocated = 0;
message::sptr message::make(long type, double arg1, double arg2, size_t length)
{
return message::sptr(new message(type, arg1, arg2, length));
}
message::sptr
message::make_from_string(const std::string s, long type, double arg1, double arg2)
{
message::sptr m = message::make(type, arg1, arg2, s.size());
memcpy(m->msg(), s.data(), s.size());
return m;
}
message::message(long type, double arg1, double arg2, size_t length)
: d_type(type), d_arg1(arg1), d_arg2(arg2), d_buf(length)
{
if (length == 0)
d_msg_start = d_msg_end = nullptr;
else {
d_msg_start = d_buf.data();
d_msg_end = d_msg_start + length;
}
s_ncurrently_allocated++;
}
message::~message()
{
assert(d_next == 0);
s_ncurrently_allocated--;
}
std::string message::to_string() const
{
return std::string((char*)d_msg_start, length());
}
long message_ncurrently_allocated() { return s_ncurrently_allocated; }
} /* namespace op25 */
} /* namespace gr */

View File

@ -0,0 +1,23 @@
/* -*- c++ -*- */
/*
* Copyright 2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <op25/msg_handler.h>
namespace gr {
namespace op25 {
msg_handler::~msg_handler() {}
} /* namespace op25 */
} /* namespace gr */

View File

@ -0,0 +1,113 @@
/* -*- c++ -*- */
/*
* Copyright 2005,2009,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/msg_queue.h>
#include <stdexcept>
namespace gr {
namespace op25 {
msg_queue::sptr msg_queue::make(unsigned int limit)
{
return msg_queue::sptr(new msg_queue(limit));
}
msg_queue::msg_queue(unsigned int limit)
: d_not_empty(),
d_not_full(),
/*d_head(0), d_tail(0),*/ d_count(0),
d_limit(limit)
{
}
msg_queue::~msg_queue() { flush(); }
void msg_queue::insert_tail(message::sptr msg)
{
if (msg->d_next)
throw std::invalid_argument("gr::msg_queue::insert_tail: msg already in queue");
gr::thread::scoped_lock guard(d_mutex);
while (full_p())
d_not_full.wait(guard);
if (d_tail == 0) {
d_tail = d_head = msg;
// msg->d_next = 0;
msg->d_next.reset();
} else {
d_tail->d_next = msg;
d_tail = msg;
// msg->d_next = 0;
msg->d_next.reset();
}
d_count++;
d_not_empty.notify_one();
}
message::sptr msg_queue::delete_head()
{
gr::thread::scoped_lock guard(d_mutex);
message::sptr m;
while ((m = d_head) == 0)
d_not_empty.wait(guard);
d_head = m->d_next;
if (d_head == 0) {
// d_tail = 0;
d_tail.reset();
}
d_count--;
// m->d_next = 0;
m->d_next.reset();
d_not_full.notify_one();
return m;
}
message::sptr msg_queue::delete_head_nowait()
{
gr::thread::scoped_lock guard(d_mutex);
message::sptr m;
if ((m = d_head) == 0) {
// return 0;
return message::sptr();
}
d_head = m->d_next;
if (d_head == 0) {
// d_tail = 0;
d_tail.reset();
}
d_count--;
// m->d_next = 0;
m->d_next.reset();
d_not_full.notify_one();
return m;
}
void msg_queue::flush()
{
message::sptr m;
while ((m = delete_head_nowait()) != 0)
;
}
} /* namespace op25 */
} /* namespace gr */

View File

@ -0,0 +1,129 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(message.h) */
/* BINDTOOL_HEADER_FILE_HASH(e324acfee988515a91a4759680dbabbf) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/op25/message.h>
// pydoc.h is automatically generated in the build directory
#include <message_pydoc.h>
void bind_message(py::module& m)
{
using message = ::gr::op25::message;
py::class_<message,
std::shared_ptr<message>>(m, "message", D(message))
.def(py::init(&message::make),
py::arg("type") = 0,
py::arg("arg1") = 0,
py::arg("arg2") = 0,
py::arg("length") = 0,
D(message,make)
)
.def_static("make_from_string",&message::make_from_string,
py::arg("s"),
py::arg("type") = 0,
py::arg("arg1") = 0,
py::arg("arg2") = 0,
D(message,make_from_string)
)
.def("type",&message::type,
D(message,type)
)
.def("arg1",&message::arg1,
D(message,arg1)
)
.def("arg2",&message::arg2,
D(message,arg2)
)
.def("set_type",&message::set_type,
py::arg("type"),
D(message,set_type)
)
.def("set_arg1",&message::set_arg1,
py::arg("arg1"),
D(message,set_arg1)
)
.def("set_arg2",&message::set_arg2,
py::arg("arg2"),
D(message,set_arg2)
)
.def("msg",&message::msg,
D(message,msg)
)
.def("to_string",&message::to_string,
D(message,to_string)
)
;
m.def("message_ncurrently_allocated",&::gr::op25::message_ncurrently_allocated,
D(message_ncurrently_allocated)
);
}

View File

@ -0,0 +1,64 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(msg_handler.h) */
/* BINDTOOL_HEADER_FILE_HASH(668ae41ad9b9d463886fcf60a87e9ede) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/op25/msg_handler.h>
// pydoc.h is automatically generated in the build directory
#include <msg_handler_pydoc.h>
void bind_msg_handler(py::module& m)
{
using msg_handler = ::gr::op25::msg_handler;
py::class_<msg_handler,
std::shared_ptr<msg_handler>>(m, "msg_handler", D(msg_handler))
// .def(py::init<>(),D(msg_handler,msg_handler,0))
// .def(py::init<gr::op25::msg_handler const &>(), py::arg("arg0"),
// D(msg_handler,msg_handler,1)
// )
.def("handle",&msg_handler::handle,
py::arg("msg"),
D(msg_handler,handle)
)
;
}

View File

@ -0,0 +1,116 @@
/*
* Copyright 2022 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
/***********************************************************************************/
/* This file is automatically generated using bindtool and can be manually edited */
/* The following lines can be configured to regenerate this file during cmake */
/* If manual edits are made, the following tags should be modified accordingly. */
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(msg_queue.h) */
/* BINDTOOL_HEADER_FILE_HASH(3f70adbde5e636fca8dc78e0505b06fd) */
/***********************************************************************************/
#include <pybind11/complex.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
#include <gnuradio/op25/msg_queue.h>
// pydoc.h is automatically generated in the build directory
#include <msg_queue_pydoc.h>
void bind_msg_queue(py::module& m)
{
using msg_queue = ::gr::op25::msg_queue;
py::class_<msg_queue,
std::shared_ptr<msg_queue>>(m, "msg_queue", D(msg_queue))
.def(py::init(&msg_queue::make),
py::arg("limit") = 0,
D(msg_queue,make)
)
.def("handle",&msg_queue::handle,
py::arg("msg"),
D(msg_queue,handle)
)
.def("insert_tail",&msg_queue::insert_tail,
py::arg("msg"),
D(msg_queue,insert_tail)
)
.def("delete_head",&msg_queue::delete_head, py::call_guard<py::gil_scoped_release>(),
D(msg_queue,delete_head)
)
.def("delete_head_nowait",&msg_queue::delete_head_nowait,
D(msg_queue,delete_head_nowait)
)
.def("flush",&msg_queue::flush,
D(msg_queue,flush)
)
.def("empty_p",&msg_queue::empty_p,
D(msg_queue,empty_p)
)
.def("full_p",&msg_queue::full_p,
D(msg_queue,full_p)
)
.def("count",&msg_queue::count,
D(msg_queue,count)
)
.def("limit",&msg_queue::limit,
D(msg_queue,limit)
)
;
}