From 4e1be5ee44057d17de80c67654ab49fea5b2efd5 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Mon, 21 Mar 2016 02:23:28 +0200 Subject: [PATCH 1/2] Add a TCP rigctl message command accepter block. The purpose of this block is to grab rigctl compatible commands from the gr-satnogs client software and use the set_freq command in order to compensate the doppler shift effect. --- grc/CMakeLists.txt | 3 +- grc/satnogs_tcp_rigctl_msg_source.xml | 34 ++++ include/satnogs/CMakeLists.txt | 3 +- include/satnogs/tc_tm.h | 224 ++++++++++++++++++++--- include/satnogs/tcp_rigctl_msg_source.h | 60 +++++++ lib/CMakeLists.txt | 2 +- lib/tc_tm.cc | 230 ------------------------ lib/tcp_rigctl_msg_source_impl.cc | 192 ++++++++++++++++++++ lib/tcp_rigctl_msg_source_impl.h | 56 ++++++ swig/satnogs_swig.i | 5 +- 10 files changed, 554 insertions(+), 255 deletions(-) create mode 100644 grc/satnogs_tcp_rigctl_msg_source.xml create mode 100644 include/satnogs/tcp_rigctl_msg_source.h delete mode 100644 lib/tc_tm.cc create mode 100644 lib/tcp_rigctl_msg_source_impl.cc create mode 100644 lib/tcp_rigctl_msg_source_impl.h diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index 2f59ac8..86b312b 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -27,5 +27,6 @@ install(FILES satnogs_ax25_encoder_bf.xml satnogs_ax25_decoder_b.xml satnogs_udp_msg_source.xml - satnogs_debug_msg_source.xml DESTINATION share/gnuradio/grc/blocks + satnogs_debug_msg_source.xml + satnogs_tcp_rigctl_msg_source.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/satnogs_tcp_rigctl_msg_source.xml b/grc/satnogs_tcp_rigctl_msg_source.xml new file mode 100644 index 0000000..8e2d886 --- /dev/null +++ b/grc/satnogs_tcp_rigctl_msg_source.xml @@ -0,0 +1,34 @@ + + + TCP rigctl Message Source + satnogs_tcp_rigctl_msg_source + satnogs + import satnogs + satnogs.tcp_rigctl_msg_source($addr, $port, $mtu) + + + IP Address + addr + "127.0.0.1" + string + + + + Listen port + port + 16886 + int + + + + MTU + mtu + 1500 + int + + + + freq + message + + \ No newline at end of file diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 29d7d77..24b753e 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -39,5 +39,6 @@ install(FILES ax25_decoder_b.h udp_msg_source.h debug_msg_source.h - tc_tm.h DESTINATION include/satnogs + tc_tm.h + tcp_rigctl_msg_source.h DESTINATION include/satnogs ) diff --git a/include/satnogs/tc_tm.h b/include/satnogs/tc_tm.h index 6196f53..4227b5d 100644 --- a/include/satnogs/tc_tm.h +++ b/include/satnogs/tc_tm.h @@ -133,12 +133,12 @@ namespace gr */ typedef enum { - R_OBC_PKT_ILLEGAL_APPID = 0, //!< R_OBC_PKT_ILLEGAL_APPID illegal application ID + R_OBC_PKT_ILLEGAL_APPID = 0, //!< R_OBC_PKT_ILLEGAL_APPID illegal application ID R_OBC_PKT_INV_LEN = 1, //!< R_OBC_PKT_INV_LEN invalid length R_OBC_PKT_INC_CRC = 2, //!< R_OBC_PKT_INC_CRC incorrect CRC R_OBC_PKT_ILLEGAL_PKT_TP = 3, //!< R_OBC_PKT_ILLEGAL_PKT_TP R_OBC_PKT_ILLEGAL_PKT_STP = 4, //!< R_OBC_PKT_ILLEGAL_PKT_STP - R_OBC_PKT_ILLEGAL_APP_DATA = 5,//!< R_OBC_PKT_ILLEGAL_APP_DATA + R_OBC_PKT_ILLEGAL_APP_DATA = 5, //!< R_OBC_PKT_ILLEGAL_APP_DATA R_OBC_OK = 6, //!< R_OBC_OK All ok R_OBC_ERROR = 7, //!< R_OBC_ERROR an error occured R_OBC_EOT = 8, //!< R_OBC_EOT End-of-transfer @@ -174,33 +174,217 @@ namespace gr uint16_t dest_id; uint8_t *data; /* variable data, this should be fixed array */ - uint8_t padding; /* x bits, padding for word alligment */ + uint8_t padding; /* x bits, padding for word alligment */ uint16_t crc; /* CRC or checksum, mission specific*/ } tc_tm_pkt; - extern const uint8_t services_verification_TC_TM[MAX_SERVICES][MAX_SUBTYPES][2]; - extern const uint8_t app_id_verification[MAX_APP_ID]; - extern const uint8_t services_verification_OBC_TC[MAX_SERVICES][MAX_SUBTYPES]; + /* + extern const uint8_t services_verification_TC_TM[MAX_SERVICES][MAX_SUBTYPES][2]; + extern const uint8_t app_id_verification[MAX_APP_ID]; + extern const uint8_t services_verification_OBC_TC[MAX_SERVICES][MAX_SUBTYPES]; - extern OBC_ret_state_t - verification_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt, - uint16_t *buf_pointer); - extern OBC_ret_state_t - hk_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *buf_pointer); + extern OBC_ret_state_t + verification_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt, + uint16_t *buf_pointer); + extern OBC_ret_state_t + hk_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *buf_pointer); + */ - uint8_t - checkSum (const uint8_t *data, uint16_t size); + static inline uint8_t + ecss_tm_checksum (const uint8_t *data, uint16_t size) + { + uint8_t CRC = 0; + for (int i = 0; i <= size; i++) { + CRC = CRC ^ data[i]; + } + return CRC; + } - OBC_ret_state_t - unpack_pkt (const uint8_t *buf, tc_tm_pkt *pkt, const uint16_t size); + /*Must check for endianess*/ + static inline OBC_ret_state_t + ecss_tm_unpack_pkt (const uint8_t *buf, tc_tm_pkt *pkt, const uint16_t size) + { + union _cnv cnv; + uint8_t tmp_crc[2]; - OBC_ret_state_t - pack_pkt (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *size); + uint8_t ver, dfield_hdr, ccsds_sec_hdr, tc_pus; - OBC_ret_state_t - crt_pkt (tc_tm_pkt *pkt, uint16_t app_id, uint8_t type, uint8_t ack, - uint8_t ser_type, uint8_t ser_subtype, uint16_t dest_id); + tmp_crc[0] = buf[size - 1]; + tmp_crc[1] = checkSum (buf, size - 2); + + ver = buf[0] >> 5; + + pkt->type = (buf[0] >> 4) & 0x01; + dfield_hdr = (buf[0] >> 3) & 0x01; + + cnv.cnv8[0] = buf[1]; + cnv.cnv8[1] = 0x07 & buf[0]; + pkt->app_id = cnv.cnv16[0]; + + pkt->seq_flags = buf[2] >> 6; + + cnv.cnv8[0] = buf[3]; + cnv.cnv8[1] = buf[2] & 0x3F; + pkt->seq_count = cnv.cnv16[0]; + + cnv.cnv8[0] = buf[4]; + cnv.cnv8[1] = buf[5]; + pkt->len = cnv.cnv16[0]; + + ccsds_sec_hdr = buf[6] >> 7; + + tc_pus = buf[6] >> 4; + + pkt->ack = 0x04 & buf[6]; + + pkt->ser_type = buf[7]; + pkt->ser_subtype = buf[8]; + pkt->dest_id = buf[9]; + + if (app_id_verification[pkt->app_id] != 1) { + return R_OBC_PKT_ILLEGAL_APPID; + } + + if (pkt->len != size - 7) { + return R_OBC_PKT_INV_LEN; + } + + if (tmp_crc[0] != tmp_crc[1]) { + return R_OBC_PKT_INC_CRC; + } + + if (services_verification_TC_TM[pkt->ser_type][pkt->ser_subtype][pkt->type] + != 1) { + return R_OBC_PKT_ILLEGAL_PKT_TP; + } + + if (ver != 0) { + return R_OBC_ERROR; + } + + if (tc_pus != 1) { + return R_OBC_ERROR; + } + + if (ccsds_sec_hdr != 0) { + return R_OBC_ERROR; + } + + if (pkt->type != TC && pkt->type != TM) { + return R_OBC_ERROR; + } + + if (dfield_hdr != 1) { + return R_OBC_ERROR; + } + + if (pkt->ack != TC_ACK_NO || pkt->ack != TC_ACK_ACC + || pkt->ack != TC_ACK_EXE_COMP) { + return R_OBC_ERROR; + } + + for (int i = 0; i < pkt->len - 4; i++) { + pkt->data[i] = buf[10 + i]; + } + + return R_OBC_OK; + } + + /** + * Packs a TC packet into a byte buffer + * @param buf buffer to store the data to be sent + * @param pkt the data to be stored in the buffer + * @param size size of the array + * @return appropriate error code or R_OBC_OK if all operation succeed + */ + static inline OBC_ret_state_t + ecss_tm_pack_pkt (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *size) + { + + union _cnv cnv; + uint8_t buf_pointer; + + cnv.cnv16[0] = pkt->app_id; + + buf[0] = ( ECSS_VER_NUMBER << 5 | pkt->type << 4 + | ECSS_DATA_FIELD_HDR_FLG << 3 | cnv.cnv8[1]); + buf[1] = cnv.cnv8[0]; + + cnv.cnv16[0] = pkt->seq_count; + buf[2] = (pkt->seq_flags << 6 | cnv.cnv8[1]); + buf[3] = cnv.cnv8[0]; + + /* TYPE = 0 TM, TYPE = 1 TC*/ + if (pkt->type == TM) { + buf[6] = ECSS_PUS_VER << 4; + } + else if (pkt->type == TC) { + buf[6] = ( ECSS_SEC_HDR_FIELD_FLG << 7 | ECSS_PUS_VER << 4 | pkt->ack); + } + else { + return R_OBC_ERROR; + } + + buf[7] = pkt->ser_type; + buf[8] = pkt->ser_subtype; + buf[9] = pkt->dest_id; /*source or destination*/ + + buf_pointer = 10; + + if (pkt->ser_type == TC_VERIFICATION_SERVICE) { + //cnv.cnv16[0] = tc_pkt_id; + //cnv.cnv16[1] = tc_pkt_seq_ctrl; + + /*verification_pack_pkt_api (buf, pkt, &buf_pointer);*/ + + } + else if (pkt->ser_type == TC_HOUSEKEEPING_SERVICE) { + + /*hk_pack_pkt_api (buf, pkt, &buf_pointer);*/ + + } + else if (pkt->ser_type == TC_FUNCTION_MANAGEMENT_SERVICE + && pkt->ser_subtype == 1) { + + buf[10] = pkt->data[0]; + + buf[11] = pkt->data[1]; + buf[12] = pkt->data[2]; + buf[13] = pkt->data[3]; + buf[14] = pkt->data[4]; + + buf_pointer += 5; + + } + else { + return R_OBC_ERROR; + } + + /*check if this is correct*/ + cnv.cnv16[0] = buf_pointer - 6; + buf[4] = cnv.cnv8[0]; + buf[5] = cnv.cnv8[1]; + + buf[buf_pointer] = checkSum (buf, buf_pointer - 1); + *size = buf_pointer; + return R_OBC_OK; + } + + static inline OBC_ret_state_t + ecss_tm_crt_pkt (tc_tm_pkt *pkt, uint16_t app_id, uint8_t type, uint8_t ack, + uint8_t ser_type, uint8_t ser_subtype, uint16_t dest_id) + { + + pkt->type = type; + pkt->app_id = app_id; + pkt->dest_id = dest_id; + + pkt->ser_type = ser_type; + pkt->ser_subtype = ser_subtype; + + return R_OBC_OK; + } } // namespace satnogs } // namespace gr diff --git a/include/satnogs/tcp_rigctl_msg_source.h b/include/satnogs/tcp_rigctl_msg_source.h new file mode 100644 index 0000000..4aaa54f --- /dev/null +++ b/include/satnogs/tcp_rigctl_msg_source.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_H +#define INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_H + +#include +#include + +namespace gr +{ + namespace satnogs + { + + /*! + * \brief Block that accepts TCP messages with rigctl commands. Depending + * the command contents this block produces an appropriate PMT message + * to control other blocks in the flowgraph + * \ingroup satnogs + * + */ + class SATNOGS_API tcp_rigctl_msg_source : virtual public gr::block + { + public: + typedef boost::shared_ptr sptr; + + + /** + * Rigctl TCP command accepter + * @param addr the address of the interface to listen at + * @param port the TCP port to listen for TCP connections + * @param mtu the maximum MTU + * @return + */ + static sptr + make (const std::string& addr, uint16_t port, size_t mtu = 1500); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 81f49e6..daafdec 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -37,7 +37,7 @@ list(APPEND satnogs_sources ax25_decoder_b_impl.cc udp_msg_source_impl.cc debug_msg_source_impl.cc - tc_tm.cc ) + tcp_rigctl_msg_source_impl.cc ) set(satnogs_sources "${satnogs_sources}" PARENT_SCOPE) if(NOT satnogs_sources) diff --git a/lib/tc_tm.cc b/lib/tc_tm.cc deleted file mode 100644 index a1ca5c9..0000000 --- a/lib/tc_tm.cc +++ /dev/null @@ -1,230 +0,0 @@ -/* -*- c++ -*- */ -/* - * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module - * - * Copyright (C) 2016, Libre Space Foundation - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -namespace gr -{ - namespace satnogs - { - - uint8_t - checkSum (const uint8_t *data, uint16_t size) - { - uint8_t CRC = 0; - for (int i = 0; i <= size; i++) { - CRC = CRC ^ data[i]; - } - return CRC; - } - - /*Must check for endianess*/ - OBC_ret_state_t - unpack_pkt (const uint8_t *buf, tc_tm_pkt *pkt, const uint16_t size) - { - union _cnv cnv; - uint8_t tmp_crc[2]; - - uint8_t ver, dfield_hdr, ccsds_sec_hdr, tc_pus; - - tmp_crc[0] = buf[size - 1]; - tmp_crc[1] = checkSum (buf, size - 2); - - ver = buf[0] >> 5; - - pkt->type = (buf[0] >> 4) & 0x01; - dfield_hdr = (buf[0] >> 3) & 0x01; - - cnv.cnv8[0] = buf[1]; - cnv.cnv8[1] = 0x07 & buf[0]; - pkt->app_id = cnv.cnv16[0]; - - pkt->seq_flags = buf[2] >> 6; - - cnv.cnv8[0] = buf[3]; - cnv.cnv8[1] = buf[2] & 0x3F; - pkt->seq_count = cnv.cnv16[0]; - - cnv.cnv8[0] = buf[4]; - cnv.cnv8[1] = buf[5]; - pkt->len = cnv.cnv16[0]; - - ccsds_sec_hdr = buf[6] >> 7; - - tc_pus = buf[6] >> 4; - - pkt->ack = 0x04 & buf[6]; - - pkt->ser_type = buf[7]; - pkt->ser_subtype = buf[8]; - pkt->dest_id = buf[9]; - - if (app_id_verification[pkt->app_id] != 1) { - return R_OBC_PKT_ILLEGAL_APPID; - } - - if (pkt->len != size - 7) { - return R_OBC_PKT_INV_LEN; - } - - if (tmp_crc[0] != tmp_crc[1]) { - return R_OBC_PKT_INC_CRC; - } - - if (services_verification_TC_TM[pkt->ser_type][pkt->ser_subtype][pkt->type] - != 1) { - return R_OBC_PKT_ILLEGAL_PKT_TP; - } - - if (ver != 0) { - return R_OBC_ERROR; - } - - if (tc_pus != 1) { - return R_OBC_ERROR; - } - - if (ccsds_sec_hdr != 0) { - return R_OBC_ERROR; - } - - if (pkt->type != TC && pkt->type != TM) { - return R_OBC_ERROR; - } - - if (dfield_hdr != 1) { - return R_OBC_ERROR; - } - - if (pkt->ack != TC_ACK_NO || pkt->ack != TC_ACK_ACC - || pkt->ack != TC_ACK_EXE_COMP) { - return R_OBC_ERROR; - } - - for (int i = 0; i < pkt->len - 4; i++) { - pkt->data[i] = buf[10 + i]; - } - - return R_OBC_OK; - } - - /** - * Packs a TC packet into a byte buffer - * @param buf buffer to store the data to be sent - * @param pkt the data to be stored in the buffer - * @param size size of the array - * @return appropriate error code or R_OBC_OK if all operation succeed - */ - OBC_ret_state_t - pack_pkt (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *size) - { - - union _cnv cnv; - uint8_t buf_pointer; - - cnv.cnv16[0] = pkt->app_id; - - buf[0] = ( ECSS_VER_NUMBER << 5 | pkt->type << 4 - | ECSS_DATA_FIELD_HDR_FLG << 3 | cnv.cnv8[1]); - buf[1] = cnv.cnv8[0]; - - cnv.cnv16[0] = pkt->seq_count; - buf[2] = (pkt->seq_flags << 6 | cnv.cnv8[1]); - buf[3] = cnv.cnv8[0]; - - /* TYPE = 0 TM, TYPE = 1 TC*/ - if (pkt->type == TM) { - buf[6] = ECSS_PUS_VER << 4; - } - else if (pkt->type == TC) { - buf[6] = ( ECSS_SEC_HDR_FIELD_FLG << 7 | ECSS_PUS_VER << 4 | pkt->ack); - } - else { - return R_OBC_ERROR; - } - - buf[7] = pkt->ser_type; - buf[8] = pkt->ser_subtype; - buf[9] = pkt->dest_id; /*source or destination*/ - - buf_pointer = 10; - - if (pkt->ser_type == TC_VERIFICATION_SERVICE) { - //cnv.cnv16[0] = tc_pkt_id; - //cnv.cnv16[1] = tc_pkt_seq_ctrl; - - /*verification_pack_pkt_api (buf, pkt, &buf_pointer);*/ - - } - else if (pkt->ser_type == TC_HOUSEKEEPING_SERVICE) { - - /*hk_pack_pkt_api (buf, pkt, &buf_pointer);*/ - - } - else if (pkt->ser_type == TC_FUNCTION_MANAGEMENT_SERVICE - && pkt->ser_subtype == 1) { - - buf[10] = pkt->data[0]; - - buf[11] = pkt->data[1]; - buf[12] = pkt->data[2]; - buf[13] = pkt->data[3]; - buf[14] = pkt->data[4]; - - buf_pointer += 5; - - } - else { - return R_OBC_ERROR; - } - - /*check if this is correct*/ - cnv.cnv16[0] = buf_pointer - 6; - buf[4] = cnv.cnv8[0]; - buf[5] = cnv.cnv8[1]; - - buf[buf_pointer] = checkSum (buf, buf_pointer - 1); - *size = buf_pointer; - return R_OBC_OK; - } - - OBC_ret_state_t - crt_pkt (tc_tm_pkt *pkt, uint16_t app_id, uint8_t type, uint8_t ack, - uint8_t ser_type, uint8_t ser_subtype, uint16_t dest_id) - { - - pkt->type = type; - pkt->app_id = app_id; - pkt->dest_id = dest_id; - - pkt->ser_type = ser_type; - pkt->ser_subtype = ser_subtype; - - return R_OBC_OK; - } - - } /* namespace satnogs */ -} /* namespace gr */ - diff --git a/lib/tcp_rigctl_msg_source_impl.cc b/lib/tcp_rigctl_msg_source_impl.cc new file mode 100644 index 0000000..bbd705e --- /dev/null +++ b/lib/tcp_rigctl_msg_source_impl.cc @@ -0,0 +1,192 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "tcp_rigctl_msg_source_impl.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace gr +{ + namespace satnogs + { + + tcp_rigctl_msg_source::sptr + tcp_rigctl_msg_source::make (const std::string& addr, uint16_t port, + size_t mtu) + { + return gnuradio::get_initial_sptr ( + new tcp_rigctl_msg_source_impl (addr, port, mtu)); + } + + /* + * The private constructor + */ + tcp_rigctl_msg_source_impl::tcp_rigctl_msg_source_impl ( + const std::string& addr, uint16_t port, size_t mtu) : + gr::block ("tcp_rigctl_msg_source", + gr::io_signature::make (0, 0, 0), + gr::io_signature::make (0, 0, 0)), + d_iface_addr (addr), + d_port (port), + d_mtu (mtu), + d_running (true) + { + message_port_register_out (pmt::mp ("freq")); + boost::shared_ptr ( + new boost::thread ( + boost::bind (&tcp_rigctl_msg_source_impl::tcp_msg_accepter, + this))); + } + + void + tcp_rigctl_msg_source_impl::tcp_msg_accepter () + { + int sock; + int listen_sock; + struct sockaddr_in sin; + struct sockaddr client_addr; + socklen_t client_addr_len; + ssize_t ret; + uint8_t *buf; + double freq; + + if ((listen_sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { + perror ("opening UDP socket"); + exit (EXIT_FAILURE); + } + + memset (&client_addr, 0, sizeof(struct sockaddr)); + memset (&sin, 0, sizeof(struct sockaddr_in)); + sin.sin_family = AF_INET; + sin.sin_port = htons (d_port); + sin.sin_addr.s_addr = INADDR_ANY; + + if (inet_aton (d_iface_addr.c_str (), &(sin.sin_addr)) == 0) { + LOG_ERROR("Wrong IP address"); + close (listen_sock); + exit (EXIT_FAILURE); + } + + if (bind (listen_sock, (struct sockaddr *) &sin, + sizeof(struct sockaddr_in)) == -1) { + perror ("TCP bind"); + close (listen_sock); + exit (EXIT_FAILURE); + } + + if (listen (listen_sock, 1000) == -1) { + perror ("TCP listen"); + close (listen_sock); + exit (EXIT_FAILURE); + } + + /* All good until now. Allocate buffer memory and proceed */ + buf = new uint8_t (d_mtu); + + while (d_running) { + sock = accept (listen_sock, &client_addr, &client_addr_len); + if (sock <= 0) { + perror ("TCP accept"); + exit (EXIT_FAILURE); + } + + while ((ret = recv (sock, buf, d_mtu, 0)) > 0) { + switch (buf[0]) + { + case 'F': + freq = get_freq_from_buf (buf + 2); + /* + * If the frequency is different than 0, then the parsed value + * is valid and an appropriate message can be generated + * + * NOTE: Comparison for equality in floats is a bit tricky. + * But here the get_freq_from_buf() will assign a 0.0 explicitly + * if something goes wrong. For this reason it is safe to compare + * the in-equality agains 0.0. + */ + if (freq != 0.0) { + message_port_pub (pmt::mp ("freq"), pmt::from_double (freq)); + } + break; + default: + LOG_WARN("Unsupported rigctl command"); + } + } + shutdown (sock, SHUT_RDWR); + close (sock); + } + close (listen_sock); + delete buf; + exit (EXIT_SUCCESS); + } + + /** + * Parses the string in the \p buf trying to extract a frequency reading + * until the newline character + * @param buf the buffer containing a line with the target frequency + * @return the frequency converted into double + */ + double + tcp_rigctl_msg_source_impl::get_freq_from_buf (const uint8_t* buf) + { + long int f; + char *end; + f = strtol ((char *) buf, &end, 10); + + /* Check for various possible errors */ + if ((errno == ERANGE && (f == LONG_MAX || f == LONG_MIN)) + || (errno != 0 && f == 0)) { + LOG_WARN("Invalid rigctl command"); + f = 0; + } + + if ((char *) buf == end) { + LOG_WARN("Invalid rigctl command"); + f = 0; + } + + return (double) f; + } + + /* + * Our virtual destructor. + */ + tcp_rigctl_msg_source_impl::~tcp_rigctl_msg_source_impl () + { + d_running = false; + d_thread->join (); + } + + } /* namespace satnogs */ +} /* namespace gr */ + diff --git a/lib/tcp_rigctl_msg_source_impl.h b/lib/tcp_rigctl_msg_source_impl.h new file mode 100644 index 0000000..3c7b50b --- /dev/null +++ b/lib/tcp_rigctl_msg_source_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_IMPL_H +#define INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_IMPL_H + +#include + +namespace gr +{ + namespace satnogs + { + + class tcp_rigctl_msg_source_impl : public tcp_rigctl_msg_source + { + private: + const std::string d_iface_addr; + const uint16_t d_port; + const size_t d_mtu; + bool d_running; + boost::shared_ptr d_thread; + + void + tcp_msg_accepter(); + + double + get_freq_from_buf(const uint8_t *buf); + + public: + tcp_rigctl_msg_source_impl (const std::string& addr, uint16_t port, + size_t mtu); + ~tcp_rigctl_msg_source_impl (); + }; + + } // namespace satnogs + } // namespace gr + +#endif /* INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_IMPL_H */ + diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index a6d40b8..66f5011 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -21,7 +21,7 @@ #include "satnogs/ax25_decoder_b.h" #include "satnogs/udp_msg_source.h" #include "satnogs/debug_msg_source.h" -#include "satnogs/tc_tm.h" +#include "satnogs/tcp_rigctl_msg_source.h" %} @@ -48,4 +48,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, ax25_decoder_b); GR_SWIG_BLOCK_MAGIC2(satnogs, udp_msg_source); %include "satnogs/debug_msg_source.h" GR_SWIG_BLOCK_MAGIC2(satnogs, debug_msg_source); -%include "satnogs/tc_tm.h" +%include "satnogs/tcp_rigctl_msg_source.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, tcp_rigctl_msg_source); From e2426243126ea374540c7ac95c53b7ba8983a0b1 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Mon, 28 Mar 2016 18:09:16 +0300 Subject: [PATCH 2/2] Create doppler shift correction block --- grc/CMakeLists.txt | 3 +- grc/satnogs_doppler_correction_cc.xml | 38 +++++++++++ include/satnogs/CMakeLists.txt | 3 +- include/satnogs/doppler_correction_cc.h | 66 +++++++++++++++++++ lib/CMakeLists.txt | 3 +- lib/doppler_correction_cc_impl.cc | 84 +++++++++++++++++++++++++ lib/doppler_correction_cc_impl.h | 55 ++++++++++++++++ swig/satnogs_swig.i | 3 + 8 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 grc/satnogs_doppler_correction_cc.xml create mode 100644 include/satnogs/doppler_correction_cc.h create mode 100644 lib/doppler_correction_cc_impl.cc create mode 100644 lib/doppler_correction_cc_impl.h diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index 86b312b..0834299 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -28,5 +28,6 @@ install(FILES satnogs_ax25_decoder_b.xml satnogs_udp_msg_source.xml satnogs_debug_msg_source.xml - satnogs_tcp_rigctl_msg_source.xml DESTINATION share/gnuradio/grc/blocks + satnogs_tcp_rigctl_msg_source.xml + satnogs_doppler_correction_cc.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/satnogs_doppler_correction_cc.xml b/grc/satnogs_doppler_correction_cc.xml new file mode 100644 index 0000000..084bb41 --- /dev/null +++ b/grc/satnogs_doppler_correction_cc.xml @@ -0,0 +1,38 @@ + + + doppler_correction_cc + satnogs_doppler_correction_cc + satnogs + import satnogs + satnogs.doppler_correction_cc($target_freq) + + + ... + ... + ... + + + + + in + + + + + + out + + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 24b753e..4c36c64 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -40,5 +40,6 @@ install(FILES udp_msg_source.h debug_msg_source.h tc_tm.h - tcp_rigctl_msg_source.h DESTINATION include/satnogs + tcp_rigctl_msg_source.h + doppler_correction_cc.h DESTINATION include/satnogs ) diff --git a/include/satnogs/doppler_correction_cc.h b/include/satnogs/doppler_correction_cc.h new file mode 100644 index 0000000..3f130f5 --- /dev/null +++ b/include/satnogs/doppler_correction_cc.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_H +#define INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_H + +#include +#include + +namespace gr +{ + namespace satnogs + { + + /*! + * \brief This block corrects the doppler effect between the ground + * station and the satellite. It takes the imput stream in baseband + * and applies proper corrections to keep the carrier at the desired + * frequency. To achieve that it uses messages containing the absolute + * predicted frequency of the satellite from software like Gpredict. + * + * \ingroup satnogs + * + */ + class SATNOGS_API doppler_correction_cc : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * The doppler correction block. The input is the complex signal at + * baseband as it comes from the SDR device. The message input \p freq + * received periodically messages containing the predicted absolute + * frequency of the satellite at the moment of the + * @param target_freq the absolute frequency of the satellite + * @param sampling_rate the sampling rate of the signal + * @param corrections_per_sec the number of the corrections every second + * that the block should perform + */ + static sptr + make (double target_freq, double sampling_rate, + size_t corrections_per_sec = 1000); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index daafdec..11aed97 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -37,7 +37,8 @@ list(APPEND satnogs_sources ax25_decoder_b_impl.cc udp_msg_source_impl.cc debug_msg_source_impl.cc - tcp_rigctl_msg_source_impl.cc ) + tcp_rigctl_msg_source_impl.cc + doppler_correction_cc_impl.cc ) set(satnogs_sources "${satnogs_sources}" PARENT_SCOPE) if(NOT satnogs_sources) diff --git a/lib/doppler_correction_cc_impl.cc b/lib/doppler_correction_cc_impl.cc new file mode 100644 index 0000000..3c12dac --- /dev/null +++ b/lib/doppler_correction_cc_impl.cc @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "doppler_correction_cc_impl.h" + +namespace gr +{ + namespace satnogs + { + + doppler_correction_cc::sptr + doppler_correction_cc::make (double target_freq, double sampling_rate, + size_t corrections_per_sec) + { + return gnuradio::get_initial_sptr ( + new doppler_correction_cc_impl (target_freq, sampling_rate, + corrections_per_sec)); + } + + /* + * The private constructor + */ + doppler_correction_cc_impl::doppler_correction_cc_impl ( + double target_freq, double sampling_rate, size_t corrections_per_sec) : + gr::sync_block ("doppler_correction_cc", + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (1, 1, sizeof(gr_complex))), + d_target_freq (target_freq), + d_samp_rate (sampling_rate), + d_update_period (sampling_rate / (double) corrections_per_sec), + d_freq_diff (0.0) + { + message_port_register_in (pmt::mp ("freq")); + /* + * Set the maximum number of samples to be equivalent of half a second. + * With this way we are sure that at least one frequency message + * per second will be processed. + */ + set_max_noutput_items (d_samp_rate / 2.0); + } + + /* + * Our virtual destructor. + */ + doppler_correction_cc_impl::~doppler_correction_cc_impl () + { + } + + int + doppler_correction_cc_impl::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + return noutput_items; + } + + } /* namespace satnogs */ +} /* namespace gr */ + diff --git a/lib/doppler_correction_cc_impl.h b/lib/doppler_correction_cc_impl.h new file mode 100644 index 0000000..7c67fc6 --- /dev/null +++ b/lib/doppler_correction_cc_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_IMPL_H +#define INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_IMPL_H + +#include + +namespace gr +{ + namespace satnogs + { + + class doppler_correction_cc_impl : public doppler_correction_cc + { + private: + const double d_target_freq; + const double d_samp_rate; + const double d_update_period; + + double d_freq_diff; + + public: + doppler_correction_cc_impl (double target_freq, double sampling_rate, + size_t corrections_per_sec); + ~doppler_correction_cc_impl (); + + // Where all the action really happens + int + work (int noutput_items, gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_IMPL_H */ + diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index 66f5011..fc09185 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -22,6 +22,7 @@ #include "satnogs/udp_msg_source.h" #include "satnogs/debug_msg_source.h" #include "satnogs/tcp_rigctl_msg_source.h" +#include "satnogs/doppler_correction_cc.h" %} @@ -50,3 +51,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, udp_msg_source); GR_SWIG_BLOCK_MAGIC2(satnogs, debug_msg_source); %include "satnogs/tcp_rigctl_msg_source.h" GR_SWIG_BLOCK_MAGIC2(satnogs, tcp_rigctl_msg_source); +%include "satnogs/doppler_correction_cc.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, doppler_correction_cc);