controller controller_create(demod dem, rtl r, scanner scan, websocket ws) { controller ctrl = (controller) malloc(sizeof(struct controller_s)); ctrl->dem = dem; ctrl->r = r; ctrl->scan = scan; ctrl->ws = ws; ctrl->heartbeat_num_samples = 0; ctrl->heartbeat_time.tv_sec = (time_t) 0; ctrl->heartbeat_time.tv_nsec = 0; // initialize the RTL dongle rtl_set_auto_gain(r); rtl_set_freq_correction(r, 100); rtl_set_center_freq(r, (uint32_t) 90.7e6); rtl_set_sample_rate(r, (uint32_t) 1e6); rtl_reset_buffer(r); demod_set_center_freq(dem, rtl_get_center_freq(ctrl->r)); demod_set_input_rate(dem, rtl_get_sample_rate(ctrl->r)); demod_set_output_rate(dem, (int) 48e3); demod_set_mode(dem, DEMOD_FM); // start demodulator demod_execute(dem); // start RTL rtl_execute(r, _rtl_callback, (void *) ctrl); // start websocket websocket_execute(ws, _websocket_receive_callback, (void *) ctrl); return ctrl; }
void controller_command(controller ctrl, char * cmd, int len) { DEBUG("Command: %s\n", cmd); int max_args = 16; int argc = 1; char * argv[max_args]; argv[0] = NULL; char * token; token = strtok(cmd, " "); while (token != NULL && argc <= max_args) { argv[argc++] = token; token = strtok(NULL, " "); } int opt; float fc = -1; int fs = -1; demod_mode current_dmode = demod_get_mode(ctrl->dem); demod_mode dmode = DEMOD_NONE; bool change_smode = false; scanner_mode smode = SCANNER_OFF; // reset getopt optind = 1; while ((opt = getopt(argc, argv, "f:m:r:s:")) != -1) { switch (opt) { case 'f': fc = (float) atoi(optarg); break; case 'r': fs = atoi(optarg); break; case 'm': dmode = demod_lookup_mode(optarg); break; case 's': change_smode = true; if ( ! strcmp(optarg, "on")) { smode = SCANNER_ON; } else if ( ! strcmp(optarg, "off")) { smode = SCANNER_OFF; } else if ( ! strcmp(optarg, "up")) { smode = SCANNER_SEEK_UP; } else if ( ! strcmp(optarg, "down")) { smode = SCANNER_SEEK_DOWN; } break; } } // change sample rate if (fs == 250e3 || fs == 1e6 || fs == 1.92e6 || fs == 2e6 || fs == 2.048e6 || fs == 2.4e6) { rtl_set_sample_rate(ctrl->r, (uint32_t) fs); demod_set_input_rate(ctrl->dem, fs); } // change demodulation mode if (dmode != DEMOD_NONE && current_dmode != dmode) { demod_set_mode(ctrl->dem, dmode); current_dmode = dmode; } // change scanning mode if (change_smode) { switch (current_dmode) { case DEMOD_FM: case DEMOD_AM: scanner_set_mode(ctrl->scan, smode); break; // not available for other modes default: break; } } // change frequency if (fc > 0) { switch (current_dmode) { case DEMOD_FM: if (87.9e6 <= fc && fc <= 107.9e6) { rtl_set_center_freq(ctrl->r, (uint32_t) fc); demod_set_center_freq(ctrl->dem, fc); } break; case DEMOD_AM: if (540e3 <= fc && fc <= 1700e3) { rtl_set_center_freq(ctrl->r, (uint32_t) (fc + 125e6)); demod_set_center_freq(ctrl->dem, fc); } break; default: break; } } // apply changes to the demodulator demod_execute(ctrl->dem); }
static int callback_rtl_ws(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { int f; int bw; int n, nn = 0; int do_write = 0; struct per_session_data__rtl_ws *pss = (struct per_session_data__rtl_ws *)user; char* buffer = NULL; char tmpbuffer[30]; memset(tmpbuffer, 0, 30); switch (reason) { case LWS_CALLBACK_ESTABLISHED: lwsl_info("protocol starting\n"); pss->id = latest_user_id++; pss->block_id = 0; printf("id: %d\n", pss->id); if (current_user_id == 0) current_user_id = pss->id; printf("cid: %d\n", current_user_id); if (current_user_id != pss->id) { return -1; } break; case LWS_CALLBACK_PROTOCOL_DESTROY: lwsl_notice("protocol cleaning up\n"); send_data = 0; if (current_user_id == pss->id) current_user_id = 0; break; case LWS_CALLBACK_SERVER_WRITEABLE: pthread_mutex_lock(&data_mutex); do_write = transfer.block_id > pss->block_id && should_write(); pss->block_id = transfer.block_id; pthread_mutex_unlock(&data_mutex); if (do_write) { memset(send_buffer, 0, LWS_SEND_BUFFER_PRE_PADDING + SEND_BUFFER_SIZE + LWS_SEND_BUFFER_POST_PADDING); n = sprintf(tmpbuffer, "f %u;b %u;", rtl_freq(), rtl_sample_rate()); memcpy(&send_buffer[LWS_SEND_BUFFER_PRE_PADDING], tmpbuffer, n); nn = write_spectrum_message(&send_buffer[LWS_SEND_BUFFER_PRE_PADDING+n], SEND_BUFFER_SIZE/2); // TODO: LWS_WRITE_BINARY n = libwebsocket_write(wsi, (unsigned char *) &send_buffer[LWS_SEND_BUFFER_PRE_PADDING], n+nn, LWS_WRITE_TEXT); } usleep(1); if (send_data) libwebsocket_callback_on_writable(context, wsi); break; case LWS_CALLBACK_RECEIVE: buffer = malloc(len+1); memset(buffer, 0, len+1); memcpy(buffer, in, len); printf("%s\n", buffer); if ((len >= strlen(FREQ_CMD)) && strncmp(FREQ_CMD, buffer, strlen(FREQ_CMD)) == 0) { f = atoi(&buffer[strlen(FREQ_CMD)])*1000; printf("Trying to tune to %d Hz...\n", f); rtl_tune(f); } else if ((len >= strlen(SAMPLE_RATE_CMD)) && strncmp(SAMPLE_RATE_CMD, buffer, strlen(SAMPLE_RATE_CMD)) == 0) { bw = atoi(&buffer[strlen(SAMPLE_RATE_CMD)])*1000; printf("Trying to set sample rate to %d Hz...\n", bw); rtl_set_sample_rate(bw); } else if ((len >= strlen(START_CMD)) && strncmp(START_CMD, buffer, strlen(START_CMD)) == 0) { send_data = 1; libwebsocket_callback_on_writable_all_protocol( libwebsockets_get_protocol(wsi)); } else if ((len >= strlen(STOP_CMD)) && strncmp(STOP_CMD, buffer, strlen(STOP_CMD)) == 0) { send_data = 0; } free(buffer); break; default: break; } return 0; }