int krad_mixer_handler ( krad_mixer_t *krad_mixer, krad_ipc_server_t *krad_ipc ) {

  uint32_t command;
  uint32_t ebml_id;
  uint64_t payload_loc;
  uint64_t ebml_data_size;

  krad_mixer_portgroup_t *portgroup;
  krad_mixer_portgroup_t *portgroup2;
  krad_mixer_portgroup_rep_t portgroup_rep;
  uint64_t response;
  krad_mixer_output_t output_type;
  kr_address_t address;
  
  char portgroupname[64];
  char portgroupname2[64];  
  char controlname[16];  
  char string[64];
  float floatval;
  int numbers[16];
  int direction;
  int number;
  int p;
  int sd1;
  int sd2;
      
  sd1 = 0;
  sd2 = 0;
  ebml_id = 0;
  number = 0;
  direction = 0;
  payload_loc = 0;

  portgroupname[0] = '\0';
  portgroupname2[0] = '\0';
  controlname[0] = '\0';
  string[0] = '\0';

  krad_ipc_server_read_command ( krad_ipc, &command, &ebml_data_size );

  switch ( command ) {
    case EBML_ID_KRAD_MIXER_CMD_SET_CONTROL:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, controlname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      if (ebml_id == EBML_ID_KRAD_MIXER_CONTROL_VALUE) {
        floatval = krad_ebml_read_float (krad_ipc->current_client->krad_ebml, ebml_data_size);
        krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
        number = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
        if ((number == 0) && (krad_ipc_server_current_client_is_subscriber (krad_ipc))) {
          krad_mixer_set_portgroup_control ( krad_mixer, portgroupname, controlname, floatval, number, krad_ipc->current_client );
        } else {
          krad_mixer_set_portgroup_control ( krad_mixer, portgroupname, controlname, floatval, number, NULL );
        }
      }
      return 0;
    case EBML_ID_KRAD_MIXER_CMD_SET_EFFECT_CONTROL:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      number = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      numbers[5] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, controlname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      floatval = krad_ebml_read_float (krad_ipc->current_client->krad_ebml, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      numbers[6] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      numbers[7] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
      portgroup = krad_mixer_get_portgroup_from_sysname (krad_mixer, portgroupname);
      if (portgroup != NULL) {
        kr_effects_effect_set_control (portgroup->effects, number, numbers[5],
                   kr_effects_string_to_effect_control(portgroup->effects->effect[number].effect_type,
                                                        controlname),
                                       floatval, numbers[6], numbers[7]);
      }
      break;
    case EBML_ID_KRAD_MIXER_CMD_PUSH_TONE:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      if (krad_mixer->push_tone == NULL) {
        krad_ebml_read_string (krad_ipc->current_client->krad_ebml, krad_mixer->push_tone_value, ebml_data_size);
        krad_mixer->push_tone = krad_mixer->push_tone_value;
      } else {
        krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
      }
      break;
    case EBML_ID_KRAD_MIXER_CMD_PORTGROUP_XMMS2_CMD:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
      krad_mixer_portgroup_xmms2_cmd (krad_mixer, portgroupname, string);
      break;
    case EBML_ID_KRAD_MIXER_CMD_PLUG_PORTGROUP:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);    
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname2, ebml_data_size);
      krad_mixer_plug_portgroup (krad_mixer, portgroupname, portgroupname2);
      break;
    case EBML_ID_KRAD_MIXER_CMD_UNPLUG_PORTGROUP:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size); 
      if (ebml_id != EBML_ID_KRAD_MIXER_PORTGROUP_NAME ) {
        printke ("hrm wtf3\n");
      }
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      if (ebml_id != EBML_ID_KRAD_MIXER_PORTGROUP_NAME ) {
        printke ("hrm wtf3\n");
      }
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname2, ebml_data_size);
      krad_mixer_unplug_portgroup (krad_mixer, portgroupname, portgroupname2);
      break;
    case EBML_ID_KRAD_MIXER_CMD_BIND_PORTGROUP_XMMS2:  
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
      krad_mixer_portgroup_bind_xmms2 (krad_mixer, portgroupname, string);
      break;
    case EBML_ID_KRAD_MIXER_CMD_UNBIND_PORTGROUP_XMMS2:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_mixer_portgroup_unbind_xmms2 (krad_mixer, portgroupname);
      break;
    case EBML_ID_KRAD_MIXER_CMD_LIST_PORTGROUPS:
      for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) {
        portgroup = krad_mixer->portgroup[p];
        if ((portgroup != NULL) && ((portgroup->active == 1) || (portgroup->active == 2))) {
          krad_mixer_portgroup_to_rep (portgroup, &portgroup_rep);
          krad_ipc_server_response_start_with_address_and_type ( krad_ipc,
                                                                 &portgroup->address,
                                                                 EBML_ID_KRAD_SUBUNIT_INFO,
                                                                 &response);
          krad_ipc_server_payload_start ( krad_ipc, &payload_loc);
          krad_mixer_portgroup_rep_to_ebml (&portgroup_rep, krad_ipc->current_client->krad_ebml2);
          krad_ipc_server_payload_finish ( krad_ipc, payload_loc );
          krad_ipc_server_response_finish ( krad_ipc, response );
        }
      }
      return 1;
    case EBML_ID_KRAD_MIXER_CMD_CREATE_PORTGROUP:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
      if (strncmp(string, "output", 6) == 0) {
        direction = OUTPUT;
        output_type = DIRECT;
      } else {
        if (strncmp(string, "auxout", 6) == 0) {
          direction = OUTPUT;
          output_type = AUX;
        } else {
          direction = INPUT;
          output_type = NOTOUTPUT;
        }
      }
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      numbers[0] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
      portgroup = krad_mixer_portgroup_create (krad_mixer, portgroupname, direction, output_type, numbers[0],
                  0.0f, krad_mixer->master_mix, KRAD_AUDIO, NULL, JACK);
      if (portgroup != NULL) {
        if (portgroup->direction == INPUT) {
          krad_radio_broadcast_subunit_created ( krad_ipc->ipc_broadcaster, &portgroup->address, (void *)portgroup);
        }
        krad_mixer_set_portgroup_control (krad_mixer, portgroupname, "volume", 100.0f, 500, NULL);
      } else {
        printke ("Krad Mixer: Failed to create portgroup: %s", portgroupname);
      }
      return 0;
    case EBML_ID_KRAD_MIXER_CMD_DESTROY_PORTGROUP:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      portgroup = krad_mixer_get_portgroup_from_sysname (krad_mixer, portgroupname);
      if (portgroup != NULL) {
        krad_mixer_portgroup_destroy (krad_mixer, portgroup);
        address.path.unit = KR_MIXER;
        address.path.subunit.mixer_subunit = KR_PORTGROUP;
        strncpy (address.id.name, portgroupname, sizeof (address.id.name));
        krad_radio_broadcast_subunit_destroyed (krad_ipc->ipc_broadcaster, &address);
      }
      break;
    case EBML_ID_KRAD_MIXER_CMD_PORTGROUP_INFO:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      portgroup = krad_mixer_get_portgroup_from_sysname (krad_mixer, portgroupname);
      if ((portgroup != NULL) && ((portgroup->active == 1) || (portgroup->active == 2))) {
        krad_ipc_server_response_start_with_address_and_type ( krad_ipc,
                                                               &portgroup->address,
                                                               EBML_ID_KRAD_SUBUNIT_INFO,
                                                               &response);
        krad_ipc_server_payload_start ( krad_ipc, &payload_loc);
        krad_mixer_portgroup_to_rep(portgroup, &portgroup_rep);
        krad_mixer_portgroup_rep_to_ebml (&portgroup_rep, krad_ipc->current_client->krad_ebml2);
        krad_ipc_server_payload_finish ( krad_ipc, payload_loc );
        krad_ipc_server_response_finish ( krad_ipc, response );
      }
      return 1;
    case EBML_ID_KRAD_MIXER_CMD_UPDATE_PORTGROUP:      
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, portgroupname, ebml_data_size);
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      if (ebml_id == EBML_ID_KRAD_MIXER_PORTGROUP_CROSSFADE_NAME) {
        krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
        portgroup = krad_mixer_get_portgroup_from_sysname (krad_mixer, portgroupname);
        if (portgroup != NULL) {
          if (portgroup->crossfade_group != NULL) {
            krad_mixer_crossfade_group_destroy (krad_mixer, portgroup->crossfade_group);
            if (strlen(string) == 0) {
              return 0;
            }
          }
          if (strlen(string) > 0) {
            portgroup2 = krad_mixer_get_portgroup_from_sysname (krad_mixer, string);
            if (portgroup2 != NULL) {
              if (portgroup2->crossfade_group != NULL) {
                krad_mixer_crossfade_group_destroy (krad_mixer, portgroup2->crossfade_group);
              }
              if (portgroup != portgroup2) {
                krad_mixer_crossfade_group_create (krad_mixer, portgroup, portgroup2);
              }
            }
          }
        }
      }
      if (ebml_id == EBML_ID_KRAD_MIXER_MAP_CHANNEL) {
        krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
        numbers[0] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
        krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
        numbers[1] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);     
        portgroup = krad_mixer_get_portgroup_from_sysname (krad_mixer, portgroupname);
        if (portgroup != NULL) {
          krad_mixer_portgroup_map_channel (portgroup, numbers[0], numbers[1]);      
        }
      }
      if (ebml_id == EBML_ID_KRAD_MIXER_MIXMAP_CHANNEL) {
        krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
        numbers[0] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
        krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
        numbers[1] = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
        portgroup = krad_mixer_get_portgroup_from_sysname (krad_mixer, portgroupname);
        if (portgroup != NULL) {
          krad_mixer_portgroup_mixmap_channel (portgroup, numbers[0], numbers[1]);
        }
      }
      break;
    case EBML_ID_KRAD_MIXER_CMD_LOCAL_AUDIOPORT_DESTROY:
      for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) {
        portgroup = krad_mixer->portgroup[p];
        if (portgroup->io_type == KLOCALSHM) {
          krad_mixer_portgroup_destroy (krad_mixer, portgroup);
        }
      }
      break;
    case EBML_ID_KRAD_MIXER_CMD_LOCAL_AUDIOPORT_CREATE:
      sd1 = 0;
      sd2 = 0;
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);  
      krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
      if (strncmp(string, "output", 6) == 0) {
        direction = OUTPUT;
      } else {
        direction = INPUT;
      }
      sd1 = krad_ipc_server_recvfd (krad_ipc->current_client);
      sd2 = krad_ipc_server_recvfd (krad_ipc->current_client);
      printk ("AUDIOPORT_CREATE Got FD's %d and %d\n", sd1, sd2);
      krad_mixer_local_portgroup_create (krad_mixer, "localport", direction, sd1, sd2);
      break;
    case EBML_ID_KRAD_MIXER_CMD_GET_INFO:
      numbers[0] = 0;
      numbers[1] = 0;
      numbers[2] = 0;
      for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) {
        portgroup = krad_mixer->portgroup[p];
        if ((portgroup != NULL) && ((portgroup->active == 1) || (portgroup->active == 2))) {
          if (portgroup->direction == INPUT) {
            numbers[0]++;
          }
          if (portgroup->direction == OUTPUT) {
            numbers[1]++;
          }
          if (portgroup->direction == MIX) {
            numbers[2]++;
          }
        }
      }
      krad_ipc_server_response_start_with_address_and_type ( krad_ipc,
                                                             &krad_mixer->address,
                                                             EBML_ID_KRAD_UNIT_INFO,
                                                             &response);
      krad_ipc_server_payload_start ( krad_ipc, &payload_loc);
      krad_ipc_server_respond_number ( krad_ipc, EBML_ID_KRAD_MIXER_SAMPLE_RATE,
                                       krad_mixer_get_sample_rate (krad_mixer));
      krad_ipc_server_respond_number ( krad_ipc, EBML_ID_KRAD_MIXER_PORTGROUP_COUNT, numbers[0]);
      krad_ipc_server_respond_number ( krad_ipc, EBML_ID_KRAD_MIXER_PORTGROUP_COUNT, numbers[1]);
      krad_ipc_server_respond_number ( krad_ipc, EBML_ID_KRAD_MIXER_PORTGROUP_COUNT, numbers[2]);
      if (krad_mixer->pusher == JACK) {
        krad_ipc_server_respond_string ( krad_ipc, EBML_ID_KRAD_MIXER_TIME_SOURCE, "Jack");
      } else {
        krad_ipc_server_respond_string ( krad_ipc, EBML_ID_KRAD_MIXER_TIME_SOURCE, "Internal Chronometer");
      }
      krad_ipc_server_payload_finish ( krad_ipc, payload_loc );
      krad_ipc_server_response_finish ( krad_ipc, response );
      return 1;
    case EBML_ID_KRAD_MIXER_CMD_SET_SAMPLE_RATE:
      krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);
      number = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
      if (krad_mixer_has_pusher (krad_mixer) == 0) {
        krad_mixer_set_sample_rate (krad_mixer, number);
      }
      break;
  }
  return 0;
}
Exemple #2
0
uint64_t krad_ipc_server_read_number (krad_ipc_server_t *krad_ipc_server, uint64_t data_size) {

	return krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, data_size);
}
int krad_transponder_handler ( krad_transponder_t *krad_transponder, krad_ipc_server_t *krad_ipc ) {

	krad_link_t *krad_link;

	uint32_t ebml_id;

	uint32_t command;
	uint64_t ebml_data_size;
  kr_address_t address;
	uint64_t element;
	uint64_t response;
	uint64_t payload_loc;
	char string[256];	
	
	uint64_t bigint;
	//int regint;
	uint8_t tinyint;
	int k;
	int devices;
	//float floatval;
	
	string[0] = '\0';
	bigint = 0;
	k = 0;
	
	krad_ipc_server_read_command ( krad_ipc, &command, &ebml_data_size);

	switch ( command ) {

		case EBML_ID_KRAD_TRANSPONDER_CMD_LIST_LINKS:
			//printk ("krad transponder handler! LIST_LINKS");
			
			krad_Xtransponder_list ( krad_transponder->krad_Xtransponder );
			
			krad_ipc_server_response_start ( krad_ipc, EBML_ID_KRAD_TRANSPONDER_MSG, &response);

			
			for (k = 0; k < KRAD_TRANSPONDER_MAX_LINKS; k++) {
				if (krad_transponder->krad_link[k] != NULL) {
					printk ("Link %d Active: %s", k, krad_transponder->krad_link[k]->mount);
					krad_transponder_link_to_ebml ( krad_ipc->current_client, krad_transponder->krad_link[k]);
				}
			}
			

			krad_ipc_server_response_finish ( krad_ipc, response );	
						
			break;
			
		case EBML_ID_KRAD_TRANSPONDER_CMD_CREATE_LINK:
			for (k = 0; k < KRAD_TRANSPONDER_MAX_LINKS; k++) {
				if (krad_transponder->krad_link[k] == NULL) {

					krad_transponder->krad_link[k] = krad_link_prepare (k);
					krad_link = krad_transponder->krad_link[k];
					krad_link->link_num = k;
					krad_link->krad_radio = krad_transponder->krad_radio;
					krad_link->krad_transponder = krad_transponder;
					krad_transponder_ebml_to_link ( krad_ipc, krad_link );
					krad_link_start (krad_link);
				
				  /*
					if ((krad_link->operation_mode == TRANSMIT) || (krad_link->operation_mode == RECORD)) {
						if (krad_link_wait_codec_init (krad_link) == 0) {
							krad_transponder_broadcast_link_created ( krad_ipc, krad_link );
						}
					} else {
						krad_transponder_broadcast_link_created ( krad_ipc, krad_link );
					}
          */
					break;
				}
			}
			break;
		case EBML_ID_KRAD_TRANSPONDER_CMD_DESTROY_LINK:
			tinyint = krad_ipc_server_read_number (krad_ipc, ebml_data_size);
			k = tinyint;
			//printk ("krad transponder handler! DESTROY_LINK: %d %u", k, tinyint);
			
			if (krad_transponder->krad_link[k] != NULL) {
				krad_link_destroy (krad_transponder->krad_link[k]);
				krad_transponder->krad_link[k] = NULL;
			}
			/*
			krad_ipc_server_simple_number_broadcast ( krad_ipc,
													  EBML_ID_KRAD_TRANSPONDER_MSG,
													  EBML_ID_KRAD_TRANSPONDER_LINK_DESTROYED,
													  EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER,
											 		  k);			
			*/
			break;
		case EBML_ID_KRAD_TRANSPONDER_CMD_UPDATE_LINK:
			//printk ("krad transponder handler! UPDATE_LINK");

			krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	
			
			if (ebml_id == EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER) {
			
				tinyint = krad_ipc_server_read_number (krad_ipc, ebml_data_size);
				k = tinyint;
				//printk ("krad transponder handler! UPDATE_LINK: %d %u", k, tinyint);
			
				if (krad_transponder->krad_link[k] != NULL) {

					krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

					if (krad_transponder->krad_link[k]->audio_codec == OPUS) {

						/*
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_APPLICATION) {
							krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
							if (strncmp(string, "OPUS_APPLICATION_VOIP", 21) == 0) {
								krad_opus_set_application (krad_transponder->krad_link[k]->krad_opus, OPUS_APPLICATION_VOIP);
							}
							if (strncmp(string, "OPUS_APPLICATION_AUDIO", 22) == 0) {
								krad_opus_set_application (krad_transponder->krad_link[k]->krad_opus, OPUS_APPLICATION_AUDIO);
							}
							if (strncmp(string, "OPUS_APPLICATION_RESTRICTED_LOWDELAY", 36) == 0) {
								krad_opus_set_application (krad_transponder->krad_link[k]->krad_opus, OPUS_APPLICATION_RESTRICTED_LOWDELAY);
							}
						}
						*/
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_SIGNAL) {
							krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);

							krad_opus_set_signal (krad_transponder->krad_link[k]->krad_opus, 
													krad_opus_string_to_signal(string));
						}
						
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BANDWIDTH) {
							
							krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
							
							krad_opus_set_bandwidth (krad_transponder->krad_link[k]->krad_opus, 
													krad_opus_string_to_bandwidth(string));
						}						

						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BITRATE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if ((bigint >= 500) && (bigint <= 512000)) {
								krad_opus_set_bitrate (krad_transponder->krad_link[k]->krad_opus, bigint);
							}
						}
						
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_COMPLEXITY) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if ((bigint >= 0) && (bigint <= 10)) {
								krad_opus_set_complexity (krad_transponder->krad_link[k]->krad_opus, bigint);
							}
						}						
				
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_FRAME_SIZE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
							if ((bigint == 120) || (bigint == 240) || (bigint == 480) || (bigint == 960) || (bigint == 1920) || (bigint == 2880)) {
								krad_opus_set_frame_size (krad_transponder->krad_link[k]->krad_opus, bigint);
							}
						}
						
						//FIXME verify ogg container
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OGG_MAX_PACKETS_PER_PAGE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
							if ((bigint > 0) && (bigint < 200)) {					
								krad_ogg_set_max_packets_per_page (krad_transponder->krad_link[k]->krad_container->krad_ogg, bigint);
							}
						}
					}
					
					if (krad_transponder->krad_link[k]->video_codec == THEORA) {
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_THEORA_QUALITY) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
							krad_theora_encoder_quality_set (krad_transponder->krad_link[k]->krad_theora_encoder, bigint);
						}
					}				
					
					if (krad_transponder->krad_link[k]->video_codec == VP8) {
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_BITRATE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_bitrate_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_MIN_QUANTIZER) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_min_quantizer_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_MAX_QUANTIZER) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_max_quantizer_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_DEADLINE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_deadline_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}												
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_FORCE_KEYFRAME) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_want_keyframe (krad_transponder->krad_link[k]->krad_vpx_encoder);
							}
						}
					}
          /*
					if ((ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BANDWIDTH) || (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_SIGNAL)) {

						krad_ipc_server_advanced_string_broadcast ( krad_ipc,
																  EBML_ID_KRAD_TRANSPONDER_MSG,
																  EBML_ID_KRAD_TRANSPONDER_LINK_UPDATED,
																  EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER,
														 		  k,
														 		  ebml_id,
														 		  string);

					} else {
						krad_ipc_server_advanced_number_broadcast ( krad_ipc,
																  EBML_ID_KRAD_TRANSPONDER_MSG,
																  EBML_ID_KRAD_TRANSPONDER_LINK_UPDATED,
																  EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER,
														 		  k,
														 		  ebml_id,
														 		  bigint);
					}
					*/
				}
			}
			
			break;
			
    case EBML_ID_KRAD_TRANSPONDER_CMD_LIST_ADAPTERS:

			address.path.unit = KR_TRANSPONDER;
			address.path.subunit.transponder_subunit = KR_ADAPTER;
#ifdef KR_LINUX
			devices = krad_v4l2_detect_devices ();			

			for (k = 0; k < devices; k++) {
				if (krad_v4l2_get_device_filename (k, string) > 0) {
          address.id.number = k;
          krad_ipc_server_response_start_with_address_and_type ( krad_ipc,
                                                                 &address,
                                                                 EBML_ID_KRAD_SUBUNIT_INFO,
                                                                 &response);
          krad_ipc_server_payload_start ( krad_ipc, &payload_loc);

					krad_ebml_write_string (krad_ipc->current_client->krad_ebml2, EBML_ID_KRAD_TRANSPONDER_V4L2_DEVICE_FILENAME, string);

	        //krad_ebml_start_element (kr_ipc->current_client->krad_ebml2, EBML_ID_KRAD_RADIO_REMOTE_STATUS, &element);
			    //krad_ipc_server_respond_string ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_INTERFACE, kr_ipc->tcp_interface[i]);
			    //krad_ipc_server_respond_number ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_PORT, kr_ipc->tcp_port[i]);
	        //krad_ebml_finish_element (kr_ipc->current_client->krad_ebml2, element);

          krad_ipc_server_payload_finish ( krad_ipc, payload_loc );
          krad_ipc_server_response_finish ( krad_ipc, response );
        }
      }
#endif
			devices = krad_decklink_detect_devices();

			for (k = 0; k < devices; k++) {
        krad_decklink_get_device_name (k, string);
        address.id.number = k;
        krad_ipc_server_response_start_with_address_and_type ( krad_ipc,
                                                               &address,
                                                               EBML_ID_KRAD_SUBUNIT_INFO,
                                                               &response);
        krad_ipc_server_payload_start ( krad_ipc, &payload_loc);

				krad_ebml_write_string (krad_ipc->current_client->krad_ebml2, EBML_ID_KRAD_TRANSPONDER_DECKLINK_DEVICE_NAME, string);

	        //krad_ebml_start_element (kr_ipc->current_client->krad_ebml2, EBML_ID_KRAD_RADIO_REMOTE_STATUS, &element);
			    //krad_ipc_server_respond_string ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_INTERFACE, kr_ipc->tcp_interface[i]);
			    //krad_ipc_server_respond_number ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_PORT, kr_ipc->tcp_port[i]);
	        //krad_ebml_finish_element (kr_ipc->current_client->krad_ebml2, element);

        krad_ipc_server_payload_finish ( krad_ipc, payload_loc );
        krad_ipc_server_response_finish ( krad_ipc, response );
      }

      return 1;
	
		case EBML_ID_KRAD_TRANSPONDER_CMD_LISTEN_ENABLE:
		
			krad_ebml_read_element ( krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_RADIO_TCP_PORT) {
				printke ("hrm wtf6");
			}
		
			bigint = krad_ebml_read_number ( krad_ipc->current_client->krad_ebml, ebml_data_size);
		
			krad_receiver_listen_on (krad_transponder->krad_receiver, bigint);
		
			break;

		case EBML_ID_KRAD_TRANSPONDER_CMD_LISTEN_DISABLE:
		
			krad_receiver_stop_listening (krad_transponder->krad_receiver);
		
			break;
			
			
		case EBML_ID_KRAD_TRANSPONDER_CMD_TRANSMITTER_ENABLE:
		
			krad_ebml_read_element ( krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_RADIO_TCP_PORT) {
				printke ("hrm wtf6");
			}
		
			bigint = krad_ebml_read_number ( krad_ipc->current_client->krad_ebml, ebml_data_size);
		
			krad_transmitter_listen_on (krad_transponder->krad_transmitter, bigint);
		
			break;

		case EBML_ID_KRAD_TRANSPONDER_CMD_TRANSMITTER_DISABLE:
		
			krad_transmitter_stop_listening (krad_transponder->krad_transmitter);
		
			break;			

	}

	return 0;
}
Exemple #4
0
int krad_websocket_ipc_handler ( krad_ipc_client_t *krad_ipc, void *ptr ) {

	krad_ipc_session_data_t *krad_ipc_session_data = (krad_ipc_session_data_t *)ptr;

	int has_xmms2;

	uint32_t message;
	uint32_t ebml_id;	
	uint64_t ebml_data_size;
	//uint64_t element;
	int list_count;
	int list_size;
	int i;
	float floatval;	
	char portname_actual[256];
	char controlname_actual[1024];
	char string_actual[1024];	
	int bytes_read;
	string_actual[0] = '\0';	
	portname_actual[0] = '\0';
	controlname_actual[0] = '\0';
	
	char *portname = portname_actual;
	char *controlname = controlname_actual;
	char *string = string_actual;	
	char crossfadename_actual[1024];	
	char *crossfadename = crossfadename_actual;
	float crossfade;	
	
	uint64_t number;
	uint64_t numbers[16];	
	
	char tag_item_actual[256];	
	char tag_name_actual[256];
	char tag_value_actual[1024];
	
	tag_name_actual[0] = '\0';
	tag_item_actual[0] = '\0';
	tag_value_actual[0] = '\0';
	
	char *tag_item = tag_item_actual;
	char *tag_name = tag_name_actual;
	char *tag_value = tag_value_actual;
	
	krad_link_rep_t *krad_link_rep;
	
	krad_link_rep = NULL;
	
	has_xmms2 = 0;	
	
	bytes_read = 0;
	ebml_id = 0;
	list_size = 0;	
	floatval = 0;
	message = 0;
	ebml_data_size = 0;
	//element = 0;
	i = 0;
	
	krad_ebml_read_element ( krad_ipc->krad_ebml, &message, &ebml_data_size);

	switch ( message ) {


	
		case EBML_ID_KRAD_RADIO_MSG:
				//printf("Received KRAD_RADIO_MSG %zu bytes of data.\n", ebml_data_size);		
		
			krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);
			switch ( ebml_id ) {
			
				case EBML_ID_KRAD_RADIO_SYSTEM_CPU_USAGE:
					number = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					//printk ("System CPU Usage: %d%%", number);
					krad_websocket_set_cpu_usage (krad_ipc_session_data, number);
					break;

				case EBML_ID_KRAD_RADIO_TAG_LIST:
					//printf("Received Tag list %"PRIu64" bytes of data.\n", ebml_data_size);
					list_size = ebml_data_size;
					while ((list_size) && ((bytes_read += krad_ipc_client_read_tag ( krad_ipc, &tag_item, &tag_name, &tag_value )) <= list_size)) {
						//printk ("%s: %s - %s", tag_item, tag_name, tag_value);
						krad_websocket_set_tag (krad_ipc_session_data, tag_item, tag_name, tag_value);
						if (bytes_read == list_size) {
							break;
						}
					}
					break;
				case EBML_ID_KRAD_RADIO_TAG:
					krad_ipc_client_read_tag_inner ( krad_ipc, &tag_item, &tag_name, &tag_value );
					//printk ("%s: %s - %s", tag_item, tag_name, tag_value);
					krad_websocket_set_tag (krad_ipc_session_data, tag_item, tag_name, tag_value);
					break;

				case EBML_ID_KRAD_RADIO_UPTIME:
					number = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					printkd ("Uptime: %"PRIu64"", number);
					break;
				case EBML_ID_KRAD_RADIO_SYSTEM_INFO:
					krad_ebml_read_string (krad_ipc->krad_ebml, string, ebml_data_size);
					printkd ("%s", string);
					break;

			}
	
	
			break;
	
		case EBML_ID_KRAD_LINK_MSG:
			krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);

			switch ( ebml_id ) {
			
				case EBML_ID_KRAD_LINK_DECKLINK_LIST:

					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);
					list_count = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					for (i = 0; i < list_count; i++) {
						krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);						
						krad_ebml_read_string (krad_ipc->krad_ebml, string, ebml_data_size);
						printk("%d: %s\n", i, string);
						krad_websocket_add_decklink_device (krad_ipc_session_data, string, i);						
					}	
					break;
							
			
				case EBML_ID_KRAD_LINK_LINK_LIST:
					//printf("Received LINK control list %"PRIu64" bytes of data.\n", ebml_data_size);

					list_size = ebml_data_size;
					i = 0;
					while ((list_size) && ((bytes_read += krad_ipc_client_read_link ( krad_ipc, string, &krad_link_rep)) <= list_size)) {
						//printkd ("%d: %s\n", i, string);						
						krad_websocket_add_link (krad_ipc_session_data, krad_link_rep);
						i++;
						free (krad_link_rep);
						
						if (bytes_read == list_size) {
							break;
						}
					}	
					break;
					
					
				case EBML_ID_KRAD_LINK_LINK_CREATED:
				
					krad_ipc_client_read_link ( krad_ipc, string, &krad_link_rep);
					krad_websocket_add_link (krad_ipc_session_data, krad_link_rep);
					free (krad_link_rep);
					
					break;

				case EBML_ID_KRAD_LINK_LINK_UPDATED:
			
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);				
					numbers[0] = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);

					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);			
					if ((ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BANDWIDTH) || (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_SIGNAL)) {
						krad_ebml_read_string (krad_ipc->krad_ebml, string, ebml_data_size);
						krad_websocket_update_link_string (krad_ipc_session_data, numbers[0], ebml_id, string);
					} else {
						numbers[1] = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
						krad_websocket_update_link_number (krad_ipc_session_data, numbers[0], ebml_id, numbers[1]);						
					}

					break;

				case EBML_ID_KRAD_LINK_LINK_DESTROYED:
					
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);				
					numbers[0] = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					
					krad_websocket_remove_link (krad_ipc_session_data, numbers[0]);
					
					break;

				default:
					//printkd ("Received KRAD_LINK_MSG %"PRIu64" bytes of data.\n", ebml_data_size);
					break;
			}

			break;

		case EBML_ID_KRAD_COMPOSITOR_MSG:
			//printkd ("krad_radio_websocket_ipc_handler got message from krad COMPOSITOR\n");
			krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);
			
			switch ( ebml_id ) {
				case EBML_ID_KRAD_COMPOSITOR_FRAME_RATE:
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);				
					numbers[0] = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);					
					numbers[1] = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					krad_websocket_set_frame_rate ( krad_ipc_session_data, numbers[0], numbers[1]);
					break;
				case EBML_ID_KRAD_COMPOSITOR_FRAME_SIZE:
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);				
					numbers[0] = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);					
					numbers[1] = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					krad_websocket_set_frame_size ( krad_ipc_session_data, numbers[0], numbers[1]);
					break;
			}
					
			
			break;
			
		case EBML_ID_KRAD_MIXER_MSG:
//			printkd ("krad_radio_websocket_ipc_handler got message from krad mixer\n");
//			krad_ipc_server_broadcast ( krad_ipc, EBML_ID_KRAD_MIXER_MSG, EBML_ID_KRAD_MIXER_CONTROL, portname, controlname, floatval);
			krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);
			
			switch ( ebml_id ) {
				case EBML_ID_KRAD_MIXER_CONTROL:
					//printkd ("Received mixer control list %"PRIu64" bytes of data.\n", ebml_data_size);

					krad_ipc_client_read_mixer_control ( krad_ipc, &portname, &controlname, &floatval );
					krad_websocket_set_control ( krad_ipc_session_data, portname, controlname, floatval);
					
					break;	
				case EBML_ID_KRAD_MIXER_PORTGROUP_LIST:
					//printkd ("Received PORTGROUP list %"PRIu64" bytes of data.\n", ebml_data_size);
					list_size = ebml_data_size;
					while ((list_size) && ((bytes_read += krad_ipc_client_read_portgroup ( krad_ipc, portname, &floatval, crossfadename, &crossfade, &has_xmms2 )) <= list_size)) {
						krad_websocket_add_portgroup (krad_ipc_session_data, portname, floatval, crossfadename, crossfade, has_xmms2);
						
						if (bytes_read == list_size) {
							break;
						}
					}	
					break;
				case EBML_ID_KRAD_MIXER_PORTGROUP_CREATED:
					//printk ("PORTGROUP_CREATED msg %"PRIu64" bytes", ebml_data_size );
					
					krad_ipc_client_read_portgroup ( krad_ipc, portname, &floatval, crossfadename, &crossfade, &has_xmms2 );

					krad_websocket_add_portgroup (krad_ipc_session_data, portname, floatval, crossfadename, crossfade, has_xmms2);

					break;
				
				case EBML_ID_KRAD_MIXER_PORTGROUP_DESTROYED:
				
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);	

					if (ebml_id != EBML_ID_KRAD_MIXER_PORTGROUP_NAME) {
						//printkd ("hrm wtf2\n");
					} else {
						//printkd ("tag name size %zu\n", ebml_data_size);
					}
				
					krad_ebml_read_string (krad_ipc->krad_ebml, portname_actual, ebml_data_size);
					//printkd ("PORTGROUP_DESTROYED msg %zu bytes  \n", ebml_data_size );
					
					krad_websocket_remove_portgroup (krad_ipc_session_data, portname_actual);
					
					break;
					
				case EBML_ID_KRAD_MIXER_PORTGROUP_UPDATED:
					//printkd ("PORTGROUP_UPDATED msg %"PRIu64" bytes  \n", ebml_data_size );
				
					krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);

					if (ebml_id == EBML_ID_KRAD_MIXER_PORTGROUP_NAME) {				
			
						krad_ebml_read_string (krad_ipc->krad_ebml, portname_actual, ebml_data_size);
			
			
						krad_ebml_read_element (krad_ipc->krad_ebml, &ebml_id, &ebml_data_size);	

						if (ebml_id == EBML_ID_KRAD_MIXER_PORTGROUP_CROSSFADE_NAME) {
					
							krad_ebml_read_string (krad_ipc->krad_ebml, crossfadename, ebml_data_size);
					
							//printkd ("ya %s %s\n", portname_actual, crossfadename);
					
						}
					}
				
				
					break;
					
				case EBML_ID_KRAD_MIXER_SAMPLE_RATE:
					number = krad_ebml_read_number (krad_ipc->krad_ebml, ebml_data_size);
					krad_websocket_set_sample_rate ( krad_ipc_session_data, number);
					break;
					
					
			}
		
		
			break;
	
	}

	return 0;

}
void krad_transponder_ebml_to_link ( krad_ipc_server_t *krad_ipc_server, krad_link_t *krad_link ) {

	uint32_t ebml_id;
	uint64_t ebml_data_size;

	char string[512];
	
	memset (string, '\0', 512);

	//FIXME default
	krad_link->av_mode = AUDIO_AND_VIDEO;

	krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
	
	if (ebml_id != EBML_ID_KRAD_TRANSPONDER_LINK) {
		printk ("hrm wtf");
	} else {
		//printk ("tag size %zu", ebml_data_size);
	}
	
	krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
	
	if (ebml_id != EBML_ID_KRAD_LINK_LINK_OPERATION_MODE) {
		printk ("hrm wtf");
	} else {
		//printk ("tag size %zu", ebml_data_size);
	}
	
	krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
	
	krad_link->operation_mode = krad_link_string_to_operation_mode (string);

	if (krad_link->operation_mode == RECEIVE) {
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_TRANSPORT_MODE) {
			printk ("hrm wtf2");
		} else {
			//printk ("tag name size %zu", ebml_data_size);
		}

		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
		
		krad_link->transport_mode = krad_link_string_to_transport_mode (string);
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_PORT) {
			printk ("hrm wtf3");
		} else {
			//printk ("tag value size %zu", ebml_data_size);
		}

		krad_link->port = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
	
		//TEMP KLUDGE
		krad_link->av_mode = AUDIO_ONLY;

	}
	
	if (krad_link->operation_mode == PLAYBACK) {
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_TRANSPORT_MODE) {
			printk ("hrm wtf2");
		} else {
			//printk ("tag name size %zu", ebml_data_size);
		}

		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
		
		krad_link->transport_mode = krad_link_string_to_transport_mode (string);
	
		if (krad_link->transport_mode == FILESYSTEM) {
	
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_FILENAME) {
				printk ("hrm wtf3");
			} else {
				//printk ("tag value size %zu", ebml_data_size);
			}

			krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->input, ebml_data_size);
		}
		
		if (krad_link->transport_mode == TCP) {
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_HOST) {
				printk ("hrm wtf2");
			} else {
				//printk ("tag name size %zu", ebml_data_size);
			}

			krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->host, ebml_data_size);
	
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_PORT) {
				printk ("hrm wtf3");
			} else {
				//printk ("tag value size %zu", ebml_data_size);
			}

			krad_link->port = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);

			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_MOUNT) {
				printk ("hrm wtf2");
			} else {
				//printk ("tag name size %zu", ebml_data_size);
			}

			krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->mount, ebml_data_size);
		}
	}
	
	if (krad_link->operation_mode == CAPTURE) {
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
	
		if (ebml_id != EBML_ID_KRAD_LINK_LINK_VIDEO_SOURCE) {
			printk ("hrm wtf");
		} else {
			//printk ("tag size %zu", ebml_data_size);
		}
	
		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
	
		krad_link->video_source = krad_link_string_to_video_source (string);
		
		if (krad_link->video_source == DECKLINK) {
			krad_link->av_mode = AUDIO_AND_VIDEO;
		}
		
		if ((krad_link->video_source == V4L2) || (krad_link->video_source == X11)) {
			krad_link->av_mode = VIDEO_ONLY;
		}

		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
	
		if (ebml_id != EBML_ID_KRAD_LINK_LINK_CAPTURE_DEVICE) {
			printk ("hrm wtf");
		} else {
			//printk ("tag size %zu", ebml_data_size);
		}
	
		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->device, ebml_data_size);
	
		if (krad_link->video_source == V4L2) {
			if (strlen(krad_link->device) == 0) {
				strncpy(krad_link->device, DEFAULT_V4L2_DEVICE, sizeof(krad_link->device));
			}
			
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
	
			if (ebml_id != EBML_ID_KRAD_LINK_LINK_CAPTURE_CODEC) {
				printk ("hrm wtf");
			} else {
				//printk ("tag size %zu", ebml_data_size);
			}
	
			string[0] = '\0';
			
			krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);

			krad_link->video_passthru = 0;

			if (strlen(string)) {
				krad_link->video_codec = krad_string_to_codec (string);
				if (krad_link->video_codec == H264) {
					krad_link->video_passthru = 1;
				}
		    if (strstr(string, "pass") != NULL) {
					krad_link->video_passthru = 1;
				}
			}
		}

		if (krad_link->video_source == DECKLINK) {
			if (strlen(krad_link->device) == 0) {
				strncpy(krad_link->device, DEFAULT_DECKLINK_DEVICE, sizeof(krad_link->device));
			}
			
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
	
			if (ebml_id != EBML_ID_KRAD_LINK_LINK_CAPTURE_DECKLINK_AUDIO_INPUT) {
				printk ("hrm wtf");
			} else {
				//printk ("tag size %zu", ebml_data_size);
			}
	
			krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->audio_input, ebml_data_size);	
		}		

		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_VIDEO_WIDTH) {
			printk ("hrm wtf2v");
		} else {
			krad_link->capture_width = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
		}
		
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_VIDEO_HEIGHT) {
			printk ("hrm wtf2v");
		} else {
			krad_link->capture_height = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
		}

		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_FPS_NUMERATOR) {
			printk ("hrm wtf2v");
		} else {
			krad_link->fps_numerator = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
		}
		
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_FPS_DENOMINATOR) {
			printk ("hrm wtf2v");
		} else {
			krad_link->fps_denominator = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
		}
	}
	
	if ((krad_link->operation_mode == TRANSMIT) || (krad_link->operation_mode == RECORD)) {

		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
	
		if (ebml_id != EBML_ID_KRAD_LINK_LINK_AV_MODE) {
			printk ("hrm wtf0");
		} else {
			//printk ("tag size %zu", ebml_data_size);
		}
	
	
		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
	
		krad_link->av_mode = krad_link_string_to_av_mode (string);

		if ((krad_link->av_mode == VIDEO_ONLY) || (krad_link->av_mode == AUDIO_AND_VIDEO)) {
		
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_VIDEO_CODEC) {
				printk ("hrm wtf2v1");
			} else {
				//printk ("tag name size %zu", ebml_data_size);
			}

			krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
			
			krad_link->video_codec = krad_string_to_codec (string);
			
			if ((krad_link->video_codec == H264) || (krad_link->video_codec == MJPEG)) {

				krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

				if (ebml_id != EBML_ID_KRAD_LINK_LINK_USE_PASSTHRU_CODEC) {
					printk ("hrm wtf2v2");
				} else {
					//printk ("tag name size %zu", ebml_data_size);
				}

				krad_link->video_passthru = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);

				if (krad_link->video_codec == MJPEG) {
					//FIXME should be optional
					krad_link->video_passthru = 1;
				}

			}			
			
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_VIDEO_WIDTH) {
				printk ("hrm wtf2v3");
			} else {
				krad_link->encoding_width = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
			}
			
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_VIDEO_HEIGHT) {
				printk ("hrm wtf2v4");
			} else {
				krad_link->encoding_height = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
			}
			
			
			if ((krad_link->video_codec == VP8) || (krad_link->video_codec == H264)) {
				krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

				if (ebml_id != EBML_ID_KRAD_LINK_LINK_VP8_BITRATE) {
					printk ("hrm wtf2v5");
				} else {
					krad_link->vp8_bitrate = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
				}
			}
			
			if (krad_link->video_codec == THEORA) {
				krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

				if (ebml_id != EBML_ID_KRAD_LINK_LINK_THEORA_QUALITY) {
					printk ("hrm wtf2v6");
				} else {
					krad_link->theora_quality = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
				}
			}			
			
		}

		if ((krad_link->av_mode == AUDIO_ONLY) || (krad_link->av_mode == AUDIO_AND_VIDEO)) {
		
			krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_LINK_LINK_AUDIO_CODEC) {
				printk ("hrm wtf2a7");
			} else {
				//printk ("tag name size %zu", ebml_data_size);
			}

			krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
			
			krad_link->audio_codec = krad_string_to_codec (string);
			
			if (krad_link->audio_codec == VORBIS) {
				krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
				if (ebml_id == EBML_ID_KRAD_LINK_LINK_VORBIS_QUALITY) {
					krad_link->vorbis_quality = krad_ebml_read_float (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
				}
			}

			if (krad_link->audio_codec == OPUS) {
				krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
				if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BITRATE) {
					krad_link->opus_bitrate = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
				}
			}
			
			if (krad_link->audio_codec == FLAC) {
				krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);
				if (ebml_id == EBML_ID_KRAD_LINK_LINK_FLAC_BIT_DEPTH) {
					krad_link->flac_bit_depth = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);
				}
			}			
			
			
		}
	}
	
	
	if (krad_link->operation_mode == TRANSMIT) {
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_TRANSPORT_MODE) {
			printk ("hrm wtf28");
		} else {
			//printk ("tag name size %zu", ebml_data_size);
		}

		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, string, ebml_data_size);
		
		krad_link->transport_mode = krad_link_string_to_transport_mode (string);
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_HOST) {
			printk ("hrm wtf29");
		} else {
			//printk ("tag name size %zu", ebml_data_size);
		}

		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->host, ebml_data_size);
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_PORT) {
			printk ("hrm wtf310");
		} else {
			//printk ("tag value size %zu", ebml_data_size);
		}

		krad_link->port = krad_ebml_read_number (krad_ipc_server->current_client->krad_ebml, ebml_data_size);

		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_MOUNT) {
			printk ("hrm wtf212");
		} else {
			//printk ("tag name size %zu", ebml_data_size);
		}

		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->mount, ebml_data_size);

		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_PASSWORD) {
			printk ("hrm wtf213");
		} else {
			//printk ("tag name size %zu", ebml_data_size);
		}

		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->password, ebml_data_size);

		if (strstr(krad_link->mount, "flac") != NULL) {
			krad_link->audio_codec = FLAC;
		}
			
		if (strstr(krad_link->mount, ".opus") != NULL) {
			krad_link->audio_codec = OPUS;
		}

	}
	
	if (krad_link->operation_mode == RECORD) {
	
		krad_ebml_read_element (krad_ipc_server->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

		if (ebml_id != EBML_ID_KRAD_LINK_LINK_FILENAME) {
			printk ("hrm wtf214");
		} else {
			//printk ("tag name size %zu", ebml_data_size);
		}

		krad_ebml_read_string (krad_ipc_server->current_client->krad_ebml, krad_link->output, ebml_data_size);

		if (strstr(krad_link->output, "flac") != NULL) {
			krad_link->audio_codec = FLAC;
		}
			
		if (strstr(krad_link->output, ".opus") != NULL) {
			krad_link->audio_codec = OPUS;
		}

		krad_link->transport_mode = FILESYSTEM;

	}
}