static void on_dispose(void *_ctx) { struct st_h2o_mruby_http_request_context_t *ctx = _ctx; /* clear the refs */ if (ctx->client != NULL) { h2o_http1client_cancel(ctx->client); ctx->client = NULL; } if (!mrb_nil_p(ctx->refs.request)) DATA_PTR(ctx->refs.request) = NULL; if (!mrb_nil_p(ctx->refs.input_stream)) DATA_PTR(ctx->refs.input_stream) = NULL; /* clear bufs */ h2o_buffer_dispose(&ctx->req.buf); h2o_buffer_dispose(&ctx->resp.after_closed); /* notify the app, if it is waiting to hear from us */ if (!mrb_nil_p(ctx->receiver)) { mrb_state *mrb = ctx->generator->ctx->mrb; int gc_arena = mrb_gc_arena_save(mrb); h2o_mruby_run_fiber(ctx->generator, detach_receiver(ctx), create_downstream_closed_exception(mrb), gc_arena, NULL); } }
static int on_body(h2o_http1client_t *client, const char *errstr) { struct st_h2o_mruby_http_request_context_t *ctx = client->data; if (errstr != NULL) { h2o_buffer_t *tmp = ctx->resp.after_closed; ctx->resp.after_closed = client->sock->input; client->sock->input = tmp; ctx->client = NULL; ctx->resp.has_content = 1; } else if (client->sock->input->size != 0) { ctx->resp.has_content = 1; } if (ctx->resp.has_content) { if (ctx->shortcut_notify_cb != NULL) { ctx->shortcut_notify_cb(ctx->generator); } else if (!mrb_nil_p(ctx->receiver)) { int gc_arena = mrb_gc_arena_save(ctx->generator->ctx->mrb); mrb_value chunk = build_chunk(ctx); h2o_mruby_run_fiber(ctx->generator, detach_receiver(ctx), chunk, gc_arena, NULL); } } return 0; }
//Client thread for RX IQ stream void* client_thread(void* arg) { CLIENT* client=(CLIENT*)arg; int old_state, old_type; char command[80]; int bytes_read; const char* response; client->receiver_state=RECEIVER_DETACHED; client->transmitter_state=TRANSMITTER_DETACHED; client->receiver_num=-1; pthread_mutex_init(&client->mox_lock, NULL ); set_mox(client,0); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&old_state); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&old_type); while(1) { bytes_read=recv(client->socket,command,sizeof(command),0); if(bytes_read<=0) { break; } command[bytes_read]=0; response=parse_command(client,command); send(client->socket,response,strlen(response),0); fprintf(stderr,"Response to DSP client (Rx%d): '%s'\n",client->receiver_num,response); } fprintf(stderr,"Exiting DSP client thread loop (Rx%d)...\n",client->receiver_num); //GRACEFUL EXIT ON DISCONNECTION set_mox(client,0); if(client->transmitter_state==TRANSMITTER_ATTACHED) { stop_tx_audio(client); //Exits the tx_audio_thread @ transmitter client->transmitter_state=TRANSMITTER_DETACHED; } sleep(1); if(client->receiver_state==RECEIVER_ATTACHED) { detach_receiver(client->receiver_num, client); receiver[client->receiver_num].client=(CLIENT*)NULL; client->receiver_state=RECEIVER_DETACHED; } client->bs_port=-1; detach_bandscope(client); #ifdef __linux__ close(client->socket); #else closesocket(client->socket); #endif fprintf(stderr,"Client Handler: Client disconnected: %s:%d\n",inet_ntoa(client->address.sin_addr),ntohs(client->address.sin_port)); free(client); return 0; }
static void post_response(struct st_h2o_mruby_http_request_context_t *ctx, int status, const h2o_http1client_header_t *headers_sorted, size_t num_headers) { mrb_state *mrb = ctx->generator->ctx->shared->mrb; int gc_arena = mrb_gc_arena_save(mrb); size_t i; mrb_value resp = mrb_ary_new_capa(mrb, 3); /* set status */ mrb_ary_set(mrb, resp, 0, mrb_fixnum_value(status)); /* set headers */ mrb_value headers_hash = mrb_hash_new_capa(mrb, (int)num_headers); for (i = 0; i < num_headers; ++i) { /* skip the headers, we determine the eos! */ if (h2o_memis(headers_sorted[i].name, headers_sorted[i].name_len, H2O_STRLIT("content-length")) || h2o_memis(headers_sorted[i].name, headers_sorted[i].name_len, H2O_STRLIT("transfer-encoding"))) continue; /* build and set the hash entry */ mrb_value k = mrb_str_new(mrb, headers_sorted[i].name, headers_sorted[i].name_len); mrb_value v = mrb_str_new(mrb, headers_sorted[i].value, headers_sorted[i].value_len); while (i + 1 < num_headers && h2o_memis(headers_sorted[i].name, headers_sorted[i].name_len, headers_sorted[i + 1].name, headers_sorted[i + 1].name_len)) { ++i; v = mrb_str_cat_lit(mrb, v, "\n"); v = mrb_str_cat(mrb, v, headers_sorted[i].value, headers_sorted[i].value_len); } mrb_hash_set(mrb, headers_hash, k, v); } mrb_ary_set(mrb, resp, 1, headers_hash); /* set input stream */ assert(mrb_nil_p(ctx->refs.input_stream)); ctx->refs.input_stream = h2o_mruby_create_data_instance( mrb, mrb_ary_entry(ctx->generator->ctx->shared->constants, H2O_MRUBY_HTTP_INPUT_STREAM_CLASS), ctx, &input_stream_type); mrb_ary_set(mrb, resp, 2, ctx->refs.input_stream); if (mrb_nil_p(ctx->receiver)) { /* is async */ mrb_funcall(mrb, ctx->refs.request, "_set_response", 1, resp); if (mrb->exc != NULL) { fprintf(stderr, "_set_response failed\n"); abort(); } } else { /* send response to the waiting receiver */ h2o_mruby_run_fiber(ctx->generator, detach_receiver(ctx), resp, NULL); } mrb_gc_arena_restore(mrb, gc_arena); }
void* client_thread(void* arg) { CLIENT* client=(CLIENT*)arg; char command[80]; int bytes_read; const char* response; fprintf(stderr,"%s: client connected: %s:%d\n", __FUNCTION__, inet_ntoa(client->address.sin_addr),ntohs(client->address.sin_port)); client->state=RECEIVER_DETACHED; while(1) { bytes_read=recv(client->socket,command,sizeof(command),0); if(bytes_read<=0) { break; } command[bytes_read]=0; response=parse_command(client,command); send(client->socket,response,strlen(response),0); //fprintf(stderr,"%s: response: '%s'\n", __FUNCTION__, response); if (strcmp(response, QUIT_ASAP) == 0) { break; } } close(client->socket); fprintf(stderr,"%s: client disconnected: %s:%d\n", __FUNCTION__, inet_ntoa(client->address.sin_addr),ntohs(client->address.sin_port)); if(client->state==RECEIVER_ATTACHED) { //int rx = client->receiver; //free(client); //receiver[rx].client=(CLIENT*)NULL; //client->state=RECEIVER_DETACHED; detach_receiver (client->receiver, client); } return 0; }
char* parse_command(CLIENT* client,char* command) { // Commands from the client are parsed here to // produce a response to be sent back to the // client. char* token; fprintf(stderr,"parse_command: '%s'\n",command); token=strtok(command," \r\n"); if(token!=NULL) { if(strcmp(token,"attach")==0) { // select receiver token=strtok(NULL," \r\n"); if(token!=NULL) { int rx=atoi(token); return attach_receiver(rx,client); } else { return INVALID_COMMAND; } } else if(strcmp(token,"detach")==0) { // select receiver token=strtok(NULL," \r\n"); if(token!=NULL) { int rx=atoi(token); return detach_receiver(rx,client); } else { return INVALID_COMMAND; } } else if(strcmp(token,"frequency")==0) { // set frequency token=strtok(NULL," \r\n"); if(token!=NULL) { long f=atol(token); return set_frequency(client,f); } else { return INVALID_COMMAND; } /*****************************************************************************/ } else if(strcmp(token,"mox")==0) { // set ptt token=strtok(NULL," \r\n"); if(token!=NULL) { int p=atoi(token); return set_ptt(client,p); } else { return INVALID_COMMAND; } /*****************************************************************************/ } else if(strcmp(token,"start")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"iq")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=atoi(token); } } if(pthread_create(&receiver[client->receiver].audio_thread_id,NULL,audio_thread,&receiver[client->receiver])!=0) { if (softrock_get_verbose()) fprintf(stderr,"failed to create audio thread for tx %d\n",client->receiver); exit(1); } return OK; if(strcmp(token,"bandscope")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { client->bs_port=atoi(token); } return OK; } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else if(strcmp(token,"stop")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"iq")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=-1; } return OK; } else if(strcmp(token,"bandscope")==0) { client->bs_port=-1; } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else { // empty command string return INVALID_COMMAND; } return 0; }
bool sockinfo::attach_receiver(flow_tuple_with_local_if &flow_key) { // This function should be called from within mutex protected context of the sockinfo!!! si_logdbg("Attaching to %s", flow_key.to_str()); // Protect against local loopback used as local_if & peer_ip // rdma_cm will accept it but we don't want to offload it if (flow_key.is_local_loopback()) { si_logdbg("VMA does not offload local loopback IP address"); return false; } if (m_rx_flow_map.find(flow_key) != m_rx_flow_map.end()) { si_logdbg("already attached %s", flow_key.to_str()); return false; } // Allocate resources on specific interface (create ring) net_device_resources_t* p_nd_resources = create_nd_resources((const ip_address)flow_key.get_local_if()); if (NULL == p_nd_resources) { // any error which occurred inside create_nd_resources() was already printed. No need to reprint errors here return false; } // Map flow in local map m_rx_flow_map[flow_key] = p_nd_resources->p_ring; #ifndef DEFINED_SOCKETXTREME // is not defined // Save the new CQ from ring rx_add_ring_cb(flow_key, p_nd_resources->p_ring); #endif // DEFINED_SOCKETXTREME // Attach tuple BULLSEYE_EXCLUDE_BLOCK_START unlock_rx_q(); if (!p_nd_resources->p_ring->attach_flow(flow_key, this)) { lock_rx_q(); si_logdbg("Failed to attach %s to ring %p", flow_key.to_str(), p_nd_resources->p_ring); return false; } set_rx_packet_processor(); lock_rx_q(); BULLSEYE_EXCLUDE_BLOCK_END // Registered as receiver successfully si_logdbg("Attached %s to ring %p", flow_key.to_str(), p_nd_resources->p_ring); // Verify 5 tuple over 3 tuple if (flow_key.is_5_tuple()) { // Check and remove lesser 3 tuple flow_tuple_with_local_if flow_key_3t(flow_key.get_dst_ip(), flow_key.get_dst_port(), INADDR_ANY, INPORT_ANY, flow_key.get_protocol(), flow_key.get_local_if()); rx_flow_map_t::iterator rx_flow_iter = m_rx_flow_map.find(flow_key_3t); if (rx_flow_iter != m_rx_flow_map.end()) { si_logdbg("Removing (and detaching) 3 tuple now that we added a stronger 5 tuple"); detach_receiver(flow_key_3t); } } return true; }
const char* parse_command(CLIENT* client,char* command) { char* token; fprintf(stderr,"parse_command: '%s'\n",command); token=strtok(command," \r\n"); if(token!=NULL) { if(strcmp(token,"attach")==0) { // select receiver token=strtok(NULL," \r\n"); if(token!=NULL) { int rx=atoi(token); return attach_receiver(rx,client); } else { return INVALID_COMMAND; } } else if(strcmp(token,"detach")==0) { // select receiver token=strtok(NULL," \r\n"); if(token!=NULL) { int rx=atoi(token); return detach_receiver(rx,client); } else { return INVALID_COMMAND; } } else if(strcmp(token,"frequency")==0) { // set frequency token=strtok(NULL," \r\n"); if(token!=NULL) { long f=atol(token); return set_frequency (client,f); } else { return INVALID_COMMAND; } } else if(strcmp(token,"start")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp (token,"iq")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=atoi(token); } printf("***************************Starting async data acquisition... CLIENT REQUESTED %d port\n", client->iq_port); (receiver[client->receiver]).samples = 0; if ( hiqsdr_start_asynch_input ( user_data_callback, &(receiver[client->receiver])) < 0 ) { printf("start async input error\n" ); return INVALID_COMMAND; } else { printf("start async input: %s\n", "STARTED"); } return OK; } else if(strcmp(token,"bandscope")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { client->bs_port=atoi(token); } return OK; } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else if(strcmp(token,"dither")==0) { // set frequency token=strtok(NULL," \r\n"); if(token!=NULL) { if (strcmp(token,"on")==0) { return set_dither (client,true); } if (strcmp(token,"off")==0) { return set_dither (client,false); } return INVALID_COMMAND; } else { return INVALID_COMMAND; } } else if(strcmp(token,"setattenuator")==0) { // set attenuator token=strtok(NULL," \r\n"); if(token!=NULL) { long av=atol(token); return set_attenuator (client,av); } else { return INVALID_COMMAND; } } else if(strcmp(token,"selectantenna")==0) { // select antenna token=strtok(NULL," \r\n"); if(token!=NULL) { long antenna = atol(token); return select_antenna (client,antenna); } else { return INVALID_COMMAND; } } else if(strcmp(token,"selectpresel")==0) { // select preselector token=strtok(NULL," \r\n"); if(token!=NULL) { long presel = atol(token); return select_preselector (client,presel); } else { return INVALID_COMMAND; } } else if(strcmp(token,"activatepreamp")==0) { // activate preamplifier token=strtok(NULL," \r\n"); if(token!=NULL) { long preamp = atol(token); return set_preamplifier (client,preamp); } else { return INVALID_COMMAND; } } else if(strcmp(token,"random")==0) { // set frequency token=strtok(NULL," \r\n"); if(token!=NULL) { if (strcmp(token,"on")==0) { return set_random (client,true); } if (strcmp(token,"off")==0) { return set_random (client,false); } return INVALID_COMMAND; } else { return INVALID_COMMAND; } } else if(strcmp(token,"stop")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"iq")==0) { token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=-1; } // try to terminate audio thread close ((receiver[client->receiver]).audio_socket); printf("Quitting...\n"); hiqsdr_stop_asynch_input (); return OK; } else if(strcmp(token,"bandscope")==0) { client->bs_port=-1; } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else if(strcmp(token,"quit")==0) { return QUIT_ASAP; } else if(strcmp(token,"hardware?")==0) { return "OK HiQSDR"; } else if(strcmp(token,"getserial?")==0) { // no serial number concept available in HiQSDR, returns instead the IP address static char buf[50]; snprintf (buf, sizeof(buf), "OK %s", hiqsdr_get_ip_address()); return buf; } else if(strcmp(token,"getpreselector?")==0) { // get preselector token=strtok(NULL," \r\n"); if(token!=NULL) { long p=atol(token); // preselector query if (p >= 0 && p < 16) { static char buf[50]; static char pd[BUFSIZ]; if (!hiqsdr_get_preselector_desc(p, pd)) { snprintf (buf, sizeof(buf), "OK \"%s\"", pd); return buf; } else return INVALID_COMMAND; } else return INVALID_COMMAND; } else { return INVALID_COMMAND; } } else if(strcmp(token,"getpreampstatus?")==0) { // returns preamp status static char buf[50]; snprintf (buf, sizeof(buf), "OK %d", hiqsdr_get_preamp ()); return buf; } else { // invalid command string return INVALID_COMMAND; } } else { // empty command string return INVALID_COMMAND; } return INVALID_COMMAND; }
const char* parse_command(CLIENT* client,char* command) { char* token; fprintf(stderr,"parse_command(Rx%d): '%s'\n",client->receiver,command); token=strtok(command," \r\n"); if(token!=NULL) { if(strcmp(token,"attach")==0) { //COMMAND: 'attach <side>' token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"tx")==0) { //COMMAND: 'attach tx' return attach_transmitter(client); } else { //COMMAND: 'attach rx#' int rx=atoi(token); return attach_receiver(rx,client); } } else { return INVALID_COMMAND; } } else if(strcmp(token,"detach")==0) { //COMMAND: 'detach <side>' token=strtok(NULL," \r\n"); if(token!=NULL) { int rx=atoi(token); return detach_receiver(rx,client); } else { return INVALID_COMMAND; } } else if(strcmp(token,"frequency")==0) { //COMMAND: 'frequency <long freq>' token=strtok(NULL," \r\n"); if(token!=NULL) { long f=atol(token); return set_frequency(client,f); } else { return INVALID_COMMAND; } } else if(strcmp(token,"start")==0) { //COMMAND: 'start <stream> <port#>' token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"iq")==0) { //COMMAND: 'start iq <port#>' token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=atoi(token); } // starts the thread to acquire USRP samples usrp_start (&receiver[client->receiver]); fprintf(stderr,"Started USRP for RX%d\n",client->receiver); //Start the audio thread if(pthread_create(&receiver[client->receiver].audio_thread_id,NULL,audio_thread,client)!=0) { fprintf(stderr,"Failed to create audio thread for rx %d\n",client->receiver); exit(1); } return OK; } else if(strcmp(token,"bandscope")==0) { //COMMAND: 'start bandscope <port#>' token=strtok(NULL," \r\n"); if(token!=NULL) { client->bs_port=atoi(token); } attach_bandscope(client); return OK; } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else if(strcmp(token,"stop")==0) { //COMMAND: 'stop <stream>' token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"iq")==0) { //COMMAND: 'stop iq' token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=-1; } return OK; } else if(strcmp(token,"bandscope")==0) { //COMMAND: 'stop bandscope' client->bs_port=-1; detach_bandscope(client); } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else if(strcmp(token,"preamp")==0) { return NOT_IMPLEMENTED_COMMAND; } else if(strcmp(token,"record")==0) { return NOT_IMPLEMENTED_COMMAND; } else if(strcmp(token,"mox")==0) { return NOT_IMPLEMENTED_COMMAND; } else if(strcmp(token,"ocoutput")==0) { return NOT_IMPLEMENTED_COMMAND; } else { // invalid command string return INVALID_COMMAND; } } else { // empty command string return INVALID_COMMAND; } return INVALID_COMMAND; }
const char* parse_command(CLIENT* client,char* command) { char* token; fprintf(stderr,"parse_command(Rx%d): '%s'\n",client->receiver_num,command); token=strtok(command," \r\n"); if(token!=NULL) { if(strcmp(token,"attach")==0) { //COMMAND: 'attach <side>' token=strtok(NULL," \r\n"); if(token!=NULL) { //COMMAND: 'attach rx#' int rx=atoi(token); const char *resp=attach_receiver(rx,client); if (strcmp(resp, "Error") == 0) return resp; else return attach_transmitter(client, resp); } } else if(strcmp(token,"detach")==0) { //COMMAND: 'detach <side>' token=strtok(NULL," \r\n"); if(token!=NULL) { int rx=atoi(token); return detach_receiver(rx,client); } else { return INVALID_COMMAND; } } else if(strcmp(token,"frequency")==0) { //COMMAND: 'frequency <long freq>' token=strtok(NULL," \r\n"); if(token!=NULL) { long f=atol(token); return set_frequency(client,f); } else { return INVALID_COMMAND; } } else if(strcmp(token,"start")==0) { //COMMAND: 'start <stream> <port#>' token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"iq")==0) { //COMMAND: 'start iq <port#>' token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=atoi(token); } //NOTE:as it is now the usrp-server, only receiver 0's is supported //then it is the only one to issue 'start' command. if (usrp_start_rx_forwarder_thread(client)!=0) exit(1); sleep(1); //some settling time... //This is executed only once if (! usrp_is_started()) { if (usrp_start (client)) fprintf(stderr,"Started USRP for Client %d\n",client->receiver_num); else { fprintf(stderr,"USRP threads start FAILED for rx %d\n",client->receiver_num); exit(1); } } sleep(1); //some settling time //Start the server side tx audio stream receiving thread //Exit program if failed (...?) if (start_tx_audio_thread(client)!=0) exit(1); return OK; } else if(strcmp(token,"bandscope")==0) { //COMMAND: 'start bandscope <port#>' token=strtok(NULL," \r\n"); if(token!=NULL) { client->bs_port=atoi(token); } attach_bandscope(client); return OK; } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else if(strcmp(token,"stop")==0) { //COMMAND: 'stop <stream>' token=strtok(NULL," \r\n"); if(token!=NULL) { if(strcmp(token,"iq")==0) { //COMMAND: 'stop iq' token=strtok(NULL," \r\n"); if(token!=NULL) { client->iq_port=-1; } return OK; } else if(strcmp(token,"bandscope")==0) { //COMMAND: 'stop bandscope' client->bs_port=-1; detach_bandscope(client); } else { // invalid command string return INVALID_COMMAND; } } else { // invalid command string return INVALID_COMMAND; } } else if(strcmp(token,"mox")==0) { //Toggle the mox int v=toggle_mox(client); fprintf(stderr,"Toggled mox to %d for Client %d\n",v, client->receiver_num); return OK; } else if(strcmp(token,"preamp")==0) { return NOT_IMPLEMENTED_COMMAND; } else if(strcmp(token,"record")==0) { return NOT_IMPLEMENTED_COMMAND; } else if(strcmp(token,"ocoutput")==0) { return NOT_IMPLEMENTED_COMMAND; } else { // invalid command string return INVALID_COMMAND; } } // empty command string return INVALID_COMMAND; }