Beispiel #1
0
/** @brief Parse the service descriptor
 * It's used to get the channel name
 * @param buf the buffer containing the descriptor
 * @param service the associated service
 */
void parse_service_descriptor(unsigned char *buf, mumudvb_service_t *service)
{
  /* Service descriptor : 
     descriptor_tag			8
     descriptor_length			8
     service_type			8
     service_provider_name_length	8
     for (i=0;i<N;I++){
     char				8
     }
     service_name_length		8
     for (i=0;i<N;I++){
     Char				8
     }
   */
  int len;

  int encoding_control_char;


  buf += 2;
  if(service)
    service->type=*buf;

  //We show the service type
  display_service_type(*buf, MSG_DEBUG,log_module);


  buf ++; //we skip the service_type
  len = *buf; //provider name len

  //we jump the provider_name + the provider_name_len
  buf += len + 1;

  //Channel name len
  len = *buf;
  buf++;  //we jump the channel_name_len

  char *name;
  char tempbuf[MAX_NAME_LEN];
  if(service)
    name=service->name;
  else
    name=tempbuf;

  //We store the channel name with the raw encoding
  memcpy (name, buf, len);
  name[len] = '\0';
  encoding_control_char=convert_en300468_string(name,MAX_NAME_LEN);
  if(encoding_control_char==-1)
    return;

  log_message( log_module, MSG_DEBUG, "service_name : \"%s\" (name encoding : %s)\n", name,encodings_en300468[encoding_control_char]);
}
Beispiel #2
0
/** @brief Convert the chained list of services into channels
 *
 * This function is called when We've got all the services, we now fill the channels structure
 * After that we go in AUTOCONF_MODE_PIDS to get audio and video pids
 * @param parameters The autoconf parameters
 * @param channels Chained list of channels
 * @param port The mulicast port
 * @param card The card number for the ip address
 * @param unicast_vars The unicast parameters
 * @param fds The file descriptors (for filters and unicast)
 */
int autoconf_services_to_channels(autoconf_parameters_t parameters, mumudvb_channel_t *channels, int port, int card, int tuner, unicast_parameters_t *unicast_vars, multicast_parameters_t *multicast_vars, int server_id)
{

  mumudvb_service_t *actual_service;
  int channel_number=0;
  int found_in_service_id_list;
  int unicast_port_per_channel;
  char tempstring[256];
  actual_service=parameters.services;
  unicast_port_per_channel=strlen(parameters.autoconf_unicast_port)?1:0;

  do
  {
    if(parameters.autoconf_scrambled && actual_service->free_ca_mode)
        log_message( log_module, MSG_DETAIL,"Service scrambled. Name \"%s\"\n", actual_service->name);

    //If there is a service_id list we look if we find it (option autoconf_sid_list)
    if(parameters.num_service_id)
    {
      int actual_service_id;
      found_in_service_id_list=0;
      for(actual_service_id=0;actual_service_id<parameters.num_service_id && !found_in_service_id_list;actual_service_id++)
      {
        if(parameters.service_id_list[actual_service_id]==actual_service->id)
        {
          found_in_service_id_list=1;
          log_message( log_module, MSG_DEBUG,"Service found in the service_id list. Name \"%s\"\n", actual_service->name);
        }
      }
    }
    else //No ts id list so it is found
      found_in_service_id_list=1;

    if(!parameters.autoconf_scrambled && actual_service->free_ca_mode)
      log_message( log_module, MSG_DETAIL,"Service scrambled, no CAM support and no autoconf_scrambled, we skip. Name \"%s\"\n", actual_service->name);
    else if(!actual_service->pmt_pid)
      log_message( log_module, MSG_DETAIL,"Service without a PMT pid, we skip. Name \"%s\"\n", actual_service->name);
    else if(!found_in_service_id_list)
      log_message( log_module, MSG_DETAIL,"Service NOT in the service_id list, we skip. Name \"%s\", id %d\n", actual_service->name, actual_service->id);
    else //service is ok, we make it a channel
    {
      //Cf EN 300 468 v1.9.1 Table 81
      if((actual_service->type==0x01||
          actual_service->type==0x11||
          actual_service->type==0x16||
          actual_service->type==0x19)||
          ((actual_service->type==0x02||
          actual_service->type==0x0a)&&parameters.autoconf_radios))
      {
        log_message( log_module, MSG_DETAIL,"We convert a new service into a channel, sid %d pmt_pid %d name \"%s\" \n",
			  actual_service->id, actual_service->pmt_pid, actual_service->name);
        display_service_type(actual_service->type, MSG_DETAIL, log_module);

        channels[channel_number].channel_type=actual_service->type;
        channels[channel_number].num_packet = 0;
        channels[channel_number].num_scrambled_packets = 0;
        channels[channel_number].scrambled_channel = 0;
        channels[channel_number].streamed_channel = 1;
        channels[channel_number].nb_bytes=0;
        channels[channel_number].pids[0]=actual_service->pmt_pid;
        channels[channel_number].pids_type[0]=PID_PMT;
        channels[channel_number].num_pids=1;
        snprintf(channels[channel_number].pids_language[0],4,"%s","---");
        if(strlen(parameters.name_template))
        {
          strcpy(channels[channel_number].name,parameters.name_template);
          int len=MAX_NAME_LEN;
          char number[10];
          mumu_string_replace(channels[channel_number].name,&len,0,"%name",actual_service->name);
          sprintf(number,"%d",channel_number+1);
          mumu_string_replace(channels[channel_number].name,&len,0,"%number",number);
          //put LCN here
        }
        else
          strcpy(channels[channel_number].name,actual_service->name);
        if(multicast_vars->multicast)
        {
          char number[10];
          char ip[80];
          int len=80;
          if(strlen(parameters.autoconf_multicast_port))
          {
            strcpy(tempstring,parameters.autoconf_multicast_port);
            sprintf(number,"%d",channel_number);
            mumu_string_replace(tempstring,&len,0,"%number",number);
            sprintf(number,"%d",card);
            mumu_string_replace(tempstring,&len,0,"%card",number);
            sprintf(number,"%d",tuner);
            mumu_string_replace(tempstring,&len,0,"%tuner",number);
            sprintf(number,"%d",server_id);
            mumu_string_replace(tempstring,&len,0,"%server",number);
            channels[channel_number].portOut=string_comput(tempstring);
          }
          else
          {
            channels[channel_number].portOut=port;//do here the job for evaluating the string
          }
	  if(multicast_vars->multicast_ipv4)
	    {
	      strcpy(ip,parameters.autoconf_ip4);
	      sprintf(number,"%d",channel_number);
	      mumu_string_replace(ip,&len,0,"%number",number);
	      sprintf(number,"%d",card);
	      mumu_string_replace(ip,&len,0,"%card",number);
	      sprintf(number,"%d",tuner);
	      mumu_string_replace(ip,&len,0,"%tuner",number);
	      sprintf(number,"%d",server_id);
	      mumu_string_replace(ip,&len,0,"%server",number);
	      strcpy(channels[channel_number].ip4Out,ip);
	      log_message( log_module, MSG_DEBUG,"Channel IPv4 : \"%s\" port : %d\n",channels[channel_number].ip4Out,channels[channel_number].portOut);
	    }
	  if(multicast_vars->multicast_ipv6)
	    {
	      strcpy(ip,parameters.autoconf_ip6);
	      sprintf(number,"%d",channel_number);
	      mumu_string_replace(ip,&len,0,"%number",number);
	      sprintf(number,"%d",card);
	      mumu_string_replace(ip,&len,0,"%card",number);
	      sprintf(number,"%d",tuner);
	      mumu_string_replace(ip,&len,0,"%tuner",number);
	      sprintf(number,"%d",server_id);
	      mumu_string_replace(ip,&len,0,"%server",number);
	      strcpy(channels[channel_number].ip6Out,ip);
	      log_message( log_module, MSG_DEBUG,"Channel IPv6 : \"%s\" port : %d\n",channels[channel_number].ip6Out,channels[channel_number].portOut);
	    }	  
        }

        //This is a scrambled channel, we will have to ask the cam for descrambling it
        if(parameters.autoconf_scrambled && actual_service->free_ca_mode)
          channels[channel_number].need_cam_ask=CAM_NEED_ASK;

        //We store the PMT and the service id in the channel
        channels[channel_number].pmt_pid=actual_service->pmt_pid;
        channels[channel_number].service_id=actual_service->id;
        init_rtp_header(&channels[channel_number]); //We init the rtp header in all cases

        if(channels[channel_number].pmt_packet==NULL)
        {
          channels[channel_number].pmt_packet=malloc(sizeof(mumudvb_ts_packet_t));
          if(channels[channel_number].pmt_packet==NULL)
          {
            log_message( log_module, MSG_ERROR,"Problem with malloc : %s file : %s line %d\n",strerror(errno),__FILE__,__LINE__);
            Interrupted=ERROR_MEMORY<<8;
            return -1;
          }
          memset (channels[channel_number].pmt_packet, 0, sizeof( mumudvb_ts_packet_t));//we clear it
          pthread_mutex_init(&channels[channel_number].pmt_packet->packetmutex,NULL);
        }
#ifdef ENABLE_CAM_SUPPORT
        //We allocate the packet for storing the PMT for CAM purposes
        if(channels[channel_number].cam_pmt_packet==NULL)
        {
          channels[channel_number].cam_pmt_packet=malloc(sizeof(mumudvb_ts_packet_t));
          if(channels[channel_number].cam_pmt_packet==NULL)
          {
            log_message( log_module, MSG_ERROR,"Problem with malloc : %s file : %s line %d\n",strerror(errno),__FILE__,__LINE__);
            Interrupted=ERROR_MEMORY<<8;
            return -1;
          }
          memset (channels[channel_number].cam_pmt_packet, 0, sizeof( mumudvb_ts_packet_t));//we clear it
          pthread_mutex_init(&channels[channel_number].cam_pmt_packet->packetmutex,NULL);
        }
#endif
        //We update the unicast port, the connection will be created in autoconf_finish_full
        if(unicast_port_per_channel && unicast_vars->unicast)
        {
          strcpy(tempstring,parameters.autoconf_unicast_port);
          int len;len=256;
          char number[10];
          sprintf(number,"%d",channel_number);
          mumu_string_replace(tempstring,&len,0,"%number",number);
          sprintf(number,"%d",card);
          mumu_string_replace(tempstring,&len,0,"%card",number);
          sprintf(number,"%d",tuner);
          mumu_string_replace(tempstring,&len,0,"%tuner",number);
          sprintf(number,"%d",server_id);
          mumu_string_replace(tempstring,&len,0,"%server",number);
          channels[channel_number].unicast_port=string_comput(tempstring);
          log_message( log_module, MSG_DEBUG,"Channel (direct) unicast port  %d\n",channels[channel_number].unicast_port);
        }
#ifdef ENABLE_TRANSCODING
        //We copy the common transcode options to the new channel
        transcode_copy_options(&global_transcode_opt,&channels[channel_number].transcode_options);
        transcode_options_apply_templates(&channels[channel_number].transcode_options,card,tuner,server_id,channel_number);
#endif
        channel_number++;
      }
      else if(actual_service->type==0x02||actual_service->type==0x0a) //service_type digital radio sound service
        log_message( log_module, MSG_DETAIL,"Service type digital radio sound service, no autoconfigure. (if you want add autoconf_radios=1 to your configuration file) Name \"%s\"\n",actual_service->name);
      else if(actual_service->type!=0) //0 is an empty service
      {
        //We show the service type
        log_message( log_module, MSG_DETAIL,"No autoconfigure due to service type : %s. Name \"%s\"\n",service_type_to_str(actual_service->type),actual_service->name);
      }
    }
    actual_service=actual_service->next;
  }
  while(actual_service && channel_number<MAX_CHANNELS);

  if(channel_number==MAX_CHANNELS)
    log_message( log_module, MSG_WARN,"Warning : We reached the maximum channel number, we drop other possible channels !\n");

  return channel_number;
}