// we otherwise lose the information about which app has been selected.
if (radio->protocol == STEMLAB_PROTOCOL) {
const int device_id = radio - discovered;
- stemlab_start_app(gtk_combo_box_get_active_id(GTK_COMBO_BOX(apps_combobox[device_id])));
+ int ret;
+ ret=stemlab_start_app(gtk_combo_box_get_active_id(GTK_COMBO_BOX(apps_combobox[device_id])));
#ifdef NO_AVAHI
// We only have started the app, but not queried e.g. the MAC address.
// Therefore, we have to clean up and re-start the discovery process.
g_idle_add(ext_discovery,NULL);
return TRUE;
#endif
+ // At this point, if stemlab_start_app failed, we cannot recover
+ if (ret != 0) exit(-1);
}
stemlab_cleanup();
#endif
static long ep4_sequence;
// DL1YCF added this variable for lost-package-check
-static long last_seq_num=0;
+// init with -1 such that there is no error message if the
+// first packet is received with seq_num = 0
+static long last_seq_num=-1;
static int current_rx=0;
}
// TODO - add Alex Antenna
- output_buffer[C3]=0x00;
- output_buffer[C3] = receiver[0]->alex_attenuation;
+ output_buffer[C3] = (receiver[0]->alex_attenuation) & 0x03; // do not set higher bits
if(active_receiver->random) {
output_buffer[C3]|=LT2208_RANDOM_ON;
}
if(display_sliders) {
gtk_range_set_value(GTK_RANGE(af_gain_scale),active_receiver->volume*100.0);
gtk_range_set_value (GTK_RANGE(agc_scale),active_receiver->agc_gain);
- gtk_range_set_value (GTK_RANGE(attenuation_scale),(double)adc_attenuation[active_receiver->adc]);
-
+ if (filter_board == CHARLY25) {
+ update_att_preamp();
+ } else {
+ gtk_range_set_value (GTK_RANGE(attenuation_scale),(double)adc_attenuation[active_receiver->adc]);
+ }
char title[64];
#ifdef RADIOBERRY
sprintf(title,"RX GAIN"/*,active_receiver->adc*/);
scale_status=ATTENUATION;
scale_dialog=gtk_dialog_new_with_buttons(title,GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
- if (filter_board == CHARLY25) {
- // although this slider is hidden, its value range does matter
- attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 36.0, 1.00);
- } else {
- attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.00);
- }
+ attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.00);
gtk_widget_set_size_request (attenuation_scale, 400, 30);
gtk_range_set_value (GTK_RANGE(attenuation_scale),(double)adc_attenuation[active_receiver->adc]);
gtk_widget_show(attenuation_scale);
}
void update_att_preamp(void) {
+ // CHARLY25: update the ATT/Pre buttons to the values of the active RX
if (filter_board == CHARLY25) {
char id[] = "x";
sprintf(id, "%d", active_receiver->alex_attenuation);
}
static void c25_att_combobox_changed(GtkWidget *widget, gpointer data) {
- int id = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)));
- //DL1YCF: store attenuation, such that in meter.c the correct level is displayed
- adc_attenuation[active_receiver->adc] = 12.0*id;
- set_alex_attenuation(id);
+ int val = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)));
+ if (active_receiver->id == 0) {
+ //DL1YCF: this button is only valid for the first receiver
+ // store attenuation, such that in meter.c the correct level is displayed
+ adc_attenuation[active_receiver->adc] = 12*val;
+ set_alex_attenuation(val);
+ } else {
+ // always show "0 dB" on the button if the second RX is active
+ if (val != 0) {
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(c25_att_combobox), "0");
+ }
+ }
}
static void c25_preamp_combobox_changed(GtkWidget *widget, gpointer data) {
- int id = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)));
- //DL1YCF comment: dither and preamp are "misused" to store the PreAmp value.
- // this has to be exploited in meter.c
- active_receiver->dither = id >= 2;
- active_receiver->preamp = id >= 1;
+ int val = atoi(gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)));
+ if (active_receiver->id == 0) {
+ //DL1YCF: This button is only valid for the first receiver
+ // dither and preamp are "misused" to store the PreAmp value.
+ // this has to be exploited in meter.c
+ active_receiver->dither = (val >= 2); // second preamp ON
+ active_receiver->preamp = (val >= 1); // first preamp ON
+ } else{
+ // always show "0 dB" on the button if the second RX is active
+ if (val != 0) {
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(c25_preamp_combobox), "0");
+ }
+ }
}
static void agcgain_value_changed_cb(GtkWidget *widget, gpointer data) {
attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 60.0, 1.0);
gtk_range_set_value (GTK_RANGE(attenuation_scale),rx_gain_slider[active_receiver->adc]);
#else
- if (filter_board == CHARLY25) {
- attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 36.0, 1.0);
- } else {
- attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.0);
- }
+ attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.0);
gtk_range_set_value (GTK_RANGE(attenuation_scale),adc_attenuation[active_receiver->adc]);
#endif
return size * nmemb;
}
-// This is essentially a no-op curl callback
+// This is essentially a no-op curl callback.
+// Its main purpose is to prevent the status message going to stderr
static size_t app_start_callback(void *buffer, size_t size, size_t nmemb, void *data) {
if (strncmp(buffer, "{\"status\":\"OK\"}", size*nmemb) != 0) {
fprintf(stderr, "stemlab_start: Receiver error from STEMlab\n");
return size * nmemb;
}
-void stemlab_start_app(const char * const app_id) {
+int stemlab_start_app(const char * const app_id) {
// Dummy string, using the longest possible app id
- char app_start_url[] = "http://123.123.123.123/bazaar?start=stemlab_sdr_transceiver_hpsdr";
- sprintf(app_start_url, "http://%s/bazaar?start=%s",
- inet_ntoa(radio->info.network.address.sin_addr),
- app_id);
+ char app_start_url[] = "http://123.123.123.123/bazaar?start=stemlab_sdr_transceiver_hpsdr_headroom_max";
+ //
+ // If there is already an SDR application running on the RedPitaya,
+ // starting the SDR app might lead to an unpredictable state, unless
+ // the "killall" command from stop.sh is included in start.sh but this
+ // is not done at the factory.
+ // Therefore, we first stop the program (this essentially includes the
+ // command "killall sdr_transceiver_hpsdr") and then start it.
+ // We return with value 0 if everything went OK, else we return -1.
+ // This is so because in the NO_AVAHI case, we can in principle recover
+ // from a failure here.
+
CURL *curl_handle = curl_easy_init();
+ CURLcode curl_error = CURLE_OK;
+
if (curl_handle == NULL) {
fprintf(stderr, "stemlab_start: Failed to create cURL handle\n");
- exit(-1);
+ return -1;
}
- CURLcode curl_error = CURLE_OK;
+
#define check_curl(description) do { \
if (curl_error != CURLE_OK) { \
fprintf(stderr, "stemlab_start: " description ": %s\n", \
curl_easy_strerror(curl_error)); \
- exit(-1); \
+ return -1; \
} \
} while (0);
+
+ sprintf(app_start_url, "http://%s/bazaar?stop=%s",
+ inet_ntoa(radio->info.network.address.sin_addr),
+ app_id);
+ curl_error = curl_easy_setopt(curl_handle, CURLOPT_URL, app_start_url);
+ check_curl("Failed setting cURL URL");
+ curl_error = curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, app_start_callback);
+ check_curl("Failed install cURL callback");
+ curl_error = curl_easy_perform(curl_handle);
+ check_curl("Failed to stop app");
+
+ sprintf(app_start_url, "http://%s/bazaar?start=%s",
+ inet_ntoa(radio->info.network.address.sin_addr),
+ app_id);
curl_error = curl_easy_setopt(curl_handle, CURLOPT_URL, app_start_url);
check_curl("Failed setting cURL URL");
curl_error = curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, app_start_callback);
check_curl("Failed install cURL callback");
curl_error = curl_easy_perform(curl_handle);
check_curl("Failed to start app");
+
#undef check_curl
+
curl_easy_cleanup(curl_handle);
// Since the SDR application is now running, we can hand it over to the
// regular HPSDR protocol handling code
radio->protocol = ORIGINAL_PROTOCOL;
+ return 0;
}
void stemlab_cleanup(void) {
*/
extern void stemlab_discovery(void);
-extern void stemlab_start_app(const char * const app_id);
+extern int stemlab_start_app(const char * const app_id);
extern void stemlab_cleanup(void);