|
@@ -30,7 +30,7 @@
|
|
|
#include "hello_fft/gpu_fft.h"
|
|
|
#include "hello_fft/mailbox.h"
|
|
|
#endif /* WITH_BCM_VC */
|
|
|
-
|
|
|
+//#define GPIOX
|
|
|
#include <fcntl.h>
|
|
|
#include <lame/lame.h>
|
|
|
#include <ogg/ogg.h>
|
|
@@ -65,8 +65,15 @@
|
|
|
#include "gperftools/profiler.h"
|
|
|
#endif /* WITH_PROFILING */
|
|
|
#include <gpiod.h>
|
|
|
+/*#include <ncurses.h>*/
|
|
|
+#include <iomanip>
|
|
|
+#include <fstream>
|
|
|
+#include <string>
|
|
|
+#include <chrono>
|
|
|
+#include "mqtt/async_client.h"
|
|
|
#include <ncurses.h>
|
|
|
-
|
|
|
+#include <curl/curl.h>
|
|
|
+#include <jsoncpp/json/json.h>
|
|
|
|
|
|
using namespace std;
|
|
|
using namespace libconfig;
|
|
@@ -79,11 +86,15 @@ using namespace libconfig;
|
|
|
|
|
|
#define MAX_BUFFERS 10
|
|
|
|
|
|
-sem_t mutex_sem, spooler_sem;
|
|
|
+sem_t mutex_lock_main_thread, mutex_unlock_main_thread;
|
|
|
+sem_t mutex_lock_main_thread_mqtt, mutex_unlock_main_thread_mqtt;
|
|
|
pthread_mutex_t lock_data;
|
|
|
+pthread_mutex_t lock_mqtt_data;
|
|
|
device_t* devices;
|
|
|
mixer_t* mixers;
|
|
|
|
|
|
+long int start_time;
|
|
|
+long int stop_time;
|
|
|
int bel_start_on_time = 0;
|
|
|
int bel_open_time = 0;
|
|
|
int bel_prolong_time = 0;
|
|
@@ -91,6 +102,11 @@ float bel_wave_out_level = 0;
|
|
|
float bel_wave_in_level = 0;
|
|
|
int bel_blink_time = 0;
|
|
|
|
|
|
+char* bel_mqtt_server;
|
|
|
+char* bel_mqtt_client_id;
|
|
|
+char* bel_mqtt_user_id;
|
|
|
+char* bel_mqtt_password;
|
|
|
+mqtt_msg_t mqtt_msg;
|
|
|
int squelch_status = 0;
|
|
|
int audio_status = 0;
|
|
|
int status_data = 0;
|
|
@@ -167,16 +183,90 @@ void multiply(float ar, float aj, float br, float bj, float* cr, float* cj) {
|
|
|
*cr = ar * br - aj * bj;
|
|
|
*cj = aj * br + ar * bj;
|
|
|
}
|
|
|
+class PublisherCallback : public virtual mqtt::callback
|
|
|
+{
|
|
|
+public:
|
|
|
+ void connection_lost(const std::string& cause) override
|
|
|
+ {
|
|
|
+ std::cout << "Connection lost: " << cause << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ void delivery_complete(mqtt::delivery_token_ptr token) override
|
|
|
+ {
|
|
|
+ token=token;
|
|
|
+ std::cout << "Message delivered" << std::endl;
|
|
|
+ }
|
|
|
+};
|
|
|
+void* mqtt_control_thread(void*){
|
|
|
+ string address = bel_mqtt_server,
|
|
|
+ clientID = bel_mqtt_client_id,
|
|
|
+ username = bel_mqtt_user_id,
|
|
|
+ password = bel_mqtt_password;
|
|
|
+ const std::string TOPIC1("device/SE0001/sq");
|
|
|
+ const std::string TOPIC2("device/SE0001/light");
|
|
|
+ const int QOS = 1;
|
|
|
+ //const int TIMEOUT = 10000;
|
|
|
+ mqtt::async_client client(address, clientID,mqtt::create_options(MQTTVERSION_5));
|
|
|
+
|
|
|
+ mqtt::connect_options connOpts;
|
|
|
+ mqtt::ssl_options ssl_options;
|
|
|
+
|
|
|
+ connOpts.set_keep_alive_interval(20);
|
|
|
+ connOpts.set_clean_session(true);
|
|
|
+ connOpts.set_user_name(username);
|
|
|
+ connOpts.set_password(password);
|
|
|
+ connOpts.set_ssl(ssl_options);
|
|
|
+ struct timespec ts;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ PublisherCallback callback;
|
|
|
+ client.set_callback(callback);
|
|
|
+
|
|
|
+ mqtt::token_ptr connectionToken = client.connect(connOpts);
|
|
|
+ connectionToken->wait();
|
|
|
+
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ int sem_try=0;
|
|
|
+ if (clock_gettime(CLOCK_REALTIME, &ts) == -1 && tui)
|
|
|
+ printf("clock_gettime");
|
|
|
+ ts.tv_sec +=1;
|
|
|
+ mqtt_msg_t temp_mess;
|
|
|
+ sem_try = sem_timedwait(&mutex_lock_main_thread_mqtt, &ts);
|
|
|
+ if (sem_try == 0){
|
|
|
+ temp_mess=mqtt_msg;
|
|
|
+ sem_post(&mutex_unlock_main_thread_mqtt);
|
|
|
+ Json::Value event;
|
|
|
+ event["sq"]=temp_mess.sq;
|
|
|
+ event["freq"]=temp_mess.freq;
|
|
|
+ Json::StreamWriterBuilder builder;
|
|
|
+ mqtt::message_ptr pubMessage = mqtt::make_message(TOPIC1,Json::writeString(builder, event), QOS, false);
|
|
|
+ client.publish(pubMessage)->wait();
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mqtt::token_ptr disconnectionToken = client.disconnect();
|
|
|
+ disconnectionToken->wait();
|
|
|
+ }
|
|
|
+ catch (const mqtt::exception& ex)
|
|
|
+ {
|
|
|
+ std::cerr << "MQTT Exception: " << ex.what() << std::endl;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
void* belysning_control_thread(void*){
|
|
|
struct timespec ts;
|
|
|
struct timeval tv;
|
|
|
- long int start_time;
|
|
|
- long int stop_time;
|
|
|
+
|
|
|
long int sq_start_time=0;
|
|
|
long int sq_stop_time=0;
|
|
|
bool sq_status = false;
|
|
|
long int audio_start_time=0;
|
|
|
bool active=false;
|
|
|
+ int status_data_temp=0;
|
|
|
gettimeofday(&tv, 0);
|
|
|
start_time=tv.tv_sec;
|
|
|
stop_time=tv.tv_sec+1;
|
|
@@ -189,22 +279,24 @@ void* belysning_control_thread(void*){
|
|
|
if (clock_gettime(CLOCK_REALTIME, &ts) == -1 && tui)
|
|
|
printf("clock_gettime");
|
|
|
ts.tv_sec +=1;
|
|
|
- sem_try = sem_timedwait(&mutex_sem, &ts);
|
|
|
+ sem_try = sem_timedwait(&mutex_lock_main_thread, &ts);
|
|
|
if (sem_try == 0){
|
|
|
- if (sq_status == false && (status_data & 1)){
|
|
|
+ status_data_temp=status_data;
|
|
|
+ sem_post(&mutex_unlock_main_thread);
|
|
|
+ if (sq_status == false && (status_data_temp & 1)){
|
|
|
sq_start_time = tv.tv_sec;
|
|
|
sq_status = true;
|
|
|
}
|
|
|
- if (sq_status == true && !(status_data & 1)){
|
|
|
+ if (sq_status == true && !(status_data_temp & 1)){
|
|
|
sq_stop_time = tv.tv_sec;
|
|
|
sq_status = false;
|
|
|
}
|
|
|
//printf("ST %u, %u ",(status_data & 1),(status_data >> 1));
|
|
|
- if ( (status_data >> 1) ){
|
|
|
+ if ( (status_data_temp >> 1) ){
|
|
|
audio_start_time = tv.tv_sec;
|
|
|
}
|
|
|
prolong = true;
|
|
|
- sem_post(&spooler_sem);
|
|
|
+
|
|
|
}
|
|
|
if (sq_status && sq_start_time < tv.tv_sec){
|
|
|
prolong = true;
|
|
@@ -244,8 +336,10 @@ void* belysning_control_thread(void*){
|
|
|
if (tui)
|
|
|
printf("Stop\n");
|
|
|
}
|
|
|
+#ifdef GPIOX
|
|
|
if (active)
|
|
|
if ((stop_time<tv.tv_sec+bel_blink_time) && tv.tv_sec % 2 && bel_blink_time ){
|
|
|
+
|
|
|
gpiod_line_set_value(led_control, 0);
|
|
|
gpiod_line_set_value(relay1, 1);
|
|
|
}else{
|
|
@@ -256,6 +350,7 @@ void* belysning_control_thread(void*){
|
|
|
gpiod_line_set_value(led_control, 0);
|
|
|
gpiod_line_set_value(relay1, 1);
|
|
|
}
|
|
|
+ #endif
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -678,26 +773,37 @@ void* demodulate(void* params) {
|
|
|
}
|
|
|
|
|
|
if ((abs(waveout)>bel_wave_out_level && channel->wavein[j]>bel_wave_in_level) ){
|
|
|
- gpiod_line_set_value(led_vox, 1);
|
|
|
+#ifdef GPIOX
|
|
|
+ gpiod_line_set_value(led_vox, 1);
|
|
|
+#endif
|
|
|
audio_status=1;
|
|
|
}else{
|
|
|
+#ifdef GPIOX
|
|
|
gpiod_line_set_value(led_vox, 0);
|
|
|
+#endif
|
|
|
audio_status=0;
|
|
|
|
|
|
}
|
|
|
+ squelch_status = channel->freqlist[channel->freq_idx].oldstatus & 1;
|
|
|
int temp_status = squelch_status + (audio_status << 1);
|
|
|
- if (status_data_old !=temp_status){
|
|
|
+
|
|
|
+ if (channel->freqlist[channel->freq_idx].oldstatus !=temp_status && (fparms->banbel)){
|
|
|
pthread_mutex_lock(&lock_data);
|
|
|
+ //fprintf(stderr,"HEJ %i,%i,%f,%f\n",channel->freqlist[channel->freq_idx].oldstatus ,temp_status,abs(waveout),channel->wavein[j]);
|
|
|
status_data = temp_status;
|
|
|
- if (sem_post (&mutex_sem) == -1) {
|
|
|
- perror ("sem_post: mutex_sem"); exit (1);
|
|
|
+ if (sem_post (&mutex_lock_main_thread) == -1) {
|
|
|
+ perror ("sem_post: mutex_lock_main_thread"); exit (1);
|
|
|
}
|
|
|
- if (sem_wait(&spooler_sem) == -1){
|
|
|
- perror ("sem_post: spooler_sem"); exit (1);
|
|
|
+ if (sem_wait(&mutex_unlock_main_thread) == -1){
|
|
|
+ perror ("sem_post: mutex_unlock_main_thread"); exit (1);
|
|
|
}
|
|
|
- status_data_old = status_data;
|
|
|
+
|
|
|
+ //channel->freqlist[channel->freq_idx].oldstatus = temp_status;;
|
|
|
pthread_mutex_unlock(&lock_data);
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
#ifdef NFM
|
|
|
else if (fparms->modulation == MOD_NFM) {
|
|
@@ -777,26 +883,54 @@ void* demodulate(void* params) {
|
|
|
//GOTOXY(i * 10, device_num * 17 + dev->row + 3);
|
|
|
//printf("%4.0f/%3.0f%c ", level_to_dBFS(fparms->squelch.signal_level()), level_to_dBFS(fparms->squelch.noise_level()), symbol);
|
|
|
}
|
|
|
- if (symbol=='*'){
|
|
|
- gpiod_line_set_value(led_squ, 1);
|
|
|
- squelch_status = 1;
|
|
|
- }else{
|
|
|
- gpiod_line_set_value(led_squ, 0);
|
|
|
- squelch_status = 0;
|
|
|
- }
|
|
|
- int temp_status = squelch_status + (audio_status << 1);
|
|
|
- if (status_data_old !=temp_status){
|
|
|
- pthread_mutex_lock(&lock_data);
|
|
|
- status_data = temp_status;
|
|
|
- if (sem_post (&mutex_sem) == -1) {
|
|
|
- perror ("sem_post: mutex_sem"); exit (1);
|
|
|
+ //BANBEL
|
|
|
+
|
|
|
+ if (symbol=='*'){
|
|
|
+#ifdef GPIOX
|
|
|
+ gpiod_line_set_value(led_squ, 1);
|
|
|
+#endif
|
|
|
+ squelch_status = 1;
|
|
|
+ }else{
|
|
|
+#ifdef GPIOX
|
|
|
+ gpiod_line_set_value(led_squ, 0);
|
|
|
+#endif
|
|
|
+ squelch_status = 0;
|
|
|
}
|
|
|
- if (sem_wait(&spooler_sem) == -1){
|
|
|
- perror ("sem_post: spooler_sem"); exit (1);
|
|
|
+ int temp_status = squelch_status + (audio_status << 1);
|
|
|
+ if (channel->freqlist[channel->freq_idx].oldstatus != temp_status){
|
|
|
+ //fprintf(stderr,"BABEL %i %i\n",fparms->banbel,temp_status);
|
|
|
+ if (fparms->banbel){
|
|
|
+ pthread_mutex_lock(&lock_data);
|
|
|
+ status_data = temp_status;
|
|
|
+ if (sem_post (&mutex_lock_main_thread) == -1) {
|
|
|
+ perror ("sem_post: mutex_lock_main_thread"); exit (1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sem_wait(&mutex_unlock_main_thread) == -1){
|
|
|
+ perror ("sem_post: mutex_unlock_main_thread"); exit (1);
|
|
|
+ }
|
|
|
+ pthread_mutex_unlock(&lock_data);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((temp_status & 1) != (channel->freqlist[channel->freq_idx].oldstatus & 1)) {
|
|
|
+ pthread_mutex_lock(&lock_mqtt_data);
|
|
|
+ if (sem_post (&mutex_lock_main_thread_mqtt) == -1) {
|
|
|
+ perror ("sem_post: mutex_lock_main_thread"); exit (1);
|
|
|
+ }
|
|
|
+ mqtt_msg.audio =(audio_status << 1);
|
|
|
+ mqtt_msg.sq = squelch_status;
|
|
|
+ mqtt_msg.freq = channel->freqlist->frequency;
|
|
|
+
|
|
|
+ if (sem_wait(&mutex_unlock_main_thread_mqtt) == -1){
|
|
|
+ perror ("sem_post: mutex_unlock_main_thread"); exit (1);
|
|
|
+ }
|
|
|
+ pthread_mutex_unlock(&lock_mqtt_data);
|
|
|
+ }
|
|
|
+ channel->freqlist[channel->freq_idx].oldstatus = temp_status;
|
|
|
+ //Here for mqtt
|
|
|
+
|
|
|
}
|
|
|
- status_data_old = status_data;
|
|
|
- pthread_mutex_unlock(&lock_data);
|
|
|
- }
|
|
|
+
|
|
|
fflush(stdout);
|
|
|
}
|
|
|
|
|
@@ -863,20 +997,25 @@ int main(int argc, char* argv[]) {
|
|
|
|
|
|
// initialization
|
|
|
|
|
|
- sem_init (&mutex_sem, 1, 0);
|
|
|
- sem_init (&spooler_sem, 1, 0);
|
|
|
+ sem_init (&mutex_lock_main_thread, 1, 0);
|
|
|
+ sem_init (&mutex_unlock_main_thread, 1, 0);
|
|
|
if (pthread_mutex_init(&lock_data, NULL) != 0) {
|
|
|
printf("\n mutex init has failed\n");
|
|
|
return 1;
|
|
|
}
|
|
|
+ if (pthread_mutex_init(&lock_mqtt_data, NULL) != 0) {
|
|
|
+ printf("\n mutex init has failed\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
printf("SEM and locks OPEN\n");
|
|
|
-
|
|
|
+#ifdef GPIOX
|
|
|
char const *chipname = "gpiochip0";
|
|
|
unsigned int gpio16 = 16;
|
|
|
unsigned int gpio20 = 20;
|
|
|
unsigned int gpio26 = 26;
|
|
|
unsigned int gpio24 = 24;
|
|
|
unsigned int gpio25 = 25;
|
|
|
+
|
|
|
chip = gpiod_chip_open_by_name(chipname);
|
|
|
if (!chip) {
|
|
|
perror("gpiod_chip_open_by_name");
|
|
@@ -887,6 +1026,8 @@ int main(int argc, char* argv[]) {
|
|
|
led_control = gpiod_chip_get_line(chip, gpio16);
|
|
|
relay1 = gpiod_chip_get_line(chip, gpio25);
|
|
|
relay2 = gpiod_chip_get_line(chip, gpio24);
|
|
|
+#endif
|
|
|
+#ifdef GPIOX
|
|
|
gpiod_line_request_output(led_squ, "Consumer1", 0);
|
|
|
gpiod_line_set_value(led_squ, 0);
|
|
|
gpiod_line_request_output(led_vox, "Consumer2", 0);
|
|
@@ -897,6 +1038,7 @@ int main(int argc, char* argv[]) {
|
|
|
gpiod_line_set_value(relay1, 1);
|
|
|
gpiod_line_request_output(relay2, "Consumer5", 0);
|
|
|
gpiod_line_set_value(relay2, 1);
|
|
|
+#endif
|
|
|
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
|
|
char* cfgfile = CFGFILE;
|
|
|
char* pidfile = PIDFILE;
|
|
@@ -1032,6 +1174,16 @@ int main(int argc, char* argv[]) {
|
|
|
bel_wave_in_level=(float)(root["bel_wave_in_level"]);
|
|
|
if (root.exists("bel_prolong_time"))
|
|
|
bel_prolong_time=(int)(root["bel_prolong_time"]);
|
|
|
+ //MQTT
|
|
|
+ if (root.exists("bel_mqtt_server"))
|
|
|
+ bel_mqtt_server = strdup(root["bel_mqtt_server"]);
|
|
|
+ if (root.exists("bel_mqtt_client_id"))
|
|
|
+ bel_mqtt_client_id = strdup(root["bel_mqtt_client_id"]);
|
|
|
+ if (root.exists("bel_mqtt_user_id"))
|
|
|
+ bel_mqtt_user_id= strdup(root["bel_mqtt_user_id"]);
|
|
|
+ if (root.exists("bel_mqtt_server"))
|
|
|
+ bel_mqtt_password= strdup(root["bel_mqtt_password"]);
|
|
|
+
|
|
|
Setting& devs = config.lookup("devices");
|
|
|
device_count = devs.getLength();
|
|
|
if (device_count < 1) {
|
|
@@ -1227,10 +1379,10 @@ int main(int argc, char* argv[]) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- int timeout = 50; // 5 seconds
|
|
|
- while ((devices_running = count_devices_running()) != device_count && timeout > 0) {
|
|
|
+ int timeout_device = 50; // 5 seconds
|
|
|
+ while ((devices_running = count_devices_running()) != device_count && timeout_device > 0) {
|
|
|
SLEEP(100);
|
|
|
- timeout--;
|
|
|
+ timeout_device--;
|
|
|
}
|
|
|
if ((devices_running = count_devices_running()) != device_count) {
|
|
|
log(LOG_ERR, "%d device(s) failed to initialize - aborting\n", device_count - devices_running);
|
|
@@ -1253,7 +1405,9 @@ int main(int argc, char* argv[]) {
|
|
|
}
|
|
|
}
|
|
|
THREAD belysning_control_check;
|
|
|
+ THREAD mqtt_control_check;
|
|
|
pthread_create(&belysning_control_check, NULL, &belysning_control_thread, NULL);
|
|
|
+ pthread_create(&mqtt_control_check, NULL, &mqtt_control_thread, NULL);
|
|
|
THREAD output_check;
|
|
|
pthread_create(&output_check, NULL, &output_check_thread, NULL);
|
|
|
|