- Timestamp:
- 08/27/19 23:48:37 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/module-dvbapi.c
r11539 r11540 4709 4709 } 4710 4710 4711 static uint32_t dvbapi_extract_sdt_string(char *buf, uint32_t buflen, uint8_t *source, uint32_t sourcelen) 4711 static void dvbapi_create_srvid_line(int32_t demux_id, char *buffer, uint32_t buflen) 4712 { 4713 int32_t i, j, pos = 0; 4714 uint16_t caid_done[32], cur_caid; 4715 uint8_t caid_done_count = 0, skip_caid; 4716 4717 if(demux[demux_id].ECMpidcount == 0) 4718 { 4719 snprintf(buffer, buflen, "%04X@%06X", NO_CAID_VALUE, NO_PROVID_VALUE); 4720 return; 4721 } 4722 4723 for(i = 0; i < demux[demux_id].ECMpidcount && i < 32; i++) 4724 { 4725 skip_caid = 0; 4726 for(j = 0; j < caid_done_count; j++) 4727 { 4728 if(caid_done[j] == demux[demux_id].ECMpids[i].CAID) 4729 { 4730 skip_caid = 1; 4731 break; 4732 } 4733 } 4734 4735 if(skip_caid) 4736 { 4737 continue; 4738 } 4739 4740 cur_caid = demux[demux_id].ECMpids[i].CAID; 4741 pos += snprintf(buffer + pos, buflen - pos, "%s%04X", caid_done_count > 0 ? "," : "", cur_caid == 0 ? NO_CAID_VALUE : cur_caid); 4742 4743 for(j = i; j < demux[demux_id].ECMpidcount; j++) 4744 { 4745 if(demux[demux_id].ECMpids[j].PROVID == 0) 4746 { 4747 continue; 4748 } 4749 4750 if(cur_caid == demux[demux_id].ECMpids[j].CAID) 4751 { 4752 pos += snprintf(buffer + pos, buflen - pos, "@%06X", demux[demux_id].ECMpids[j].PROVID); 4753 } 4754 } 4755 4756 caid_done[caid_done_count] = demux[demux_id].ECMpids[i].CAID; 4757 caid_done_count++; 4758 } 4759 } 4760 4761 static void dvbapi_write_sdt_info(int32_t demux_id, const char *provider_name, const char* service_name, const char *service_type) 4762 { 4763 int8_t did_save_srvid = 0; 4764 int32_t provid, caid, pidindex; 4765 char tmp[256], srvid_line[1024]; 4766 FILE *fpsave = NULL; 4767 4768 pidindex = demux[demux_id].pidindex; 4769 if(pidindex != -1) 4770 { 4771 caid = demux[demux_id].ECMpids[pidindex].CAID; 4772 provid = demux[demux_id].ECMpids[pidindex].PROVID; 4773 } 4774 else 4775 { 4776 if(demux[demux_id].ECMpidcount == 0 || demux[demux_id].ECMpids[0].CAID == 0) 4777 { 4778 caid = NO_CAID_VALUE; 4779 provid = NO_PROVID_VALUE; 4780 } 4781 else 4782 { 4783 caid = demux[demux_id].ECMpids[0].CAID; 4784 provid = demux[demux_id].ECMpids[0].PROVID; 4785 } 4786 } 4787 4788 if(strlen(provider_name) && caid != NO_CAID_VALUE) 4789 { 4790 get_providername_or_null(provid, caid, tmp, sizeof(tmp)); 4791 4792 if(tmp[0] == '\0') 4793 { 4794 get_config_filename(tmp, sizeof(tmp), "oscam.provid"); 4795 4796 if((fpsave = fopen(tmp, "a"))) 4797 { 4798 fprintf(fpsave, "\n%04X@%06X|%s|", caid, provid, provider_name); 4799 fclose(fpsave); 4800 init_provid(); 4801 } 4802 } 4803 } 4804 4805 if(strlen(service_name)) 4806 { 4807 get_servicename_or_null(cur_client(), demux[demux_id].program_number, provid, caid, tmp, sizeof(tmp)); 4808 4809 if(tmp[0] == '\0') 4810 { 4811 get_config_filename(tmp, sizeof(tmp), "oscam.srvid2"); 4812 4813 if(!access(tmp, F_OK) && (fpsave = fopen(tmp, "a"))) 4814 { 4815 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1)) 4816 { 4817 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line)); 4818 4819 if(cfg.dvbapi_write_sdt_prov) 4820 { 4821 fprintf(fpsave, "\n%04X:%s|%s|%s||%s", demux[demux_id].program_number, srvid_line, service_name, service_type, provider_name); 4822 } 4823 else 4824 { 4825 fprintf(fpsave, "\n%04X:%s|%s|%s", demux[demux_id].program_number, srvid_line, service_name, service_type); 4826 } 4827 4828 did_save_srvid = 1; 4829 } 4830 } 4831 else 4832 { 4833 get_config_filename(tmp, sizeof(tmp), "oscam.srvid"); 4834 4835 if((fpsave = fopen(tmp, "a"))) 4836 { 4837 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1)) 4838 { 4839 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line)); 4840 4841 if(cfg.dvbapi_write_sdt_prov) 4842 { 4843 fprintf(fpsave, "\n%s:%04X|%s|%s|%s", srvid_line, demux[demux_id].program_number, provider_name, service_name, service_type); 4844 } 4845 else 4846 { 4847 fprintf(fpsave, "\n%s:%04X||%s|%s", srvid_line, demux[demux_id].program_number, service_name, service_type); 4848 } 4849 4850 did_save_srvid = 1; 4851 } 4852 } 4853 } 4854 4855 if(fpsave) 4856 { 4857 fclose(fpsave); 4858 } 4859 4860 if(did_save_srvid) 4861 { 4862 init_srvid(); 4863 } 4864 } 4865 } 4866 } 4867 4868 static uint32_t dvbapi_extract_sdt_string(char *buf, uint32_t buflen, const uint8_t *source, uint8_t sourcelen) 4712 4869 { 4713 4870 uint32_t i, j, offset = 0; … … 4729 4886 } 4730 4887 4731 if( (sourcelen + 1) > buflen)4888 if(sourcelen > buflen - 1) 4732 4889 { 4733 4890 sourcelen = buflen - 1; … … 4736 4893 if(sourcelen > 0 && source[0] < 0x20) 4737 4894 { 4738 //ISO-8859 4739 if(source[0] >= 0x01 && source[0] <= 0x0B && source[0] != 0x08) 4895 if(source[0] >= 0x01 && source[0] <= 0x0B && source[0] != 0x08) // ISO/IEC 8859 4740 4896 { 4741 4897 offset = 1; 4742 4898 iso_mode = 4 + source[0]; 4743 4899 } 4744 //ISO-8859 4745 else if(source[0] == 0x10 && source[1] == 0x00 && source[2] >= 0x01 && source[2] <= 0x0F && source[2] != 0x0C) 4746 { 4747 offset = 3; iso_mode = source[2]; 4748 } 4749 //Unicode 4750 else if(source[0] == 0x11) 4900 else if(source[0] == 0x10) // Dynamically selected part of ISO/IEC 8859 4901 { 4902 if(source[1] == 0x00 && source[2] >= 0x01 && source[2] <= 0x0F && source[2] != 0x0C) 4903 { 4904 offset = 3; 4905 iso_mode = source[2]; 4906 } 4907 } 4908 else if(source[0] == 0x11) // ISO/IEC 10646 4751 4909 { 4752 4910 offset = 1; 4753 4911 iso_mode = -2; 4754 4912 } 4755 //missing: 0x12 Korean Character Set KSC5601-1987 4756 //missing: 0x13 Simplified Chinese Character Set GB-2312-1980 4757 //missing: 0x14 Big5 subset of ISO/IEC 10646-1 (Traditional Chinese) 4758 //Unicode as UTF-8 4759 else if(source[0] == 0x15) 4913 // missing: 0x12 KSX1001-2004 (Korean Character Set) 4914 // missing: 0x13 GB-2312-1980 (Simplified Chinese Character Set) 4915 // missing: 0x14 Big5 subset of ISO/IEC 10646 (Traditional Chinese) 4916 else if(source[0] == 0x15) // UTF-8 encoding of ISO/IEC 10646 4760 4917 { 4761 4918 offset = 1; 4762 4919 iso_mode = -3; 4763 4920 } 4764 //missing: 0x1F Described by encoding_type_id *standard not finished yet* 4765 //Reserved for future use 4921 // missing: 0x1F Described by encoding_type_id 4766 4922 else 4767 4923 { 4768 NULLFREE(tmpbuf); return 0; 4924 NULLFREE(tmpbuf); 4925 return 0; 4769 4926 } 4770 4927 } … … 4772 4929 if(offset >= sourcelen) 4773 4930 { 4774 NULLFREE(tmpbuf); return 0; 4931 NULLFREE(tmpbuf); 4932 return 0; 4775 4933 } 4776 4934 4777 4935 if(iso_mode >= -1) 4778 4936 { 4779 for(i = 0, j = 0; i < (sourcelen - offset); i++)4780 { 4781 if( ((uint8_t)source[offset + i]) >= 0x80 && ((uint8_t)source[offset + i])<= 0x9F)4937 for(i = 0, j = 0; i < sourcelen - offset; i++) 4938 { 4939 if(source[offset + i] >= 0x80 && source[offset + i] <= 0x9F) 4782 4940 { 4783 4941 continue; 4784 4942 } 4943 4785 4944 tmpbuf[j] = source[offset + i]; 4786 4945 j++; 4787 4946 } 4947 4788 4948 tmpbuf[j] = '\0'; 4789 4949 } … … 4799 4959 memset(buf, 0, buflen); 4800 4960 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: %d offset: %u", iso_mode, offset); 4801 cs_log_dump_dbg(D_DVBAPI, (uint8_t *)tmpbuf, in_bytes, "sdt-info dbg: raw string: 4961 cs_log_dump_dbg(D_DVBAPI, (uint8_t *)tmpbuf, in_bytes, "sdt-info dbg: raw string:"); 4802 4962 4803 4963 if(iso_mode == -1) … … 4839 4999 } 4840 5000 } 4841 else if(iso_mode == -3) 5001 else if(iso_mode == -3) // No conversion, already in UTF-8 4842 5002 { 4843 5003 memcpy(buf, source + offset, sourcelen - offset); … … 4845 5005 cs_log_dbg(D_DVBAPI, "sdt-info dbg: iso_mode: -3 offset: %u", offset); 4846 5006 } 4847 cs_log_dump_dbg(D_DVBAPI, (uint8_t*)buf, strlen(buf), "sdt-info dbg: encoded string: "); 5007 5008 cs_log_dump_dbg(D_DVBAPI, (uint8_t *)buf, strlen(buf), "sdt-info dbg: encoded string:"); 4848 5009 NULLFREE(tmpbuf); 4849 5010 return 1; 4850 5011 } 4851 5012 4852 static void dvbapi_create_srvid_line(int32_t demux_id, char *buffer, uint32_t buflen) 4853 { 4854 int32_t i, j; 4855 uint16_t caid_done[32], cur_caid; 4856 uint8_t caid_done_count = 0, skip_caid; 4857 int32_t pos = 0; 4858 4859 if(demux[demux_id].ECMpidcount == 0) 4860 { 4861 snprintf(buffer, buflen, "%04X@%06X", NO_CAID_VALUE, NO_PROVID_VALUE); 4862 return; 4863 } 4864 4865 for(i = 0; i < demux[demux_id].ECMpidcount && i < 32; i++) 4866 { 4867 skip_caid = 0; 4868 for(j = 0; j < caid_done_count; j++) 4869 { 4870 if(caid_done[j] == demux[demux_id].ECMpids[i].CAID) 4871 { 4872 skip_caid = 1; 4873 break; 4874 } 4875 } 4876 4877 if(skip_caid) 4878 { 4879 continue; 4880 } 4881 4882 cur_caid = demux[demux_id].ECMpids[i].CAID; 4883 pos += snprintf(buffer + pos, buflen - pos, "%s%04X", caid_done_count > 0 ? "," : "", cur_caid == 0 ? NO_CAID_VALUE : cur_caid); 4884 4885 for(j = i; j < demux[demux_id].ECMpidcount; j++) 4886 { 4887 if(demux[demux_id].ECMpids[j].PROVID == 0) 4888 { 4889 continue; 4890 } 4891 4892 if(cur_caid == demux[demux_id].ECMpids[j].CAID) 4893 { 4894 pos += snprintf(buffer + pos, buflen - pos, "@%06X", demux[demux_id].ECMpids[j].PROVID); 4895 } 4896 } 4897 caid_done[caid_done_count] = demux[demux_id].ECMpids[i].CAID; 4898 caid_done_count++; 4899 } 4900 } 4901 4902 static const char *dvbapi_get_service_type(uint8_t service_type_id) 4903 { 4904 switch(service_type_id) 5013 static const char *dvbapi_get_service_type(uint8_t service_type) 5014 { 5015 switch(service_type) 4905 5016 { 4906 5017 case 0x01: 5018 case 0x0B: 4907 5019 case 0x11: 5020 case 0x16: 5021 case 0x17: 5022 case 0x18: 5023 case 0x19: 5024 case 0x1A: 5025 case 0x1B: 5026 case 0x1C: 5027 case 0x1D: 5028 case 0x1E: 5029 case 0x1F: 5030 case 0x20: 4908 5031 return "TV"; 4909 5032 … … 4920 5043 4921 5044 default: 4922 return "TV"; 4923 } 4924 } 4925 4926 static void dvbapi_parse_sdt(int32_t demux_id, uint8_t *buffer, uint32_t length, uint32_t msgid) 4927 { 4928 uint8_t tag, data_length = 0, provider_name_length, service_name_length, service_type; 4929 uint16_t service_id, descriptor_length, dpos; 4930 uint32_t section_length, pos; 4931 int8_t did_save_srvid = 0; 4932 int32_t provid, caid, pidindex; 4933 char provider_name[64], service_name[64], tmp[256], srvid_line[1024]; 4934 const char *type; 4935 FILE *fpsave = NULL; 4936 4937 cs_log_dump_dbg(D_DVBAPI, buffer, length, "sdt-info dbg: sdt data: "); 4938 4939 if(length < 3) 5045 return "unknown"; 5046 } 5047 } 5048 5049 static void dvbapi_parse_service_descriptor(int32_t demux_id, const uint8_t *buffer, uint8_t descriptor_length) 5050 { 5051 uint8_t service_provider_name_length, service_name_length; 5052 char service_provider_name[64], service_name[64]; 5053 const char *service_type; 5054 5055 if(descriptor_length < 3) 5056 { 5057 return; // Service descriptor has a minimum length of 3 bytes 5058 } 5059 5060 service_type = dvbapi_get_service_type(buffer[0]); 5061 5062 service_provider_name_length = buffer[1]; 5063 if(2 + service_provider_name_length + 1 > descriptor_length) 4940 5064 { 4941 5065 return; 4942 5066 } 4943 5067 4944 if(buffer[0] != 0x42) 5068 service_name_length = buffer[2 + service_provider_name_length]; 5069 if(2 + service_provider_name_length + 1 + service_name_length > descriptor_length) 4945 5070 { 4946 5071 return; 4947 5072 } 4948 5073 4949 section_length = b2i(2, buffer + 1) & 0xFFF;4950 if(section_length + 3 != length)5074 if(!dvbapi_extract_sdt_string(service_provider_name, sizeof(service_provider_name), buffer + 2, service_provider_name_length) || 5075 !dvbapi_extract_sdt_string(service_name, sizeof(service_name), buffer + 2 + service_provider_name_length + 1, service_name_length)) 4951 5076 { 4952 5077 return; 4953 5078 } 4954 5079 4955 for(pos = 11; pos + 5 < length; pos += descriptor_length) 4956 { 4957 service_id = b2i(2, buffer + pos); 4958 descriptor_length = b2i(2, buffer + pos + 3) & 0xFFF; 4959 4960 if((pos + 5 + descriptor_length) >= length) 4961 { 4962 return; 4963 } 4964 pos += 5; 5080 cs_log_dbg(D_DVBAPI, "Demuxer %d got service info (provider: %s - name: %s - type: %s)", 5081 demux_id, service_provider_name, service_name, service_type); 5082 5083 dvbapi_write_sdt_info(demux_id, service_provider_name, service_name, service_type); 5084 } 5085 5086 static void dvbapi_parse_sdt(int32_t demux_id, const uint8_t *buffer, uint16_t length, uint32_t msgid) 5087 { 5088 uint8_t descriptor_tag, descriptor_length; 5089 uint16_t service_id, descriptors_loop_length, i, j; 5090 5091 if(buffer[0] != 0x42) // SDT sections with table_id value 0x42 describe the actual TS 5092 { 5093 return; 5094 } 5095 5096 // Get the tsid and onid (in enigma2 STBs we have 5097 // already received them in the CA PMT message) 5098 demux[demux_id].tsid = b2i(2, buffer + 3); 5099 demux[demux_id].onid = b2i(2, buffer + 8); 5100 5101 for(i = 11; i + 5 < length; i += 5 + descriptors_loop_length) 5102 { 5103 service_id = b2i(2, buffer + i); 5104 descriptors_loop_length = b2i(2, buffer + i + 3) & 0x0FFF; 4965 5105 4966 5106 if(service_id != demux[demux_id].program_number) … … 4969 5109 } 4970 5110 4971 for(dpos = 0; dpos + 1 < descriptor_length; dpos += (2 + data_length)) 4972 { 4973 tag = buffer[pos + dpos]; 4974 data_length = buffer[pos + dpos + 1]; 4975 4976 if(dpos + 1 + data_length >= descriptor_length) 4977 { 4978 break; 4979 } 4980 4981 if(tag != 0x48) 4982 { 4983 continue; 4984 } 4985 4986 if(dpos + 3 >= descriptor_length) 4987 { 4988 break; 4989 } 4990 4991 service_type = buffer[pos + dpos + 2]; 4992 provider_name_length = buffer[pos + dpos + 3]; 4993 4994 if((dpos + 4 + provider_name_length + 1) > descriptor_length) 4995 { 4996 break; 4997 } 4998 4999 service_name_length = buffer[pos + dpos + 4 + provider_name_length]; 5000 if((dpos + 4 + provider_name_length + 1 + service_name_length) > descriptor_length) 5001 { 5002 break; 5003 } 5004 5005 pidindex = demux[demux_id].pidindex; 5006 if(pidindex !=-1) 5007 { 5008 provid = demux[demux_id].ECMpids[pidindex].PROVID; 5009 caid = demux[demux_id].ECMpids[pidindex].CAID; 5010 } 5011 else 5012 { 5013 if(demux[demux_id].ECMpidcount == 0 || demux[demux_id].ECMpids[0].CAID == 0) 5014 { 5015 caid = NO_CAID_VALUE; 5016 provid = NO_PROVID_VALUE; 5017 } 5018 else 5019 { 5020 caid = demux[demux_id].ECMpids[0].CAID; 5021 provid = demux[demux_id].ECMpids[0].PROVID; 5022 } 5023 } 5024 5025 if(!dvbapi_extract_sdt_string(provider_name, sizeof(provider_name), buffer + pos + dpos + 4, provider_name_length)) 5026 { 5027 break; 5028 } 5029 5030 if(!dvbapi_extract_sdt_string(service_name, sizeof(service_name), buffer + pos + dpos + 4 + provider_name_length + 1, service_name_length)) 5031 { 5032 break; 5033 } 5034 5035 cs_log_dbg(D_DVBAPI,"sdt-info (provider: %s - channel: %s)", provider_name, service_name); 5036 dvbapi_stop_filter(demux_id, TYPE_SDT, msgid); 5037 5038 if(strlen(provider_name) && caid != NO_CAID_VALUE) 5039 { 5040 get_providername_or_null(provid, caid, tmp, sizeof(tmp)); 5041 if(tmp[0] == '\0') 5042 { 5043 get_config_filename(tmp, sizeof(tmp), "oscam.provid"); 5044 if((fpsave = fopen(tmp, "a"))) 5045 { 5046 fprintf(fpsave, "\n%04X@%06X|%s|", caid, provid, provider_name); 5047 fclose(fpsave); 5048 init_provid(); 5049 } 5050 } 5051 } 5052 5053 if(strlen(service_name)) 5054 { 5055 get_servicename_or_null(cur_client(), service_id, provid, caid, tmp, sizeof(tmp)); 5056 5057 if(tmp[0] == '\0') 5058 { 5059 type = dvbapi_get_service_type(service_type); 5060 get_config_filename(tmp, sizeof(tmp), "oscam.srvid2"); 5061 5062 if(!access(tmp, F_OK) && (fpsave = fopen(tmp, "a"))) 5063 { 5064 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1)) 5065 { 5066 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line)); 5067 5068 if(cfg.dvbapi_write_sdt_prov) 5069 { 5070 fprintf(fpsave, "\n%04X:%s|%s|%s||%s", service_id, srvid_line, service_name, type, provider_name); 5071 } 5072 else 5073 { 5074 fprintf(fpsave, "\n%04X:%s|%s|%s", service_id, srvid_line, service_name, type); 5075 } 5076 did_save_srvid = 1; 5077 } 5078 } 5079 else 5080 { 5081 get_config_filename(tmp, sizeof(tmp), "oscam.srvid"); 5082 5083 if((fpsave = fopen(tmp, "a"))) 5084 { 5085 if((caid != NO_CAID_VALUE) || (cfg.dvbapi_read_sdt > 1)) 5086 { 5087 dvbapi_create_srvid_line(demux_id, srvid_line, sizeof(srvid_line)); 5088 5089 if(cfg.dvbapi_write_sdt_prov) 5090 { 5091 fprintf(fpsave, "\n%s:%04X|%s|%s|%s", srvid_line, service_id, provider_name, service_name, type); 5092 } 5093 else 5094 { 5095 fprintf(fpsave, "\n%s:%04X||%s|%s", srvid_line, service_id, service_name, type); 5096 } 5097 did_save_srvid = 1; 5098 } 5099 } 5100 } 5101 5102 if(fpsave) 5103 { 5104 fclose(fpsave); 5105 } 5106 5107 if(did_save_srvid) 5108 { 5109 init_srvid(); 5110 } 5111 } 5112 } 5113 return; 5114 } 5111 for(j = 0; j + 1 < descriptors_loop_length; j += 2 + descriptor_length) 5112 { 5113 descriptor_tag = buffer[i + 5 + j]; 5114 descriptor_length = buffer[i + 5 + j + 1]; 5115 5116 if(descriptor_tag == 0x48) 5117 { 5118 dvbapi_parse_service_descriptor(demux_id, buffer + i + 5 + j + 2, descriptor_length); 5119 } 5120 } 5121 5122 dvbapi_stop_filter(demux_id, TYPE_SDT, msgid); 5115 5123 } 5116 5124 }
Note:
See TracChangeset
for help on using the changeset viewer.