# HG changeset patch # User Yoshiki Yazawa # Date 1234766509 -32400 # Node ID 67e8eca28a802cc7fbf007d5ed73f52254eff99f initial import diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/.cproject --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/.cproject Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/.project --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/.project Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,82 @@ + + + arib25 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + ?name? + + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/arib25} + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/.settings/org.eclipse.core.resources.prefs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/.settings/org.eclipse.core.resources.prefs Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,3 @@ +#Wed Jan 23 22:50:22 JST 2008 +eclipse.preferences.version=1 +encoding/=Windows-31J diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/Makefile Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,6 @@ +all: + cd src; make all + +clean: + cd src; make clean + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/arib_std_b25.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/arib_std_b25.sln Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "arib_std_b25", "arib_std_b25.vcproj", "{6E77C1AC-A31A-49B9-9A52-9FE1E03B8FEC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6E77C1AC-A31A-49B9-9A52-9FE1E03B8FEC}.Debug|Win32.ActiveCfg = Debug|Win32 + {6E77C1AC-A31A-49B9-9A52-9FE1E03B8FEC}.Debug|Win32.Build.0 = Debug|Win32 + {6E77C1AC-A31A-49B9-9A52-9FE1E03B8FEC}.Release|Win32.ActiveCfg = Release|Win32 + {6E77C1AC-A31A-49B9-9A52-9FE1E03B8FEC}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/arib_std_b25.vcproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/arib_std_b25.vcproj Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/readme.txt Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,334 @@ +ýz + +@ARIB STD-B25 dlmFeXgvO\[XR[h + +yo[Wz + +@0.2.0 + +yҁz + +@Ζ am (MOGI, Kazuhiro) +@kazhiro@marumo.ne.jp + +yꎟzzz + +@http://www.marumo.ne.jp/db2008_4.htm#09 + +@邢 + +@http://www.marumo.ne.jp/junk/arib_std_b25-0.2.1.lzh + +yړIz + +@ARIB STD-B25 ̎dl𗝉ׂ́AQlp̎ƂČJ + +ywiz + +@2011 N 7 ̒nAiOgTAȒnfW^ +@M@̔̔҂Ă + +@AARIB ̕W͂킴ƔɂĊJ܂ +@悤ƂĂƂvȂقǂɈӖsĂȋLqɂȂĂ +@̂܂܂ł͒ቿiM@̊JȂǕs”\Ɏv + +@ŁAȂ ARIB Wǂ݁A͈͂\[X +@R[ȟ`ɂ܂Ƃ߂ČJ邱Ƃɂ + +@̃R[hȎM@̊J̈ꏕƂȂ邱Ƃ҂ + +@ȂA܂łdlړIƂ̂ł邽߁Arhς +@oCit@C͔zzȂ + +ý͈z + +@CA VXe (B-CAS J[h֘A) 𒆐S ECM ̏ƃXg[ +@Í̕AEMM ܂ł + +@EMM bZ[W֘A͖ƂȂĂ + +yvO̓‹z + +@ISO 7816 Ή IC J[h[_CXg[ꂽ Windows PC +@z蓮‹Ƃ + +@ISO 7816 ΉX}[gJ[h[_[͈ʂ +@uZJ[hΉ IC J[h[_vue-Tax Ή IC J[h[_v +@ȂǂƂ 4000 ~xŔ̔Ă̂p”\ł + +@}NZ HX-520UJJ Őɓ삷邱ƂmFĂ + +y\[XR[h̃CZXɂ‚āz + +@E\[XR[h𗘗pƂɂāÃguĂ +@@Ζ am͐ӔC𕉂Ȃ +@E\[XR[h𗘗pƂɂāAvOɖ肪Ă +@@Ζ am͐ӔC𕉂Ȃ + +@L 2 ɓӂč쐬ꂽ񎟓I앨ɑ΂āAΖ am +@҂ɗ^鏔sgȂ + +yvO̍\z + +@Earib_std_b25.h/c + +@@ARIB STD-B25 Lڂ̏s߂̃W[ +@@MPEG-2 TS ̕ACA VXe (B-CAS J[h) @\̌ĂяoA +@@MULTI2 @\̌ĂяoS + +@Ets_section_parser.h/c + +@@MPEG-2 TS ̃ZNV`f[^̕S + +@Eb_cas_card.h/c + +@@CA VXe (B-CAS J[h) ̃\[XǗђڂ̐ +@@S + +@Emulti2.h/c + +@@MULTI2 Í̕ƕS + +@Etd.c + +@@eXghCo +@@PAT/PMT/ECM ܂ MPEG-2 TS t@Cǂݍ݁A +@@MPEG-2 TS t@Co͂ + +@@R}hCIvV MULTI2 Í̃Ehw”\ +@@Ehw肵Ȃꍇ̏l 4 + +@@̃Eh 4 MULTI2 pł 32 ɑ + +@@ARIB STD-B25 ł MULTI2 ̃Eh͔Jp[^ +@@Ŏۂ̃Eh͐”\ł + +y̗z + +@EN + +@@1 AvP[V B_CAS_CARD W[̃CX^X +@@@쐬AB_CAS_CARD W[ɁA˗ + +@@1.a B_CAS_CARD W[ WIN32 API ̃X}[gJ[h֘A +@@@@API ĂяoACA VXeɐڑ +@@1.b B_CAS_CARD W[ ARIB STD-B25 Lڂ́u +@@@@ݒR}h CA VXeɔsAVXe (64 byte) +@@@@ CBC (8 byte) 󂯎 + +@@2 AvP[V ARIB_STD_B25 W[̃CX^X +@@@쐬AB_CAS_CARD W[ ARIB_STD_B25 W[ +@@@o^ + +@Ef[^ + +@@1 AvP[V ARIB_STD_B25 W[ɏf[^ +@@@񋟂AARIB_STD_B25 W[珈f[^ +@@@ăt@Cɏo͂Ă + +@@EARIB_STD_B25 W[ + +@@@1 TS pPbg̃jbgTCY (188/192/204 ȂǂʓI) +@@@@肳ĂȂꍇ 8K ܂œ̓f[^obt@ĂA +@@@@jbgTCY肷 +@@@@jbgTCYłȂꍇ́AG[I + +@@@2 PAT ĂȂꍇAPAT ł܂œ +@@@@f[^obt@ +@@@@PAT łɃobt@TCY 16M 𒴉߂ꍇ +@@@@G[I +@@@@PAT łꍇAvOz쐬 PID }bv +@@@@zɓo^ + +@@@3 PAT ɓo^Ă PMT ׂĂ邩Aǂꂩ +@@@@ЂƂ‚ PMT 2 –ڂ̃ZNV܂œ +@@@@f[^obt@ +@@@@L𖞂Ƀobt@TCY 32M 𒴉߂ꍇ +@@@@G[I +@@@@PMT 閈 ECM ̗LmFAECM ݂ +@@@@ꍇ̓fNv^쐬ăvOɏXg[ +@@@@ PID }bvŊ֘At + +@@@4 PMT ɓo^Ă ECM ׂĂ邩Aǂꂩ +@@@@ЂƂ‚ ECM 2 –ڂ̃ZNV܂œ +@@@@f[^obt@ +@@@@L𖞂Ƀobt@TCY 32M 𒴉߂ꍇ +@@@@G[I +@@@@e ECM ɑ΂āAŏ̃ZNVf[^_ +@@@@MULTI2 W[̃CX^XfNv^ɍ쐬 +@@@@ECM ZNVf[^ B_CAS_CARD W[ɒ񋟂 +@@@@XNu󂯎AMULTI2 W[ɃVXeA +@@@@ CBC ԁAXNunAMULTI2 ̏ +@@@@s + +@@@5.a ÍĂ TS pPbgł΁APID Ή +@@@@@ECM Xg[肵AfNv^ MULTI2 W[ +@@@@@ɕďo̓obt@ɐς +@@@@ +@@@5.b ÍĂȂ TS pPbgł΁Â܂܏o +@@@@@obt@ɐς + +@@@5.c CAT oꍇAEMM PID 擾 EMM ̏ +@@@@@s + +@@@5.d EMM 󂯎ꍇAB-CAS J[h ID ƔrA +@@@@@Ă EMM ł B-CAS J[hɈnď +@@@@@# EMM IvVw肳Ăꍇ + +@@@6 ECM XVꂽꍇAB_CAS_CARD W[ɏ +@@@@˗Ao͂ꂽXNu MULTI2 W[ +@@@@o^ + +@@@7 PMT XVꂽꍇAECM PID ωĂΐV +@@@@fNv^쐬 4 ɖ߂ + +@@@8 PAT XVꂽꍇAvOzj +@@@@3 ɖ߂ + +@EI + +@@1 eW[mۂ\[X + +yXVz + +@E2008, 4/9 - ver. 0.2.1 + +@@PAT XVɕRꂪĂoOC +@@(ver. 0.2.0 ł̃GoO) + +@@ PID (PMT ɋLڂĂȂXg[) ݂ꍇ +@@TS ECM ЂƂ‚Ȃ΁A ECM ŕ`ɕύX + +@@EMM B-CAS J[hւ̑MIvVőI”\ɕύX (-m) +@@i󋵂̕\IvVőI”\ɕύX (-v) +@@ʓd (EMMMp) \IvVlj (-p) + +@@http://www.marumo.ne.jp/db2008_4.htm#9 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.2.1.lzh + +@E2008, 4/6 - ver. 0.2.0 + +@@EMM Ή +@@p B-CAS J[h ID EMM oꍇAEMM +@@B-CAS J[hɓnlj + +@@ECM ̍ۂɖ_񉞓ԂꂽꍇA׌ÿׁA +@@ȍ~A PID ECM B-CAS J[hŏȂ悤ɕ +@@X (EMM ꍇ͍Ă ECM 悤ɖ߂) + +@@i nn.nn% ̏ŕWG[o͂ɕ\悤ɕύX +@@ +@@http://www.marumo.ne.jp/db2008_4.htm#6 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.2.0.lzh + +@E2008, 3/31 - ver. 0.1.9 + +@@MULTI2 W[̃CX^X쐻̏󋵂ŁAMULTI2 +@@@\ĂяoėO𔭐邱ƂoOC + +@@# pb`񋟂ĂꂽɊ + +@@http://www.marumo.ne.jp/db2008_3.htm#31 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.9.lzh + +@E2008, 3/24 - ver. 0.1.8 + +@@-s IvV (NULL pPbg̍폜) lj +@@-s 1 NULL pPbgo̓t@Cɂ͕ۑȂȂ +@@ftHg -s 0 NULL pPbgێ + +@@http://www.marumo.ne.jp/db2008_3.htm#24 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.8.lzh + +@E2008, 3/17 - ver. 0.1.7 + +@@arib_std_b25.h Ɂuextern "C" {v‚R[hȂ +@@(C++ R[h痘pꍇɃRpCG[𔭐) +@@C + +@@TS pPbg̒rŃXg[؂ւP[XŖ肪 +@@ɂȂ悤ɁAarib_std_b25.c ̃R[hC + +@@http://www.marumo.ne.jp/db2008_3.htm#17 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.7.lzh + +@E2008, 3/16 - ver. 0.1.6 + +@@PMT XV̍ہAECM ֘Ȁ󋵂ύX (XNu - mXN +@@u̐؂ւAECM PID ̕ύX) sĂAꂪ +@@fĂȂC + +@@http://www.marumo.ne.jp/db2008_3.htm#16 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.6.lzh + +@E2008, 2/14 + +@@readme.txt (̃t@C) C +@@\[XR[h̃CZXɂ‚Ă̋Lqlj + +@E2008, 2/12 - ver. 0.1.5 + +@@PMT ̍XVɔAǂ̃vOɂȂȂ PID (Xg +@@[) ŃpPbgMꑱꍇÃpPbg̕ +@@łȂȂĂC + +@@http://www.marumo.ne.jp/db2008_2.htm#12 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.5.lzh + +@E2008, 2/2 - ver. 0.1.4 + +@@ver. 0.1.3 ł PMT @ύXɖ肪APMT XVꂽ +@@ꍇAȍ~ŐȏsȂȂĂoOC + +@@B-CAS J[hƂ̒ʐMŃG[ꍇ̃gC@\ +@@ĂȂoOC + +@@http://www.marumo.ne.jp/db2008_2.htm#2 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.4.lzh + +@E2008, 2/1 - ver. 0.1.3 + +@@LŖ_Ԃ B-CAS J[hgۂɁA擾 +@@ĂȂɂ炸AԈŕĂɑΏ + +@@擾łȂ ECM Ɋ֘AtꂽXg[ł͕ +@@s킸AXNutOc܂ܓ͂fʂ`ɕύX +@@擾łȂ ECM ݂ꍇAIɃ`lԍ +@@B-CAS J[h擾łG[ԍxbZ[WƂĕ\ +@@`ɕύX + +@@ÍĂȂvOŗO𔭐ĂoOC + +@@http://www.marumo.ne.jp/db2008_2.htm#1 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.3.lzh + +@E2008, 1/11 - ver. 0.1.2 + +@@fW^ BS ŁAPAT ɓo^Ă̂ɁAXg[ +@@PMT ؏oȂƂꍇɑΉ + +@@PMT ̋Lqq̈ 2 CA_descriptor ݂ꍇɑΉ +@@ arib_std_b25.c ł̏\ύX + +@@ʃvOƓs邽߂ɃX}[gJ[h̔rw +@@ύX + +@@http://www.marumo.ne.jp/db2008_1.htm#11 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.2.lzh + +@E2008, 1/7 - ver. 0.1.1 + +@@ZNV (PAT/PMT/ECM ) TS pPbgɕĂ +@@ꍇɁAɏłȂAO𔭐邱Ƃ +@@oOC + +@@http://www.marumo.ne.jp/db2008_1.htm#7 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.1.lzh + +@E2007, 11/25 - ver. 0.1.0 + +@@J + +@@http://www.marumo.ne.jp/db2007_b.htm#25 +@@http://www.marumo.ne.jp/junk/arib_std_b25-0.1.0.lzh + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/Makefile Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,25 @@ +# PC/SC Lite libraries and headers. +PCSC_CFLAGS ?= `pkg-config libpcsclite --cflags` +PCSC_LDLIBS ?= `pkg-config libpcsclite --libs` + +CC = gcc +CFLAGS = -Wall -O2 -g $(PCSC_CFLAGS) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 +LDLIBS = $(PCSC_LDLIBS) -lm + +TARGET = b25 +OBJS = arib_std_b25.o b_cas_card.o multi2.o td.o ts_section_parser.o + +all: $(TARGET) + +arib_std_b25.o: arib_std_b25.c arib_std_b25.h portable.h b_cas_card.h arib_std_b25_error_code.h multi2.h ts_section_parser.h ts_common_types.h +b_cas_card.o: b_cas_card.c b_cas_card.h portable.h b_cas_card_error_code.h +multi2.o: multi2.c multi2.h portable.h multi2_error_code.h +td.o: td.c arib_std_b25.h portable.h b_cas_card.h +ts_section_parser.o: ts_section_parser.c ts_section_parser.h ts_common_types.h portable.h ts_section_parser_error_code.h + +$(TARGET): $(OBJS) + $(CC) $(LDLIBS) -o $(TARGET) $(OBJS) + +clean: + rm -f *.o + rm -f $(TARGET) diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/arib_std_b25.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/arib_std_b25.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,2592 @@ +#include +#include + +#include "arib_std_b25.h" +#include "arib_std_b25_error_code.h" +#include "multi2.h" +#include "ts_common_types.h" +#include "ts_section_parser.h" + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + inner structures + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +typedef struct { + int32_t pid; + int32_t type; + void *prev; + void *next; +} TS_STREAM_ELEM; + +typedef struct { + TS_STREAM_ELEM *head; + TS_STREAM_ELEM *tail; + int32_t count; +} TS_STREAM_LIST; + +typedef struct { + + uint8_t *pool; + uint8_t *head; + uint8_t *tail; + int32_t max; + +} TS_WORK_BUFFER; + +typedef struct { + + int32_t phase; + + int32_t program_number; + + int32_t pmt_pid; + TS_SECTION_PARSER *pmt; + + int32_t pcr_pid; + + TS_STREAM_LIST streams; + TS_STREAM_LIST old_strm; + +} TS_PROGRAM; + +typedef struct { + + int32_t ref; + int32_t phase; + + int32_t locked; + + int32_t ecm_pid; + TS_SECTION_PARSER *ecm; + + MULTI2 *m2; + + int32_t unpurchased; + int32_t last_error; + + void *prev; + void *next; + +} DECRYPTOR_ELEM; + +typedef struct { + DECRYPTOR_ELEM *head; + DECRYPTOR_ELEM *tail; + int32_t count; +} DECRYPTOR_LIST; + +typedef struct { + uint32_t ref; + uint32_t type; + int64_t normal_packet; + int64_t undecrypted; + void *target; +} PID_MAP; + +typedef struct { + + int32_t multi2_round; + int32_t strip; + int32_t emm_proc_on; + + int32_t unit_size; + + int32_t sbuf_offset; + + TS_SECTION_PARSER *pat; + TS_SECTION_PARSER *cat; + + TS_STREAM_LIST strm_pool; + + int32_t p_count; + TS_PROGRAM *program; + + DECRYPTOR_LIST decrypt; + + PID_MAP map[0x2000]; + + B_CAS_CARD *bcas; + B_CAS_ID casid; + + int32_t emm_pid; + TS_SECTION_PARSER *emm; + + TS_WORK_BUFFER sbuf; + TS_WORK_BUFFER dbuf; + +} ARIB_STD_B25_PRIVATE_DATA; + +typedef struct { + int64_t card_id; + int32_t associated_information_length; + int32_t protocol_number; + int32_t broadcaster_group_id; + int32_t update_number; + int32_t expiration_date; +} EMM_FIXED_PART; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + constant values + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +enum TS_STREAM_TYPE { + TS_STREAM_TYPE_11172_2_VIDEO = 0x01, + TS_STREAM_TYPE_13818_2_VIDEO = 0x02, + TS_STREAM_TYPE_11172_3_AUDIO = 0x03, + TS_STREAM_TYPE_13818_3_AUDIO = 0x04, + TS_STREAM_TYPE_13818_1_PRIVATE_SECTIONS = 0x05, + TS_STREAM_TYPE_13818_1_PES_PRIVATE_DATA = 0x06, + TS_STREAM_TYPE_13522_MHEG = 0x07, + TS_STREAM_TYPE_13818_1_DSM_CC = 0x08, + TS_STREAM_TYPE_H_222_1 = 0x09, + TS_STREAM_TYPE_13818_6_TYPE_A = 0x0a, + TS_STREAM_TYPE_13818_6_TYPE_B = 0x0b, + TS_STREAM_TYPE_13818_6_TYPE_C = 0x0c, + TS_STREAM_TYPE_13818_6_TYPE_D = 0x0d, + TS_STREAM_TYPE_13818_1_AUX = 0x0e, + TS_STREAM_TYPE_13818_7_AUDIO_ADTS = 0x0f, + TS_STREAM_TYPE_14496_2_VISUAL = 0x10, + TS_STREAM_TYPE_14496_3_AUDIO_LATM = 0x11, + TS_STREAM_TYPE_14496_1_PES_SL_PACKET = 0x12, + TS_STREAM_TYPE_14496_1_SECTIONS_SL_PACKET = 0x13, + TS_STREAM_TYPE_13818_6_SYNC_DWLOAD_PROTCOL = 0x14, +}; + +enum TS_SECTION_ID { + TS_SECTION_ID_PROGRAM_ASSOCIATION = 0x00, + TS_SECTION_ID_CONDITIONAL_ACCESS = 0x01, + TS_SECTION_ID_PROGRAM_MAP = 0x02, + TS_SECTION_ID_DESCRIPTION = 0x03, + TS_SECTION_ID_14496_SCENE_DESCRIPTION = 0x04, + TS_SECTION_ID_14496_OBJECT_DESCRIPTION = 0x05, + + /* ARIB STD-B10 stuff */ + TS_SECTION_ID_DSM_CC_HEAD = 0x3a, + TS_SECTION_ID_DSM_CC_TAIL = 0x3f, + TS_SECTION_ID_NIT_ACTUAL = 0x40, + TS_SECTION_ID_NIT_OTHER = 0x41, + TS_SECTION_ID_SDT_ACTUAL = 0x42, + TS_SECTION_ID_SDT_OTHER = 0x46, + TS_SECTION_ID_BAT = 0x4a, + TS_SECTION_ID_EIT_ACTUAL_CURRENT = 0x4e, + TS_SECTION_ID_EIT_OTHER_CURRENT = 0x4f, + TS_SECTION_ID_EIT_ACTUAL_SCHEDULE_HEAD = 0x50, + TS_SECTION_ID_EIT_ACTUAL_SCHEDULE_TAIL = 0x5f, + TS_SECTION_ID_EIT_OTHER_SCHEDULE_HEAD = 0x60, + TS_SECTION_ID_EIT_OTHER_SCHEDULE_TAIL = 0x6f, + TS_SECTION_ID_TDT = 0x70, + TS_SECTION_ID_RST = 0x71, + TS_SECTION_ID_ST = 0x72, + TS_SECTION_ID_TOT = 0x73, + TS_SECTION_ID_AIT = 0x74, + TS_SECTION_ID_DIT = 0x7e, + TS_SECTION_ID_SIT = 0x7f, + TS_SECTION_ID_ECM_S = 0x82, + TS_SECTION_ID_ECM = 0x83, + TS_SECTION_ID_EMM_S = 0x84, + TS_SECTION_ID_EMM_MESSAGE = 0x85, + TS_SECTION_ID_DCT = 0xc0, + TS_SECTION_ID_DLT = 0xc1, + TS_SECTION_ID_PCAT = 0xc2, + TS_SECTION_ID_SDTT = 0xc3, + TS_SECTION_ID_BIT = 0xc4, + TS_SECTION_ID_NBIT_BODY = 0xc5, + TS_SECTION_ID_NBIT_REFERENCE = 0xc6, + TS_SECTION_ID_LDT = 0xc7, + TS_SECTION_ID_CDT = 0xc8, + TS_SECTION_ID_LIT = 0xd0, + TS_SECTION_ID_ERT = 0xd1, + TS_SECTION_ID_ITT = 0xd2, +}; + +enum TS_DESCRIPTOR_TAG { + TS_DESCRIPTOR_TAG_VIDEO_STREAM = 0x02, + TS_DESCRIPTOR_TAG_AUDIO_STREAM = 0x03, + TS_DESCRIPTOR_TAG_HIERARCHY = 0x04, + TS_DESCRIPTOR_TAG_REGISTRATION = 0x05, + TS_DESCRIPTOR_TAG_DATA_STREAM_ALIGNMENT = 0x06, + TS_DESCRIPTOR_TAG_TARGET_BACKGROUND_GRID = 0x07, + TS_DESCRIPTOR_TAG_VIDEO_WINDOW = 0x08, + TS_DESCRIPTOR_TAG_CA = 0x09, + TS_DESCRIPTOR_TAG_ISO_639_LANGUAGE = 0x0a, + TS_DESCRIPTOR_TAG_SYSTEM_CLOCK = 0x0b, + TS_DESCRIPTOR_TAG_MULTIPLEX_BUF_UTILIZ = 0x0c, + TS_DESCRIPTOR_TAG_COPYRIGHT = 0x0d, + TS_DESCRIPTOR_TAG_MAXIMUM_BITRATE = 0x0e, + TS_DESCRIPTOR_TAG_PRIVATE_DATA_INDICATOR = 0x0f, + TS_DESCRIPTOR_TAG_SMOOTHING_BUFFER = 0x10, + TS_DESCRIPTOR_TAG_STD = 0x11, + TS_DESCRIPTOR_TAG_IBP = 0x12, + TS_DESCRIPTOR_TAG_MPEG4_VIDEO = 0x1b, + TS_DESCRIPTOR_TAG_MPEG4_AUDIO = 0x1c, + TS_DESCRIPTOR_TAG_IOD = 0x1d, + TS_DESCRIPTOR_TAG_SL = 0x1e, + TS_DESCRIPTOR_TAG_FMC = 0x1f, + TS_DESCRIPTOR_TAG_EXTERNAL_ES_ID = 0x20, + TS_DESCRIPTOR_TAG_MUXCODE = 0x21, + TS_DESCRIPTOR_TAG_FMX_BUFFER_SIZE = 0x22, + TS_DESCRIPTOR_TAG_MULTIPLEX_BUFFER = 0x23, + TS_DESCRIPTOR_TAG_AVC_VIDEO = 0x28, + TS_DESCRIPTOR_TAG_AVC_TIMING_HRD = 0x2a, + + /* ARIB STD-B10 stuff */ + TS_DESCRIPTOR_TAG_NETWORK_NAME = 0x40, + TS_DESCRIPTOR_TAG_SERVICE_LIST = 0x41, + TS_DESCRIPTOR_TAG_STUFFING = 0x42, + TS_DESCRIPTOR_TAG_SATELLITE_DELIVERY_SYS = 0x43, + TS_DESCRIPTOR_TAG_CABLE_DISTRIBUTION = 0x44, + TS_DESCRIPTOR_TAG_BOUNQUET_NAME = 0x47, + TS_DESCRIPTOR_TAG_SERVICE = 0x48, + TS_DESCRIPTOR_TAG_COUNTRY_AVAILABILITY = 0x49, + TS_DESCRIPTOR_TAG_LINKAGE = 0x4a, + TS_DESCRIPTOR_TAG_NVOD_REFERENCE = 0x4b, + TS_DESCRIPTOR_TAG_TIME_SHIFTED_SERVICE = 0x4c, + TS_DESCRIPTOR_TAG_SHORT_EVENT = 0x4d, + TS_DESCRIPTOR_TAG_EXTENDED_EVENT = 0x4e, + TS_DESCRIPTOR_TAG_TIME_SHIFTED_EVENT = 0x4f, + TS_DESCRIPTOR_TAG_COMPONENT = 0x50, + TS_DESCRIPTOR_TAG_MOSAIC = 0x51, + TS_DESCRIPTOR_TAG_STREAM_IDENTIFIER = 0x52, + TS_DESCRIPTOR_TAG_CA_IDENTIFIER = 0x53, + TS_DESCRIPTOR_TAG_CONTENT = 0x54, + TS_DESCRIPTOR_TAG_PARENTAL_RATING = 0x55, + TS_DESCRIPTOR_TAG_LOCAL_TIME_OFFSET = 0x58, + TS_DESCRIPTOR_TAG_PARTIAL_TRANSPORT_STREAM = 0x63, + TS_DESCRIPTOR_TAG_HIERARCHICAL_TRANSMISSION = 0xc0, + TS_DESCRIPTOR_TAG_DIGITAL_COPY_CONTROL = 0xc1, + TS_DESCRIPTOR_TAG_NETWORK_IDENTIFICATION = 0xc2, + TS_DESCRIPTOR_TAG_PARTIAL_TRANSPORT_TIME = 0xc3, + TS_DESCRIPTOR_TAG_AUDIO_COMPONENT = 0xc4, + TS_DESCRIPTOR_TAG_HYPERLINK = 0xc5, + TS_DESCRIPTOR_TAG_TARGET_REGION = 0xc6, + TS_DESCRIPTOR_TAG_DATA_COTENT = 0xc7, + TS_DESCRIPTOR_TAG_VIDEO_DECODE_CONTROL = 0xc8, + TS_DESCRIPTOR_TAG_DOWNLOAD_CONTENT = 0xc9, + TS_DESCRIPTOR_TAG_CA_EMM_TS = 0xca, + TS_DESCRIPTOR_TAG_CA_CONTRACT_INFORMATION = 0xcb, + TS_DESCRIPTOR_TAG_CA_SERVICE = 0xcc, + TS_DESCRIPTOR_TAG_TS_INFORMATION = 0xcd, + TS_DESCRIPTOR_TAG_EXTENDED_BROADCASTER = 0xce, + TS_DESCRIPTOR_TAG_LOGO_TRANSMISSION = 0xcf, + TS_DESCRIPTOR_TAG_BASIC_LOCAL_EVENT = 0xd0, + TS_DESCRIPTOR_TAG_REFERENCE = 0xd1, + TS_DESCRIPTOR_TAG_NODE_RELATION = 0xd2, + TS_DESCRIPTOR_TAG_SHORT_NODE_INFORMATION = 0xd3, + TS_DESCRIPTOR_TAG_STC_REFERENCE = 0xd4, + TS_DESCRIPTOR_TAG_SERIES = 0xd5, + TS_DESCRIPTOR_TAG_EVENT_GROUP = 0xd6, + TS_DESCRIPTOR_TAG_SI_PARAMETER = 0xd7, + TS_DESCRIPTOR_TAG_BROADCASTER_NAME = 0xd8, + TS_DESCRIPTOR_TAG_COMPONENT_GROUP = 0xd9, + TS_DESCRIPTOR_TAG_SI_PRIME_TS = 0xda, + TS_DESCRIPTOR_TAG_BOARD_INFORMATION = 0xdb, + TS_DESCRIPTOR_TAG_LDT_LINKAGE = 0xdc, + TS_DESCRIPTOR_TAG_CONNECTED_TRANSMISSION = 0xdd, + TS_DESCRIPTOR_TAG_CONTENT_AVAILABILITY = 0xde, + TS_DESCRIPTOR_TAG_VALUE_EXTENSION = 0xdf, + TS_DESCRIPTOR_TAG_SERVICE_GROUP = 0xe0, + TS_DESCRIPTOR_TAG_CARUSEL_COMPOSITE = 0xf7, + TS_DESCRIPTOR_TAG_CONDITIONAL_PLAYBACK = 0xf8, + TS_DESCRIPTOR_TAG_CABLE_TS_DIVISSION = 0xf9, + TS_DESCRIPTOR_TAG_TERRESTRIAL_DELIVERY_SYS = 0xfa, + TS_DESCRIPTOR_TAG_PARTIAL_RECEPTION = 0xfb, + TS_DESCRIPTOR_TAG_EMERGENCY_INFOMATION = 0xfc, + TS_DESCRIPTOR_TAG_DATA_COMPONENT = 0xfd, + TS_DESCRIPTOR_TAG_SYSTEM_MANAGEMENT = 0xfe, +}; + +enum PID_MAP_TYPE { + PID_MAP_TYPE_UNKNOWN = 0x0000, + PID_MAP_TYPE_PAT = 0x0100, + PID_MAP_TYPE_PMT = 0x0200, + PID_MAP_TYPE_NIT = 0x0300, + PID_MAP_TYPE_PCR = 0x0400, + PID_MAP_TYPE_ECM = 0x0500, + PID_MAP_TYPE_EMM = 0x0600, + PID_MAP_TYPE_EIT = 0x0700, + PID_MAP_TYPE_CAT = 0x0800, + PID_MAP_TYPE_OTHER = 0xff00, +}; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (interface method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_arib_std_b25(void *std_b25); +static int set_multi2_round_arib_std_b25(void *std_b25, int32_t round); +static int set_strip_arib_std_b25(void *std_b25, int32_t strip); +static int set_emm_proc_arib_std_b25(void *std_b25, int32_t on); +static int set_b_cas_card_arib_std_b25(void *std_b25, B_CAS_CARD *bcas); +static int reset_arib_std_b25(void *std_b25); +static int flush_arib_std_b25(void *std_b25); +static int put_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf); +static int get_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf); +static int get_program_count_arib_std_b25(void *std_b25); +static int get_program_info_arib_std_b25(void *std_b25, ARIB_STD_B25_PROGRAM_INFO *info, int idx); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + global function implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +ARIB_STD_B25 *create_arib_std_b25() +{ + int n; + + ARIB_STD_B25 *r; + ARIB_STD_B25_PRIVATE_DATA *prv; + + n = sizeof(ARIB_STD_B25_PRIVATE_DATA); + n += sizeof(ARIB_STD_B25); + + prv = (ARIB_STD_B25_PRIVATE_DATA *)calloc(1, n); + if(prv == NULL){ + return NULL; + } + + prv->multi2_round = 4; + + r = (ARIB_STD_B25 *)(prv+1); + r->private_data = prv; + + r->release = release_arib_std_b25; + r->set_multi2_round = set_multi2_round_arib_std_b25; + r->set_strip = set_strip_arib_std_b25; + r->set_emm_proc = set_emm_proc_arib_std_b25; + r->set_b_cas_card = set_b_cas_card_arib_std_b25; + r->reset = reset_arib_std_b25; + r->flush = flush_arib_std_b25; + r->put = put_arib_std_b25; + r->get = get_arib_std_b25; + r->get_program_count = get_program_count_arib_std_b25; + r->get_program_info = get_program_info_arib_std_b25; + + return r; +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (private method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static ARIB_STD_B25_PRIVATE_DATA *private_data(void *std_b25); +static void teardown(ARIB_STD_B25_PRIVATE_DATA *prv); +static int select_unit_size(ARIB_STD_B25_PRIVATE_DATA *prv); +static int find_pat(ARIB_STD_B25_PRIVATE_DATA *prv); +static int proc_pat(ARIB_STD_B25_PRIVATE_DATA *prv); +static int check_pmt_complete(ARIB_STD_B25_PRIVATE_DATA *prv); +static int find_pmt(ARIB_STD_B25_PRIVATE_DATA *prv); +static int proc_pmt(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm); +static int32_t find_ca_descriptor_pid(uint8_t *head, uint8_t *tail); +static int32_t add_ecm_stream(ARIB_STD_B25_PRIVATE_DATA *prv, TS_STREAM_LIST *list, int32_t ecm_pid); +static int check_ecm_complete(ARIB_STD_B25_PRIVATE_DATA *prv); +static int find_ecm(ARIB_STD_B25_PRIVATE_DATA *prv); +static int proc_ecm(DECRYPTOR_ELEM *dec, B_CAS_CARD *bcas, int32_t multi2_round); +static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv); + +static int proc_cat(ARIB_STD_B25_PRIVATE_DATA *prv); +static int proc_emm(ARIB_STD_B25_PRIVATE_DATA *prv); + +static void release_program(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm); + +static void unref_stream(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid); + +static DECRYPTOR_ELEM *set_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid); +static void remove_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, DECRYPTOR_ELEM *dec); +static DECRYPTOR_ELEM *select_active_decryptor(DECRYPTOR_ELEM *a, DECRYPTOR_ELEM *b, int32_t pid); +static void bind_stream_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid, DECRYPTOR_ELEM *dec); +static void unlock_all_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv); + +static TS_STREAM_ELEM *get_stream_list_head(TS_STREAM_LIST *list); +static TS_STREAM_ELEM *find_stream_list_elem(TS_STREAM_LIST *list, int32_t pid); +static TS_STREAM_ELEM *create_stream_elem(int32_t pid, int32_t type); +static void put_stream_list_tail(TS_STREAM_LIST *list, TS_STREAM_ELEM *elem); +static void clear_stream_list(TS_STREAM_LIST *list); + +static int reserve_work_buffer(TS_WORK_BUFFER *buf, int32_t size); +static int append_work_buffer(TS_WORK_BUFFER *buf, uint8_t *data, int32_t size); +static void reset_work_buffer(TS_WORK_BUFFER *buf); +static void release_work_buffer(TS_WORK_BUFFER *buf); + +static void extract_ts_header(TS_HEADER *dst, uint8_t *src); +static void extract_emm_fixed_part(EMM_FIXED_PART *dst, uint8_t *src); + +static int check_unit_invert(unsigned char *head, unsigned char *tail); + +static uint8_t *resync(uint8_t *head, uint8_t *tail, int32_t unit); +static uint8_t *resync_force(uint8_t *head, uint8_t *tail, int32_t unit); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + interface method implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_arib_std_b25(void *std_b25) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return; + } + + teardown(prv); + free(prv); +} + +static int set_multi2_round_arib_std_b25(void *std_b25, int32_t round) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + prv->multi2_round = round; + + return 0; +} + +static int set_strip_arib_std_b25(void *std_b25, int32_t strip) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + prv->strip = strip; + + return 0; +} + +static int set_emm_proc_arib_std_b25(void *std_b25, int32_t on) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + prv->emm_proc_on = on; + + return 0; +} + +static int set_b_cas_card_arib_std_b25(void *std_b25, B_CAS_CARD *bcas) +{ + int n; + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + prv->bcas = bcas; + if(prv->bcas != NULL){ + n = prv->bcas->get_id(prv->bcas, &(prv->casid)); + if(n < 0){ + return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS; + } + } + + return 0; +} + +static int reset_arib_std_b25(void *std_b25) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + teardown(prv); + + return 0; +} + +static int flush_arib_std_b25(void *std_b25) +{ + int r; + int m,n; + + int32_t crypt; + int32_t unit; + int32_t pid; + + uint8_t *p; + uint8_t *curr; + uint8_t *tail; + + TS_HEADER hdr; + DECRYPTOR_ELEM *dec; + TS_PROGRAM *pgrm; + + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + if(prv->unit_size < 188){ + r = select_unit_size(prv); + if(r < 0){ + return r; + } + } + + r = proc_arib_std_b25(prv); + if(r < 0){ + return r; + } + + unit = prv->unit_size; + curr = prv->sbuf.head; + tail = prv->sbuf.tail; + + m = prv->dbuf.tail - prv->dbuf.head; + n = tail - curr; + if(!reserve_work_buffer(&(prv->dbuf), m+n)){ + return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + } + + r = 0; + + while( (curr+188) <= tail ){ + + if(curr[0] != 0x47){ + p = resync_force(curr, tail, unit); + if(p == NULL){ + goto LAST; + } + curr = p; + } + + extract_ts_header(&hdr, curr); + crypt = hdr.transport_scrambling_control; + pid = hdr.pid; + + if( (pid == 0x1fff) && (prv->strip) ){ + goto NEXT; + } + + p = curr+4; + if(hdr.adaptation_field_control & 0x02){ + p += (p[0]+1); + } + n = 188 - (p-curr); + if( (n < 1) && ((n < 0) || (hdr.adaptation_field_control & 0x01)) ){ + /* broken packet */ + curr += 1; + continue; + } + + if( (crypt != 0) && + (hdr.adaptation_field_control & 0x01) ){ + + if(prv->map[pid].type == PID_MAP_TYPE_OTHER){ + dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); + }else{ + dec = NULL; + } + + if( (dec != NULL) && (dec->m2 != NULL) ){ + m = dec->m2->decrypt(dec->m2, crypt, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_DECRYPT_FAILURE; + goto LAST; + } + curr[3] &= 0x3f; + prv->map[pid].normal_packet += 1; + }else{ + prv->map[pid].undecrypted += 1; + } + }else{ + prv->map[pid].normal_packet += 1; + } + + if(!append_work_buffer(&(prv->dbuf), curr, 188)){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + + if(prv->map[pid].type == PID_MAP_TYPE_ECM){ + dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); + if( (dec == NULL) || (dec->ecm == NULL) ){ + /* this code will never execute */ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + goto LAST; + } + m = dec->ecm->put(dec->ecm, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + goto LAST; + } + m = dec->ecm->get_count(dec->ecm); + if(m < 0){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_ecm(dec, prv->bcas, prv->multi2_round); + if(r < 0){ + goto LAST; + } + }else if(prv->map[pid].type == PID_MAP_TYPE_PMT){ + pgrm = (TS_PROGRAM *)(prv->map[pid].target); + if( (pgrm == NULL) || (pgrm->pmt == NULL) ){ + /* this code will never execute */ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + goto LAST; + } + m = pgrm->pmt->put(pgrm->pmt, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + goto LAST; + } + m = pgrm->pmt->get_count(pgrm->pmt); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_pmt(prv, pgrm); + if(r < 0){ + goto LAST; + } + }else if(prv->map[pid].type == PID_MAP_TYPE_EMM){ + if( prv->emm_proc_on == 0){ + goto NEXT; + } + if( prv->emm == NULL ){ + prv->emm = create_ts_section_parser(); + if(prv->emm == NULL){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + goto LAST; + } + } + m = prv->emm->put(prv->emm, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + goto LAST; + } + m = prv->emm->get_count(prv->emm); + if(m < 0){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_emm(prv); + if(r < 0){ + goto LAST; + } + }else if(pid == 0x0001){ + if( prv->cat == NULL ){ + prv->cat = create_ts_section_parser(); + if(prv->cat == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + } + m = prv->cat->put(prv->cat, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; + goto LAST; + } + m = prv->cat->get_count(prv->cat); + if(m < 0){ + r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_cat(prv); + if(r < 0){ + goto LAST; + } + }else if(pid == 0x0000){ + if( prv->pat == NULL ){ + prv->pat = create_ts_section_parser(); + if(prv->pat == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + } + m = prv->pat->put(prv->pat, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + goto LAST; + } + m = prv->pat->get_count(prv->pat); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_pat(prv); + if(r < 0){ + goto LAST; + } + } + + NEXT: + curr += unit; + } + +LAST: + + m = curr - prv->sbuf.head; + n = tail - curr; + if( (n < 1024) || (m > (prv->sbuf.max/2) ) ){ + p = prv->sbuf.pool; + memcpy(p, curr, n); + prv->sbuf.head = p; + prv->sbuf.tail = p+n; + }else{ + prv->sbuf.head = curr; + } + + return r; +} + +static int put_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf) +{ + int32_t n; + + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if( (prv == NULL) || (buf == NULL) ){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + if(!append_work_buffer(&(prv->sbuf), buf->data, buf->size)){ + return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + } + + if(prv->unit_size < 188){ + n = select_unit_size(prv); + if(n < 0){ + return n; + } + if(prv->unit_size < 188){ + /* need more data */ + return 0; + } + } + + if(prv->p_count < 1){ + n = find_pat(prv); + if(n < 0){ + return n; + } + if(prv->p_count < 1){ + if(prv->sbuf_offset < (16*1024*1024)){ + /* need more data */ + return 0; + }else{ + /* exceed sbuf limit */ + return ARIB_STD_B25_ERROR_NO_PAT_IN_HEAD_16M; + } + } + prv->sbuf_offset = 0; + } + + if(!check_pmt_complete(prv)){ + n = find_pmt(prv); + if(n < 0){ + return n; + } + if(!check_pmt_complete(prv)){ + if(prv->sbuf_offset < (32*1024*1024)){ + /* need more data */ + return 0; + }else{ + /* exceed sbuf limit */ + return ARIB_STD_B25_ERROR_NO_PMT_IN_HEAD_32M; + } + } + prv->sbuf_offset = 0; + } + + if(!check_ecm_complete(prv)){ + n = find_ecm(prv); + if(n < 0){ + return n; + } + if(!check_ecm_complete(prv)){ + if(prv->sbuf_offset < (32*1024*1024)){ + /* need more data */ + return 0; + }else{ + /* exceed sbuf limit */ + return ARIB_STD_B25_ERROR_NO_ECM_IN_HEAD_32M; + } + } + prv->sbuf_offset = 0; + } + + return proc_arib_std_b25(prv); +} + +static int get_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + prv = private_data(std_b25); + if( (prv == NULL) || (buf == NULL) ){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + buf->data = prv->dbuf.head; + buf->size = prv->dbuf.tail - prv->dbuf.head; + + reset_work_buffer(&(prv->dbuf)); + + return 0; +} + +static int get_program_count_arib_std_b25(void *std_b25) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + + prv = private_data(std_b25); + if(prv == NULL){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + return prv->p_count; +} + +static int get_program_info_arib_std_b25(void *std_b25, ARIB_STD_B25_PROGRAM_INFO *info, int idx) +{ + ARIB_STD_B25_PRIVATE_DATA *prv; + + TS_PROGRAM *pgrm; + + TS_STREAM_ELEM *strm; + DECRYPTOR_ELEM *dec; + + int32_t pid; + + prv = private_data(std_b25); + if( (prv == NULL) || (info == NULL) || (idx < 0) || (idx >= prv->p_count) ){ + return ARIB_STD_B25_ERROR_INVALID_PARAM; + } + + pgrm = prv->program + idx; + + memset(info, 0, sizeof(ARIB_STD_B25_PROGRAM_INFO)); + + info->program_number = pgrm->program_number; + + pid = pgrm->pmt_pid; + info->total_packet_count += prv->map[pid].normal_packet; + info->total_packet_count += prv->map[pid].undecrypted; + info->undecrypted_packet_count += prv->map[pid].undecrypted; + + pid = pgrm->pcr_pid; + if( (pid != 0) && (pid != 0x1fff) ){ + info->total_packet_count += prv->map[pid].normal_packet; + info->total_packet_count += prv->map[pid].undecrypted; + info->undecrypted_packet_count += prv->map[pid].undecrypted; + } + + strm = pgrm->streams.head; + while(strm != NULL){ + pid = strm->pid; + if(prv->map[pid].type == PID_MAP_TYPE_ECM){ + dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); + info->ecm_unpurchased_count += dec->unpurchased; + info->last_ecm_error_code = dec->last_error; + } + info->total_packet_count += prv->map[pid].normal_packet; + info->total_packet_count += prv->map[pid].undecrypted; + info->undecrypted_packet_count += prv->map[pid].undecrypted; + strm = (TS_STREAM_ELEM *)(strm->next); + } + + return 0; +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + private method implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static ARIB_STD_B25_PRIVATE_DATA *private_data(void *std_b25) +{ + ARIB_STD_B25 *p; + ARIB_STD_B25_PRIVATE_DATA *r; + + p = (ARIB_STD_B25 *)std_b25; + if(p == NULL){ + return NULL; + } + + r = (ARIB_STD_B25_PRIVATE_DATA *)p->private_data; + if( ((void *)(r+1)) != ((void *)p) ){ + return NULL; + } + + return r; +} + +static void teardown(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int i; + + prv->unit_size = 0; + prv->sbuf_offset = 0; + + if(prv->pat != NULL){ + prv->pat->release(prv->pat); + prv->pat = NULL; + } + if(prv->cat != NULL){ + prv->cat->release(prv->cat); + prv->cat = NULL; + } + + if(prv->program != NULL){ + for(i=0;ip_count;i++){ + release_program(prv, prv->program+i); + } + free(prv->program); + prv->program = NULL; + } + prv->p_count = 0; + + clear_stream_list(&(prv->strm_pool)); + + while(prv->decrypt.head != NULL){ + remove_decryptor(prv, prv->decrypt.head); + } + + memset(prv->map, 0, sizeof(prv->map)); + + prv->emm_pid = 0; + if(prv->emm != NULL){ + prv->emm->release(prv->emm); + prv->emm = NULL; + } + + release_work_buffer(&(prv->sbuf)); + release_work_buffer(&(prv->dbuf)); +} + +static int select_unit_size(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int i; + int m,n,w; + int count[320]; + + unsigned char *head; + unsigned char *pre; + unsigned char *buf; + unsigned char *tail; + + head = prv->sbuf.head; + tail = prv->sbuf.tail; + pre = NULL; + buf = head; + memset(count, 0, sizeof(count)); + + // 1st step, find head 0x47 + while(buf < tail){ + if(buf[0] == 0x47){ + pre = buf; + break; + } + buf += 1; + } + + if(pre == NULL){ + return ARIB_STD_B25_ERROR_NON_TS_INPUT_STREAM; + } + + // 2nd step, count up 0x47 interval + buf = pre + 1; + while( buf < tail ){ + if(buf[0] == 0x47){ + m = buf - pre; + if(m < 188){ + n = check_unit_invert(head, buf); + if( (n >= 188) && (n < 320) ){ + count[n] += 1; + pre = buf; + } + }else if(m < 320){ + count[m] += 1; + pre = buf; + }else{ + pre = buf; + } + } + buf += 1; + } + + // 3rd step, select maximum appeared interval + m = 0; + n = 0; + for(i=188;i<320;i++){ + if(m < count[i]){ + m = count[i]; + n = i; + } + } + + // 4th step, verify unit_size + w = m*n; + if( (m < 8) || (w < ((tail-head) - (w/8))) ){ + return ARIB_STD_B25_ERROR_NON_TS_INPUT_STREAM; + } + + prv->unit_size = n; + + return 0; +} + +static int find_pat(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int r; + int n,size; + + int32_t unit; + + uint8_t *p; + uint8_t *curr; + uint8_t *tail; + + TS_HEADER hdr; + + r = 0; + unit = prv->unit_size; + curr = prv->sbuf.head + prv->sbuf_offset; + tail = prv->sbuf.tail; + + while( (curr+unit) < tail ){ + if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ + p = resync(curr, tail, unit); + if(p == NULL){ + goto LAST; + } + curr = p; + } + extract_ts_header(&hdr, curr); + if(hdr.pid == 0x0000){ + + p = curr+4; + if(hdr.adaptation_field_control & 0x02){ + p += (p[0]+1); + } + size = 188 - (p-curr); + if(size < 1){ + goto NEXT; + } + + if(prv->pat == NULL){ + prv->pat = create_ts_section_parser(); + if(prv->pat == NULL){ + return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + } + } + + n = prv->pat->put(prv->pat, &hdr, p, size); + if(n < 0){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + curr += unit; + goto LAST; + } + n = prv->pat->get_count(prv->pat); + if(n < 0){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + curr += unit; + goto LAST; + } + if(n > 0){ + curr += unit; + goto LAST; + } + } + NEXT: + curr += unit; + } + +LAST: + prv->sbuf_offset = curr - prv->sbuf.head; + + if( (prv->pat != NULL) && (prv->pat->get_count(prv->pat) > 0) ){ + r = proc_pat(prv); + } + + return r; +} + +static int proc_pat(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int r; + int i,n; + int len; + int count; + + int32_t program_number; + int32_t pid; + + uint8_t *head; + uint8_t *tail; + + TS_PROGRAM *work; + TS_SECTION sect; + + r = 0; + memset(§, 0, sizeof(sect)); + + n = prv->pat->get(prv->pat, §); + if(n < 0){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + goto LAST; + } + + if(sect.hdr.table_id != TS_SECTION_ID_PROGRAM_ASSOCIATION){ + r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; + goto LAST; + } + + len = (sect.tail - sect.data) - 4; + + count = len / 4; + work = (TS_PROGRAM *)calloc(count, sizeof(TS_PROGRAM)); + if(work == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + + if(prv->program != NULL){ + for(i=0;ip_count;i++){ + release_program(prv, prv->program+i); + } + free(prv->program); + prv->program = NULL; + } + prv->p_count = 0; + memset(&(prv->map), 0, sizeof(prv->map)); + + head = sect.data; + tail = sect.tail-4; + + i = 0; + while( (head+4) <= tail ){ + program_number = ((head[0] << 8) | head[1]); + pid = ((head[2] << 8) | head[3]) & 0x1fff; + if(program_number != 0){ + work[i].program_number = program_number; + work[i].pmt_pid = pid; + work[i].pmt = create_ts_section_parser(); + if(work[i].pmt == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + break; + } + prv->map[pid].type = PID_MAP_TYPE_PMT; + prv->map[pid].target = work+i; + i += 1; + } + head += 4; + } + + prv->program = work; + prv->p_count = i; + + prv->map[0x0000].ref = 1; + prv->map[0x0000].type = PID_MAP_TYPE_PAT; + prv->map[0x0000].target = NULL; + +LAST: + if(sect.raw != NULL){ + n = prv->pat->ret(prv->pat, §); + if( (n < 0) && (r == 0) ){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + } + } + + return r; +} + +static int check_pmt_complete(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int i,n; + int num[3]; + + memset(num, 0, sizeof(num)); + + for(i=0;ip_count;i++){ + n = prv->program[i].phase; + if(n < 0){ + n = 0; + }else if(n > 2){ + n = 2; + } + num[n] += 1; + } + + if(num[2] > 0){ + return 1; + } + + if(num[0] > 0){ + return 0; + } + + return 1; +} + +static int find_pmt(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int r; + int n,size; + + int32_t unit; + + uint8_t *p; + uint8_t *curr; + uint8_t *tail; + + TS_HEADER hdr; + TS_PROGRAM *pgrm; + + r = 0; + unit = prv->unit_size; + curr = prv->sbuf.head + prv->sbuf_offset; + tail = prv->sbuf.tail; + + while( (curr+unit) < tail ){ + + if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ + p = resync(curr, tail, unit); + if(p == NULL){ + goto LAST; + } + curr = p; + } + + extract_ts_header(&hdr, curr); + + if(prv->map[hdr.pid].type != PID_MAP_TYPE_PMT){ + goto NEXT; + } + pgrm = (TS_PROGRAM *)(prv->map[hdr.pid].target); + if(pgrm == NULL){ + goto NEXT; + } + + if(pgrm->phase == 0){ + + p = curr + 4; + if(hdr.adaptation_field_control & 0x02){ + p += (p[0]+1); + } + size = 188 - (p-curr); + if(size < 1){ + goto NEXT; + } + + if(pgrm->pmt == NULL){ + /* this code will never execute */ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + curr += unit; + goto LAST; + } + + n = pgrm->pmt->put(pgrm->pmt, &hdr, p, size); + if(n < 0){ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + curr += unit; + goto LAST; + } + n = pgrm->pmt->get_count(pgrm->pmt); + if(n < 0){ + r =ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + curr += unit; + goto LAST; + } + if(n == 0){ + goto NEXT; + } + r = proc_pmt(prv, pgrm); + if(r < 0){ + curr += unit; + goto LAST; + } + if(r > 0){ + /* broken or unexpected section data */ + goto NEXT; + } + pgrm->phase = 1; + if(check_pmt_complete(prv)){ + curr += unit; + goto LAST; + } + }else{ + pgrm->phase = 2; + curr += unit; + goto LAST; + } + + NEXT: + curr += unit; + } + +LAST: + prv->sbuf_offset = curr - prv->sbuf.head; + + return r; +} + +static int proc_pmt(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm) +{ + int r; + + int n; + int length; + + uint8_t *head; + uint8_t *tail; + + int32_t ecm_pid; + int32_t pid; + int32_t type; + + TS_SECTION sect; + + DECRYPTOR_ELEM *dec[2]; + DECRYPTOR_ELEM *dw; + + TS_STREAM_ELEM *strm; + + r = 0; + dec[0] = NULL; + memset(§, 0, sizeof(sect)); + + n = pgrm->pmt->get(pgrm->pmt, §); + if(n < 0){ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + goto LAST; + } + if(sect.hdr.table_id != TS_SECTION_ID_PROGRAM_MAP){ + r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; + goto LAST; + } + + head = sect.data; + tail = sect.tail-4; + + pgrm->pcr_pid = ((head[0] << 8) | head[1]) & 0x1fff; + length = ((head[2] << 8) | head[3]) & 0x0fff; + head += 4; + if(head+length > tail){ + r = ARIB_STD_B25_WARN_BROKEN_TS_SECTION; + goto LAST; + } + + /* find major ecm_pid and regist decryptor */ + ecm_pid = find_ca_descriptor_pid(head, head+length); + if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){ + dec[0] = set_decryptor(prv, ecm_pid); + if(dec[0] == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + dec[0]->ref += 1; + } + head += length; + + /* unref old stream entries */ + while( (strm = get_stream_list_head(&(pgrm->old_strm))) != NULL ){ + unref_stream(prv, strm->pid); + memset(strm, 0, sizeof(TS_STREAM_ELEM)); + put_stream_list_tail(&(prv->strm_pool), strm); + } + + /* save current streams */ + memcpy(&(pgrm->old_strm), &(pgrm->streams), sizeof(TS_STREAM_LIST)); + memset(&(pgrm->streams), 0, sizeof(TS_STREAM_LIST)); + + /* add current stream entries */ + if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){ + if(!add_ecm_stream(prv, &(pgrm->streams), ecm_pid)){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + } + + while( head+4 < tail ){ + + type = head[0]; + pid = ((head[1] << 8) | head[2]) & 0x1fff; + length = ((head[3] << 8) | head[4]) & 0x0fff; + head += 5; + ecm_pid = find_ca_descriptor_pid(head, head+length); + head += length; + + if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){ + dec[1] = set_decryptor(prv, ecm_pid); + if(dec[1] == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + if(!add_ecm_stream(prv, &(pgrm->streams), ecm_pid)){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + }else{ + dec[1] = NULL; + } + + strm = get_stream_list_head(&(prv->strm_pool)); + if( strm == NULL ){ + strm = create_stream_elem(pid, type); + if(strm == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + }else{ + strm->pid = pid; + strm->type = type; + } + + prv->map[pid].type = PID_MAP_TYPE_OTHER; + prv->map[pid].ref += 1; + + dw = select_active_decryptor(dec[0], dec[1], ecm_pid); + bind_stream_decryptor(prv, pid, dw); + + put_stream_list_tail(&(pgrm->streams), strm); + } + +LAST: + if( dec[0] != NULL ){ + dec[0]->ref -= 1; + if( dec[0]->ref < 1 ){ + remove_decryptor(prv, dec[0]); + dec[0] = NULL; + } + } + + if(sect.raw != NULL){ + n = pgrm->pmt->ret(pgrm->pmt, §); + if( (n < 0) && (r == 0) ){ + return ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + } + } + + return 0; +} + +static int32_t find_ca_descriptor_pid(uint8_t *head, uint8_t *tail) +{ + uint32_t ca_pid; + uint32_t ca_sys_id; + + uint32_t tag; + uint32_t len; + + while(head+1 < tail){ + tag = head[0]; + len = head[1]; + head += 2; + if( (tag == 0x09) && /* CA_descriptor */ + (len >= 4) && + (head+len <= tail) ){ + ca_sys_id = ((head[0] << 8) | head[1]); + ca_pid = ((head[2] << 8) | head[3]) & 0x1fff; + return ca_pid; + } + head += len; + } + + return 0; +} + +static int add_ecm_stream(ARIB_STD_B25_PRIVATE_DATA *prv, TS_STREAM_LIST *list, int32_t ecm_pid) +{ + TS_STREAM_ELEM *strm; + + strm = find_stream_list_elem(list, ecm_pid); + if(strm != NULL){ + // ECM is already registered + return 1; + } + + strm = get_stream_list_head(&(prv->strm_pool)); + if(strm == NULL){ + strm = create_stream_elem(ecm_pid, PID_MAP_TYPE_ECM); + if(strm == NULL){ + return 0; + } + }else{ + strm->pid = ecm_pid; + strm->type = PID_MAP_TYPE_ECM; + } + + put_stream_list_tail(list, strm); + prv->map[ecm_pid].ref += 1; + + return 1; +} + +static int check_ecm_complete(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int n,num[3]; + DECRYPTOR_ELEM *e; + + memset(num, 0, sizeof(num)); + + e = prv->decrypt.head; + while( e != NULL ){ + n = e->phase; + if(n < 0){ + n = 0; + }else if(n > 2){ + n = 2; + } + num[n] += 1; + e = (DECRYPTOR_ELEM *)(e->next); + } + + if(num[2] > 0){ + return 1; + } + + if(num[0] > 0){ + return 0; + } + + return 1; +} + +static int find_ecm(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int r; + int n,size; + + int32_t unit; + + uint8_t *p; + uint8_t *curr; + uint8_t *tail; + + TS_HEADER hdr; + DECRYPTOR_ELEM *dec; + + r = 0; + unit = prv->unit_size; + curr = prv->sbuf.head + prv->sbuf_offset; + tail = prv->sbuf.tail; + + while( (curr+unit) < tail ){ + if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ + p = resync(curr, tail, unit); + if(p == NULL){ + goto LAST; + } + curr = p; + } + extract_ts_header(&hdr, curr); + if(prv->map[hdr.pid].type != PID_MAP_TYPE_ECM){ + goto NEXT; + } + dec = (DECRYPTOR_ELEM *)(prv->map[hdr.pid].target); + if(dec == NULL){ + goto NEXT; + } + + if(dec->phase == 0){ + + p = curr + 4; + if(hdr.adaptation_field_control & 0x02){ + p += (p[0]+1); + } + size = 188 - (p-curr); + if(size < 1){ + goto NEXT; + } + + if(dec->ecm == NULL){ + /* this code will never execute */ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + curr += unit; + goto LAST; + } + + n = dec->ecm->put(dec->ecm, &hdr, p, size); + if(n < 0){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + curr += unit; + goto LAST; + } + n = dec->ecm->get_count(dec->ecm); + if(n < 0){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + curr += unit; + goto LAST; + } + if(n == 0){ + goto NEXT; + } + + r = proc_ecm(dec, prv->bcas, prv->multi2_round); + if(r < 0){ + curr += unit; + goto LAST; + } + if( (r > 0) && (r != ARIB_STD_B25_WARN_UNPURCHASED_ECM) ){ + /* broken or unexpected section data */ + goto NEXT; + } + + dec->phase = 1; + if(check_ecm_complete(prv)){ + curr += unit; + goto LAST; + } + + }else{ + dec->phase = 2; + curr += unit; + goto LAST; + } + + NEXT: + curr += unit; + } + +LAST: + prv->sbuf_offset = curr - prv->sbuf.head; + + return r; +} + +static int proc_ecm(DECRYPTOR_ELEM *dec, B_CAS_CARD *bcas, int32_t multi2_round) +{ + int r,n; + int length; + + uint8_t *p; + + B_CAS_INIT_STATUS is; + B_CAS_ECM_RESULT res; + + TS_SECTION sect; + + r = 0; + memset(§, 0, sizeof(sect)); + + if(bcas == NULL){ + r = ARIB_STD_B25_ERROR_EMPTY_B_CAS_CARD; + goto LAST; + } + + n = dec->ecm->get(dec->ecm, §); + if(n < 0){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + goto LAST; + } + if(sect.hdr.table_id != TS_SECTION_ID_ECM_S){ + r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; + goto LAST; + } + + if(dec->locked){ + /* previous ECM has returned unpurchased + skip this pid for B-CAS card load reduction */ + dec->unpurchased += 1; + r = ARIB_STD_B25_WARN_UNPURCHASED_ECM; + goto LAST; + } + + length = (sect.tail - sect.data) - 4; + p = sect.data; + + r = bcas->proc_ecm(bcas, &res, p, length); + if(r < 0){ + if(dec->m2 != NULL){ + dec->m2->clear_scramble_key(dec->m2); + } + r = ARIB_STD_B25_ERROR_ECM_PROC_FAILURE; + goto LAST; + } + + if( (res.return_code != 0x0800) && + (res.return_code != 0x0400) && + (res.return_code != 0x0200) ){ + /* return_code is not equal "purchased" */ + if(dec->m2 != NULL){ + dec->m2->release(dec->m2); + dec->m2 = NULL; + } + dec->unpurchased += 1; + dec->last_error = res.return_code; + dec->locked += 1; + r = ARIB_STD_B25_WARN_UNPURCHASED_ECM; + goto LAST; + } + + if(dec->m2 == NULL){ + dec->m2 = create_multi2(); + if(dec->m2 == NULL){ + return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + } + r = bcas->get_init_status(bcas, &is); + if(r < 0){ + return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS; + } + dec->m2->set_system_key(dec->m2, is.system_key); + dec->m2->set_init_cbc(dec->m2, is.init_cbc); + dec->m2->set_round(dec->m2, multi2_round); + } + + dec->m2->set_scramble_key(dec->m2, res.scramble_key); + +LAST: + if(sect.raw != NULL){ + n = dec->ecm->ret(dec->ecm, §); + if( (n < 0) && (r == 0) ){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + } + } + + return r; +} + +static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int r; + int m,n; + + int32_t crypt; + int32_t unit; + int32_t pid; + + uint8_t *p; + uint8_t *curr; + uint8_t *tail; + + TS_HEADER hdr; + DECRYPTOR_ELEM *dec; + TS_PROGRAM *pgrm; + + unit = prv->unit_size; + curr = prv->sbuf.head; + tail = prv->sbuf.tail; + + m = prv->dbuf.tail - prv->dbuf.head; + n = tail - curr; + if(!reserve_work_buffer(&(prv->dbuf), m+n)){ + return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + } + + r = 0; + + while( (curr+unit) < tail ){ + + if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ + p = resync(curr, tail, unit); + if(p == NULL){ + goto LAST; + } + curr = p; + } + + extract_ts_header(&hdr, curr); + crypt = hdr.transport_scrambling_control; + pid = hdr.pid; + + if( (pid == 0x1fff) && (prv->strip) ){ + /* strip null(padding) stream */ + goto NEXT; + } + + p = curr+4; + if(hdr.adaptation_field_control & 0x02){ + p += (p[0]+1); + } + n = 188 - (p-curr); + if( (n < 1) && ((n < 0) || (hdr.adaptation_field_control & 0x01)) ){ + /* broken packet */ + curr += 1; + continue; + } + + if( (crypt != 0) && + (hdr.adaptation_field_control & 0x01) ){ + + if(prv->map[pid].type == PID_MAP_TYPE_OTHER){ + dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); + }else if( (prv->map[pid].type == 0) && + (prv->decrypt.count == 1) ){ + dec = prv->decrypt.head; + }else{ + dec = NULL; + } + + if( (dec != NULL) && (dec->m2 != NULL) ){ + m = dec->m2->decrypt(dec->m2, crypt, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_DECRYPT_FAILURE; + goto LAST; + } + curr[3] &= 0x3f; + prv->map[pid].normal_packet += 1; + }else{ + prv->map[pid].undecrypted += 1; + } + }else{ + prv->map[pid].normal_packet += 1; + } + + if(!append_work_buffer(&(prv->dbuf), curr, 188)){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + + if(prv->map[pid].type == PID_MAP_TYPE_ECM){ + dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); + if( (dec == NULL) || (dec->ecm == NULL) ){ + /* this code will never execute */ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + goto LAST; + } + m = dec->ecm->put(dec->ecm, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + goto LAST; + } + m = dec->ecm->get_count(dec->ecm); + if(m < 0){ + r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_ecm(dec, prv->bcas, prv->multi2_round); + if(r < 0){ + goto LAST; + } + }else if(prv->map[pid].type == PID_MAP_TYPE_PMT){ + pgrm = (TS_PROGRAM *)(prv->map[pid].target); + if( (pgrm == NULL) || (pgrm->pmt == NULL) ){ + /* this code will never execute */ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + goto LAST; + } + m = pgrm->pmt->put(pgrm->pmt, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + goto LAST; + } + m = pgrm->pmt->get_count(pgrm->pmt); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_pmt(prv, pgrm); + if(r < 0){ + goto LAST; + } + }else if(prv->map[pid].type == PID_MAP_TYPE_EMM){ + if( prv->emm_proc_on == 0){ + goto NEXT; + } + if( prv->emm == NULL ){ + prv->emm = create_ts_section_parser(); + if(prv->emm == NULL){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + goto LAST; + } + } + m = prv->emm->put(prv->emm, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + goto LAST; + } + m = prv->emm->get_count(prv->emm); + if(m < 0){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_emm(prv); + if(r < 0){ + goto LAST; + } + }else if(pid == 0x0001){ + if( prv->cat == NULL ){ + prv->cat = create_ts_section_parser(); + if(prv->cat == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + } + m = prv->cat->put(prv->cat, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; + goto LAST; + } + m = prv->cat->get_count(prv->cat); + if(m < 0){ + r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_cat(prv); + if(r < 0){ + goto LAST; + } + }else if(pid == 0x0000){ + if( prv->pat == NULL ){ + prv->pat = create_ts_section_parser(); + if(prv->pat == NULL){ + r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; + goto LAST; + } + } + m = prv->pat->put(prv->pat, &hdr, p, n); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + goto LAST; + } + m = prv->pat->get_count(prv->pat); + if(m < 0){ + r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; + goto LAST; + } + if(m == 0){ + goto NEXT; + } + r = proc_pat(prv); + goto LAST; + } + + NEXT: + curr += unit; + } + +LAST: + m = curr - prv->sbuf.head; + n = tail - curr; + if( (n < 1024) || (m > (prv->sbuf.max/2) ) ){ + p = prv->sbuf.pool; + memcpy(p, curr, n); + prv->sbuf.head = p; + prv->sbuf.tail = p+n; + }else{ + prv->sbuf.head = curr; + } + + return r; +} + +static int proc_cat(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int r; + int n; + int emm_pid; + + TS_SECTION sect; + + r = 0; + memset(§, 0, sizeof(sect)); + + n = prv->cat->get(prv->cat, §); + if(n < 0){ + r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; + goto LAST; + } + + if(sect.hdr.table_id != TS_SECTION_ID_CONDITIONAL_ACCESS){ + r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; + goto LAST; + } + + emm_pid = find_ca_descriptor_pid(sect.data, sect.tail-4); + if( (emm_pid != 0x0000) && (emm_pid != 0x1fff) ){ + if( (prv->map[emm_pid].target != NULL) && + (prv->map[emm_pid].type == PID_MAP_TYPE_OTHER) ){ + DECRYPTOR_ELEM *dec; + dec = (DECRYPTOR_ELEM *)(prv->map[emm_pid].target); + dec->ref -= 1; + if(dec->ref < 1){ + remove_decryptor(prv, dec); + } + } + prv->emm_pid = emm_pid; + prv->map[emm_pid].ref = 1; + prv->map[emm_pid].type = PID_MAP_TYPE_EMM; + prv->map[emm_pid].target = NULL; + } + + prv->map[0x0001].ref = 1; + prv->map[0x0001].type = PID_MAP_TYPE_CAT; + prv->map[0x0001].target = NULL; + +LAST: + + if(sect.raw != NULL){ + n = prv->cat->ret(prv->cat, §); + if( (n < 0) && (r == 0) ){ + r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; + } + } + + return r; +} + +static int proc_emm(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + int r; + int i,j,n; + + int len; + + uint8_t *head; + uint8_t *tail; + + TS_SECTION sect; + EMM_FIXED_PART emm_hdr; + + r = 0; + memset(§, 0, sizeof(sect)); + + if(prv->bcas == NULL){ + r = ARIB_STD_B25_ERROR_EMPTY_B_CAS_CARD; + goto LAST; + } + + while( (n = prv->emm->get_count(prv->emm)) > 0 ){ + + n = prv->emm->get(prv->emm, §); + if(n < 0){ + r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; + goto LAST; + } + + if(sect.hdr.table_id == TS_SECTION_ID_EMM_MESSAGE){ + /* EMM_MESSAGE is not supported */ + goto NEXT; + }else if(sect.hdr.table_id != TS_SECTION_ID_EMM_S){ + r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; + goto LAST; + } + + head = sect.data; + tail = sect.tail - 4; + + i = 0; + while( (head+13) <= tail ){ + + extract_emm_fixed_part(&emm_hdr, head); + len = emm_hdr.associated_information_length+7; + if( (head+len) > tail ){ + /* broken EMM element */ + goto NEXT; + } + + for(j=0;jcasid.count;j++){ + if(prv->casid.data[j] == emm_hdr.card_id){ + n = prv->bcas->proc_emm(prv->bcas, head, len); + if(n < 0){ + r = ARIB_STD_B25_ERROR_EMM_PROC_FAILURE; + goto LAST; + } + unlock_all_decryptor(prv); + } + } + + head += len; + } + + NEXT: + if(sect.raw != NULL){ + n = prv->emm->ret(prv->emm, §); + if( (n < 0) && (r == 0) ){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + goto LAST; + } + memset(§, 0, sizeof(sect)); + } + } + +LAST: + if(sect.raw != NULL){ + n = prv->emm->ret(prv->emm, §); + if( (n < 0) && (r == 0) ){ + r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; + } + } + + return r; +} + +static void release_program(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm) +{ + int32_t pid; + TS_STREAM_ELEM *strm; + + pid = pgrm->pmt_pid; + + if(pgrm->pmt != NULL){ + pgrm->pmt->release(pgrm->pmt); + pgrm->pmt = NULL; + } + + while( (strm = get_stream_list_head(&(pgrm->old_strm))) != NULL ){ + unref_stream(prv, strm->pid); + memset(strm, 0, sizeof(TS_STREAM_ELEM)); + put_stream_list_tail(&(prv->strm_pool), strm); + } + + while( (strm = get_stream_list_head(&(pgrm->streams))) != NULL ){ + unref_stream(prv, strm->pid); + memset(strm, 0, sizeof(TS_STREAM_ELEM)); + put_stream_list_tail(&(prv->strm_pool), strm); + } + + prv->map[pid].type = PID_MAP_TYPE_UNKNOWN; + prv->map[pid].ref = 0; + prv->map[pid].target = NULL; +} + +static void unref_stream(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid) +{ + DECRYPTOR_ELEM *dec; + + prv->map[pid].ref -= 1; + if( prv->map[pid].ref < 1 ){ + if( (prv->map[pid].target != NULL) && + (prv->map[pid].type == PID_MAP_TYPE_OTHER) ){ + dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); + dec->ref -= 1; + if(dec->ref < 1){ + remove_decryptor(prv, dec); + } + } + prv->map[pid].type = PID_MAP_TYPE_UNKNOWN; + prv->map[pid].ref = 0; + prv->map[pid].target = NULL; + } +} + +static DECRYPTOR_ELEM *set_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid) +{ + DECRYPTOR_ELEM *r; + + r = NULL; + if(prv->map[pid].type == PID_MAP_TYPE_ECM){ + r = (DECRYPTOR_ELEM *)(prv->map[pid].target); + if(r != NULL){ + return r; + } + } + r = (DECRYPTOR_ELEM *)calloc(1, sizeof(DECRYPTOR_ELEM)); + if(r == NULL){ + return NULL; + } + r->ecm_pid = pid; + r->ecm = create_ts_section_parser(); + if(r->ecm == NULL){ + free(r); + return NULL; + } + + if(prv->decrypt.tail != NULL){ + r->prev = prv->decrypt.tail; + r->next = NULL; + prv->decrypt.tail->next = r; + prv->decrypt.tail = r; + prv->decrypt.count += 1; + }else{ + r->prev = NULL; + r->next = NULL; + prv->decrypt.head = r; + prv->decrypt.tail = r; + prv->decrypt.count = 1; + } + + if( (prv->map[pid].type == PID_MAP_TYPE_OTHER) && + (prv->map[pid].target != NULL) ){ + DECRYPTOR_ELEM *dec; + dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); + dec->ref -= 1; + if(dec->ref < 1){ + remove_decryptor(prv, dec); + } + } + + prv->map[pid].type = PID_MAP_TYPE_ECM; + prv->map[pid].target = r; + + return r; +} + +static void remove_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, DECRYPTOR_ELEM *dec) +{ + int32_t pid; + + DECRYPTOR_ELEM *prev; + DECRYPTOR_ELEM *next; + + pid = dec->ecm_pid; + if( (prv->map[pid].type == PID_MAP_TYPE_ECM) && + (prv->map[pid].target == ((void *)dec)) ){ + prv->map[pid].type = PID_MAP_TYPE_UNKNOWN; + prv->map[pid].target = NULL; + } + + prev = (DECRYPTOR_ELEM *)(dec->prev); + next = (DECRYPTOR_ELEM *)(dec->next); + if(prev != NULL){ + prev->next = next; + }else{ + prv->decrypt.head = next; + } + if(next != NULL){ + next->prev = prev; + }else{ + prv->decrypt.tail = prev; + } + prv->decrypt.count -= 1; + + if(dec->ecm != NULL){ + dec->ecm->release(dec->ecm); + dec->ecm = NULL; + } + + if(dec->m2 != NULL){ + dec->m2->release(dec->m2); + dec->m2 = NULL; + } + + free(dec); +} + +static DECRYPTOR_ELEM *select_active_decryptor(DECRYPTOR_ELEM *a, DECRYPTOR_ELEM *b, int32_t pid) +{ + if( b != NULL ){ + return b; + } + if( pid == 0x1fff ){ + return NULL; + } + return a; +} + +static void bind_stream_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid, DECRYPTOR_ELEM *dec) +{ + DECRYPTOR_ELEM *old; + + old = (DECRYPTOR_ELEM *)(prv->map[pid].target); + if(old == dec){ + /* already binded - do nothing */ + return; + } + + if(old != NULL){ + old->ref -= 1; + if(old->ref == 0){ + remove_decryptor(prv, old); + } + prv->map[pid].target = NULL; + } + + if(dec != NULL){ + prv->map[pid].target = dec; + dec->ref += 1; + } +} + +static void unlock_all_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv) +{ + DECRYPTOR_ELEM *e; + + e = prv->decrypt.head; + while(e != NULL){ + e->locked = 0; + e = (DECRYPTOR_ELEM *)(e->next); + } +} + +static TS_STREAM_ELEM *get_stream_list_head(TS_STREAM_LIST *list) +{ + TS_STREAM_ELEM *r; + + r = list->head; + if(r == NULL){ + return NULL; + } + + list->head = (TS_STREAM_ELEM *)(r->next); + if(list->head == NULL){ + list->tail = NULL; + list->count = 0; + }else{ + list->head->prev = NULL; + list->count -= 1; + } + + r->prev = NULL; + r->next = NULL; + + return r; +} + +static TS_STREAM_ELEM *find_stream_list_elem(TS_STREAM_LIST *list, int32_t pid) +{ + TS_STREAM_ELEM *r; + + r = list->head; + while(r != NULL){ + if(r->pid == pid){ + break; + } + r = (TS_STREAM_ELEM *)(r->next); + } + + return r; +} + +static TS_STREAM_ELEM *create_stream_elem(int32_t pid, int32_t type) +{ + TS_STREAM_ELEM *r; + + r = (TS_STREAM_ELEM *)calloc(1, sizeof(TS_STREAM_ELEM)); + if(r == NULL){ + return NULL; + } + + r->pid = pid; + r->type = type; + + return r; +} + +static void put_stream_list_tail(TS_STREAM_LIST *list, TS_STREAM_ELEM *elem) +{ + if(list->tail != NULL){ + elem->prev = list->tail; + elem->next = NULL; + list->tail->next = elem; + list->tail = elem; + list->count += 1; + }else{ + elem->prev = NULL; + elem->next = NULL; + list->head = elem; + list->tail = elem; + list->count = 1; + } +} + +static void clear_stream_list(TS_STREAM_LIST *list) +{ + TS_STREAM_ELEM *p,*n; + + p = list->head; + while(p != NULL){ + n = (TS_STREAM_ELEM *)(p->next); + free(p); + p = n; + } + + list->head = NULL; + list->tail = NULL; + list->count = 0; +} + +static int reserve_work_buffer(TS_WORK_BUFFER *buf, int32_t size) +{ + int m,n; + uint8_t *p; + + if(buf->max >= size){ + return 1; + } + + if(buf->max < 512){ + n = 512; + }else{ + n = buf->max * 2; + } + + while(n < size){ + n += n; + } + + p = (uint8_t *)malloc(n); + if(p == NULL){ + return 0; + } + + m = 0; + if(buf->pool != NULL){ + m = buf->tail - buf->head; + if(m > 0){ + memcpy(p, buf->head, m); + } + free(buf->pool); + buf->pool = NULL; + } + + buf->pool = p; + buf->head = p; + buf->tail = p+m; + buf->max = n; + + return 1; +} + +static int append_work_buffer(TS_WORK_BUFFER *buf, uint8_t *data, int32_t size) +{ + int m; + + if(size < 1){ + /* ignore - do nothing */ + return 1; + } + + m = buf->tail - buf->pool; + + if( (m+size) > buf->max ){ + if(!reserve_work_buffer(buf, m+size)){ + return 0; + } + } + + memcpy(buf->tail, data, size); + buf->tail += size; + + return 1; +} + +static void reset_work_buffer(TS_WORK_BUFFER *buf) +{ + buf->head = buf->pool; + buf->tail = buf->pool; +} + +static void release_work_buffer(TS_WORK_BUFFER *buf) +{ + if(buf->pool != NULL){ + free(buf->pool); + } + buf->pool = NULL; + buf->head = NULL; + buf->tail = NULL; + buf->max = 0; +} + +static void extract_ts_header(TS_HEADER *dst, uint8_t *src) +{ + dst->sync = src[0]; + dst->transport_error_indicator = (src[1] >> 7) & 0x01; + dst->payload_unit_start_indicator = (src[1] >> 6) & 0x01; + dst->transport_priority = (src[1] >> 5) & 0x01; + dst->pid = ((src[1] & 0x1f) << 8) | src[2]; + dst->transport_scrambling_control = (src[3] >> 6) & 0x03; + dst->adaptation_field_control = (src[3] >> 4) & 0x03; + dst->continuity_counter = src[3] & 0x0f; +} + +static void extract_emm_fixed_part(EMM_FIXED_PART *dst, uint8_t *src) +{ + int i; + + dst->card_id = 0; + for(i=0;i<6;i++){ + dst->card_id = (dst->card_id << 8) | src[i]; + } + + dst->associated_information_length = src[ 6]; + dst->protocol_number = src[ 7]; + dst->broadcaster_group_id = src[ 8]; + dst->update_number = (src[ 9]<<8)|src[10]; + dst->expiration_date = (src[11]<<8)|src[12]; +} + +static int check_unit_invert(unsigned char *head, unsigned char *tail) +{ + unsigned char *buf; + + buf = tail-188; + + while(head <= buf){ + if(buf[0] == 0x47){ + return tail-buf; + } + buf -= 1; + } + + return 0; +} + +static uint8_t *resync(uint8_t *head, uint8_t *tail, int32_t unit_size) +{ + int i; + unsigned char *buf; + + buf = head; + tail -= unit_size * 8; + while( buf <= tail ){ + if(buf[0] == 0x47){ + for(i=1;i<8;i++){ + if(buf[unit_size*i] != 0x47){ + break; + } + } + if(i == 8){ + return buf; + } + } + buf += 1; + } + + return NULL; +} + +static uint8_t *resync_force(uint8_t *head, uint8_t *tail, int32_t unit_size) +{ + int i,n; + unsigned char *buf; + + buf = head; + while( buf <= (tail-188) ){ + if(buf[0] == 0x47){ + n = (tail - buf) / unit_size; + if(n == 0){ + return buf; + } + for(i=1;i +#include + +#include + +#if defined(WIN32) + #include +#endif +#include + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + inner structures + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +typedef struct { + + SCARDCONTEXT mng; + SCARDHANDLE card; + + uint8_t *pool; + char *reader; + + uint8_t *sbuf; + uint8_t *rbuf; + + B_CAS_INIT_STATUS stat; + + B_CAS_ID id; + int32_t id_max; + + B_CAS_PWR_ON_CTRL_INFO pwc; + int32_t pwc_max; + +} B_CAS_CARD_PRIVATE_DATA; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + constant values + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static const uint8_t INITIAL_SETTING_CONDITIONS_CMD[] = { + 0x90, 0x30, 0x00, 0x00, 0x00, +}; + +static const uint8_t CARD_ID_INFORMATION_ACQUIRE_CMD[] = { + 0x90, 0x32, 0x00, 0x00, 0x00, +}; + +static const uint8_t POWER_ON_CONTROL_INFORMATION_REQUEST_CMD[] = { + 0x90, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, +}; + +static const uint8_t ECM_RECEIVE_CMD_HEADER[] = { + 0x90, 0x34, 0x00, 0x00, +}; + +static const uint8_t EMM_RECEIVE_CMD_HEADER[] = { + 0x90, 0x36, 0x00, 0x00, +}; + +#define B_CAS_BUFFER_MAX (4*1024) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (interface method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_b_cas_card(void *bcas); +static int init_b_cas_card(void *bcas); +static int get_init_status_b_cas_card(void *bcas, B_CAS_INIT_STATUS *stat); +static int get_id_b_cas_card(void *bcas, B_CAS_ID *dst); +static int get_pwr_on_ctrl_b_cas_card(void *bcas, B_CAS_PWR_ON_CTRL_INFO *dst); +static int proc_ecm_b_cas_card(void *bcas, B_CAS_ECM_RESULT *dst, uint8_t *src, int len); +static int proc_emm_b_cas_card(void *bcas, uint8_t *src, int len); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + global function implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +B_CAS_CARD *create_b_cas_card() +{ + int n; + + B_CAS_CARD *r; + B_CAS_CARD_PRIVATE_DATA *prv; + + n = sizeof(B_CAS_CARD) + sizeof(B_CAS_CARD_PRIVATE_DATA); + prv = (B_CAS_CARD_PRIVATE_DATA *)calloc(1, n); + if(prv == NULL){ + return NULL; + } + + r = (B_CAS_CARD *)(prv+1); + + r->private_data = prv; + + r->release = release_b_cas_card; + r->init = init_b_cas_card; + r->get_init_status = get_init_status_b_cas_card; + r->get_id = get_id_b_cas_card; + r->get_pwr_on_ctrl = get_pwr_on_ctrl_b_cas_card; + r->proc_ecm = proc_ecm_b_cas_card; + r->proc_emm = proc_emm_b_cas_card; + + return r; +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (private method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static B_CAS_CARD_PRIVATE_DATA *private_data(void *bcas); +static void teardown(B_CAS_CARD_PRIVATE_DATA *prv); +static int change_id_max(B_CAS_CARD_PRIVATE_DATA *prv, int max); +static int change_pwc_max(B_CAS_CARD_PRIVATE_DATA *prv, int max); +static int connect_card(B_CAS_CARD_PRIVATE_DATA *prv, const char *reader_name); +static void extract_power_on_ctrl_response(B_CAS_PWR_ON_CTRL *dst, uint8_t *src); +static void extract_mjd(int *yy, int *mm, int *dd, int mjd); +static int setup_ecm_receive_command(uint8_t *dst, uint8_t *src, int len); +static int setup_emm_receive_command(uint8_t *dst, uint8_t *src, int len); +static int32_t load_be_uint16(uint8_t *p); +static int64_t load_be_uint48(uint8_t *p); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + interface method implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_b_cas_card(void *bcas) +{ + B_CAS_CARD_PRIVATE_DATA *prv; + + prv = private_data(bcas); + if(prv == NULL){ + /* do nothing */ + return; + } + + teardown(prv); + free(prv); +} + +static int init_b_cas_card(void *bcas) +{ + int m; + LONG ret; + DWORD len; + + B_CAS_CARD_PRIVATE_DATA *prv; + + prv = private_data(bcas); + if(prv == NULL){ + return B_CAS_CARD_ERROR_INVALID_PARAMETER; + } + + teardown(prv); + + ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &(prv->mng)); + if(ret != SCARD_S_SUCCESS){ + return B_CAS_CARD_ERROR_NO_SMART_CARD_READER; + } + + ret = SCardListReaders(prv->mng, NULL, NULL, &len); + if(ret != SCARD_S_SUCCESS){ + return B_CAS_CARD_ERROR_NO_SMART_CARD_READER; + } + len += 256; + + m = len + (2*B_CAS_BUFFER_MAX) + (sizeof(int64_t)*16) + (sizeof(B_CAS_PWR_ON_CTRL)*16); + prv->pool = (uint8_t *)malloc(m); + if(prv->pool == NULL){ + return B_CAS_CARD_ERROR_NO_ENOUGH_MEMORY; + } + + prv->reader = (char *)(prv->pool); + prv->sbuf = prv->pool + len; + prv->rbuf = prv->sbuf + B_CAS_BUFFER_MAX; + prv->id.data = (int64_t *)(prv->rbuf + B_CAS_BUFFER_MAX); + prv->id_max = 16; + prv->pwc.data = (B_CAS_PWR_ON_CTRL *)(prv->id.data + prv->id_max); + prv->pwc_max = 16; + + ret = SCardListReaders(prv->mng, NULL, prv->reader, &len); + if(ret != SCARD_S_SUCCESS){ + return B_CAS_CARD_ERROR_NO_SMART_CARD_READER; + } + + while( prv->reader[0] != 0 ){ + if(connect_card(prv, prv->reader)){ + break; + } + prv->reader += (strlen(prv->reader) + 1); + } + + if(prv->card == 0){ + return B_CAS_CARD_ERROR_ALL_READERS_CONNECTION_FAILED; + } + + return 0; +} + +static int get_init_status_b_cas_card(void *bcas, B_CAS_INIT_STATUS *stat) +{ + B_CAS_CARD_PRIVATE_DATA *prv; + + prv = private_data(bcas); + if( (prv == NULL) || (stat == NULL) ){ + return B_CAS_CARD_ERROR_INVALID_PARAMETER; + } + + if(prv->card == 0){ + return B_CAS_CARD_ERROR_NOT_INITIALIZED; + } + + memcpy(stat, &(prv->stat), sizeof(B_CAS_INIT_STATUS)); + + return 0; +} + +static int get_id_b_cas_card(void *bcas, B_CAS_ID *dst) +{ + LONG ret; + + DWORD slen; + DWORD rlen; + + int i,num; + + uint8_t *p; + uint8_t *tail; + + B_CAS_CARD_PRIVATE_DATA *prv; + SCARD_IO_REQUEST sir; + + prv = private_data(bcas); + if( (prv == NULL) || (dst == NULL) ){ + return B_CAS_CARD_ERROR_INVALID_PARAMETER; + } + + if(prv->card == 0){ + return B_CAS_CARD_ERROR_NOT_INITIALIZED; + } + + slen = sizeof(CARD_ID_INFORMATION_ACQUIRE_CMD); + memcpy(prv->sbuf, CARD_ID_INFORMATION_ACQUIRE_CMD, slen); + memcpy(&sir, SCARD_PCI_T1, sizeof(sir)); + rlen = B_CAS_BUFFER_MAX; + + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, slen, &sir, prv->rbuf, &rlen); + if( (ret != SCARD_S_SUCCESS) || (rlen < 19) ){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + p = prv->rbuf + 6; + tail = prv->rbuf + rlen; + if( p+1 > tail ){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + num = p[0]; + if(num > prv->id_max){ + if(change_id_max(prv, num+4) < 0){ + return B_CAS_CARD_ERROR_NO_ENOUGH_MEMORY; + } + } + + p += 1; + for(i=0;i tail ){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + { + int maker_id; + int version; + int check_code; + + maker_id = p[0]; + version = p[1]; + prv->id.data[i] = load_be_uint48(p+2); + check_code = load_be_uint16(p+8); + } + + p += 10; + } + + prv->id.count = num; + + memcpy(dst, &(prv->id), sizeof(B_CAS_ID)); + + return 0; +} + +static int get_pwr_on_ctrl_b_cas_card(void *bcas, B_CAS_PWR_ON_CTRL_INFO *dst) +{ + LONG ret; + + DWORD slen; + DWORD rlen; + + int i,num,code; + + B_CAS_CARD_PRIVATE_DATA *prv; + SCARD_IO_REQUEST sir; + + memset(dst, 0, sizeof(B_CAS_PWR_ON_CTRL_INFO)); + + prv = private_data(bcas); + if( (prv == NULL) || (dst == NULL) ){ + return B_CAS_CARD_ERROR_INVALID_PARAMETER; + } + + if(prv->card == 0){ + return B_CAS_CARD_ERROR_NOT_INITIALIZED; + } + + slen = sizeof(POWER_ON_CONTROL_INFORMATION_REQUEST_CMD); + memcpy(prv->sbuf, POWER_ON_CONTROL_INFORMATION_REQUEST_CMD, slen); + prv->sbuf[5] = 0; + memcpy(&sir, SCARD_PCI_T1, sizeof(sir)); + rlen = B_CAS_BUFFER_MAX; + + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, slen, &sir, prv->rbuf, &rlen); + if( (ret != SCARD_S_SUCCESS) || (rlen < 18) || (prv->rbuf[6] != 0) ){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + code = load_be_uint16(prv->rbuf+4); + if(code == 0xa101){ + /* no data */ + return 0; + }else if(code != 0x2100){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + num = (prv->rbuf[7] + 1); + if(prv->pwc_max < num){ + if(change_pwc_max(prv, num+4) < 0){ + return B_CAS_CARD_ERROR_NO_ENOUGH_MEMORY; + } + } + + extract_power_on_ctrl_response(prv->pwc.data+0, prv->rbuf); + + for(i=1;isbuf[5] = i; + rlen = B_CAS_BUFFER_MAX; + + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, slen, &sir, prv->rbuf, &rlen); + if( (ret != SCARD_S_SUCCESS) || (rlen < 18) || (prv->rbuf[6] != i) ){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + extract_power_on_ctrl_response(prv->pwc.data+i, prv->rbuf); + } + + prv->pwc.count = num; + + memcpy(dst, &(prv->pwc), sizeof(B_CAS_PWR_ON_CTRL_INFO)); + + return 0; +} + +static int proc_ecm_b_cas_card(void *bcas, B_CAS_ECM_RESULT *dst, uint8_t *src, int len) +{ + int retry_count; + + LONG ret; + DWORD slen; + DWORD rlen; + + B_CAS_CARD_PRIVATE_DATA *prv; + + SCARD_IO_REQUEST sir; + + prv = private_data(bcas); + if( (prv == NULL) || + (dst == NULL) || + (src == NULL) || + (len < 1) ){ + return B_CAS_CARD_ERROR_INVALID_PARAMETER; + } + + if(prv->card == 0){ + return B_CAS_CARD_ERROR_NOT_INITIALIZED; + } + + slen = setup_ecm_receive_command(prv->sbuf, src, len); + memcpy(&sir, SCARD_PCI_T1, sizeof(sir)); + rlen = B_CAS_BUFFER_MAX; + + retry_count = 0; + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, slen, &sir, prv->rbuf, &rlen); + while( ((ret != SCARD_S_SUCCESS) || (rlen < 25)) && (retry_count < 10) ){ + retry_count += 1; + if(!connect_card(prv, prv->reader)){ + continue; + } + slen = setup_ecm_receive_command(prv->sbuf, src, len); + memcpy(&sir, SCARD_PCI_T1, sizeof(sir)); + rlen = B_CAS_BUFFER_MAX; + + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, slen, &sir, prv->rbuf, &rlen); + } + + if( (ret != SCARD_S_SUCCESS) || (rlen < 25) ){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + memcpy(dst->scramble_key, prv->rbuf+6, 16); + dst->return_code = load_be_uint16(prv->rbuf+4); + + return 0; +} + +static int proc_emm_b_cas_card(void *bcas, uint8_t *src, int len) +{ + int retry_count; + + LONG ret; + DWORD slen; + DWORD rlen; + + B_CAS_CARD_PRIVATE_DATA *prv; + + SCARD_IO_REQUEST sir; + + prv = private_data(bcas); + if( (prv == NULL) || + (src == NULL) || + (len < 1) ){ + return B_CAS_CARD_ERROR_INVALID_PARAMETER; + } + + if(prv->card == 0){ + return B_CAS_CARD_ERROR_NOT_INITIALIZED; + } + + slen = setup_emm_receive_command(prv->sbuf, src, len); + memcpy(&sir, SCARD_PCI_T1, sizeof(sir)); + rlen = B_CAS_BUFFER_MAX; + + retry_count = 0; + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, slen, &sir, prv->rbuf, &rlen); + while( ((ret != SCARD_S_SUCCESS) || (rlen < 6)) && (retry_count < 2) ){ + retry_count += 1; + if(!connect_card(prv, prv->reader)){ + continue; + } + slen = setup_emm_receive_command(prv->sbuf, src, len); + memcpy(&sir, SCARD_PCI_T1, sizeof(sir)); + rlen = B_CAS_BUFFER_MAX; + + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, slen, &sir, prv->rbuf, &rlen); + } + + if( (ret != SCARD_S_SUCCESS) || (rlen < 6) ){ + return B_CAS_CARD_ERROR_TRANSMIT_FAILED; + } + + return 0; +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + private method implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static B_CAS_CARD_PRIVATE_DATA *private_data(void *bcas) +{ + B_CAS_CARD_PRIVATE_DATA *r; + B_CAS_CARD *p; + + p = (B_CAS_CARD *)bcas; + if(p == NULL){ + return NULL; + } + + r = (B_CAS_CARD_PRIVATE_DATA *)(p->private_data); + if( ((void *)(r+1)) != ((void *)p) ){ + return NULL; + } + + return r; +} + +static void teardown(B_CAS_CARD_PRIVATE_DATA *prv) +{ + if(prv->card != 0){ + SCardDisconnect(prv->card, SCARD_LEAVE_CARD); + prv->card = 0; + } + + if(prv->mng != 0){ + SCardReleaseContext(prv->mng); + prv->mng = 0; + } + + if(prv->pool != NULL){ + free(prv->pool); + prv->pool = NULL; + } + + prv->reader = NULL; + prv->sbuf = NULL; + prv->rbuf = NULL; + prv->id.data = NULL; + prv->id_max = 0; +} + +static int change_id_max(B_CAS_CARD_PRIVATE_DATA *prv, int max) +{ + int m; + int reader_size; + int pwctrl_size; + + uint8_t *p; + uint8_t *old_reader; + uint8_t *old_pwctrl; + + reader_size = prv->sbuf - prv->pool; + pwctrl_size = prv->pwc.count * sizeof(B_CAS_PWR_ON_CTRL); + + m = reader_size; + m += (2*B_CAS_BUFFER_MAX); + m += (max*sizeof(int64_t)); + m += (prv->pwc_max*sizeof(B_CAS_PWR_ON_CTRL)); + p = (uint8_t *)malloc(m); + if(p == NULL){ + return B_CAS_CARD_ERROR_NO_ENOUGH_MEMORY; + } + + old_reader = (uint8_t *)(prv->reader); + old_pwctrl = (uint8_t *)(prv->pwc.data); + + prv->reader = (char *)p; + prv->sbuf = prv->pool + reader_size; + prv->rbuf = prv->sbuf + B_CAS_BUFFER_MAX; + prv->id.data = (int64_t *)(prv->rbuf + B_CAS_BUFFER_MAX); + prv->id_max = max; + prv->pwc.data = (B_CAS_PWR_ON_CTRL *)(prv->id.data + prv->id_max); + + memcpy(prv->reader, old_reader, reader_size); + memcpy(prv->pwc.data, old_pwctrl, pwctrl_size); + + free(prv->pool); + prv->pool = p; + + return 0; +} + +static int change_pwc_max(B_CAS_CARD_PRIVATE_DATA *prv, int max) +{ + int m; + int reader_size; + int cardid_size; + + uint8_t *p; + uint8_t *old_reader; + uint8_t *old_cardid; + + reader_size = prv->sbuf - prv->pool; + cardid_size = prv->id.count * sizeof(int64_t); + + m = reader_size; + m += (2*B_CAS_BUFFER_MAX); + m += (prv->id_max*sizeof(int64_t)); + m += (max*sizeof(B_CAS_PWR_ON_CTRL)); + p = (uint8_t *)malloc(m); + if(p == NULL){ + return B_CAS_CARD_ERROR_NO_ENOUGH_MEMORY; + } + + old_reader = (uint8_t *)(prv->reader); + old_cardid = (uint8_t *)(prv->id.data); + + prv->reader = (char *)p; + prv->sbuf = prv->pool + reader_size; + prv->rbuf = prv->sbuf + B_CAS_BUFFER_MAX; + prv->id.data = (int64_t *)(prv->rbuf + B_CAS_BUFFER_MAX); + prv->pwc.data = (B_CAS_PWR_ON_CTRL *)(prv->id.data + prv->id_max); + prv->pwc_max = max; + + memcpy(prv->reader, old_reader, reader_size); + memcpy(prv->id.data, old_cardid, cardid_size); + + free(prv->pool); + prv->pool = p; + + return 0; +} + +static int connect_card(B_CAS_CARD_PRIVATE_DATA *prv, const char *reader_name) +{ + int m,n; + + LONG ret; + DWORD rlen,protocol; + + uint8_t *p; + + SCARD_IO_REQUEST sir; + + if(prv->card != 0){ + SCardDisconnect(prv->card, SCARD_RESET_CARD); + prv->card = 0; + } + + ret = SCardConnect(prv->mng, reader_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &(prv->card), &protocol); + if(ret != SCARD_S_SUCCESS){ + return 0; + } + + m = sizeof(INITIAL_SETTING_CONDITIONS_CMD); + memcpy(prv->sbuf, INITIAL_SETTING_CONDITIONS_CMD, m); + memcpy(&sir, SCARD_PCI_T1, sizeof(sir)); + rlen = B_CAS_BUFFER_MAX; + ret = SCardTransmit(prv->card, SCARD_PCI_T1, prv->sbuf, m, &sir, prv->rbuf, &rlen); + if(ret != SCARD_S_SUCCESS){ + return 0; + } + + if(rlen < 57){ + return 0; + } + + p = prv->rbuf; + + n = load_be_uint16(p+4); + if(n != 0x2100){ // return code missmatch + return 0; + } + + memcpy(prv->stat.system_key, p+16, 32); + memcpy(prv->stat.init_cbc, p+48, 8); + prv->stat.bcas_card_id = load_be_uint48(p+8); + prv->stat.card_status = load_be_uint16(p+2); + + return 1; +} + +static void extract_power_on_ctrl_response(B_CAS_PWR_ON_CTRL *dst, uint8_t *src) +{ + int referrence; + int start; + int limit; + + + dst->broadcaster_group_id = src[8]; + referrence = (src[9]<<8)|src[10]; + start = referrence - src[11]; + limit = start + (src[12]-1); + + extract_mjd(&(dst->s_yy), &(dst->s_mm), &(dst->s_dd), start); + extract_mjd(&(dst->l_yy), &(dst->l_mm), &(dst->l_dd), limit); + + dst->hold_time = src[13]; + dst->network_id = (src[14]<<8)|src[15]; + dst->transport_id = (src[16]<<8)|src[17]; + +} + +static void extract_mjd(int *yy, int *mm, int *dd, int mjd) +{ + int yd; + int md; + int d; + + yd = (int)floor( (mjd-15078.2) / 365.25 ); + md = (int)floor( ((mjd-14956.1) - (yd*365.25)) / 30.6001 ); + d = mjd - 14956 - (int)floor(yd*365.25) - (int)floor(md*30.6001); + if( md > 13 ){ + *dd = d; + *mm = md-13; + *yy = 1900+yd+1; + }else{ + *dd = d; + *mm = md-1; + *yy = 1900+yd; + } + + if(*yy < 2000){ /* mjd bit overflow - retry */ + extract_mjd(yy, mm, dd, mjd+0x10000); + } +} + +static int setup_ecm_receive_command(uint8_t *dst, uint8_t *src, int len) +{ + int r; + + r = sizeof(ECM_RECEIVE_CMD_HEADER); + memcpy(dst+0, ECM_RECEIVE_CMD_HEADER, r); + dst[r] = (uint8_t)(len & 0xff); + r += 1; + memcpy(dst+r, src, len); + r += len; + dst[r] = 0; + r += 1; + + return r; +} + +static int setup_emm_receive_command(uint8_t *dst, uint8_t *src, int len) +{ + int r; + + r = sizeof(EMM_RECEIVE_CMD_HEADER); + memcpy(dst+0, EMM_RECEIVE_CMD_HEADER, r); + dst[r] = (uint8_t)(len & 0xff); + r += 1; + memcpy(dst+r, src, len); + r += len; + dst[r] = 0; + r += 1; + + return r; +} + +static int32_t load_be_uint16(uint8_t *p) +{ + return ((p[0]<<8)|p[1]); +} + +static int64_t load_be_uint48(uint8_t *p) +{ + int i; + int64_t r; + + r = p[0]; + for(i=1;i<6;i++){ + r <<= 8; + r |= p[i]; + } + + return r; +} + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/b_cas_card.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/b_cas_card.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,74 @@ +#ifndef B_CAS_CARD_H +#define B_CAS_CARD_H + +#include "portable.h" + +typedef struct { + uint8_t system_key[32]; + uint8_t init_cbc[8]; + int64_t bcas_card_id; + int32_t card_status; +} B_CAS_INIT_STATUS; + +typedef struct { + int64_t *data; + int32_t count; +} B_CAS_ID; + +typedef struct { + + int32_t s_yy; /* start date : year */ + int32_t s_mm; /* start date : month */ + int32_t s_dd; /* start date : day */ + + int32_t l_yy; /* limit date : year */ + int32_t l_mm; /* limit date : month */ + int32_t l_dd; /* limit date : day */ + + int32_t hold_time; /* in hour unit */ + + int32_t broadcaster_group_id; + + int32_t network_id; + int32_t transport_id; + +} B_CAS_PWR_ON_CTRL; + +typedef struct { + B_CAS_PWR_ON_CTRL *data; + int32_t count; +} B_CAS_PWR_ON_CTRL_INFO; + +typedef struct { + uint8_t scramble_key[16]; + uint32_t return_code; +} B_CAS_ECM_RESULT; + +typedef struct { + + void *private_data; + + void (* release)(void *bcas); + + int (* init)(void *bcas); + + int (* get_init_status)(void *bcas, B_CAS_INIT_STATUS *stat); + int (* get_id)(void *bcas, B_CAS_ID *dst); + int (* get_pwr_on_ctrl)(void *bcas, B_CAS_PWR_ON_CTRL_INFO *dst); + + int (* proc_ecm)(void *bcas, B_CAS_ECM_RESULT *dst, uint8_t *src, int len); + int (* proc_emm)(void *bcas, uint8_t *src, int len); + +} B_CAS_CARD; + +#ifdef __cplusplus +extern "C" { +#endif + +extern B_CAS_CARD *create_b_cas_card(); + +#ifdef __cplusplus +} +#endif + +#endif /* B_CAS_CARD_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/b_cas_card_error_code.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/b_cas_card_error_code.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,11 @@ +#ifndef B_CAS_CARD_ERROR_CODE_H +#define B_CAS_CARD_ERROR_CODE_H + +#define B_CAS_CARD_ERROR_INVALID_PARAMETER -1 +#define B_CAS_CARD_ERROR_NOT_INITIALIZED -2 +#define B_CAS_CARD_ERROR_NO_SMART_CARD_READER -3 +#define B_CAS_CARD_ERROR_ALL_READERS_CONNECTION_FAILED -4 +#define B_CAS_CARD_ERROR_NO_ENOUGH_MEMORY -5 +#define B_CAS_CARD_ERROR_TRANSMIT_FAILED -6 + +#endif /* B_CAS_CARD_ERROR_CODE_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/makefile.win --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/makefile.win Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,33 @@ +CC = cl +CFLAG = /c /MT /W4 /O2 +LINK = link +LFLAG = /nologo +LIBS = winscard.lib + +ALL: b25.exe + +arib_std_b25.obj: arib_std_b25.c arib_std_b25.h portable.h b_cas_card.h arib_std_b25_error_code.h multi2.h ts_section_parser.h ts_common_types.h + $(CC) $(CFLAG) arib_std_b25.c + +b_cas_card.obj: b_cas_card.c b_cas_card.h portable.h b_cas_card_error_code.h + $(CC) $(CFLAG) b_cas_card.c + +multi2.obj: multi2.c multi2.h portable.h multi2_error_code.h + $(CC) $(CFLAG) multi2.c + +td.obj: td.c arib_std_b25.h portable.h b_cas_card.h + $(CC) $(CFLAG) td.c + +ts_section_parser.obj: ts_section_parser.c ts_section_parser.h ts_common_types.h portable.h ts_section_parser_error_code.h + $(CC) $(CFLAG) ts_section_parser.c + +OBJ = arib_std_b25.obj b_cas_card.obj multi2.obj td.obj ts_section_parser.obj + +b25.exe: $(OBJ) + $(LINK) $(LFLAG) $(LIBS) /OUT:b25.exe $(OBJ) + +clean: + DEL *.obj + DEL *.exe + + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/multi2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/multi2.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,527 @@ +#include +#include + +#include "multi2.h" +#include "multi2_error_code.h" + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + inline functions + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static __inline uint8_t *load_be_uint32(uint32_t *dst, uint8_t *src) +{ + *dst = ((src[0]<<24)|(src[1]<<16)|(src[2]<<8)|src[3]); + return src+4; +} + +static __inline uint8_t *save_be_uint32(uint8_t *dst, uint32_t src) +{ + dst[0] = (uint8_t)((src>>24) & 0xff); + dst[1] = (uint8_t)((src>>16) & 0xff); + dst[2] = (uint8_t)((src>> 8) & 0xff); + dst[3] = (uint8_t)( src & 0xff); + return dst+4; +} + +static __inline uint32_t left_rotate_uint32(uint32_t val, uint32_t count) +{ + return ((val << count) | (val >> (32-count))); +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + inner structures + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +typedef struct { + uint32_t key[8]; +} CORE_PARAM; + +typedef struct { + uint32_t l; + uint32_t r; +} CORE_DATA; + +typedef struct { + + int32_t ref_count; + + CORE_DATA cbc_init; + + CORE_PARAM sys; + CORE_DATA scr[2]; /* 0: odd, 1: even */ + CORE_PARAM wrk[2]; /* 0: odd, 1: even */ + + uint32_t round; + uint32_t state; + +} MULTI2_PRIVATE_DATA; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + constant values + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#define MULTI2_STATE_CBC_INIT_SET (0x0001) +#define MULTI2_STATE_SYSTEM_KEY_SET (0x0002) +#define MULTI2_STATE_SCRAMBLE_KEY_SET (0x0004) + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (interface method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_multi2(void *m2); +static int add_ref_multi2(void *m2); +static int set_round_multi2(void *m2, int32_t val); +static int set_system_key_multi2(void *m2, uint8_t *val); +static int set_init_cbc_multi2(void *m2, uint8_t *val); +static int set_scramble_key_multi2(void *m2, uint8_t *val); +static int clear_scramble_key_multi2(void *m2); +static int encrypt_multi2(void *m2, int32_t type, uint8_t *buf, int32_t size); +static int decrypt_multi2(void *m2, int32_t type, uint8_t *buf, int32_t size); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + global function implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +MULTI2 *create_multi2() +{ + int n; + + MULTI2 *r; + MULTI2_PRIVATE_DATA *prv; + + n = sizeof(MULTI2_PRIVATE_DATA); + n += sizeof(MULTI2); + + prv = (MULTI2_PRIVATE_DATA *)calloc(1, n); + if(prv == NULL){ + return NULL; + } + + r = (MULTI2 *)(prv+1); + r->private_data = prv; + + prv->ref_count = 1; + prv->round = 4; + + r->release = release_multi2; + r->add_ref = add_ref_multi2; + r->set_round = set_round_multi2; + r->set_system_key = set_system_key_multi2; + r->set_init_cbc = set_init_cbc_multi2; + r->set_scramble_key = set_scramble_key_multi2; + r->clear_scramble_key = clear_scramble_key_multi2; + r->encrypt = encrypt_multi2; + r->decrypt = decrypt_multi2; + + return r; +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (private method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static MULTI2_PRIVATE_DATA *private_data(void *m2); + +static void core_schedule(CORE_PARAM *work, CORE_PARAM *skey, CORE_DATA *dkey); + +static void core_encrypt(CORE_DATA *dst, CORE_DATA *src, CORE_PARAM *w, int32_t round); +static void core_decrypt(CORE_DATA *dst, CORE_DATA *src, CORE_PARAM *w, int32_t round); + +static void core_pi1(CORE_DATA *dst, CORE_DATA *src); +static void core_pi2(CORE_DATA *dst, CORE_DATA *src, uint32_t a); +static void core_pi3(CORE_DATA *dst, CORE_DATA *src, uint32_t a, uint32_t b); +static void core_pi4(CORE_DATA *dst, CORE_DATA *src, uint32_t a); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + interface method implementation + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_multi2(void *m2) +{ + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if(prv == NULL){ + /* do nothing */ + return; + } + + prv->ref_count -= 1; + if(prv->ref_count == 0){ + free(prv); + } +} + +static int add_ref_multi2(void *m2) +{ + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if(prv == NULL){ + return MULTI2_ERROR_INVALID_PARAMETER; + } + + prv->ref_count += 1; + + return 0; +} + +static int set_round_multi2(void *m2, int32_t val) +{ + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if(prv == NULL){ + /* do nothing */ + return MULTI2_ERROR_INVALID_PARAMETER; + } + + prv->round = val; + + return 0; +} + +static int set_system_key_multi2(void *m2, uint8_t *val) +{ + int i; + uint8_t *p; + + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if( (prv == NULL) || (val == NULL) ){ + return MULTI2_ERROR_INVALID_PARAMETER; + } + + p = val; + for(i=0;i<8;i++){ + p = load_be_uint32(prv->sys.key+i, p); + } + + prv->state |= MULTI2_STATE_SYSTEM_KEY_SET; + + return 0; +} + +static int set_init_cbc_multi2(void *m2, uint8_t *val) +{ + uint8_t *p; + + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if( (prv == NULL) || (val == NULL) ){ + return MULTI2_ERROR_INVALID_PARAMETER; + } + + p = val; + + p = load_be_uint32(&(prv->cbc_init.l), p); + p = load_be_uint32(&(prv->cbc_init.r), p); + + prv->state |= MULTI2_STATE_CBC_INIT_SET; + + return 0; +} + +static int set_scramble_key_multi2(void *m2, uint8_t *val) +{ + uint8_t *p; + + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if( (prv == NULL) || (val == NULL) ){ + return MULTI2_ERROR_INVALID_PARAMETER; + } + + p = val; + + p = load_be_uint32(&(prv->scr[0].l), p); + p = load_be_uint32(&(prv->scr[0].r), p); + p = load_be_uint32(&(prv->scr[1].l), p); + p = load_be_uint32(&(prv->scr[1].r), p); + + core_schedule(prv->wrk+0, &(prv->sys), prv->scr+0); + core_schedule(prv->wrk+1, &(prv->sys), prv->scr+1); + + prv->state |= MULTI2_STATE_SCRAMBLE_KEY_SET; + + return 0; +} + +static int clear_scramble_key_multi2(void *m2) +{ + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if(prv == NULL){ + return MULTI2_ERROR_INVALID_PARAMETER; + } + + memset(prv->scr, 0, sizeof(prv->scr)); + memset(prv->wrk, 0, sizeof(prv->wrk)); + + prv->state &= (~MULTI2_STATE_SCRAMBLE_KEY_SET); + + return 0; +} + +static int encrypt_multi2(void *m2, int32_t type, uint8_t *buf, int32_t size) +{ + CORE_DATA src,dst; + CORE_PARAM *prm; + + uint8_t *p; + + MULTI2_PRIVATE_DATA *prv; + + prv = private_data(m2); + if( (prv == NULL) || (buf == NULL) || (size < 1) ){ + return MULTI2_ERROR_INVALID_PARAMETER; + } + + if(prv->state != (MULTI2_STATE_CBC_INIT_SET|MULTI2_STATE_SYSTEM_KEY_SET|MULTI2_STATE_SCRAMBLE_KEY_SET)){ + if( (prv->state & MULTI2_STATE_CBC_INIT_SET) == 0 ){ + return MULTI2_ERROR_UNSET_CBC_INIT; + } + if( (prv->state & MULTI2_STATE_SYSTEM_KEY_SET) == 0 ){ + return MULTI2_ERROR_UNSET_SYSTEM_KEY; + } + if( (prv->state & MULTI2_STATE_SCRAMBLE_KEY_SET) == 0 ){ + return MULTI2_ERROR_UNSET_SCRAMBLE_KEY; + } + } + + if(type == 0x02){ + prm = prv->wrk+1; + }else{ + prm = prv->wrk+0; + } + + dst.l = prv->cbc_init.l; + dst.r = prv->cbc_init.r; + + p = buf; + while(size >= 8){ + load_be_uint32(&(src.l), p+0); + load_be_uint32(&(src.r), p+4); + src.l = src.l ^ dst.l; + src.r = src.r ^ dst.r; + core_encrypt(&dst, &src, prm, prv->round); + p = save_be_uint32(p, dst.l); + p = save_be_uint32(p, dst.r); + size -= 8; + } + + if(size > 0){ + int i; + uint8_t tmp[8]; + + src.l = dst.l; + src.r = dst.r; + core_encrypt(&dst, &src, prm, prv->round); + save_be_uint32(tmp+0, dst.l); + save_be_uint32(tmp+4, dst.r); + + for(i=0;istate != (MULTI2_STATE_CBC_INIT_SET|MULTI2_STATE_SYSTEM_KEY_SET|MULTI2_STATE_SCRAMBLE_KEY_SET)){ + if( (prv->state & MULTI2_STATE_CBC_INIT_SET) == 0 ){ + return MULTI2_ERROR_UNSET_CBC_INIT; + } + if( (prv->state & MULTI2_STATE_SYSTEM_KEY_SET) == 0 ){ + return MULTI2_ERROR_UNSET_SYSTEM_KEY; + } + if( (prv->state & MULTI2_STATE_SCRAMBLE_KEY_SET) == 0 ){ + return MULTI2_ERROR_UNSET_SCRAMBLE_KEY; + } + } + + if(type == 0x02){ + prm = prv->wrk+1; + }else{ + prm = prv->wrk+0; + } + + cbc.l = prv->cbc_init.l; + cbc.r = prv->cbc_init.r; + + p = buf; + while(size >= 8){ + load_be_uint32(&(src.l), p+0); + load_be_uint32(&(src.r), p+4); + core_decrypt(&dst, &src, prm, prv->round); + dst.l = dst.l ^ cbc.l; + dst.r = dst.r ^ cbc.r; + cbc.l = src.l; + cbc.r = src.r; + p = save_be_uint32(p, dst.l); + p = save_be_uint32(p, dst.r); + size -= 8; + } + + if(size > 0){ + int i; + uint8_t tmp[8]; + + core_encrypt(&dst, &cbc, prm, prv->round); + save_be_uint32(tmp+0, dst.l); + save_be_uint32(tmp+4, dst.r); + + for(i=0;iprivate_data); + if( ((void *)(r+1)) != ((void *)p) ){ + return NULL; + } + + return r; +} + +static void core_schedule(CORE_PARAM *work, CORE_PARAM *skey, CORE_DATA *dkey) +{ + CORE_DATA b1,b2,b3,b4,b5,b6,b7,b8,b9; + + core_pi1(&b1, dkey); + + core_pi2(&b2, &b1, skey->key[0]); + work->key[0] = b2.l; + + core_pi3(&b3, &b2, skey->key[1], skey->key[2]); + work->key[1] = b3.r; + + core_pi4(&b4, &b3, skey->key[3]); + work->key[2] = b4.l; + + core_pi1(&b5, &b4); + work->key[3] = b5.r; + + core_pi2(&b6, &b5, skey->key[4]); + work->key[4] = b6.l; + + core_pi3(&b7, &b6, skey->key[5], skey->key[6]); + work->key[5] = b7.r; + + core_pi4(&b8, &b7, skey->key[7]); + work->key[6] = b8.l; + + core_pi1(&b9, &b8); + work->key[7] = b9.r; +} + +static void core_encrypt(CORE_DATA *dst, CORE_DATA *src, CORE_PARAM *w, int32_t round) +{ + int32_t i; + + CORE_DATA tmp; + + dst->l = src->l; + dst->r = src->r; + for(i=0;ikey[0]); + core_pi3(&tmp, dst, w->key[1], w->key[2]); + core_pi4( dst, &tmp, w->key[3]); + core_pi1(&tmp, dst); + core_pi2( dst, &tmp, w->key[4]); + core_pi3(&tmp, dst, w->key[5], w->key[6]); + core_pi4( dst, &tmp, w->key[7]); + } +} + +static void core_decrypt(CORE_DATA *dst, CORE_DATA *src, CORE_PARAM *w, int32_t round) +{ + int32_t i; + + CORE_DATA tmp; + + dst->l = src->l; + dst->r = src->r; + for(i=0;ikey[7]); + core_pi3( dst, &tmp, w->key[5], w->key[6]); + core_pi2(&tmp, dst, w->key[4]); + core_pi1( dst, &tmp); + core_pi4(&tmp, dst, w->key[3]); + core_pi3( dst, &tmp, w->key[1], w->key[2]); + core_pi2(&tmp, dst, w->key[0]); + core_pi1( dst, &tmp); + } +} + +static void core_pi1(CORE_DATA *dst, CORE_DATA *src) +{ + dst->l = src->l; + dst->r = src->r ^ src->l; +} + +static void core_pi2(CORE_DATA *dst, CORE_DATA *src, uint32_t a) +{ + uint32_t t0,t1,t2; + + t0 = src->r + a; + t1 = left_rotate_uint32(t0, 1) + t0 - 1; + t2 = left_rotate_uint32(t1, 4) ^ t1; + + dst->l = src->l ^ t2; + dst->r = src->r; +} + +static void core_pi3(CORE_DATA *dst, CORE_DATA *src, uint32_t a, uint32_t b) +{ + uint32_t t0,t1,t2,t3,t4,t5; + + t0 = src->l + a; + t1 = left_rotate_uint32(t0, 2) + t0 + 1; + t2 = left_rotate_uint32(t1, 8) ^ t1; + t3 = t2 + b; + t4 = left_rotate_uint32(t3, 1) - t3; + t5 = left_rotate_uint32(t4, 16) ^ (t4 | src->l); + + dst->l = src->l; + dst->r = src->r ^ t5; +} + +static void core_pi4(CORE_DATA *dst, CORE_DATA *src, uint32_t a) +{ + uint32_t t0,t1; + + t0 = src->r + a; + t1 = left_rotate_uint32(t0, 2) + t0 + 1; + + dst->l = src->l ^ t1; + dst->r = src->r; +} diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/multi2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/multi2.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,35 @@ +#ifndef MULTI2_H +#define MULTI2_H + +#include "portable.h" + +typedef struct { + + void *private_data; + + void (* release)(void *m2); + int (* add_ref)(void *m2); + + int (* set_round)(void *m2, int32_t val); + + int (* set_system_key)(void *m2, uint8_t *val); + int (* set_init_cbc)(void *m2, uint8_t *val); + int (* set_scramble_key)(void *m2, uint8_t *val); + int (* clear_scramble_key)(void *m2); + + int (* encrypt)(void *m2, int32_t type, uint8_t *buf, int32_t size); + int (* decrypt)(void *m2, int32_t type, uint8_t *buf, int32_t size); + +} MULTI2; + +#ifdef __cplusplus +extern "C" { +#endif + +extern MULTI2 *create_multi2(); + +#ifdef __cplusplus +} +#endif + +#endif /* MULTI2_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/multi2_error_code.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/multi2_error_code.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,9 @@ +#ifndef MULTI2_ERROR_CODE_H +#define MULTI2_ERROR_CODE_H + +#define MULTI2_ERROR_INVALID_PARAMETER -1 +#define MULTI2_ERROR_UNSET_SYSTEM_KEY -2 +#define MULTI2_ERROR_UNSET_CBC_INIT -3 +#define MULTI2_ERROR_UNSET_SCRAMBLE_KEY -4 + +#endif /* MULTI2_ERROR_CODE_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/portable.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/portable.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,38 @@ +#ifndef PORTABLE_H +#define PORTABLE_H + +#if (defined(WIN32) && MSC_VER < 1300) + +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef signed short int16_t; +typedef unsigned int uint32_t; +typedef signed int int32_t; +typedef unsigned __int64 uint64_t; +typedef signed __int64 int64_t; + +#else + +#include + +#endif + +#if !defined(WIN32) + #define _open open + #define _close close + #define _read read + #define _write write + #define _lseeki64 lseek + #define _telli64(fd) (lseek(fd,0,SEEK_CUR)) + #define _O_BINARY (0) + #define _O_RDONLY (O_RDONLY) + #define _O_WRONLY (O_WRONLY) + #define _O_SEQUENTIAL (0) + #define _O_CREAT (O_CREAT) + #define _O_TRUNC (O_TRUNC) + #define _S_IREAD (S_IRUSR|S_IRGRP|S_IROTH) + #define _S_IWRITE (S_IWUSR|S_IWGRP|S_IWOTH) +#endif + +#endif /* PORTABLE_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/td.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/td.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,385 @@ +#include +#include +#include + +#include +#include +#include + +#if defined(WIN32) + #include + #include + #include +#else + #define __STDC_FORMAT_MACROS + #include + #include +#endif + +#include "arib_std_b25.h" +#include "b_cas_card.h" + +typedef struct { + int32_t round; + int32_t strip; + int32_t emm; + int32_t verbose; + int32_t power_ctrl; +} OPTION; + +static void show_usage(); +static int parse_arg(OPTION *dst, int argc, char **argv); +static void test_arib_std_b25(const char *src, const char *dst, OPTION *opt); +static void show_bcas_power_on_control_info(B_CAS_CARD *bcas); + +int main(int argc, char **argv) +{ + int n; + OPTION opt; + + #if defined(WIN32) + _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT ); + _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT ); + _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT ); + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_DELAY_FREE_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_LEAK_CHECK_DF); + #endif + + n = parse_arg(&opt, argc, argv); + if(n+2 > argc){ + show_usage(); + exit(EXIT_FAILURE); + } + + test_arib_std_b25(argv[n+0], argv[n+1], &opt); + + #if defined(WIN32) + _CrtDumpMemoryLeaks(); + #endif + + return EXIT_SUCCESS; +} + +static void show_usage() +{ + fprintf(stderr, "b25 - ARIB STD-B25 test program ver. 0.2.1 (2008, 4/9)\n"); + fprintf(stderr, "usage: b25 [options] src.m2t dst.m2t\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -r round (integer, default=4)\n"); + fprintf(stderr, " -s strip\n"); + fprintf(stderr, " 0: keep null(padding) stream (default)\n"); + fprintf(stderr, " 1: strip null stream\n"); + fprintf(stderr, " -m EMM\n"); + fprintf(stderr, " 0: ignore EMM (default)\n"); + fprintf(stderr, " 1: send EMM to B-CAS card\n"); + fprintf(stderr, " -p power_on_control_info\n"); + fprintf(stderr, " 0: do nothing additionaly\n"); + fprintf(stderr, " 1: show B-CAS EMM receiving request (default)\n"); + fprintf(stderr, " -v verbose\n"); + fprintf(stderr, " 0: silent\n"); + fprintf(stderr, " 1: show processing status (default)\n"); + fprintf(stderr, "\n"); +} + +static int parse_arg(OPTION *dst, int argc, char **argv) +{ + int i; + + dst->round = 4; + dst->strip = 0; + dst->emm = 0; + dst->power_ctrl = 1; + dst->verbose = 1; + + for(i=1;iemm = atoi(argv[i]+2); + }else{ + dst->emm = atoi(argv[i+1]); + i += 1; + } + break; + case 'p': + if(argv[i][2]){ + dst->power_ctrl = atoi(argv[i]+2); + }else{ + dst->power_ctrl = atoi(argv[i+1]); + i += 1; + } + break; + case 'r': + if(argv[i][2]){ + dst->round = atoi(argv[i]+2); + }else{ + dst->round = atoi(argv[i+1]); + i += 1; + } + break; + case 's': + if(argv[i][2]){ + dst->strip = atoi(argv[i]+2); + }else{ + dst->strip = atoi(argv[i+1]); + i += 1; + } + break; + case 'v': + if(argv[i][2]){ + dst->verbose = atoi(argv[i]+2); + }else{ + dst->verbose = atoi(argv[i+1]); + i += 1; + } + break; + default: + fprintf(stderr, "error - unknown option '-%c'\n", argv[i][1]); + return argc; + } + } + + return i; +} + +static void test_arib_std_b25(const char *src, const char *dst, OPTION *opt) +{ + int code,i,n,m; + int sfd,dfd; + + int64_t total; + int64_t offset; + + ARIB_STD_B25 *b25; + B_CAS_CARD *bcas; + + ARIB_STD_B25_PROGRAM_INFO pgrm; + + uint8_t data[8*1024]; + + ARIB_STD_B25_BUFFER sbuf; + ARIB_STD_B25_BUFFER dbuf; + + sfd = -1; + dfd = -1; + b25 = NULL; + bcas = NULL; + + sfd = _open(src, _O_BINARY|_O_RDONLY|_O_SEQUENTIAL); + if(sfd < 0){ + fprintf(stderr, "error - failed on _open(%s) [src]\n", src); + goto LAST; + } + + _lseeki64(sfd, 0, SEEK_END); + total = _telli64(sfd); + _lseeki64(sfd, 0, SEEK_SET); + + b25 = create_arib_std_b25(); + if(b25 == NULL){ + fprintf(stderr, "error - failed on create_arib_std_b25()\n"); + goto LAST; + } + + code = b25->set_multi2_round(b25, opt->round); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::set_multi2_round() : code=%d\n", code); + goto LAST; + } + + code = b25->set_strip(b25, opt->strip); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::set_strip() : code=%d\n", code); + goto LAST; + } + + code = b25->set_emm_proc(b25, opt->emm); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::set_emm_proc() : code=%d\n", code); + goto LAST; + } + + bcas = create_b_cas_card(); + if(bcas == NULL){ + fprintf(stderr, "error - failed on create_b_cas_card()\n"); + goto LAST; + } + + code = bcas->init(bcas); + if(code < 0){ + fprintf(stderr, "error - failed on B_CAS_CARD::init() : code=%d\n", code); + goto LAST; + } + + code = b25->set_b_cas_card(b25, bcas); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::set_b_cas_card() : code=%d\n", code); + goto LAST; + } + + dfd = _open(dst, _O_BINARY|_O_WRONLY|_O_SEQUENTIAL|_O_CREAT|_O_TRUNC, _S_IREAD|_S_IWRITE); + if(dfd < 0){ + fprintf(stderr, "error - failed on _open(%s) [dst]\n", dst); + goto LAST; + } + + offset = 0; + while( (n = _read(sfd, data, sizeof(data))) > 0 ){ + sbuf.data = data; + sbuf.size = n; + + if(offset == 0x000000006dfd2000){ + offset = 0x000000006dfd2000; + } + + code = b25->put(b25, &sbuf); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::put() : code=%d\n", code); + goto LAST; + } + + code = b25->get(b25, &dbuf); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::get() : code=%d\n", code); + goto LAST; + } + + if(dbuf.size > 0){ + n = _write(dfd, dbuf.data, dbuf.size); + if(n != dbuf.size){ + fprintf(stderr, "error failed on _write(%d)\n", dbuf.size); + goto LAST; + } + } + + offset += sbuf.size; + if(opt->verbose != 0){ + m = (int)(10000*offset/total); + fprintf(stderr, "\rprocessing: %2d.%02d%% ", m/100, m%100); + } + } + + code = b25->flush(b25); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::flush() : code=%d\n", code); + goto LAST; + } + + code = b25->get(b25, &dbuf); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::get() : code=%d\n", code); + goto LAST; + } + + if(dbuf.size > 0){ + n = _write(dfd, dbuf.data, dbuf.size); + if(n != dbuf.size){ + fprintf(stderr, "error - failed on _write(%d)\n", dbuf.size); + goto LAST; + } + } + + if(opt->verbose != 0){ + fprintf(stderr, "\rprocessing: finish \n"); + fflush(stderr); + fflush(stdout); + } + + n = b25->get_program_count(b25); + if(n < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::get_program_count() : code=%d\n", code); + goto LAST; + } + for(i=0;iget_program_info(b25, &pgrm, i); + if(code < 0){ + fprintf(stderr, "error - failed on ARIB_STD_B25::get_program_info(%d) : code=%d\n", i, code); + goto LAST; + } + if(pgrm.ecm_unpurchased_count > 0){ + fprintf(stderr, "warning - unpurchased ECM is detected\n"); + fprintf(stderr, " channel: %d\n", pgrm.program_number); + fprintf(stderr, " unpurchased ECM count: %d\n", pgrm.ecm_unpurchased_count); + fprintf(stderr, " last ECM error code: %04x\n", pgrm.last_ecm_error_code); + #if defined(WIN32) + fprintf(stderr, " undecrypted TS packet: %d\n", pgrm.undecrypted_packet_count); + fprintf(stderr, " total TS packet: %d\n", pgrm.total_packet_count); + #else + fprintf(stderr, " undecrypted TS packet: %"PRId64"\n", pgrm.undecrypted_packet_count); + fprintf(stderr, " total TS packet: %"PRId64"\n", pgrm.total_packet_count); + #endif + } + } + + if(opt->power_ctrl != 0){ + show_bcas_power_on_control_info(bcas); + } + +LAST: + + if(sfd >= 0){ + _close(sfd); + sfd = -1; + } + + if(dfd >= 0){ + _close(dfd); + dfd = -1; + } + + if(b25 != NULL){ + b25->release(b25); + b25 = NULL; + } + + if(bcas != NULL){ + bcas->release(bcas); + bcas = NULL; + } +} + +static void show_bcas_power_on_control_info(B_CAS_CARD *bcas) +{ + int code; + int i,w; + B_CAS_PWR_ON_CTRL_INFO pwc; + + code = bcas->get_pwr_on_ctrl(bcas, &pwc); + if(code < 0){ + fprintf(stderr, "error - failed on B_CAS_CARD::get_pwr_on_ctrl() : code=%d\n", code); + return; + } + + if(pwc.count == 0){ + fprintf(stdout, "no EMM receiving request\n"); + return; + } + + fprintf(stdout, "total %d EMM receiving request\n", pwc.count); + for(i=0;i> 4) & 0x1f), (w & 7)); + break; + case 6: + case 7: + w = pwc.data[i].transport_id; + fprintf(stdout, "ND-%d/TS-%d ", ((w >> 4) & 0x1f), (w & 7)); + break; + default: + fprintf(stdout, "unknown(b:0x%02x,n:0x%04x,t:0x%04x) ", pwc.data[i].broadcaster_group_id, pwc.data[i].network_id, pwc.data[i].transport_id); + break; + } + fprintf(stdout, "between %04d %02d/%02d ", pwc.data[i].s_yy, pwc.data[i].s_mm, pwc.data[i].s_dd); + fprintf(stdout, "to %04d %02d/%02d ", pwc.data[i].l_yy, pwc.data[i].l_mm, pwc.data[i].l_dd); + fprintf(stdout, "least %d hours\n", pwc.data[i].hold_time); + } +} + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/ts_common_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/ts_common_types.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,36 @@ +#ifndef TS_COMMON_TYPES_H +#define TS_COMMON_TYPES_H + +#include "portable.h" + +typedef struct { + int32_t sync; /* 0- 7 : 8 bits */ + int32_t transport_error_indicator; /* 8- 8 : 1 bit */ + int32_t payload_unit_start_indicator; /* 9- 9 : 1 bit */ + int32_t transport_priority; /* 10-10 : 1 bits */ + int32_t pid; /* 11-23 : 13 bits */ + int32_t transport_scrambling_control; /* 24-25 : 2 bits */ + int32_t adaptation_field_control; /* 26-27 : 2 bits */ + int32_t continuity_counter; /* 28-31 : 4 bits */ +} TS_HEADER; + +typedef struct { + int32_t table_id; /* 0- 7 : 8 bits */ + int32_t section_syntax_indicator; /* 8- 8 : 1 bit */ + int32_t private_indicator; /* 9- 9 : 1 bit */ + int32_t section_length; /* 12-23 : 12 bits */ + int32_t table_id_extension; /* 24-39 : 16 bits */ + int32_t version_number; /* 42-46 : 5 bits */ + int32_t current_next_indicator; /* 47-57 : 1 bit */ + int32_t section_number; /* 48-55 : 8 bits */ + int32_t last_section_number; /* 56-63 : 8 bits */ +} TS_SECTION_HEADER; + +typedef struct { + TS_SECTION_HEADER hdr; + uint8_t *raw; + uint8_t *data; + uint8_t *tail; +} TS_SECTION; + +#endif /* TS_COMMON_TYPES_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/ts_section_parser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/ts_section_parser.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,802 @@ +#include +#include + +#include "ts_section_parser.h" +#include "ts_section_parser_error_code.h" + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + inner structures + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +typedef struct { + void *prev; + void *next; + TS_SECTION sect; + int32_t ref; +} TS_SECTION_ELEM; + +typedef struct { + TS_SECTION_ELEM *head; + TS_SECTION_ELEM *tail; + int32_t count; +} TS_SECTION_LIST; + +typedef struct { + + int32_t pid; + + TS_SECTION_ELEM *work; + TS_SECTION_ELEM *last; + + TS_SECTION_LIST pool; + TS_SECTION_LIST buff; + + TS_SECTION_PARSER_STAT stat; + +} TS_SECTION_PARSER_PRIVATE_DATA; + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + constant values + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#define MAX_RAW_SECTION_SIZE 4100 + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (interface method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_ts_section_parser(void *parser); +static int reset_ts_section_parser(void *parser); +static int put_ts_section_parser(void *parser, TS_HEADER *hdr, uint8_t *data, int size); +static int get_ts_section_parser(void *parser, TS_SECTION *sect); +static int ret_ts_section_parser(void *parser, TS_SECTION *sect); +static int get_count_ts_section_parser(void *parser); +static int get_stat_ts_section_parser(void *parser, TS_SECTION_PARSER_STAT *stat); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + global function implementation (factory method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +TS_SECTION_PARSER *create_ts_section_parser() +{ + TS_SECTION_PARSER *r; + TS_SECTION_PARSER_PRIVATE_DATA *prv; + + int n; + + n = sizeof(TS_SECTION_PARSER_PRIVATE_DATA); + n += sizeof(TS_SECTION_PARSER); + + prv = (TS_SECTION_PARSER_PRIVATE_DATA *)calloc(1, n); + if(prv == NULL){ + /* failed on malloc() - no enough memory */ + return NULL; + } + + prv->pid = -1; + + r = (TS_SECTION_PARSER *)(prv+1); + r->private_data = prv; + + r->release = release_ts_section_parser; + r->reset = reset_ts_section_parser; + + r->put = put_ts_section_parser; + r->get = get_ts_section_parser; + r->ret = ret_ts_section_parser; + + r->get_count = get_count_ts_section_parser; + + r->get_stat = get_stat_ts_section_parser; + + return r; +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function prottypes (private method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static TS_SECTION_PARSER_PRIVATE_DATA *private_data(void *parser); +static void teardown(TS_SECTION_PARSER_PRIVATE_DATA *prv); + +static int put_exclude_section_start(TS_SECTION_PARSER_PRIVATE_DATA *prv, uint8_t *data, int size); +static int put_include_section_start(TS_SECTION_PARSER_PRIVATE_DATA *prv, uint8_t *data, int size); + +static void reset_section(TS_SECTION *sect); +static void append_section_data(TS_SECTION *sect, uint8_t *data, int size); +static int check_section_complete(TS_SECTION *sect); + +static int compare_elem_section(TS_SECTION_ELEM *a, TS_SECTION_ELEM *b); + +static void cancel_elem_empty(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem); +static void cancel_elem_error(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem); +static void cancel_elem_same(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem); +static void commit_elem_updated(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem); + +static TS_SECTION_ELEM *query_work_elem(TS_SECTION_PARSER_PRIVATE_DATA *prv); + +static void extract_ts_section_header(TS_SECTION *sect); + +static TS_SECTION_ELEM *create_ts_section_elem(); +static TS_SECTION_ELEM *get_ts_section_list_head(TS_SECTION_LIST *list); +static void put_ts_section_list_tail(TS_SECTION_LIST *list, TS_SECTION_ELEM *elem); +static void unlink_ts_section_list(TS_SECTION_LIST *list, TS_SECTION_ELEM *elem); +static void clear_ts_section_list(TS_SECTION_LIST *list); + +static uint32_t crc32(uint8_t *head, uint8_t *tail); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function implementation (interface method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static void release_ts_section_parser(void *parser) +{ + TS_SECTION_PARSER_PRIVATE_DATA *prv; + + prv = private_data(parser); + if(prv == NULL){ + return; + } + + teardown(prv); + + memset(parser, 0, sizeof(TS_SECTION_PARSER)); + free(prv); +} + +static int reset_ts_section_parser(void *parser) +{ + TS_SECTION_PARSER_PRIVATE_DATA *prv; + + prv = private_data(parser); + if(prv == NULL){ + return TS_SECTION_PARSER_ERROR_INVALID_PARAM; + } + + teardown(prv); + + return 0; +} + +static int put_ts_section_parser(void *parser, TS_HEADER *hdr, uint8_t *data, int size) +{ + TS_SECTION_PARSER_PRIVATE_DATA *prv; + + prv = private_data(parser); + if( (prv == NULL) || (hdr == NULL) || (data == NULL) || (size < 1) ){ + return TS_SECTION_PARSER_ERROR_INVALID_PARAM; + } + + if( (prv->pid >= 0) && (prv->pid != hdr->pid) ){ + return TS_SECTION_PARSER_ERROR_INVALID_TS_PID; + } + + prv->pid = hdr->pid; + + if(hdr->payload_unit_start_indicator == 0){ + /* exclude section start */ + return put_exclude_section_start(prv, data, size); + }else{ + /* include section start */ + return put_include_section_start(prv, data, size); + } +} + +static int get_ts_section_parser(void *parser, TS_SECTION *sect) +{ + TS_SECTION_PARSER_PRIVATE_DATA *prv; + TS_SECTION_ELEM *w; + + prv = private_data(parser); + if( (prv == NULL) || (sect == NULL) ){ + return TS_SECTION_PARSER_ERROR_INVALID_PARAM; + } + + w = get_ts_section_list_head(&(prv->buff)); + if(w == NULL){ + memset(sect, 0, sizeof(TS_SECTION)); + return TS_SECTION_PARSER_ERROR_NO_SECTION_DATA; + } + + memcpy(sect, &(w->sect), sizeof(TS_SECTION)); + put_ts_section_list_tail(&(prv->pool), w); + + return 0; +} + +static int ret_ts_section_parser(void *parser, TS_SECTION *sect) +{ + TS_SECTION_PARSER_PRIVATE_DATA *prv; + TS_SECTION_ELEM *w; + + prv = private_data(parser); + if( (prv == NULL) || (sect == NULL) ){ + return TS_SECTION_PARSER_ERROR_INVALID_PARAM; + } + + w = prv->pool.tail; + while(w != NULL){ + if(w->sect.data == sect->data){ + break; + } + w = (TS_SECTION_ELEM *)(w->prev); + } + + if( (w != NULL) && (w->ref > 0) ){ + w->ref -= 1; + } + + return 0; +} + +static int get_count_ts_section_parser(void *parser) +{ + TS_SECTION_PARSER_PRIVATE_DATA *prv; + + prv = private_data(parser); + if(prv == NULL){ + return TS_SECTION_PARSER_ERROR_INVALID_PARAM; + } + + return prv->buff.count; +} + +static int get_stat_ts_section_parser(void *parser, TS_SECTION_PARSER_STAT *stat) +{ + TS_SECTION_PARSER_PRIVATE_DATA *prv; + + prv = private_data(parser); + if( (prv == NULL) || (stat == NULL) ){ + return TS_SECTION_PARSER_ERROR_INVALID_PARAM; + } + + memcpy(stat, &(prv->stat), sizeof(TS_SECTION_PARSER_STAT)); + + return 0; +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function implementation (private method) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +static TS_SECTION_PARSER_PRIVATE_DATA *private_data(void *parser) +{ + TS_SECTION_PARSER_PRIVATE_DATA *r; + TS_SECTION_PARSER *p; + + p = (TS_SECTION_PARSER *)parser; + if(p == NULL){ + return NULL; + } + + r = (TS_SECTION_PARSER_PRIVATE_DATA *)(p->private_data); + if( ((void *)(r+1)) != parser ){ + return NULL; + } + + return r; +} + +static void teardown(TS_SECTION_PARSER_PRIVATE_DATA *prv) +{ + prv->pid = -1; + + if(prv->work != NULL){ + free(prv->work); + prv->work = NULL; + } + + prv->last = NULL; + + clear_ts_section_list(&(prv->pool)); + clear_ts_section_list(&(prv->buff)); + + memset(&(prv->stat), 0, sizeof(TS_SECTION_PARSER_STAT)); +} + +static int put_exclude_section_start(TS_SECTION_PARSER_PRIVATE_DATA *prv, uint8_t *data, int size) +{ + TS_SECTION_ELEM *w; + + w = prv->work; + if( (w == NULL) || (w->sect.raw == w->sect.tail) ){ + /* no previous data */ + return 0; + } + + append_section_data(&(w->sect), data, size); + if(check_section_complete(&(w->sect)) == 0){ + /* need more data */ + return 0; + } + + prv->work = NULL; + + if( (w->sect.hdr.section_syntax_indicator != 0) && + (crc32(w->sect.raw, w->sect.tail) != 0) ){ + cancel_elem_error(prv, w); + return TS_SECTION_PARSER_WARN_CRC_MISSMATCH; + } + + if(compare_elem_section(w, prv->last) == 0){ + /* same section data */ + cancel_elem_same(prv, w); + return 0; + } + + commit_elem_updated(prv, w); + return 0; +} + +static int put_include_section_start(TS_SECTION_PARSER_PRIVATE_DATA *prv, uint8_t *data, int size) +{ + TS_SECTION_ELEM *w; + + int pointer_field; + + uint8_t *p; + uint8_t *tail; + + int r; + int length; + + p = data; + tail = p + size; + + r = 0; + + pointer_field = p[0]; + p += 1; + + if( (p+pointer_field) >= tail ){ + /* input data is probably broken */ + w = prv->work; + prv->work = NULL; + if(w != NULL) { + if(w->sect.raw != w->sect.tail){ + cancel_elem_error(prv, w); + return TS_SECTION_PARSER_WARN_LENGTH_MISSMATCH; + } + cancel_elem_empty(prv, w); + } + return 0; + } + + if(pointer_field > 0){ + r = put_exclude_section_start(prv, p, pointer_field); + if(r < 0){ + return r; + } + p += pointer_field; + } + + w = prv->work; + prv->work = NULL; + + if(w != NULL){ + if(w->sect.raw != w->sect.tail){ + cancel_elem_error(prv, w); + r = TS_SECTION_PARSER_WARN_LENGTH_MISSMATCH; + }else{ + cancel_elem_empty(prv, w); + } + w = NULL; + } + + do { + + w = query_work_elem(prv); + if(w == NULL){ + return TS_SECTION_PARSER_ERROR_NO_ENOUGH_MEMORY; + } + + append_section_data(&(w->sect), p, tail-p); + if(check_section_complete(&(w->sect)) == 0){ + /* need more data */ + prv->work = w; + return 0; + } + length = (w->sect.tail - w->sect.raw); + + if( (w->sect.hdr.section_syntax_indicator != 0) && + (crc32(w->sect.raw, w->sect.tail) != 0) ){ + cancel_elem_error(prv, w); + r = TS_SECTION_PARSER_WARN_CRC_MISSMATCH; + }else if(compare_elem_section(w, prv->last) == 0){ + cancel_elem_same(prv, w); + }else{ + commit_elem_updated(prv, w); + } + + p += length; + + } while ( (p < tail) && (p[0] != 0xff) ); + + return r; +} + +static void reset_section(TS_SECTION *sect) +{ + memset(&(sect->hdr), 0, sizeof(TS_SECTION_HEADER)); + sect->tail = sect->raw; + sect->data = NULL; +} + +static void append_section_data(TS_SECTION *sect, uint8_t *data, int size) +{ + int m,n; + + m = sect->tail - sect->raw; + n = MAX_RAW_SECTION_SIZE - m; + + if(size < n){ + n = size; + } + memcpy(sect->tail, data, n); + sect->tail += n; + m += n; + + if(sect->data == NULL){ + extract_ts_section_header(sect); + } + + if(sect->data == NULL){ + /* need more data */ + return; + } + + n = sect->hdr.section_length + 3; + if(m > n){ + sect->tail = sect->raw + n; + } + + return; +} + +static int check_section_complete(TS_SECTION *sect) +{ + int m,n; + + if(sect->data == NULL){ + return 0; + } + + m = sect->tail - sect->raw; + n = sect->hdr.section_length + 3; + + if(n > m){ + return 0; + } + + return 1; +} + +static int compare_elem_section(TS_SECTION_ELEM *a, TS_SECTION_ELEM *b) +{ + int m,n; + + if( (a == NULL) || (b == NULL) ){ + return 1; + } + + m = a->sect.tail - a->sect.raw; + n = b->sect.tail - b->sect.raw; + if( m != n ){ + return 1; + } + + if(memcmp(a->sect.raw, b->sect.raw, m) != 0){ + return 1; + } + + return 0; +} + +static void cancel_elem_empty(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem) +{ + reset_section(&(elem->sect)); + elem->ref = 0; + put_ts_section_list_tail(&(prv->pool), elem); +} + +static void cancel_elem_error(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem) +{ + reset_section(&(elem->sect)); + elem->ref = 0; + put_ts_section_list_tail(&(prv->pool), elem); + prv->stat.total += 1; + prv->stat.error += 1; +} + +static void cancel_elem_same(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem) +{ + reset_section(&(elem->sect)); + elem->ref = 0; + put_ts_section_list_tail(&(prv->pool), elem); + prv->stat.total +=1; +} + +static void commit_elem_updated(TS_SECTION_PARSER_PRIVATE_DATA *prv, TS_SECTION_ELEM *elem) +{ + if( (prv->last != NULL) && (prv->last->ref > 0) ){ + prv->last->ref -= 1; + } + + elem->ref = 2; + prv->last = elem; + put_ts_section_list_tail(&(prv->buff), elem); + prv->stat.total += 1; + prv->stat.unique += 1; +} + +static TS_SECTION_ELEM *query_work_elem(TS_SECTION_PARSER_PRIVATE_DATA *prv) +{ + TS_SECTION_ELEM *r; + + r = prv->pool.head; + while(r != NULL){ + if(r->ref < 1){ + break; + } + r = (TS_SECTION_ELEM *)(r->next); + } + + if(r != NULL){ + unlink_ts_section_list(&(prv->pool), r); + reset_section(&(r->sect)); + r->ref = 0; + return r; + } + + return create_ts_section_elem(); +} + +static void extract_ts_section_header(TS_SECTION *sect) +{ + int size; + uint8_t *p; + + sect->data = NULL; + + size = sect->tail - sect->raw; + if(size < 3){ + /* need more data */ + return; + } + + p = sect->raw; + + sect->hdr.table_id = p[0]; + sect->hdr.section_syntax_indicator = (p[1] >> 7) & 0x01; + sect->hdr.private_indicator = (p[1] >> 6) & 0x01; + sect->hdr.section_length =((p[1] << 8) | p[2]) & 0x0fff; + + if(sect->hdr.section_syntax_indicator == 0){ + /* short format section header */ + sect->data = p+3; + return; + } + + /* long format section header */ + + if(size < 8){ + /* need more data */ + return; + } + + sect->hdr.table_id_extension =((p[3] << 8) | p[4]); + sect->hdr.version_number = (p[5] >> 1) & 0x1f; + sect->hdr.current_next_indicator = p[5] & 0x01; + sect->hdr.section_number = p[6]; + sect->hdr.last_section_number = p[7]; + + sect->data = p+8; + + return; +} + +static TS_SECTION_ELEM *create_ts_section_elem() +{ + TS_SECTION_ELEM *r; + int n; + + n = sizeof(TS_SECTION_ELEM) + MAX_RAW_SECTION_SIZE; + r = (TS_SECTION_ELEM *)calloc(1, n); + if(r == NULL){ + /* failed on malloc() */ + return NULL; + } + + r->sect.raw = (uint8_t *)(r+1); + r->sect.tail = r->sect.raw; + + return r; +} + +static TS_SECTION_ELEM *get_ts_section_list_head(TS_SECTION_LIST *list) +{ + TS_SECTION_ELEM *r; + + if(list == NULL){/* invalid param */ + return NULL; + } + + r = list->head; + if(r == NULL){ + return NULL; + } + + list->head = (TS_SECTION_ELEM *)(r->next); + if(list->head != NULL){ + list->head->prev = NULL; + list->count -= 1; + }else{ + list->tail = NULL; + list->count = 0; + } + + r->next = NULL; + + return r; +} + +static void put_ts_section_list_tail(TS_SECTION_LIST *list, TS_SECTION_ELEM *elem) +{ + if( (list == NULL) || (elem == NULL) ){ + /* invalid param */ + return; + } + + if(list->tail != NULL){ + elem->prev = list->tail; + elem->next = NULL; + list->tail->next = elem; + list->tail = elem; + list->count += 1; + }else{ + elem->prev = NULL; + elem->next = NULL; + list->head = elem; + list->tail = elem; + list->count = 1; + } +} + +static void unlink_ts_section_list(TS_SECTION_LIST *list, TS_SECTION_ELEM *elem) +{ + TS_SECTION_ELEM *prev; + TS_SECTION_ELEM *next; + + if( (list == NULL) || (elem == NULL) ){ + /* invalid param */ + return; + } + + prev = (TS_SECTION_ELEM *)(elem->prev); + next = (TS_SECTION_ELEM *)(elem->next); + + if(prev != NULL){ + prev->next = next; + }else{ + list->head = next; + } + if(next != NULL){ + next->prev = prev; + }else{ + list->tail = prev; + } + list->count -= 1; +} + +static void clear_ts_section_list(TS_SECTION_LIST *list) +{ + TS_SECTION_ELEM *e; + TS_SECTION_ELEM *n; + + if(list == NULL){ /* invalid param */ + return; + } + + e = list->head; + while(e != NULL){ + n = (TS_SECTION_ELEM *)(e->next); + free(e); + e = n; + } + + list->head = NULL; + list->tail = NULL; + list->count = 0; +} + +static uint32_t crc32(uint8_t *head, uint8_t *tail) +{ + uint32_t crc; + uint8_t *p; + + static const uint32_t table[256] = { + 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, + 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, + 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, + 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, + + 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, + 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75, + 0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011, + 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD, + + 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, + 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, + 0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81, + 0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D, + + 0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49, + 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95, + 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, + 0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, + + 0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE, + 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072, + 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, + 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, + + 0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, + 0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, + 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066, + 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA, + + 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, + 0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692, + 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, + 0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A, + + 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E, + 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, + 0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, + 0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A, + + 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, + 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, + 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, + 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53, + + 0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47, + 0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B, + 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF, + 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, + + 0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, + 0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B, + 0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F, + 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3, + + 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, + 0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, + 0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F, + 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3, + + 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, + 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, + 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, + 0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24, + + 0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30, + 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC, + 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, + 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, + + 0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0, + 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C, + 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18, + 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, + + 0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, + 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C, + 0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668, + 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4, + }; + + crc = 0xffffffff; + + p = head; + while(p < tail){ + crc = (crc << 8) ^ table[ ((crc >> 24) ^ p[0]) & 0xff ]; + p += 1; + } + + return crc; +} + diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/ts_section_parser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/ts_section_parser.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,40 @@ +#ifndef TS_SECTION_PARSER_H +#define TS_SECTION_PARSER_H + +#include "ts_common_types.h" + +typedef struct { + int64_t total; /* total received section count */ + int64_t unique; /* unique section count */ + int64_t error; /* crc and other error section count */ +} TS_SECTION_PARSER_STAT; + +typedef struct { + + void *private_data; + + void (* release)(void *parser); + + int (* reset)(void *parser); + + int (* put)(void *parser, TS_HEADER *hdr, uint8_t *data, int size); + int (* get)(void *parser, TS_SECTION *sect); + int (* ret)(void *parser, TS_SECTION *sect); + + int (* get_count)(void *parser); + + int (* get_stat)(void *parser, TS_SECTION_PARSER_STAT *stat); + +} TS_SECTION_PARSER; + +#ifdef __cplusplus +extern "C" { +#endif + +extern TS_SECTION_PARSER *create_ts_section_parser(); + +#ifdef __cplusplus +} +#endif + +#endif /* TS_SECTION_PARSER_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/arib25/src/ts_section_parser_error_code.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/arib25/src/ts_section_parser_error_code.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,12 @@ +#ifndef TS_SECTION_PARSER_ERROR_CODE_H +#define TS_SECTION_PARESR_ERROR_CODE_H + +#define TS_SECTION_PARSER_ERROR_INVALID_PARAM -1 +#define TS_SECTION_PARSER_ERROR_NO_ENOUGH_MEMORY -2 +#define TS_SECTION_PARSER_ERROR_INVALID_TS_PID -3 +#define TS_SECTION_PARSER_ERROR_NO_SECTION_DATA -4 + +#define TS_SECTION_PARSER_WARN_CRC_MISSMATCH 1 +#define TS_SECTION_PARSER_WARN_LENGTH_MISSMATCH 2 + +#endif /* TS_SECTION_PARSER_ERROR_CODE_H */ diff -r 000000000000 -r 67e8eca28a80 arib25v021/libccid_Info.plist --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/libccid_Info.plist Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,368 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + ifdCapabilities + 0x00000001 + + + + ifdProtocolSupport + 0x00000001 + ifdVersionNumber + 0x00000001 + + ifdLogLevel + 0x0003 + + + + ifdDriverOptions + 0x0000 + + + + CFBundleExecutable + libccid.so.1.3.1 + + ifdManufacturerString + Ludovic Rousseau (ludovic.rousseau@free.fr) + + ifdProductString + Generic CCID driver v1.3.1 + + ifdVendorID + + 0x08E6 + 0x08E6 + 0x08E6 + 0x08E6 + 0x08E6 + 0x08E6 + 0x08E6 + 0x08E6 + 0x08E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x04E6 + 0x076B + 0x076B + 0x076B + 0x076B + 0x076B + 0x076B + 0x076B + 0x076B + 0x076B + 0x076B + 0x0783 + 0x0783 + 0x0783 + 0x0783 + 0x0783 + 0x0783 + 0x09C3 + 0x09C3 + 0x047B + 0x413c + 0x413c + 0x046a + 0x046a + 0x046a + 0x046a + 0x072f + 0x0b97 + 0x0b97 + 0x0D46 + 0x0D46 + 0x0d46 + 0x0d46 + 0x0d46 + 0x0d46 + 0x073D + 0x073D + 0x073D + 0x073D + 0x073D + 0x0DC3 + 0x0DC3 + 0x09BE + 0x0416 + 0x03F0 + 0x03F0 + 0x0B81 + 0x058F + 0x058F + 0x15E1 + 0x0BF8 + 0x0BF8 + 0x0DF6 + 0x0973 + 0x0471 + 0x04B9 + 0x1059 + 0x1059 + 0x17EF + 0x19E7 + 0x09C3 + 0x0783 + 0x0C4B + + + ifdProductID + + 0x3437 + 0x3438 + 0x4433 + 0x3478 + 0x3479 + 0x3480 + 0x34EC + 0xACE0 + 0x1359 + 0x5111 + 0x5113 + 0x5115 + 0x5116 + 0x5117 + 0x5119 + 0x511A + 0x511C + 0x511D + 0x5120 + 0x5121 + 0xE001 + 0x5410 + 0xE003 + 0x1021 + 0x3021 + 0x3621 + 0x3821 + 0x4321 + 0x5121 + 0x5125 + 0x5321 + 0x6622 + 0xA022 + 0x0006 + 0x0007 + 0x0008 + 0x0009 + 0x0010 + 0x9002 + 0x0013 + 0x0014 + 0x020B + 0x2100 + 0X2101 + 0x0005 + 0x0010 + 0x002D + 0x003E + 0x90cc + 0x7762 + 0x7772 + 0x3001 + 0x3002 + 0x3003 + 0x3010 + 0x4000 + 0x4001 + 0x0B00 + 0x0C00 + 0x0C01 + 0x0007 + 0x0008 + 0x1004 + 0x1102 + 0x0002 + 0x3815 + 0x1024 + 0x0824 + 0x0200 + 0x9520 + 0x9522 + 0x2007 + 0x1005 + 0x1006 + 0x800A + 0x0003 + 0x040F + 0x1400 + 0x000C + 0x000D + 0x1003 + 0x0002 + 0x0008 + 0x0003 + 0x0300 + + + ifdFriendlyName + + Gemplus GemPC Twin + Gemplus GemPC Key + Gemplus GemPC433 SL + Gemplus GemPC Pinpad + Gemplus GemCore POS Pro + Gemplus GemCore SIM Pro + Gemplus GemPC Express + Verisign Secure Token + VeriSign Secure Storage Token + SCM SCR 331-DI + SCM SCR 333 + SCM SCR 335 + SCM SCR 3310 + SCM SCR 3320 + SCM SCR 3340 ExpressCard54 + SCM SCR 3310 NTTCom + Axalto Reflex USB v3 + SCM SCR 3311 + SCM SCR 331-DI NTTCom + SCM SDI 010 + SCM SCR 331 + SCM SCR 355 + SCM SPR 532 + OmniKey CardMan 1021 + OmniKey CardMan 3121 + OmniKey CardMan 3621 + OmniKey CardMan 3821 + OmniKey CardMan 4321 + OmniKey CardMan 5121 + OmniKey CardMan 5125 + OmniKey CardMan 5321 + OmniKey CardMan 6121 + Teo by Xiring + C3PO LTC31 + C3PO TLTC2USB + C3PO LTC32 USBv2 with keyboard support + C3PO KBR36 + C3PO LTC32 + C3PO TLTC2USB + ActivCard USB Reader 3.0 + Activkey Sim + Silitek SK-3105 + Dell keyboard SK-3106 + Dell smart card reader keyboard + Cherry XX33 + Cherry XX44 + Cherry ST1044U + Cherry SmartTerminal ST-2XXX + ACS ACR 38U-CCID + O2 Micro Oz776 + O2 Micro Oz776 + KOBIL KAAN Base + KOBIL KAAN Advanced + KOBIL KAAN SIM III + KOBIL EMV CAP - SecOVID Reader III + KOBIL mIDentity + KOBIL mIDentity + Eutron Digipass 860 + Eutron SIM Pocket Combo + Eutron Smart Pocket + Eutron CryptoIdentity + Eutron CryptoIdentity + Athena ASE IIIe + Athena ASEDrive IIIe KB + SmartEpad + Winbond + HP USB Smart Card Keyboard + HP USB Smartcard Reader + id3 CL1356D + Alcor Micro AU9520 + Alcor Micro AU9522 + RSA SecurID + Fujitsu Siemens SmartCard Keyboard USB 2A + Fujitsu Siemens SmartCard USB 2A + Sitecom USB simcard reader MD-010 + SchlumbergerSema Cyberflex Access + Philips JCOP41V221 + SafeNet IKey4000 + G&D CardToken 350 + G&D CardToken 550 + Lenovo Integrated Smart Card Reader + Charismathics token + ActivCard USB Reader 2.0 + C3PO LTC31 + Reiner-SCT cyberJack pinpad(a) + + + Copyright + This driver is protected by terms of the GNU Lesser General Public License version 2.1, or (at your option) any later version. + + + diff -r 000000000000 -r 67e8eca28a80 arib25v021/readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/readme.txt Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,73 @@ +b25.exe ver.0.2.1 LinuxΉłłB +arib25fBNgmakeƑłĂarib25/src/b25Ƀrh܂B +gpCuPCSC-Lite(http://pcsclite.alioth.debian.org/)ŁAJ[h[_gp”\ȏԂɂȂĂ邱ƂKvłB +Windowsł͓S‚HX-520UJJLinuxł͎gpłȂ̂ŒӂKvłB +NTTComSCR3310-NTTComyathena-scs.hs.shopserve.jp/SHOP/RW001.htmlœ񍐂܂B +B-CASJ[h̕\ɒӂĉB`bvʂłB +ł̔}̃J[h[_gpꍇ́APCSC-Litẽy[WɂCCID drivergpA +/etc/libccid_Info.plist +==== + ifdVendorID + + 0xXXXX + + + + ifdProductID + + 0xXXXX + + + + ifdFriendlyName + + XXXXXXXXXXXXXXXXXX + + +==== +zipɂ铯̃t@C̓ƓւĉB +̃t@CʒuDebianˑ܂B + Gentooł/usr/lib/readers/usb/ifd-ccid.bundle/Contents/Info.plistɂƂ񍐂܂B +}yэŋ߂̔}ł̓J[h[_ςĂׁA/etc/libccid_Info.plist̕ύX͕svłB + +smartcard_list.txtPCSC-LiteɊ܂܂pcsc_scanpłB +PCSC-Litẽt@CƒuB-CASB-CASƂĔF܂B + +PCSC-LiteAPIWindowsX}[gJ[hANZXpAPIƌ݊łׁA +قLinuxŃRpCG[ɂȂ镔̑Ώ݂̂łB +ver.0.2.032bit‹2Gbytet@C̖肪ȂȂ͂łB64bit‹ł2Gbyteȏ̃t@Co邱ƂmFĂ܂B + +PCSC-LiteɊ܂܂DWORD̒`͔32bit‹̏ꍇɖ肪܂A֌WȂ܂B + +ύX_: +ver.0.1.2ɑ΂pb`open̈Ă܂Ăӏɖ߂܂B +ver.0.1.5ŏo̓t@C̃p[~bVK̂𒼂܂Bumaskɏ]悤ɂȂĂ͂łB +ver.0.2.0ŁA32bitLinux2GByteȏ̃t@CłȂoOC͂łB + +extrecdgpĂւ̒ӓ_: +b25̌Ăяo-p 0 -v 0IvVtKv܂(b25牽o͂΃G[Ƃ݂ȂĂ)Bȉ̏CsȂĉB +430s +my @b25_cmd = (@b25_prefix, $path_b25, $target_encts, $target_ts); + +my @b25_cmd = (@b25_prefix, $path_b25, "-p", "0", "-v", "0", $target_encts, $target_ts); + +CZX: +̃\[X͂܂쐬b25قڂ̂܂܂Ȃ̂ŁA܂̔fɏ]܂B +arib25/readme.txtɂIWib25ɓYtĂreadme.txtɏĂA +>@E\[XR[h𗘗pƂɂāÃguĂ +>@@Ζ am͐ӔC𕉂Ȃ +>@E\[XR[h𗘗pƂɂāAvOɖ肪Ă +>@@Ζ am͐ӔC𕉂Ȃ +> +>@L 2 ɓӂč쐬ꂽ񎟓I앨ɑ΂āAΖ am +>@҂ɗ^鏔sgȂ +Kp܂B + +̑: +̃vOAS-ISŒ񋟂܂BȂɂ肪NĂӔC͎Ă܂B + +mF‹: + Debian GNU/Linux lenny(testing) + Linux 2.6.22.6 SMP PREEMPT x86_64 + +N/E9PqspSk diff -r 000000000000 -r 67e8eca28a80 arib25v021/smartcard_list.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arib25v021/smartcard_list.txt Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,1874 @@ +# +# smartcard_list.txt +# Copyright (C) 2002-2006 Ludovic Rousseau +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA + +# +# This list contains a match between an ATR and a card type +# The list is sorted for edition purposes +# +# You can get the latest version of this file from: +# http://ludovic.rousseau.free.fr/softwares/pcsc-tools/smartcard_list.txt +# +# $Id: smartcard_list.txt,v 1.290 2007-10-30 21:12:54 rousseau Exp $ +# + +# syntax: +# ATR in regular expression form +# \t descriptive text +# \t descriptive text +# \t descriptive text +# empty line + +3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99 + B-CAS + +3B 02 14 50 + Schlumberger Multiflex 3k + +3B 02 53 01 + Gemplus GemClub Memo + +3B 04 41 11 77 81 + Sample Mifare DESFire contactless smartcard from Phillips + +3B 04 41 11 77 B1 + IBM JCOP 30 contactless + +3B 04 49 32 43 2E + German Health Insurance Card + "LogCard" from concept2.com (a indoor rower manufacturer) + I2C card + +3B 04 92 23 10 91 + Siemens SLE 4432/42 card + +3B 04 A2 13 10 91 + PM2P Chipkarte SLE 4442, Code FFFFFF + Bahn BKK (Deutsche Bahn AG - Insurance Company) + +3B 05 68 01 01 02 05 + Certinomis card (electronic certificates) + +3B 06 A2 13 10 91 90 00 + C3P2K SAMPLE CARD (C3PO, S.L) + +3B 09 41 04 11 DD 82 2F 00 00 88 + 1k contactless Mifare + +3B 0A 20 62 0C 01 4F 53 45 99 14 AA + GSM-SIM BEN (1800MHz) + +3B 0F 80 6A 16 32 46 49 53 45 53 8C E0 FF 07 90 00 + GSM-SIM Sonera (from 1998) + +3B 0F FF C1 B5 CC 72 CA 00 00 ?? + Mifare Std 1K + +3B 15 13 80 53 41 52 03 + Eutron CryptoIdentity (ATMEL AT903232C - 6464C Cryptographic + processors, 64KB EEPROM, RSA 2048) + +3B 15 94 C3 02 08 16 01 + GSM-SIM EMT (Estonia) + +3B 16 94 71 01 01 00 27 00 + Cingular GSM SIM Card + +3B 16 94 71 01 01 05 02 00 + GSM SIM Bouygues Telecom + +3B 16 94 81 10 06 01 81 2F + Schlumberger Cyberflex Access Augmented Crypto + +3B 16 94 81 10 06 01 81 3F + Schlumberger Cyberflex Access Crypto + +3B 16 96 41 73 74 72 69 64 + Gemalto .NET v2.0 + +3B 17 13 9C 12 02 01 01 07 40 + Schlumberger Cyberflex Access Developer 32k + +3B 17 94 18 01 01 02 01 41 49 + white SFR SIM card + +3B 17 94 18 02 01 25 01 41 93 + AT&T Wireless GSM SIM Card + +3B 17 94 89 01 02 01 02 41 87 + Vodafone/Omnitel 16K GSM SIM + +3B 19 14 55 90 01 01 01 00 05 08 B0 + Schlumberger Multiflex 8k + +3B 19 14 55 90 01 02 01 00 05 04 B0 + Schlumberger Multiflex 4k + +3B 19 14 59 01 01 0F 01 00 05 08 B0 + Schlumberger Multiflex 8k + +3B 19 94 31 02 05 10 45 98 01 02 4E + GSM-SIM EMT (Estonia) + +3B 1F 11 00 67 42 41 46 49 53 45 53 52 66 FF 81 90 00 + Finnish student id card + +3B 1F 11 00 67 80 42 46 49 53 45 10 52 66 FF 81 90 00 + Nokia branded SC (Setec) + +3B 1F 11 00 6A 01 38 46 49 53 45 10 8C 02 FF 07 90 00 + GSM-SIM Saunalahti (from 2004) + Finnish cell phone operator "Sonera" SIM card (from 2002) + +3B 1F 11 00 6A 31 36 46 49 53 45 13 8C 02 FF 07 90 00 + GSM-SIM card - Telenor Mobil - http://www.telenor.com/ + +3B 1F 11 80 6A 16 32 46 49 53 45 15 8C E6 FF 07 90 00 + GSM SIM card - Tele2 Estonia - http://www.tele2.ee + +3B 1F 11 80 6A 32 37 46 49 53 45 12 8C 00 FF 07 90 00 + Setec Test card, SetCOS 3.7.2, rel 1.3 + +3B 1F 11 80 6A 32 37 46 49 53 45 12 8C 02 FF 07 90 00 + GSM-SIM DNA Finland (from 2001) + +3B 1F 11 80 6A 80 34 46 49 53 45 53 94 36 FF 07 90 00 + SetCOS 3.4.0c + RSA SecurID 3100 + +3B 1F 94 00 6A 01 38 46 49 53 45 10 8C 02 FF 07 90 00 + GSM-SIM Saunalahti (from 2004) + +3B 1F 94 80 6A 16 32 46 49 53 45 15 8C E6 FF 07 90 00 + GSM-SIM Sonera (from 2002) + +3B 23 00 00 36 41 81 + Schlumberger Payflex 4k SAM + +3B 23 00 35 11 80 + Schlumberger Payflex 1k User + +3B 23 00 35 11 81 + Schlumberger Payflex 1k SAM + +3B 23 00 35 13 80 + Schlumberger Cyberflex Access Campus + +3B 23 00 35 13 FF + Schlumberger MicroPayflex + +3B 23 00 35 41 80 + PayflexHID (idenfitied by Sun Ray Services) + +3B 24 00 .. .. .. 45 + Conax + +3B 24 00 30 42 30 30 + ComHem Digital-TV smartcard (Sweden) + +3B 24 00 80 72 94 43 + MPCOS-3DES 64K \ EMV Filter (Gemplus) + +3B 26 00 00 26 40 00 90 00 + Schlumberger, purse? + +3B 26 00 11 04 5C 03 90 00 + Caixa Abierta (Barcelona, Spain) Cash/Visa Electron + +3B 26 00 11 06 23 03 90 00 + Tarjeta de la Seguridad Social (Spanish Social Insurance Card) + +3B 27 00 80 65 A2 .. 01 01 37 + Gemplus GemSAFE Smart Card (4K) + +3B 27 00 80 65 A2 00 01 01 37 + Gemplus GemSAFE Card CSP v1.0 + +3B 27 00 80 65 A2 02 02 82 37 + Gemplus GPK2000s + +3B 27 00 80 65 A2 02 03 82 37 + Gemplus GPK2000sp + +3B 27 00 80 65 A2 04 01 01 37 + Gemplus GPK4000s + +3B 27 00 80 65 A2 05 01 01 37 + Gemplus GPK4000sp + +3B 27 00 80 65 A2 06 01 01 37 + GPK 4000, RSA 512 bits Sign, Unwrap 40 bits + +3B 27 00 80 65 A2 0C 01 01 37 + Gemplus GPK4000 + +3B 27 00 80 65 A2 8C 3B 27 00 + GPK 4000, RSA 1024 bits Sign, Unwrap 256 bits + +3B 29 00 24 93 01 00 00 00 00 01 A9 + Telephone chipcard for the Vienna University of Technology + http://nic.tuwien.ac.at/telefonie/chipkarte/ + +3B 29 00 80 72 A4 45 64 00 00 D0 15 + Moeda Electronica Bradesco (Gemplus MPCOS?) (Brasilia) + +3B 29 00 80 72 A4 45 64 00 FF 00 10 + MPCOS-3DES 8K (Gemplus) + MBNA Europe Platinum Plus Mastercard + MasterCard Card - Worldcard - Yapıkredi / Turkey + +3B 2A 00 80 65 A0 58 04 01 62 72 D6 43 + Gemplus GemCombiXplore MPCOS Pro + +3B 2A 00 80 65 A2 01 00 00 00 72 D6 41 + MPCOS_EMV_1B + +3B 2A 00 80 65 A2 01 00 00 00 72 D6 43 + MPCOS_EMV_4B + +3B 2A 00 80 65 A2 01 .. .. .. 72 D6 41 + Gemplus MPCOS EMV 1 Byte sectors + +3B 2A 00 80 65 A2 01 02 01 31 72 D6 43 + MPCOS-EMV 64K Functional Sample + +3B 2A 00 80 65 A2 01 .. .. .. 72 D6 43 + Gemplus MPCOS EMV 4 Byte sectors + +3B 2F 00 80 69 10 80 00 01 A1 0A 01 01 59 83 0E 90 00 + Belgium Dexia (Axion) Bank Card + Proton/Bancontact Mister Cash/Maestro + +3B 32 15 00 06 80 + Schlumberger Multiflex 8k + +3B 32 15 00 06 95 + Schlumberger Multiflex 8k DES + +3B 37 11 00 46 4C 4F 4D 41 90 00 + SLE 4428 + +3B 3B .. 00 80 6. A[F,E] 03 0[C,D] .. .. 83 .. 90 00 + GemXplore Xpresso V3 + +3B 3B 11 00 80 65 AF 03 0C 01 6F 83 0F 90 00 + Gemplus GemX{plore,presso} V3-B1 + +3B 3B 11 00 80 69 AF 03 0C 01 6F 83 0[0,1] 90 00 + GemXplore'Xpresso V3 64K + +3B 3B 94 00 4F 34 10 20 01 04 C0 33 33 90 00 + SIM card from the italian operator WIND + +3B 3B 94 00 67 37 10 00 00 39 60 33 33 90 00 + Avea GSM / Turkey + +3B 3B 94 00 80 65 AF 03 0D 01 74 83 0F 90 00 + Gemplus GemXplore Xpresso V3 B1P + Mobistar SIM - Belgium (Gemplus) + +3B 3C 94 00 4B 31 25 A2 10 13 14 47 83 83 90 00 + GSM SFR + +3B 3C 94 00 4C 31 25 A7 20 1B 00 15 83 83 90 00 + GSM-SIM (900MHz) card of the carrier vodafone for their cellular + network (phase 2+ with 3V) + +3B 3D 94 00 01 0F 00 36 00 00 86 60 18 04 00 01 07 + Vodafone GSM / Turkey + +3B 3F 11 00 6F AF 65 03 12 01 80 73 32 21 1B 83 0F 90 00 + GSM SIM card Orange J2RE postpaid + +3B 3F 94 00 80 65 AF 03 12 01 79 73 32 21 1B 83 0F 90 00 + UK O2 GSM SIM (2G Online Prepay Maldives) + +3F 3F 94 00 80 69 AF 03 07 01 59 00 00 0A 0E 83 3E 9F 16 + Finnish SIM card from "Radiolinja" now "Elisa" + +3B 3F 94 00 80 69 AF 03 07 06 67 00 00 0A 0E 83 3E 9F 16 + SFR SIM card (red Gemplus Répertoire) + +3B 3F 94 00 80 69 AF 03 07 06 67 09 97 0A 0E 83 3E 9F 16 + BASE SIM - Belgium (Gemplus) + +3B 3F 94 00 80 69 AF 03 0F 02 80 FF FF 06 0E 83 3E 9F 16 + GSM-SIM Telefonica Movistar, prepaid (Spain) + +3B 3F 95 00 80 65 AF 03 12 01 6F 73 32 21 1B 83 00 90 00 + Gemplus GemXpresso PRO 64 PK SIM + +3B 3F 95 00 80 65 AF 03 14 01 8A 73 32 21 1B 83 0F 90 00 + SIM Vodafone 64k + +3F 96 18 80 01 80 51 00 61 10 30 9F + Atmel/Athena T0 Inverse Convention PC/SC Compliance Test Card No. 2 + +3B 3F 95 00 80 69 AF 03 0F 02 80 FF FF 06 0E 83 3E 9F 16 + AT&T Wireless GSM SIM Card + +3B 57 18 02 93 02 01 01 01 90 00 + Easyflex FastOS 2.0 / Schlumberger + +3B 63 00 00 36 41 80 + Schlumberger Payflex 4k User + +3B 64 00 00 80 62 0. 51 + Setec SetCOS 5.1.0 EMV + +3B 64 00 FF 80 62 02 A2 + VISA credit card (Nordea bank) + +3B 64 .. FF 80 62 .. A2 + JCOP20 + +3B 65 00 00 29 05 01 02 01 + ActivCard (Schlumberger) CyberFlex 64K V1 SM 2.1 + +3B 65 00 00 58 01 01 00 80 + RBS Advanta Platinum Reserve Master Card + +3B 65 00 00 9C 02 02 07 02 + US Department of Defense, TEST Common Access Card (CAC) + Schlumberger Cyberflex Access #2 + Axalto Cyberflex Access 32K V2 + +3B 65 00 00 9C 1[0,1] 01 01 03 + Schlumberger Cyberflex Palmera + +3B 66 00 00 00 9C 11 01 01 03 + Axalto Cyberflex Access 32K V4 SM 1.3 + +3B 66 00 00 00 9C 11 01 03 01 + Axalto Cyberflex Access 64K V1 Bio SM 3.1 + +3B 66 00 00 31 4B 01 01 00 80 + VISA credit card (Skandiabanken) + +3B 66 00 FF 4A 43 4F 50 33 30 + JCOP30 "OP-DI 16k VISA v2 (JCOP30) ORGA" + +3B 66 00 FF 4A 43 4F 50 30 33 + IBM JCOP 30 + +3B 67 00 00 00 00 00 00 00 90 00 + Axa Bank (Belgium) Mastercard Gold / Axa Bank Belgium + MisterCash & Proton card + VISA Card (emitted by Bank Card Company - Belgium) + +3B 67 00 00 00 00 20 00 00 90 00 + BankID card from Sparebank1 + +3B 67 00 00 00 31 80 71 86 90 00 + Swiss ZKB-Bancomat-Card + +3B 67 00 00 29 20 00 6F 78 90 00 + Postbank Chippas (chipknip) Netherlands + +3B 67 00 00 2D 20 36 00 78 90 00 + Swedish cashcard, http://www.ida.liu.se/~TDDB31/Cashcard.pdf + Bank Card (ING - Belgium) + +3B 67 00 00 7D 20 40 34 3B 90 00 + Nordea Visa Sweden + +3B 67 00 00 85 20 36 30 78 90 00 + Belgium Fortis Bank + Belgium Keytrade Bank + Belgium Post Bank + +3B 67 00 00 9C 10 01 01 03 FF 07 + Schlumberger Cyberflex Palmera Protect + +3B 67 00 00 A5 20 40 10 1F 90 00 + Swedish eLegitimation (eID) from Nordea Bank http://www.elegitimation.se/ + +3B 67 25 00 2A 20 00 4[0,5] 68 90 00 + Swedish cashcard (proton) + +3B 67 25 00 62 24 33 03 .. + Bull TB1000 ? (SAM for ATM in Luxemburg) + +3B 68 00 00 56 53 44 43 4C 43 31 30 + VISA (Estonian), made by www.trueb.ch + +3B 68 00 00 80 66 A2 06 02 01 32 0E + Gemplus GemClub 1K + +3B 68 00 00 9D 08 01 02 01 56 49 53 + Visa Card - bonus - DenizBank / Turkey + +3B 68 00 00 9D 08 01 03 01 4F 54 53 + MasterCard Card - bonus - Garanti Bank / Turkey + +3B 68 00 00 9D 08 01 03 01 56 49 53 + MasterCard Card - bonus - Garanti Bank / Turkey + MasterCard Card - bonus plus (paypass) - Garanti Bank / Turkey + +3B 68 00 00 9D 08 01 05 01 56 49 53 + MasterCard Card - CartaSi (Italian Credit Card) + +3B 68 00 00 A1 02 02 01 01 56 49 53 + UK NatWest Business MasterCard + UK Barclaycard VISA + UK NatWest Platinum MasterCard + Visa Card - DenizBank / Turkey + +3B 69 00 00 24 94 01 02 01 00 01 01 A9 + Chipcard from SUN to be used in SunRay's + 370-4328-01 (31091) + +3B 69 00 00 24 94 01 03 01 00 01 00 A9 + Schlumberger MicroPayflex S card + +3B 69 00 00 4A 43 4F 50 33 31 56 32 32 + Visa Europe Sample Card / Axalto + +3B 69 00 00 50 01 01 04 01 00 01 01 A9 + Sample card given to all attendees of the CTST 2004 SmartCard Conference + +3B 69 00 FF 53 6D 40 72 74 43 61 66 65 + G&D (Giesecke&Devrient) Sm@rtCafé + +3B 6A 00 00 80 31 C0 A1 02 03 01 32 81 16 + Lloyds TSB Visa Credit/Debit Card + +3B 6A 00 00 80 65 A2 01 01 01 3D 72 D6 43 + GemSafe Xpresso 16k + +3B 6A 00 00 80 66 A1 09 02 01 63 0E 90 00 + Danish Visa/Dankort + UK MBNA MasterCard + Visa Card - Worldcard - YapıKredi / Turkey + +3B 6B 00 00 00 31 80 64 2D A0 02 0C 8C 61 27 + SmartEMV prototype + +3B 6B 00 00 00 31 80 64 43 B0 02 00 8C 61 27 + Bull Odyssey 1.2 (Javacard 2.0) + +3B 6B 00 00 80 65 A1 09 03 01 97 83 0E 90 00 + Visa Card - Worldcard - YapıKredi / Turkey + +3B 6B 00 00 80 65 B0 83 01 01 74 83 00 90 00 + GemXpresso Pro R3 with 64K EEPROM + +3B 6B 00 00 80 65 B0 83 01 03 74 83 00 90 00 + Gemplus GemXpresso PRO 64K R3 v1 + +3B 6B 00 00 80 65 B0 83 01 04 74 83 00 90 00 + Gemplus GXP3 64V2N + U.S. Department of Defense Common Access Card (DoD CAC) + +3B 6B 00 FF 33 00 00 09 FA 10 00 80 01 FF FF + Atmel 6464C PRO 64K + +3B 6B .. FF 80 62 .. A2 56 46 69 6E 45 49 44 + JCOP20 v2.x + +3B 6C 00 00 10 10 10 30 00 00 00 00 00 00 00 00 + Datacard Group Aptura Development Card V1.1b + +3B 6D 00 00 00 31 C0 71 D6 64 11 22 33 01 83 90 00 + UK Barclaycard VISA + UK Halifax Platinum VISA + +3B 6D 00 00 00 31 C0 71 D6 64 34 C7 01 00 84 90 00 + DeLaRue ProlifIC + +3B 6D 00 00 00 31 C0 71 D6 64 34 C7 02 00 84 90 00 + Cybelys card (Thalys fidelity card) + +3B 6D 00 00 00 31 C0 71 D6 64 38 D0 02 00 84 90 00 + EMV Visa Electron (Oberthur) + +3B 6D 00 00 00 31 C0 71 D6 64 38 D0 03 00 84 90 00 + HSBC Visa/MasterCard credit card + Barclay Card MasterCard + +3B 6D 00 00 00 31 C0 71 D6 64 4E D8 01 01 84 90 00 + UK Capital One Platinum MasterCard + +3B 6D 00 00 00 31 C0 71 D6 64 58 D7 01 00 84 90 00 + UK Nationwide Bank Visa Delta + UK First Direct Maestro + UK Halifax Platinum Visa + +3B 6D 00 00 80 31 80 65 B0 06 01 01 77 83 00 90 00 + GemXpresso Lite: with EMV application + +3B 6D 00 00 80 31 80 65 B0 43 01 00 77 83 00 90 00 + Gemplus GemXpresso Lite + +3B 6D 00 00 80 31 80 65 B0 83 01 02 90 83 00 90 00 + DeutscheBank Identification card + +3B 6D 00 FF 00 31 80 71 8E 64 48 D5 02 00 82 90 00 + Blue for Business, American Express@Business + +3B 6E 00 00 00 31 80 71 86 65 01 64 02 22 32 80 90 00 + MasterCard Card - bonus plus (paypass) - Garanti Bank / Turkey + +3B 6E 00 00 00 31 80 71 86 65 01 64 02 22 32 83 90 00 + MasterCard Card - bonus YKM - Garanti Bank / Turkey + +3B 6E 00 00 00 31 80 71 86 65 01 67 02 A0 0A 83 90 00 + Australian ANZ First Visa Card from the ANZ + (Australia and New Zealand) Bank + +3B 6E 00 00 00 31 80 71 86 65 47 44 23 01 02 83 90 00 + Nat West Master Card + +3B 6E 00 00 00 31 80 71 86 65 47 44 24 01 81 83 90 00 + MasterCard Card - Maximum - IS Bank / Turkey + Visa Card - Axess - Akbank / Turkey + +3B 6E 00 00 00 31 C0 71 86 65 01 64 02 22 33 83 90 00 + UK NatWest ServiceCard 100 Maestro + Visa Card - bonus - Garanti Bank / Turkey + +3B 6E 00 00 00 31 C0 71 86 65 01 78 01 27 34 83 90 00 + UK NatWest ServiceCard 100 Maestro + Visa Card - Gold - CARDFINANS / Turkey + +3B 6E 00 00 00 31 C0 71 C6 65 01 B0 01 03 37 83 90 00 + UK NatWest Business MasterCard + +3B 6E 00 00 00 31 C0 71 D6 65 7D E4 01 10 A0 83 90 00 + VISA card, issued by the ANWB, the Dutch national Automobile club + Visa Card - Maximum - Oyak Bank / Turkey + +3B 6E 00 00 00 31 C0 71 D6 65 7D E4 01 11 A0 83 90 00 + UK CapitalOne Platinum Mastercard + +3B 6E 00 00 00 31 C0 71 D6 65 A3 03 01 80 00 83 90 00 + UK First Direct (HSBC) Maestro / Cirrus + +3B 6E 00 00 00 62 .. 43 57 41 56 41 4E 54 10 81 90 00 + Setec SetCOS 4.3.0 + +3B 6E 00 00 00 62 00 00 57 41 56 41 4E 54 10 81 90 00 + Setec SetCOS 5.1.0 EMV + AVANT + +3B 6E 00 00 45 73 74 45 49 44 20 76 65 72 20 31 2E 30 + Estonian Identity Card (EstEID v1.5 multos) + +3B 6E 00 00 80 31 80 65 B0 03 01 01 5E 83 00 00 90 00 + FirstUSA Visa + +3B 6E 00 00 80 31 80 65 B0 03 02 01 5E 83 00 00 90 00 + Gemplus GemXpresso 211is + +3B 6E 00 FF 00 62 00 00 57 41 56 41 4E 54 10 81 90 00 + debit card (Visa Electron) issued by Nordea bank + +3B 6E 00 FF 45 73 74 45 49 44 20 76 65 72 20 31 2E 30 + Estonian Identity Card (EstEID v1.0 warm) + +3B 6F 00 00 00 67 2. 43 46 49 53 45 12 52 66 FF 81 90 00 + Setec SetCOS 4.3.2 + +3B 6F 00 00 80 31 C0 52 00 83 64 02 19 08 32 83 83 90 00 + Bancomer Mexican Bank + +3B 6F 00 00 80 31 C0 52 16 B9 64 05 66 80 32 83 83 90 00 + Banorte Mexican Bank + +3B 6F 00 00 80 31 E0 5B 4E 4F 4B 00 00 00 00 00 00 02 00 + Norsk-Tipping (Buypass) Monodex card + +3B 6F 00 00 80 31 E0 6B 04 06 03 04 40 55 55 55 55 55 55 + Blue American Express Card + +3B 6F 00 00 80 31 E0 6B 04 06 05 02 17 55 55 55 55 55 55 + Marx Software Security - Cryptoken M2048, MULTOS, Infineon SLE66CX, 64kByte + http://www.marx.com/en/ + +3B 6F 00 00 80 31 E0 6B 04 20 05 02 30 55 55 55 55 55 55 + Buypass card for Norsk Tipping (http://norsk-tipping.no) + +3B 6F 00 00 80 31 E0 6B 84 06 03 04 31 55 55 55 55 55 55 + Multos Developer Sample + +3B 6F 00 00 80 31 E0 6B 84 06 0E 02 02 55 55 55 55 55 55 + Multos Developer Sample + +3B 6F 00 00 80 31 E0 6B 84 20 05 02 39 55 55 55 55 55 55 + Multos 14D (2-0-10) 64K Developer Card + +3B 6F 00 00 80 31 E0 6B 84 20 05 02 42 55 55 55 55 55 55 + Multos 14Dc(6-0-13) 64K Dual-Interface Developer Card + +3B 6F 00 00 80 5A .. 0[1-5] .. .. .. .. .. .. .. .. 82 90 00 + Card supporting a Calypso application Rev 1 + Typically: French "Navigo" transport card + +3B 6F 00 00 80 66 45 46 01 38 18 03 53 02 31 10 82 90 00 + Fábrica Nacional de Moneda y Timbre FNMT WG10 + http://www.fnmt.es/es/html/tage/fichaTarjeta/fp1_ta_01.asp + +3B 6F 00 FF 52 53 41 53 65 63 75 72 49 44 28 52 29 31 30 + RSA SecurID SID800 token + +3B 6F 00 FF 53 46 53 45 2D 43 58 33 32 32 2D 56 18 02 02 + Giesecke & Devrient SmartCafe Expert 2.0 + +3B 75 12 00 00 29 05 01 04 01 + CAC Cryptographic Service Provider + Axalto Cyberflex Access 64K V1 SM 4.1 + +3B 75 13 00 00 9C 02 02 01 02 + Cyberflex Access 32k v2 + +3B 75 94 00 00 62 02 02 0[1-3] 01 + Schlumberger Cyberflex 32K e-gate + +3B 76 11 00 00 00 9C 11 01 02 02 + Schlumberger Cyberflex Access 32K + +3B 76 11 00 00 00 9C 11 01 02 03 + RSA SecureID 5100 + +3B 76 12 00 00 00 9C 11 01 03 03 + Precise BioMatch (TM) JavaCard (Schlumberger) + www.precisebiometrics.com + +3B 76 98 00 00 00 9C 11 01 01 02 + CyberFlex Access 32 + +3B 7A 11 00 02 48 4F 53 54 06 03 19 02 90 00 + Swedish bankcard with Mastercard from ICA-banken + +3B 7A 13 00 00 00 09 A5 05 01 00 B7 01 A6 01 + "cleyris" authentication card. monpass.santé from Mutuelle Générale + +3B 7A 94 00 00 80 65 A2 01 01 01 3D 72 D6 43 + Gemplus GemXpresso Pro R3 E32 PK + +3B 7B .. 00 00 80 62 0. 51 56 46 69 6E 45 49 44 + Setec SetCOS 5.1.0 + +3B 7B 18 00 00 00 31 C0 64 77 E3 03 00 82 90 00 + Oberthur Cosmopolic 64K v5.2 D + +3B 7B 94 00 00 80 62 11 51 56 46 69 6E 45 49 44 + Finnish Electronic ID card (fineid card www.fineid.fi) + +3B 7B 94 00 00 80 65 B0 83 01 0[1,3] 74 83 00 90 00 + Gemplus GemXpresso Pro R3 (E64 PK) + +3B 7B 95 00 00 80 65 B0 83 01 04 74 83 00 90 00 + Gemplus GemXpresso Pro 64K R3 FIPS v2 + +3B 7D 11 00 00 00 31 80 71 8E 64 52 D9 01 00 82 90 00 + Oberthur Galactic V2 + +3B 7D 11 00 00 00 31 80 71 8E 64 77 E3 01 00 82 90 00 + Oberthur Cosmo 64k RSA v5 + +3B 7D 11 00 00 00 31 80 71 8E 64 77 E3 02 00 82 90 00 + Oberthur 64k v5/2.2.0 + +3B 7D 11 00 00 00 31 80 71 8E 64 86 D6 01 00 81 90 00 + DOD-CAC + +3B 7D 18 00 00 00 31 80 71 8E 64 77 E3 01 00 82 90 00 + Oberthur 64k v4/2.1.1 + +3B 7D 94 00 00 80 31 80 65 B0 83 01 02 90 83 00 90 00 + Gem e-Seal + (GemSafeXpresso 16k R3.2?) + +3B 7D 94 00 00 80 31 80 65 B0 83 01 01 90 83 00 90 00 + GemSafeXpresso 16k R3.2 + +3B 7D 94 00 00 80 31 80 65 B0 83 02 04 7E 83 00 90 00 + GXP Pro R3.2 64K, GemSafe applet MPCOS v1.11 + +3B 7D 96 00 00 80 31 80 65 B0 83 11 40 AC 83 00 90 00 + GemXpresso R4 64k + +3B 7D 96 00 00 80 31 80 65 B0 83 11 C0 A9 83 00 90 00 + Gemplus X-Presso Pro 64k + +3B 7E 11 00 00 00 6A 11 63 54 08 30 24 01 .. .. 21 90 01 + Sagem Windows for smart cards + +3B 7F 11 00 00 00 6A 43 45 52 45 53 02 2C 34 02 00 03 90 00 + FNMT-CERES ST (Fábrica Nacional de Moneda y Timbre) + +3B 7F 11 00 00 80 31 C0 52 21 57 64 02 18 19 53 83 83 90 00 + banking card (www.caixacatalunya.com) + student id of Universitat Autonoma de Barcelona + +3B 7E 13 00 00 00 6A 11 63 54 05 48 .. .. .. 01 22 90 00 + Sagem Windows for smart cards + +3B 7F 13 00 FF 45 43 4F 53 76 31 31 30 28 63 29 50 46 42 4D + ECOS-Card [Experimental Card Operating System V.1.1] by Philipp Maier + http://www.runningserver.com/?page=runningserver.content.download.ecos + +3B 7F 11 00 00 00 31 C0 53 CA C4 01 64 52 D9 04 00 82 90 00 + DoD CAC, Oberthur CosmopolIC 32K V4 + +3B 7F 18 00 00 00 31 C0 73 9E 01 0B 64 52 D9 03 00 82 90 00 + Oberthur Galactic V3 (32k) + +3B 7F 18 00 00 00 31 C0 73 9E 01 0B 64 52 D9 04 00 82 90 00 + Oberthur CosmopolIC 32K v4 Fast ATR + Oberthur Authentic + +3B 7F 18 00 00 00 31 C0 73 9E 01 0B 64 52 D9 05 00 82 90 00 + Oberthur 32k BIO + +3B 7F 38 00 00 00 6A 43 45 52 45 53 02 2C 34 02 02 03 90 00 + WG10 + +3B 7F 38 00 00 00 6A 44 4E 49 65 20 02 4C 34 01 13 03 90 00 + DNI electronico (Spanish electronic ID card) + http://www.dnielectronico.es + +3B 81 1F 00 CC 52 + eToken R2 2242 + +3B 81 80 01 80 80 + Mifare DESFire + +3B 82 00 55 22 + GSM-SIM TELE2 Smart (Estonia, prepaid) + +3B 82 81 31 76 43 C0 02 C5 + CardOS/M2 V2.01(SLE44CxxS) + +3B 82 81 31 76 43 C1 03 C5 + i.ti (ticket card for Collogne/Bonn) + CardOS M2 Combi V2.02 (SLE44R42S) + +3B 83 00 12 10 96 + GSM-SIM T-Mobil D1 (900MHz) + +3B 85 00 12 02 01 00 96 + GSM-SIM Victorvox D1 (900MHz) + +3B 85 00 87 25 01 38 02 + GSM-SIM Viag Interkom E2 Loop GSM (1800MHz) + +3B 85 00 87 25 01 39 00 + GSM-SIM Telfort (Netherlands) 900 MHz + +3B 85 40 20 68 01 01 .. .. + Schlumberger Cryptoflex 8k + +3B 85 40 20 68 01 01 03 05 + Schlumberger Cryptoflex Key Generation + +3B 85 40 20 68 01 01 05 01 + Schlumberger Cryptoflex 8k + +3B 86 40 20 68 01 01 02 04 AC + Activcard Gold, SchlumbergerSema Cryptoflex 8k + +3B 85 40 FF 63 01 01 03 01 + Axalto Cryptoflex 16K + +3B 85 40 FE 68 01 01 02 04 + Axalto CryptoFlex 8K + +3B 86 80 01 4A 43 4F 50 33 30 12 + Mifare ProX T=CL + +3B 86 80 01 4A 43 4F 50 33 31 13 + JCOP BIO 31 Contactless Card + +3B 87 81 31 40 43 4D 46 43 20 31 33 31 6F + Telekom Paycard + +3B 88 81 31 20 55 00 57 69 6E 43 61 72 64 29 + SmartCard for Windows 1.0 + +3B 89 00 91 26 91 06 00 01 22 01 00 + BT Cellnet SIM + +3B 8B 80 01 00 64 04 11 01 01 31 80 00 90 00 5A + German Passport (issued Nov 2006) + United Kingdom e-Passport + +3B 89 40 14 47 47 32 36 4D 35 32 38 30 + GSM-SIM e-plus (1800MHz) + +3B 89 80 01 00 64 04 15 01 02 00 90 00 EE + German Passport (issued Apr 2007) + +3B 89 80 01 4A 43 4F 50 34 31 56 32 32 4D + New Zealand e-Passport + +3B 89 80 01 4D 54 43 4F 53 73 01 02 01 3F + Contactless MTCOS + http://www.masktech.de/ + +3B 89 80 01 53 50 4B 32 35 44 49 90 00 DA + SPK 2.5 D1 + +3B 8A 80 01 00 64 05 5C 02 03 31 80 90 00 16 + T-System Contactless Netkey Card + +3B 8A 80 01 00 64 05 76 02 03 31 80 90 00 3C + T-System Contactless TCOS Min + +3B 8A 00 91 01 00 16 00 01 16 01 00 96 + GSM-SIM T-Mobil D1 (900MHz) + +3B 8A 00 91 01 00 16 00 01 20 01 00 96 + GSM-SIM T-D1 prepaid (Xtra) + +3B 8A 00 91 01 00 16 00 01 20 02 00 96 + GSM-SIM (900MHz) card of the carrier t-mobile for their cellular + network (phase 2+ with 3V) + +3B 8A 00 91 91 00 17 00 01 07 03 00 96 + T-Mobile prepaid 2G SIM + +3B 8E 80 01 80 31 80 66 40 90 89 12 08 02 83 01 90 00 0B + ISO 14443B Type T = CL Infineon Card + +3B 8E 80 01 80 91 91 31 C0 64 77 E3 03 00 83 82 90 00 1C + Belgian Passport + +3B 8F 01 80 25 A0 00 00 00 56 57 44 4B 34 30 30 06 00 B7 + SafeNet IKey4000 + +3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 01 00 00 00 00 6A + Philips MIFARE Standard (1 Kbytes EEPROM) + http://www.nxp.com/products/identification/mifare/classic/ + RFID - ISO 14443 Type A - Transport for London Oyster + +3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 02 00 00 00 00 69 + Mifare card with 4k EEPROM + +3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 03 00 00 00 00 68 + Contactless Mifare Ultralight + +3B 8F 80 01 80 4F 0C A0 00 00 03 06 0B 00 00 00 00 00 00 63 + RFID - ISO 15693 - EM Microelectronic-Marin SA + +3B 8F 80 01 80 4F 0C A0 00 00 03 06 0B 00 12 00 00 00 00 71 + RFID - ISO 15693 - Texas Instrument + +3B 8F 80 01 80 4F 0C A0 00 00 03 06 0A 00 1C 00 00 00 00 7E + RFID - HID iCLASS 16K CL + +3B 8F 80 01 80 4F 0C A0 00 00 03 06 0B 00 14 00 00 00 00 77 + Philips ICode + RFID - ISO 15693 - Philips Semiconductors + +3B 90 95 80 1F C3 59 + Dai Nippon Printing Co., DNP Standard-J T3.1 + +3B 95 15 40 .. 68 01 02 .. .. + Schlumberger CryptoFlex 8k v2 + +3B 95 18 40 FF 62 01 02 01 04 + Schlumberger Cryptoflex 32K e-gate + +3B 95 18 40 FF 62 04 01 01 05 + Schlumberger CryptoFlex 32Ko V1 + +3B 95 18 40 FF 64 02 01 01 02 + Schlumberger CryptoFlex 32Ko + +3B 95 94 40 FF 63 01 01 02 01 + Schlumberger Cryptoflex 16Ko + +3B 95 95 40 FF AE 01 01 02 03 + Axalto Cyberflex Access 64K v2a SM 2.3 + +3B 95 95 40 FF AE 01 03 00 00 + Axalto - Cyberflex 64K + +3B 95 95 40 FF D0 00 1A 01 01 + Cyberflex Access 64k (v3) + +3B 98 13 40 0A A5 03 01 01 01 AD 13 11 + Belgium Electronic ID card + +3B 98 94 40 0A A5 03 01 01 01 AD 13 10 + Belgium Electronic ID card + +3B 99 94 00 91 08 91 06 00 01 06 06 00 + GSM-SIM Orange-UK (1800) + +3B 9A 94 00 91 01 00 17 00 01 23 10 00 96 + GSM-SIM Victorvox D1 (900MHz) + +3B 9A 94 00 91 01 00 17 00 01 23 11 00 96 + GSM-SIM Card T-D1 (900MHz) + +3B 99 94 00 91 99 93 12 00 01 16 02 00 + ORGA test systems - GSM Phase 2+ Test SIM + +3B 9A 96 00 92 03 49 93 16 00 01 21 01 00 + GSM-SIM card of the Austrian provider Yesss! (http://www.yesss.at) + +3B 9B 95 80 1F 47 80 31 A0 73 BE 21 00 53 34 99 05 D0 + GSM-SIM EMT "Diil", prepaid (Estonia) + +3B 9C 13 11 81 64 72 65 61 6D 63 72 79 70 74 00 04 08 + XPlusTV & INXCT Access Card-9 (FIRECrypt) + +3B 9D 11 40 23 00 68 10 11 4D 69 6F 43 4F 53 00 90 00 + MioCOS 1.0 + +3B 9D 94 40 23 00 68 20 01 4D 69 6F 43 4F 53 00 90 00 + Miotec (http://www.miotec.fi) smartcard running Miocos 2.0 on an Atmel AT90SC646 + +3B 9E 95 80 1F C3 80 31 A0 73 BE 21 13 67 29 02 01 04 04 CD 39 + Hutchison/3 3G USIM + J+ SWIM WIB UMTS SIM Test card + http://www.exceldata.es/microprocess/j%2Bswinwibusim.html + +3B 9D 95 80 1F C3 80 31 E0 52 4B 54 62 11 03 73 FE 21 1B 8F + KT WiBro UICC (2.3 GHz mobile WiMAX in South Korea) + +3B 9F 21 0E 49 52 44 45 54 4F 20 41 43 53 20 56 34 2E 31 9D + Foxtel paytv decoder in Australia acs 4.1 Irdeto2 + +3B 9F .. 80 1F C3 00 68 1. 44 05 01 46 49 53 45 31 C8 .. 90 00 .. + Setec SetCOS 4.4.1 + +3B 9F 94 40 1E 00 67 11 43 46 49 53 45 10 52 66 FF 81 90 00 + Setec / FINEID + SETEC Instant EID + +3B 9F 94 40 1E 00 67 16 43 46 49 53 45 10 52 66 FF 81 90 00 + RSA SecurID 3100 or Utimaco Safeware Smartcard + SetCOS 4.3.1 Revision Unknown + +3B 9F 94 40 1E 00 67 .. 43 46 49 53 45 10 52 66 FF 81 90 00 + SLE66CX160S running SETCOS 4.3.1 Revision A + +3B 9F 94 80 1F C3 00 68 10 44 05 01 46 49 53 45 31 C8 07 90 00 18 + SetCOS 4.3.0 32K RSA + Instant EID IP2 + SETEC SetCard 32K PKI Evaluated SetCOS 4.4.1a2 + +3B 9F 95 80 1F C3 80 31 E0 73 FE 21 1B 63 E2 09 A9 83 0F 90 00 8D + GSM-SIM EMT (Estonia, WPKI eID support) + +3B 9F 95 80 1F C3 80 31 E0 73 FE 21 1B B3 E2 01 74 83 0F 90 00 88 + Gemplus GemXplore 3G USIM + +3B 9F 95 80 1F C7 80 31 E0 73 FE 21 1B 63 E2 04 A5 83 0F 90 00 88 + Cingular "64Ksmartchip" GSM SIM + +3B 9F 96 80 1F C3 00 68 10 44 05 01 46 49 53 45 31 C8 07 90 00 1A + SETEC SetCard 32K PKI Evaluated SetCOS 4.4.1 + +3B 9F 96 80 1F C3 80 31 E0 73 FE 21 1B B3 E2 02 7E 83 0F 90 00 82 + Vodafone SIM Card (D2, 1800Mhz, Germany, Twincard, possibly others too?), manufactured by Gemplus (See stamp on the chip) + +3B A7 00 40 .. 80 65 A2 08 .. .. .. + Gemplus GemSAFE Smart Card (8K) + +3B A7 00 40 14 80 65 A2 14 01 01 37 + Gemplus GPK4000sdo + +3B A7 00 40 18 80 65 A2 08 01 01 52 + Gemplus GPK8000 + GemSAFE Smart Card (8K) + +3B A7 00 40 18 80 65 A2 09 01 01 52 + Gemplus GPK16000 + +3B A7 00 40 18 80 65 A2 09 01 02 52 + Gemplus GPK16000 + +3B A7 00 40 18 80 65 A2 09 01 03 52 + Gemplus GemSAFE std (GPK16000?) + +3B A8 00 81 71 46 5D 00 54 43 4F 53 31 2E 32 00 65 + Telesec TCOS 1.2 + +3B A8 00 81 71 46 5D 00 54 43 4F 53 31 2E 32 4B 2E + CeloCom Card with TCOS 1.2 + +3B AA 00 40 14 47 47 32 47 54 35 53 34 38 30 + GSM-SIM Libertel (900MHz) + +3B AA 00 40 80 53 4F 80 53 45 03 04 11 AA A3 + "open platform" ATMEGA "new Generation" + http://www.masterixweb-italy.com/new/images/articoli/atmega.jpg + +3B AB 00 81 31 40 45 80 31 C0 65 08 06 80 00 00 00 00 84 + Reloadable Visa Cash card (Schlumberger), Bank of America + +3B AD 00 40 FF 80 31 80 65 B0 05 01 01 5E 83 00 90 00 + Dallas Semiconductor iButton + JIB + +3B B0 11 00 81 31 90 73 F2 + SamOS 2.7 + +3B B2 11 00 10 80 00 01 + Atmel memory card AT88SC0104C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B2 11 00 10 80 00 02 + Atmel memory card AT88SC0204C (Atmel memory card) + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B2 11 00 10 80 00 04 + Atmel memory card AT88SC0404C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B2 11 00 10 80 00 08 + Atmel memory card AT88SC0808C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B2 11 00 10 80 00 16 + Atmel memory card AT88SC1616C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B3 11 00 00 00 00 32 + Atmel memory card AT88SC3216C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B3 11 00 00 00 00 64 + Atmel memory card AT88SC6416C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B3 11 00 00 00 01 28 + Atmel memory card AT88SC12816C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B3 11 00 00 00 02 56 + Atmel memory card AT88SC25616C + http://www.atmel.com/dyn/resources/prod_documents/doc5210.pdf + +3B B2 11 00 10 80 00 08 + Smart VR Card - GD Burti + +3B B7 11 00 81 31 90 43 A5 .. .. .. .. .. .. .. + Siemens CardOS/M V1.4 (SLE44C80S) + +3B B7 11 00 81 31 90 53 B5 .. .. .. .. .. .. .. + CardOS EM/V1.4 (SLE44CR80S) + +3B B7 18 00 81 31 FE 65 53 50 4B 32 34 90 00 5A + Giesecke & Devrient Starcos 2.4 + +3B B7 18 00 C0 3E 31 FE 65 53 50 4B 32 34 90 00 25 + G&D STARCOS SPK 2.4 + +3B B7 94 00 81 31 FE 65 53 50 4B 32 32 90 00 D0 + Giesecke & Devrient STARCOS SPK2.2 + +3B B7 94 00 81 31 FE 65 53 50 4B 32 33 90 00 D1 + Giesecke & Devrient Starcos 2.3 + Deutsche Bank WebSign (RSA-Card) + G&D StarSign Token + +3B B8 13 00 81 31 20 5D 00 57 69 6E 43 61 72 64 02 + SmartCard for Windows 1.1 + +3B B9 94 00 40 14 47 47 33 4E 48 38 36 34 30 + GSM-SIM card of the Austrian mobile phone provider One, http://www.one.at + Proximus SIM - Belgium (SetCOS?) + +3B BA 11 00 81 31 FE 4D 55 45 4B 41 45 20 56 31 2E 30 AE + AKİS v1.0 + +3B BA 13 00 81 31 86 5D 00 64 05 0A 02 01 31 80 90 00 8B + Telesec TCOS 2 (SLE44) + TCOS 2.0 (on CR80S) + Cryptokarte with RSA-Controller, T=1 Protocol + +3B BA 14 00 81 31 86 5D 00 64 05 14 02 02 31 80 90 00 91 + TCOS 2.0 (on CX160S) + Telesec TCOS 2 (SLE66) + +3B BA 94 00 40 14 + GG3RS732S0 ? + +3B BA 94 00 40 14 47 47 33 52 53 37 31 36 53 30 + GSM-SIM Viag Interkom E2 Loop (1800MHz) + GSM-SIM card of the Austrian A1, http://www.a1.net/privat/home + +3B BA 96 00 81 31 86 5D 00 64 05 60 02 03 31 80 90 00 66 + Telesec TCOS 2 (SLE66P) + TCOS 2.0 (on CX320P) + TeleSec Netkey Card + +3B BA 96 00 81 31 86 5D 00 64 05 7B 02 03 31 80 90 00 7D + TeleSec NetKey Card + Deutsche Post card (tcos) + +3B BC 94 00 40 14 47 47 33 48 33 35 58 53 32 30 30 30 + GSM-SIM Era-PL + T-Mobile GSM SIM Card + +3B BC 94 00 40 14 47 47 33 48 33 35 58 56 32 30 30 30 + GSM SIM CARD 32K, Vodafone + +3B BC 94 00 40 14 47 47 33 49 35 43 41 43 31 30 30 30 + Siemens SIM card + +3B BC 94 00 40 14 47 47 33 53 30 35 31 53 31 30 31 30 + GSM SIM (Tele2, Estonia) + +3B BE 11 00 00 41 01 38 00 00 00 00 00 00 00 00 01 90 00 + ACS (Advanced Card System) ACOS-1 + +3B BE 11 00 00 41 01 38 00 00 00 00 00 00 00 00 02 90 00 + ACS (Advanced Card System) ACOS-1 8K + +3B BE 11 00 00 41 01 38 01 00 03 00 00 00 00 00 02 90 00 + ACOS2 test card from ACS reading off a ACR38U + +3B BF 11 00 81 31 FE 45 45 50 41 00 00 00 00 21 00 93 42 00 00 00 00 01 + Austrian BankCard (Old Version - ca. 2004) + +3B BF 11 00 81 31 FE 45 45 50 41 00 00 00 00 26 24 68 30 00 00 00 00 AB + Austrian BankCard (Maestro + Quick) (New Version, since 02/2005, + with Digital-Signature etc.) + +3B BF 11 00 81 31 FE 45 45 50 41 00 00 00 00 28 93 66 23 00 00 03 E8 E4 + Austrian Maestro BankCard +Quick Buergerkarte + +3B BF 11 00 81 31 .. 45 45 50 41 00 00 00 00 .. .. .. .. 00 00 .. .. .. + Austrian Quick E-purse + +3B BE 18 00 00 41 05 .. 00 00 00 00 00 00 00 00 00 90 00 + Advanced Card Systems (ACS) ACOS5 Cryptographic Smart Card + +3B BE 18 00 00 41 05 10 00 00 00 00 00 00 00 00 00 90 00 + ACS ACOS5 "ACOS5-32-G" http://www.acs.com.hk/acos5.asp + +3B BD 18 00 81 31 FE 45 80 51 02 67 04 14 B1 01 01 02 00 81 05 3D + Austrian "e-Card" (=Health Card), BRANDNEW (since 06/2005) + special Version of Starcos 3.1 + +3B BF 11 00 C0 10 31 FE 44 53 4D 40 52 54 20 43 41 46 45 20 31 2E 31 43 C1 + Giesecke&Devrient SmartCafe 1.1 + +3B BF 18 00 80 31 70 35 53 54 41 52 43 4F 53 20 53 32 31 20 43 90 00 9B + Giesecke & Devrient STARCOS S2.1 + +3B BF 18 00 81 31 70 55 53 54 41 52 43 4F 53 20 53 32 31 20 43 90 00 FA + Giesecke & Devrient STARCOS S2.1 + +3B BF 18 00 C0 20 31 70 52 53 54 41 52 43 4F 53 20 53 32 31 20 43 90 00 9C + Giesecke & Devrient SPK 2.1 C + +3B BF 94 00 81 31 FE 65 45 4C 55 20 41 75 73 74 72 69 61 20 31 2E 32 38 + A-Trust: trust-sign (Old Version, ca. 2002) for Digital Signature etc. + A-Trust: a-sign-premium (ca. 2004) "Bürgerkarte" ("Citizen-Card") + for Identifikation, Digital Signature etc. + ("should be" Starcos 2.3) + +3B BF 94 00 81 31 FE 65 45 4C 55 20 41 75 73 74 72 69 61 20 31 2E 32 38 + +3B BF 96 00 81 31 FE 5D 00 64 .. .. .. .. 31 C0 73 F7 01 D0 00 90 00 .. + TCOS 3.0 / NetKey 3.0 + +3B D0 A8 FF 81 F1 FB 24 00 1F C3 F4 + Philips DESFire SAM + +3B D5 95 04 00 AE 01 02 01 01 + Axalto Cyberflex Access 64K v2b SM 1.1 + +3B D6 18 00 80 B1 80 6D 1F 03 80 51 00 61 10 30 9E + Atmel/Athena T0 PC/SC Compliance Test Card No. 1 + +3B D6 18 00 81 B1 80 7D 1F 03 80 51 00 61 10 30 8F + ASECard Crypto, http://www.athena-scs.com/product.asp?pid=8 + +3B DB 11 FF 50 00 FF 00 00 00 00 00 00 00 07 92 16 03 + NEC V-WAY64 v2.1 + +3B DB 96 00 80 1F 03 00 31 C0 64 77 E3 03 00 82 90 00 C1 + CAC (Common Access Card) + +3B DB 96 00 81 B1 FE 45 1F 03 80 F9 A0 00 00 03 08 00 00 10 00 18 + Oberthur CS PIV End Point v1.08 FIPS201 Certified + +3B DE 18 FF 81 F1 FB 34 00 1F 07 44 45 53 46 69 72 65 53 41 4D 56 31 2E 30 D2 + Mifare Desfire SAM Module + +3B DE 18 FF C0 80 B1 FE 45 1F 03 45 73 74 45 49 44 20 76 65 72 20 31 2E 30 2B + Estonian Identity Card (EstEID v1.0 2006 cold) + +3B DF 18 00 81 31 FE 67 00 5C 49 43 4D D4 91 47 D2 76 00 00 38 33 00 58 + Infineon SICRYPT Card Module D4 PC/SC Compliance Test Card + +3B E0 00 00 81 31 20 40 30 + SmarTEC + +3B E2 00 00 40 20 49 .. + Schlumberger Cryptoflex 4k + +3B E2 00 00 40 20 49 05 + Schlumberger Cryptoflex DES + +3B E2 00 00 40 20 49 06 + Schlumberger Cryptoflex + +3B E2 00 00 40 20 49 07 + Schlumberger Cryptoflex Key Generation + +3B E2 00 FF C1 10 31 FE 55 C8 02 9C + Aladdin eToken PRO (USB token) + Siemens CardOS M4.0 + +3B E3 00 FF 91 81 71 26 44 00 01 13 20 2D + Metrebus Card + (used in Rome to store personal information and Atac subscription. + Atac is the public transport company of the city of Rome.) + http://www.atac.roma.it/smart/smart.asp?A=2&S=22&PR=4&LNG=2 + +3B E6 00 FF 81 31 FE 45 4A 43 4F 50 30 33 07 + IBM JCOP 30/16 + +3B E6 00 FF 81 31 FE 45 4A 43 4F 50 31 30 05 + IBM JCOP 10/16 + +3B E6 00 FF 81 31 FE 45 4A 43 4F 50 32 30 06 + IBM JCOP 20/16 + IBM JCOP20 with MIFARE + or Datakey Smart Card Model 330J + (http://www.datakey.com/products/smart_cards/products_sc_330j.shtml) + +3B E6 00 FF 81 31 FE 45 4A 43 4F 50 32 31 07 + IBM JCOP ID21 + +3B E6 00 FF 81 31 FE 45 4A 43 4F 50 33 30 07 + Mifare ProX T=1 + +3B E6 00 FF 81 31 FE 45 4A 43 4F 50 33 31 06 + IBM JCOP 30/31bio (contact interface) + +3B E7 00 00 91 81 31 FE 41 01 10 30 01 00 90 80 49 + "FirmenTicket" from the "Rheinbahn" for the "VRR" + its a ticket corporates can buy for their employees. so its called + "FirmenTicket". "Rheinbahn" is the local service operator for the + mass traffic in and around duesseldorf/germany. "VRR" is traffic + network spanning over at least a big part of north rhine westphalia + (Verkehrsverbund Rhein-Ruhr) + (http://www.vrr.de/de/tickets_und_tarife/vielfahrer/firmenticket/index.php) + +3B E9 00 00 81 21 45 45 4D 56 5F 41 54 52 20 06 6C + VISA card, issued by HVB Bank Czech Republic (http://www.hvb.cz) + +3B E9 00 00 81 21 45 56 49 53 5F 49 4E 46 20 06 78 + VISA card, issued by the Austrian "Raiffeisen" bank (http://www.raiffeisen.at/ + Visa Card - Maximum - Oyak Bank / Turkey + +3B E9 00 00 81 31 FE 45 4A 43 4F 50 34 31 56 32 32 A7 + IBM JCOP v2.2 41 + +3B E9 00 FF C1 10 31 FE 55 C8 01 20 50 4E 34 30 31 32 AD + Siemens CardOS/M 3.0 (SLE66CX160S) + +3B EA 00 FF 81 31 20 75 00 64 05 14 01 02 31 00 90 00 27 + GCOS-MDK + +3B EA 00 FF 81 31 FE 45 54 55 42 2D 43 4B 01 03 01 00 7B + Technische Universität Berlin - Campus Karte + Maybe Sm@rtCafé Expert 2.0 (Giesecke & Devrient) + or GemXpresso 211 PK (Gemplus) + Includes a Mifare-Chip (1 KB - Memory-Chip) + +3B EB 00 00 81 31 42 45 4E 4C 43 68 53 43 4B 30 34 30 31 2B + Dutch University accesscard & Electronic purse & telphone card + +3B EB 00 00 81 31 42 45 4E 4C 43 68 69 70 70 65 72 30 31 0A + Dutch Post (Chipper) + +3B EC 00 FF 81 31 FE 45 A0 00 00 00 56 33 33 30 4A 33 06 00 A1 + Datakey model 330J card, www.datakey.com + http://www.hmk.de/downloads/datakey/Model_330J_Smart_Card.pdf + Model 330J JavaCard v2.1.1 + Global Platform v2.0.1 specifications. + JCCOS operating system applet (Java-based Cryptographic Card + Operating System) + +3B EF 00 00 40 14 80 25 43 45 52 45 53 57 01 16 01 01 03 90 00 + Electronic Identification Card from the FNMT, the Spanish Official + Certification Authority (Fábrica Nacional de Moneda y Timbre) + FNMT-Ceres Siemens Infineon SLE 19 + +3B EF 00 00 40 14 80 25 43 45 52 45 53 57 05 60 01 02 03 90 00 + FNMT-Ceres Siemens Infineon SLE 20 + Fábrica Nacional de Moneda y Timbre + +3B EF 00 00 81 31 20 49 00 5C 50 43 54 10 27 F8 D2 76 00 00 38 33 00 4D + Infineon Technologies PC/SC Compliance Test Card V1.0 + +3B EF 00 00 81 31 FC 45 80 31 80 65 11 01 13 00 01 53 41 43 45 81 04 21 + Slovenska sporitelna (SLSP) Bank card, Maestro Card with chip + +3B EF 00 FF 81 31 20 45 42 61 73 69 63 43 61 72 64 20 5A 43 32 2E 33 BD + ZeitControl BasicCard Enhanced 2.3 + +3B EF 00 FF 81 31 20 45 42 61 73 69 63 43 61 72 64 20 5A 43 33 2E 33 BC + Electronic Purse (Elton Senegal) + +3B EF 00 FF 81 31 50 45 65 63 0D 24 20 02 80 00 05 08 33 56 10 01 02 43 + German ec card + +3B EF 00 FF 81 31 20 75 42 61 73 69 63 43 61 72 64 20 5A 43 33 2E 33 8C + ZeitControl BasicCard Enhanced 3.3 + +3B EF 00 FF 81 31 20 75 42 61 73 69 63 43 61 72 64 20 5A 43 33 2E 37 88 + ZeitControl BasicCard Enhanced 3.7 + +3B EF 00 FF 81 31 20 75 42 61 73 69 63 43 61 72 64 20 5A 43 33 2E 39 86 + ZeitControl BasicCard Enhanced 3.9 + +3B EF 00 FF 81 31 42 45 .* 38 + UNI-Card + +3B EF 00 FF 81 31 42 45 65 63 03 02 03 02 80 00 22 40 48 95 96 00 20 28 + Scard Sparkasse Detmold, Deutschland BLZ 47650130 + +3B EF 00 FF 81 31 50 45 42 61 73 69 63 43 61 72 64 20 5A 43 31 2E 31 CC + ZeitControl BasicCard Compact 1.1 + +3B EF 00 FF 81 31 50 45 65 63 .. .. .. .. .. .. .. .. .. .. .. .. .. .. + GeldKarte v2 (Germany) + +3B EF 00 FF 81 31 50 45 65 63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + Geldkarte v2 + +3B EF 00 FF 81 31 50 45 65 63 08 0B 40 02 80 00 08 15 20 03 36 04 00 7E + old banking card (electronic-card / Maestro / Geldkarte) of the + Stadt-Sparkasse Duesseldorf (like the above, but old - around 2002). + +3B EF 00 FF 81 31 52 45 4D 46 43 20 49 42 4D 20 34 30 48 39 36 30 31 FB + IBM MFC 3.5 file system smart card + (Card from the book "Smart Card Application Development Using Java") + +3B EF 00 FF 81 31 60 45 65 63 04 02 11 00 00 00 00 00 A5 32 A5 01 11 B6 + GledKarte + Siemens M3-Module with a Motorola SC-28. + G&D (Giesecke&Devrient) Geldkarten-OS mit der Version 11 + +3B EF 00 FF 81 31 60 45 65 63 06 03 14 02 50 00 06 51 08 11 5E 01 41 90 + Geldkarte from Deutsche Bank, Thomson-Chip + +3B EF 00 FF 81 31 66 45 49 42 4D 20 4D 46 43 34 30 30 32 30 38 33 31 A1 + IBM MFC 4.1 file system smart card + Card from the book "Smart Card Application Development Using Java" + authors: Uwe Hansmann, Martin. S. Nicklous, Thomas Schäck, Achim Schneider, Frank Seliger + +3B EF 00 FF 81 31 66 45 65 63 20 20 49 42 4D 20 33 2E 31 20 20 20 20 + IBM eCash + +3B EF 00 FF 81 31 66 45 65 63 20 20 49 42 4D 20 33 2E 31 20 20 20 20 CF + IBM eCash + +3B EF 00 FF 81 31 86 45 49 42 4D 20 4D 46 43 34 30 30 30 30 38 33 31 43 + ComCard MFC 4.1 + +3B EF 00 FF 81 31 FE 45 65 63 11 04 01 02 80 00 0F 27 40 00 03 01 00 E1 + Postbank Geldkarte + +3B EF 00 FF 81 31 FE 45 65 63 11 04 01 02 80 00 0F 46 20 04 23 01 00 C4 + Postbank ec/Maestro (Germany) + +3B EF 00 FF 81 31 FE 45 80 31 C0 6B 49 42 4D 20 4A 65 74 5A 20 4D 32 39 + UBS Internet Card (IBM JetZ M2) + +3B F2 18 00 02 C1 0A 31 FE 55 C8 07 76 + Siemens CardOS V4.3 + +3B F2 18 00 02 C1 0A 31 FE 58 C8 08 74 + Siemens CardOS V4.3B + +3B F2 18 00 02 C1 0A 31 FE 58 C8 09 75 + Siemens CardOS V4.2B + +3B F2 18 00 FF C1 0A 31 FE 55 C8 06 8A + Siemens CardOS M 4.2 (SLE66CX642P) + +3B F2 98 00 FF C1 10 31 FE 55 C8 03 15 + Siemens CardOS M 4.01 (SLE66CX320P) + +3B F2 98 00 FF C1 10 31 FE 55 C8 04 12 + CardOS M4.01a (SLE66CX322P) + +3B F4 18 00 02 C1 0A 31 FE 58 56 34 63 76 C5 + Eutron CryptoIdentity (reader + card token) + +3B F4 18 00 FF 81 31 80 55 00 31 80 00 C7 + Identity card of Italian Republic + +3B F4 98 00 FF C1 10 31 FE 55 4D 34 63 76 B4 + Eutron Digipass 860 (reader + card token) + +3B F5 91 00 FF 91 81 71 FE 40 00 41 00 00 00 00 05 + Contactless Mifare Ultralight + +3B F5 91 00 FF 91 81 71 FE 40 00 41 08 00 00 00 0D + Contactless Mifare + +3B F5 91 00 FF 91 81 71 FE 40 00 41 18 00 00 00 1D + Contactless Mifare 4k + +3B F5 91 00 FF 91 81 71 FE 40 00 41 88 00 00 00 8D + Contactless Mifare 1k or 4k + +3B F6 18 00 FF 81 31 FE 45 4A 43 4F 50 32 30 0E + IBM JCOP20 + +3B F6 18 00 FF 81 31 FE 45 4A 43 4F 50 33 30 0F + Philips P8RF5016 running IBM JCOP 30 (contact interface) + +3B F6 18 00 FF 81 31 FE 45 4A 43 4F 50 33 31 0E + IBM JCOP BIO31 + IBM JCOP BIO31 Java card + +3B F7 11 00 01 40 96 54 30 04 0E 6C B6 D6 90 00 + PIC16F876-04/SP (PICCard2) or + PIC16F84A-04/P + 24LC16B (PICCard1) or + Canal + Canal Digital Spain year 2000/2001 or + PIC Silver Card 2 (PIC16F876/7 + 24C64) + +3B F7 11 00 01 40 96 58 42 14 0E 6C B6 D6 + UK on digital (terrestrial digital TV card) + +3B F7 11 00 01 40 96 70 70 07 0E 6C B6 D6 90 00 + M-II (a.k.a. M-2, a.k.a. Platinum Card), AT90SC6464C based + KnotCard II + TitaniumElite + +3B F7 11 00 01 40 96 70 70 17 0E 6C B6 D6 + Canal Satellite card (VERSION 7.1 SYSTEM / SECA2) + +3B F7 91 00 FF 91 81 71 FE 40 00 41 20 00 11 77 81 80 40 + Contactless Mifare DESFire + +3B F8 18 00 00 81 31 FE 45 00 73 C8 40 13 00 90 00 93 + Giesecke & Devrient Sm@rtCafé Expert 3.0 + +3B F9 94 00 00 81 31 FE 65 46 54 20 56 31 30 30 90 00 83 + ePass 2000 + +3B FA 11 00 02 40 60 43 C6 02 F8 03 03 00 00 90 00 + DeLaRue DX(?) + +3B FA 13 00 00 81 31 FE 45 4A 43 4F 50 34 31 56 + JCOP41 V221 + +3B FA 13 00 FF 81 31 80 45 00 31 C1 73 C0 01 00 00 90 00 B1 + OpenPGP + +3B FA 94 00 00 81 31 20 43 80 65 A2 01 01 01 3D 72 D6 43 21 + GemXpresso Pro R3 32PK (MPCOS, T=1) + +3B FA 98 00 FF C1 10 31 FE 55 C8 03 53 41 47 5F 50 4B 49 32 77 + Siemens corporate ID card (access to the building / rooms etc, + stores PKI private keys/certificates) + +3B FA 98 00 FF C1 10 31 FE 55 C8 04 53 41 47 5F 50 4B 49 32 70 + Siemens Belgium Corporate Card + +3B FB 13 00 FF 81 31 80 75 5A 43 36 2E 35 20 52 45 56 20 43 64 + ZeitControl BasicCard 6.5, multiapplication with 30 kByte EEPROM + +3B FB 13 00 FF 81 31 80 75 5A 43 35 2E 35 20 52 45 56 20 47 63 + ZeitControl BasicCard 5.5 + +3B FB 13 00 FF C0 80 31 80 75 5A 43 35 2E 34 20 52 45 56 20 41 A5 + ZeitControl BasicCard Professional 5.4 Revision A + +3B FB 96 00 00 80 31 FE 45 00 31 C0 64 77 E3 02 00 82 90 00 76 + Oberthur ID-One Cosmo + +3B FB 98 00 FF C1 10 31 FE 55 00 64 05 20 47 03 31 80 00 90 00 F3 + Gemplus GemGate 32K + distributed by Postecert (www.postecert.it) to legally sign documents + +3B FC 98 00 FF C1 10 31 FE 55 C8 03 49 6E 66 6F 63 61 6D 65 72 65 28 + New Card Infocamere (Italy) series 1402... + http://www.card.infocamere.it/ + Siemens Informatica - Siemens M4.01a + chip Infineon SLE66CX322P (CC EAL5) + Memory EEPROM: 32KB + Operating system CARDOS + Max numero dei tentativi PIN: 3 + Pin: da 5 a 8 digit + Unblocked by tool CARDOS API 2.2 + +3B FD 18 00 00 80 31 FE 45 00 31 80 71 8E 64 52 D9 04 00 81 90 00 5B + Oberthur Card Systems, authentIC + +3B FD 94 00 00 81 31 20 43 80 31 80 65 B0 83 02 04 7E 83 00 90 00 B6 + GXPPRo-R3.x STD PTS T=1 + +3B FD 94 00 00 81 31 60 65 80 31 C0 69 4D 54 43 4F 53 73 01 01 11 E0 + MTCOS Light, http://www.masktech.de/products/mtcoslight/index.html + +3B FE 91 00 FF 91 81 71 FE 40 00 41 28 00 01 80 81 00 73 C8 40 00 00 90 00 4D + Philips SmartMX chip (IBMs JCOP OS) + +3B FE 94 00 FF 80 B1 FA 45 1F 03 45 73 74 45 49 44 20 76 65 72 20 31 2E 30 43 + Estonian Identity Card (EstEID v1.0 cold) + +3B FF 11 00 00 81 31 FE 4D 80 25 A0 00 00 00 56 57 44 4B 33 33 30 06 00 D0 + Datakey 32K PKI Smart Card Model 330 + (http://www.datakey.com/products/smart_cards/products_sc_330.shtml) + +3B FF 11 00 00 81 71 40 42 00 00 21 01 31 42 52 00 0[0,5] 63 .. .. .. .. 90 00.* + Smart Card "The Smart Way to Login" + Used on Acer TravelMate to secure boot + +3B FF 11 00 02 40 64 80 69 A2 07 01 03 57 00 00 FF 00 83 00 90 00 + Gemplus GemXpresso + +3B FF 13 00 00 81 31 FE 4D 80 25 A0 00 00 00 56 57 44 4B 33 33 30 06 00 D2 + Datakey DCOS model 330 (DKCCOS 6.0 token) + +3B FF 13 00 FF 80 31 FE 45 53 46 53 45 2D 43 58 33 32 32 2D 56 18 02 08 76 + SmartCafe Expert Java + +3B FF 13 00 FF 80 31 FE 45 53 46 53 45 2D 43 58 33 32 32 2D 56 18 03 08 77 + Giesecke & Devrient SmartCafe Expert 32K v2.0 #2 + +3B FF 13 00 FF 81 31 FE 45 65 63 11 04 50 02 80 00 08 39 00 04 02 05 02 E9 + German "Geldkarte" supplied by the Deutsche Bank in Karlsruhe, + Baden-Württemberg, Germany. + +3B FF 13 00 FF 81 31 FE 45 65 63 11 04 50 02 80 00 08 54 00 04 23 05 02 A5 + Maestrocard/Geldkarte (Stadtsparkasse Haltern, Germany) + +3B FF 13 00 FF 81 31 FE 5D 80 25 A0 00 00 00 56 57 44 4B 33 32 30 05 00 3F + Datakey DCOS model 320 + +3B FF 18 00 00 81 31 FE 45 00 6B 04 05 01 00 01 11 01 43 4E 53 10 31 80 69 + Sanitary Card of "Friuli Venezia Giulia" region (Italian Republic) + Carta Nazionale dei Servizi (Italia) http://cartaservizi.regione.fvg.it/ + +3B FF 18 00 FF 80 31 FE 45 53 46 53 45 2D 43 58 33 32 32 2D 56 18 03 08 7C + Giesecke & Devrient Sm@rtCafé Expert 2.0 + +3B FF 18 00 FF 80 31 FE 45 53 6D 40 72 74 43 61 66 65 45 78 70 65 72 74 65 + Giesecke & Devrient SmartCafe 32K v1 + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 50 00 10 90 00 26 00 04 10 09 + Maestrocard/Geldkarte (Postbank, Germany) + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 50 00 10 90 01 55 00 04 10 7B + Volksbank VR-BankCard (GeldKarte) + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 50 00 10 90 07 88 00 04 10 A0 + HBCI-Karte (Berliner Sparkasse, Germany) + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 50 00 10 90 05 29 00 04 10 03 + Geldkarte/HBCI(DDV-1) (Stadtsparkasse Vorpommern, Germany) + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 50 00 10 90 13 82 00 04 10 BE + Bremer Karte ("Geldkarte und BSAG-Kundenkarte in einem.") + http://www.bsag.de/4911.php + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 50 00 10 90 14 06 00 04 10 3D + Geldkarte/HBCI(DDV-1) (Staedtische Sparkasse Offenbach, Germany) + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 50 00 10 90 55 70 00 04 10 0A + EC-Card from DKB (Deutsche Kreditbank AG) + +3B FF 18 00 FF 81 31 3C 45 65 63 0D 02 31 02 80 00 12 24 30 00 20 04 10 59 + Geldkarte (Germany) + +3B FF 18 00 FF 81 31 50 45 65 63 .. .. .. .. .. .. .. .. .. .. .. .. .. .. + GeldKarte v3 (Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 0D 08 65 07 64 00 0D 91 04 90 00 06 16 0E + German Railway's (Deutsche Bahn AG) "Konzernausweis" + +3B FF 18 00 FF 81 31 FE 45 65 63 0D 04 50 02 80 00 08 90 09 70 00 05 00 2A + Landesbank baden-Württemberg Geldkarte + +3B FF 18 00 FF 81 31 FE 45 65 63 0D 07 63 05 28 00 0D 90 81 06 00 06 15 58 + Geldkarte/HBCI (Frankfurter Sparkasse, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 0D 07 63 07 64 00 0D 90 58 45 00 06 15 8C + Stadtsparkasse München electronic cash card / Geldkarte + +3B FF 18 00 FF 81 31 FE 45 65 63 0D 07 63 07 64 00 0D 90 73 07 00 06 15 E5 + Sparkasse Acchen HBCI Geld Karte + +3B FF 18 00 FF 81 31 FE 45 65 63 0D 07 63 07 64 00 0D 90 74 32 00 06 15 D7 + German HBCI-Banking Card with 'Geldkarte' from the bank "Sparkasse Marburg-Biedenkopf" + +3B FF 18 00 FF 81 31 FE 45 65 63 0D 07 63 07 64 00 0D 90 92 61 00 06 15 62 + Geldkarte (Frankfurter Sparkasse, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 03 50 02 80 00 08 27 70 02 06 05 01 8A + old banking card (electronic-card / Maestro / Geldkarte) of the + "Volksbank Gelderland eG" (around 2003) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 05 40 02 50 00 10 55 10 03 03 05 00 43 + belongs to a banking card (electronic-card / Maestro / Geldkarte). + the bank calls it "VR-BankCard". the banks name is "Volksbank + Gelderland eG" and is part of the "Volksbanken und Raiffeisenbanken" + (http://www.vb-gelderland.de/html/5/2394/rubrik/1282.html) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 40 02 50 00 10 05 50 03 10 05 00 43 + HBCI-Karte (Bordesholmer Sparkasse, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 40 02 50 00 10 19 10 04 20 05 00 28 + Stadtsparkasse München HBCI card / Geldkarte + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 40 02 50 00 10 25 60 05 12 05 00 57 + Geldkarte/HBCI(DDV-1) (Stadtsparkasse Vorpommern, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 40 02 50 00 10 27 30 02 16 05 00 06 + GeldKarte from Sparkasse bank + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 40 02 50 00 10 27 80 03 25 05 00 84 + Volksbank VR-BankCard (GeldKarte) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 40 02 50 00 10 28 50 01 11 05 00 6D + HBCI Bancing Card of Sparkasse Pforzheim + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 62 02 80 00 11 06 60 03 04 06 13 87 + Geldkarte (Volksbank Offenburg, Germany) + +3B FF 18 00 FF 81 31 .. 45 65 63 .. .. .. .. .. .. .. .. .. .. .. .. .. .. + Geldkarte (generic ATR) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 62 02 80 00 11 20 90 03 09 06 13 5C + Geldkarte [ec, Maestro] (1822 direkt Frankfurter Sparkasse, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 62 02 80 00 11 43 50 01 17 06 13 E3 + EC-Card of Sparkasse Pforzheim Calw + +3B FF 18 00 FF 81 31 FE 45 65 63 11 06 62 02 80 00 11 16 50 05 17 06 13 B2 + FinTS (BBBank Karlsruhe, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 08 43 02 50 00 10 46 50 01 08 05 30 27 + HBCI-Karte (Sparkasse Altmark-West, Salzwedel, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 11 08 66 02 80 00 11 40 50 03 18 06 20 D4 + banking card (electronic-card / Maestro / Geldkarte). the bank+calls + it "S-Card" or "Sparkassen-Card". the banks name is "Stadtsparkasse + Duesseldorf" and is part of the "Sparkassen-Finanzgruppe" (a finance + group, network of local banks). + +3B FF 18 00 FF 81 31 FE 45 65 63 11 08 66 02 80 00 11 56 00 03 18 06 20 92 + Geldkarte [ec, Maestro] (Sparkasse Langen-Seligenstadt, Germany) + +3B FF 18 00 FF 81 31 FE 45 65 63 1A 01 41 02 50 00 10 52 09 05 67 05 10 21 + Maestro/Geldkarte (BBBank Karlsruhe, Germany) + +3B FF 18 00 FF 81 31 FE 55 00 6B 02 09 02 00 01 01 01 43 4E 53 10 31 80 9F + Carta Nazionale dei Servizi - InfoCamere + +3B FF 18 00 FF 81 31 FE 55 00 6B 02 09 02 00 01 11 01 43 4E 53 10 31 80 8F + Carta Regionale dei Servizi - Regione Lombardia + +3B FF 18 00 FF 81 31 FE 55 00 6B 02 09 02 00 01 11 01 43 4E 53 11 31 80 8E + Infocamere CNS + +3B FF 18 00 FF C1 0A 31 FE 55 00 6B 05 08 C8 05 01 11 01 43 4E 53 10 31 80 0C + Carta Regionale dei Servizi - Regione Lombardia + +3B FF 32 00 00 10 80 80 31 E0 5B 47 42 50 00 00 00 00 00 00 02 55 + UK NatWest BT PayToView Mondex + +3B FF 94 00 00 40 0A 80 31 00 73 12 21 13 57 4A 33 0E 02 32 41 00 + Turkcell SIMPlus64 / Turkey + +3B FF 94 00 FF 80 B1 FE 45 1F 03 00 68 D2 76 00 00 28 FF 05 1E 31 80 00 90 00 23 + D-Trust Signature Card (www.d-trust.net): + - Citizencard of the People of Ulm in Germany (Bürgerkarte) + - Qualified Electronic Signature Card (Qualifizierte Signaturkarte) + +3B FF 94 00 FF C0 0A 1F 43 80 31 E0 73 36 21 13 57 4A 43 49 1C 31 30 32 1C + Giesecke & Devrient - UniverSIM Pegasus + +3B FF 95 00 FF 40 0A 80 31 00 73 1A 21 13 57 4A 50 48 60 31 41 47 + Vodafone 64 KB SIM with Javacard + +3B FF 95 00 FF 40 0A 80 31 E8 73 F6 21 13 67 4A 47 48 60 31 42 00 + Giesecke & Devrient STARSIM + +3B FF 96 00 FF C0 0A 1F 43 80 31 E0 73 36 21 13 57 4A 43 49 1C 31 30 32 1E + Giesecke & Devrient - UniverSIM Pegasus + +3B FF 95 00 FF C0 0A 1F 43 80 31 E0 73 F6 21 13 57 4A 33 48 61 32 41 47 D6 + GSM SIM (issued by e-plus, Germany) + +3F 05 DC 20 FC 00 01 + DigiCash Facility Card + +3F 28 00 00 11 14 00 03 68 90 00 + SIMEMU - a DIY GSM SIM card - http://simemu.cjb.net/ + +3F 2D 00 27 A0 51 82 7D 00 00 00 52 00 0C 90 00 + Porta Moedas Multibanco (Portugeese electronic purse) + +3F 2F 00 80 59 AF 02 01 01 30 00 00 0A 0E 83 06 9F 12 + Gemplus GemXplore + +3F 2F 00 80 59 AF 02 01 02 30 00 0C 0A 0E 83 1E 9F 16 + GSM-SIM (900MHz) card of the carrier "Mannesmann Mobilfunk" for + their network "D2-Privat" - now known as Vodafone Mobilfunk + (http://www.vodafone.de/). + +3F 2F 00 80 69 AE 02 02 01 36 00 00 0A 0E 83 3E 9F 16 + GSM-SIM e-plus (1800MHz) + +3F 2F 00 80 69 AF 02 04 01 36 00 02 0A 0E 83 3E 9F 16 + GSM-SIM D2 CallYa (900MHz) + +3F 2F 00 80 69 AF 03 07 03 52 00 00 0A 0E 83 3E 9F 16 + GemXplore 98 V1 16K + +3F 2F 00 80 69 AF 03 07 03 52 00 0D 0A 0E 83 3E 9F 16 + GSM-SIM Debitel D2 (900MHz) + +3F 2F 00 80 69 AF 03 07 03 5A 00 15 0A 0E 83 3E 9F 16 + Virgin Mobile SIM (Gemplus) + +3F 67 25 00 21 20 00 0F 78 90 00 + Bank Nederlandse Gemeenten, BNG Data Services + +3F 65 25 .. .. 04 6C 90 .0 + Carte Bancaire (French banking card) + +3F 65 25 00 2[2,C] 09 [F,6]9 90 00 + Sesam Vitale (French health card) + +3F 65 25 00 2B 09 62 90 00 + Coinamatic SmartyCity smartcard + +3F 65 25 00 2B 09 EB 90 00 + Bull Scot 5 + +3F 65 25 00 52 09 6A 90 00 + French carte Vitale + +3F 65 25 08 22 04 68 90 00 + France Telecom card (ex Pastel card) + +3F 65 25 08 33 04 20 90 00 + D-Trust card + +3F 65 35 10 02 04 6C 90 00 + Postcard (Switzerland) + +3F 65 35 64 02 04 6C 90 40 + Postcard (Switzerland) + +3F 67 25 00 26 14 00 20 68 90 00 + Pay-TV card from Casema Cable Television, Netherland + +3F 67 25 00 2A 20 00 0F 68 90 00 + Carte Grand Voyageur (SNCF: French train company) + +3F 67 25 00 2A 20 00 40 68 9F 00 + Swiss Cash card + +3F 67 25 00 2A 20 00 4[0,1] 68 90 00 + Dutch ChipKnip, Proton + (chip Bull CC 60 V1, Bull CC 60 V2 or Bull CC 1000) + +3F 67 25 04 21 20 00 07 68 90 00 + Philips TB100 (C-MOS chip) + +3F 67 2F 04 11 20 00 00 68 90 00 + BULL HN ITALIA 06/92 - 100.000 - 64MP + La Sapienza - Universita' di Roma + +3F 69 00 00 24 AF 01 70 01 01 FF 90 00 + French GSM SIM card (900MHz) + +3F 6C 00 00 24 A0 30 00 FF 00 00 01 00 04 90 00 + Gemplus MCOS 16K DES Sample Card + +3F 6C 00 00 25 A0 30 89 76 00 00 04 01 0C 90 00 + MCOS 24k EEPROM + +3F 6C 00 00 3C A0 30 9E 61 00 00 01 00 04 90 00 + Gemplus - British Gas - Gascard + +3F 6C 00 00 3C A0 30 A7 58 00 00 01 01 8C 90 00 + Rendezvous Series 7 (D2-Mac satellite TV card) + +3F 6D 00 00 80 31 80 65 B0 05 01 02 5E 83 00 90 00 + Gemplus GemXpresso 211PK or 211PK-IS + +3F 6D 00 00 80 31 80 65 B0 05 01 02 5E 92 00 90 00 + Gemplus GemXpresso 32K + +3F 77 18 25 00 29 14 00 62 68 90 00 + Viaccess card + +3F 78 12 25 01 40 B0 03 4A 50 20 48 55 + DSS/DTV H + +3F 7E 11 25 05 40 B0 08 00 00 4D 59 00 00 00 53 4B 0B 07 + BSkyB Series 11 (DSS satellite TV card) + +3F 7F 11 25 05 40 B0 0F 69 FF 4D 59 00 00 00 53 4B 0C 06 00 + Sky Series 12 (DSS satellite TV card) + +3F 7E 11 25 09 40 B0 01 00 00 4D 59 00 00 03 53 4B 0A 01 + Sky Series 10 (DSS satellite TV card) + +3F 7E 11 25 05 40 B0 08 00 00 4D 59 00 00 00 53 4B 0B 08 + Sky Series 11 (DSS satellite TV card) + +3F 7F 13 25 03 33 B0 06 69 FF 4A 50 D0 00 00 53 59 00 00 00 + Sky 2005/6 (DSS satellite TV card) + +3F 7F 13 25 03 38 B0 04 FF FF 4A 50 00 00 29 48 55 .. .. .. + DSS/DTV HU + +3F 7F 13 25 03 40 B0 0B 69 4C 4A 50 C0 00 00 53 59 00 00 00 + Sky Digital (DSS satellite TV card) + +3F 78 13 25 03 40 B0 20 FF FF 4A 50 00 + DSS/DTV P4 + +3F FF 95 00 FF 91 81 71 A0 47 00 44 4E 41 53 50 30 31 30 20 52 65 76 41 32 30 48 + DSS/DISH ROM10 + +3F FF 95 00 FF 91 81 71 A0 47 00 44 4E 41 53 50 30 31 30 20 52 65 76 41 32 31 49 + PayTV card for DishNetwork Sat receiver http://www.dishnetwork.com/ + +3F FF 95 00 FF 91 81 71 A0 47 00 44 4E 41 53 50 30 31 31 20 52 65 76 42 + NTL digial TV card (Nagravision) + +3F FF 95 00 FF 91 81 71 A0 47 00 44 4E 41 53 50 30 31 31 20 52 65 76 42 30 36 4E + Telewest Broadband (Nagravision) + +3F FF 95 00 FF 91 81 71 A0 47 00 44 4E 41 53 50 30 31 31 20 52 65 76 42 30 42 3A + NagraVision card for StarHub Digital Cable DVB-C Singapore + +3F FF 95 00 FF 91 81 71 A0 47 00 44 4E 41 53 50 30 31 31 20 52 65 76 42 30 44 3C + NagraVision card for Virgin Media in the UK + +3F FF 95 00 FF 91 81 71 FE 47 00 44 4E 41 53 50 31 31 30 20 52 65 76 41 30 31 14 + TVA Digital - Nagra Vision ID TV-01 + +3F FF 95 00 FF 91 81 71 FE 47 00 44 4E 41 53 50 31 31 30 20 52 65 76 41 43 33 65 + Brazilian NET Digital (Cable TV provider) - Nagra Vision "NASP110 RevA01" + +# do not delete diff -r 000000000000 -r 67e8eca28a80 driver/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/Makefile Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,17 @@ +# + +TARGET:= pt1_drv.ko + +all: ${TARGET} + +pt1_drv.ko: pt1_pci.c pt1_i2c.c pt1_tuner.c pt1_tuner_data.c + make -C /usr/src/linux-`uname -r` M=`pwd` V=1 modules + +clean: + make -C /usr/src/linux-`uname -r` M=`pwd` V=1 clean + +obj-m:= pt1_drv.o + +pt1_drv-objs := pt1_pci.o pt1_i2c.o pt1_tuner.o pt1_tuner_data.o + +clean-files := *.o *.ko *.mod.[co] *~ diff -r 000000000000 -r 67e8eca28a80 driver/Module.markers diff -r 000000000000 -r 67e8eca28a80 driver/modules.order --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/modules.order Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,1 @@ +kernel//home/yaz/develop/pt1/driver/pt1_drv.ko diff -r 000000000000 -r 67e8eca28a80 driver/pt1_com.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_com.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,23 @@ +#ifndef __PT1_COM_H__ +#define __PT1_COM_H__ +/***************************************************************************/ +/* I2Cǡ */ +/***************************************************************************/ +#define MAX_CHANNEL 4 // ͥ +#define FALSE 0 +#define TRUE 1 +#define MAX_TUNER 2 //塼ʿ +enum{ + CHANNEL_TYPE_ISDB_S, + CHANNEL_TYPE_ISDB_T, + CHANNEL_TYPE_MAX +}; +/***************************************************************************/ +/* */ +/***************************************************************************/ +enum{ + STATE_STOP, // ľ + STATE_START, // ̾ + STATE_FULL // ȥåѡ +}; +#endif diff -r 000000000000 -r 67e8eca28a80 driver/pt1_i2c.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_i2c.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,475 @@ +/***************************************************************************/ +/* I2C */ +/***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pt1_com.h" +#include "pt1_i2c.h" +#include "pt1_pci.h" + +#define PROGRAM_ADDRESS 1024 +static int state = STATE_STOP ; +static int i2c_lock(void __iomem *, __u32, __u32, __u32); +static int i2c_lock_one(void __iomem *, __u32, __u32); +static int i2c_unlock(void __iomem *, int); +static void writebits(void __iomem *, __u32 *, __u32, __u32); +static void begin_i2c(void __iomem *, __u32 *, __u32 *); +static void start_i2c(void __iomem *, __u32 *, __u32 *, __u32); +static void stop_i2c(void __iomem *, __u32 *, __u32 *, __u32, __u32); + + +// PCI˽񤭹I2Cǡ +void makei2c(void __iomem *regs, __u32 base_addr, __u32 i2caddr, __u32 writemode, __u32 data_en, __u32 clock, __u32 busy) +{ + + __u32 val ; + val = ((base_addr << I2C_DATA) | (writemode << I2C_WRIET_MODE) | + ( data_en << I2C_DATA_EN) | + (clock << I2C_CLOCK) | (busy << I2C_BUSY) | i2caddr) ; + writel(val, regs + FIFO_ADDR); +} + +int xc3s_init(void __iomem *regs) +{ + + __u32 val ; + int lp ; + int rc ; + +/* + val = (1 << 19) | (1 << 27) | (1 << 16) | (1 << 24) | (1 << 17) | (1 << 25); + writel(WRITE_PULSE, regs); +BIT 19, 19+8 ON +BIT 16, 16+8 ON +BIT 17, 17+8 ON + */ + // XC3S + for(lp = 0 ; lp < PROGRAM_ADDRESS ; lp++){ + makei2c(regs, lp, 0, READ_EN, DATA_DIS, CLOCK_DIS, BUSY_DIS); + } + // XC3S Ԥ (512 PCI Clocks) + for(lp = 0 ; lp < XC3S_PCI_CLOCK ; lp++){ + makei2c(regs, 0, 0, READ_EN, DATA_DIS, CLOCK_DIS, BUSY_DIS); + } + // ץƥȲ + // ϲտޤƤ + // ɤɤȽʤ + for(lp = 0 ; lp < 57 ; lp++){ + val = readl(regs); + if(val & I2C_READ_SYNC){ + break ; + } + writel(WRITE_PULSE, regs); + } + + for(lp = 0 ; lp < 57 ; lp++){ + val = readl(regs); + if(val & READ_DATA){ + break ; + } + writel(WRITE_PULSE, regs); + } + + // UNLOCK + rc = i2c_unlock(regs, READ_UNLOCK); + if(rc < 0){ + return rc ; + } + + // Enable PCI + rc =i2c_lock(regs, (WRITE_PCI_RESET | WRITE_PCI_RESET_), WRITE_PCI_RESET_, PCI_LOCKED); + if(rc < 0){ + return -EIO ; + } + + // Enable RAM + rc =i2c_lock(regs, (WRITE_RAM_RESET | WRITE_RAM_RESET_), WRITE_RAM_RESET_, RAM_LOCKED); + if(rc){ + return -EIO ; + } + for(lp = 0 ; lp < XC3S_PCI_CLOCK ; lp++){ + rc = i2c_lock_one(regs, WRITE_RAM_ENABLE, RAM_SHIFT); + if(rc < 0){ + printk(KERN_ERR "PT1:LOCK FALUT\n"); + return rc ; + } + } + + // ȥ꡼ऴȤž(OFF) + for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ + SetStream(regs, lp, 0); + SetStream(regs, lp, 0); + } + return 0 ; +} +// +// +//BIT 0. 1 : Tunerֹ (Enable/Disable) +//BIT 8. 9 : Tunerֹ +// +// +void SetStream(void __iomem *regs, __u32 channel, __u32 enable) +{ + __u32 val ; + + val = (1 << (8 + channel)); + if(enable){ + val |= (1 << channel); + } + writel(val, regs + TS_TEST_ENABLE_ADDR); +} + +static int i2c_lock(void __iomem *regs, __u32 firstval, __u32 secondval, __u32 lockval) +{ + + __u32 val ; + int lp ; + + writel(firstval, regs); + writel(secondval, regs); + + // RAMå줿 + for(lp = 0 ; lp < XC3S_PCI_CLOCK ; lp++){ + val = readl(regs); + if((val & lockval)){ + return 0 ; + } + schedule_timeout_interruptible(msecs_to_jiffies(1)); + } + return -EIO ; +} + +static int i2c_lock_one(void __iomem *regs, __u32 firstval, __u32 lockval) +{ + + __u32 val ; + __u32 val2 ; + int lp ; + + val = (readl(regs) & lockval); + writel(firstval, regs); + + // RAMå줿 + for(lp = 0 ; lp < 10 ; lp++){ + for(lp = 0 ; lp < 1024 ; lp++){ + val2 = readl(regs); + // ǽ˼ǡȵդˤʤOK + if(((val2 & lockval) != val)){ + return 0 ; + } + } + schedule_timeout_interruptible(msecs_to_jiffies(1)); + } + printk(KERN_INFO "PT1:Lock Fault(%x:%x)\n", val, val2); + return -EIO ; +} +static int i2c_unlock(void __iomem *regs, int lockval) +{ + int lp ; + __u32 val ; + + writel(WRITE_PULSE, regs); + + for(lp = 0 ; lp < 3 ; lp++){ + val = readl(regs); + if((val &lockval)){ + return 0 ; + } + schedule_timeout_interruptible(msecs_to_jiffies(1)); + } + return -EIO ; +} +void blockwrite(void __iomem *regs, WBLOCK *wblock) +{ + int lp ; + int bitpos ; + __u32 bits ; + __u32 old_bits = 1 ; + __u32 address = 0; + __u32 clock = 0; + + begin_i2c(regs, &address, &clock); + if(state == STATE_STOP){ + start_i2c(regs, &address, &clock, old_bits); + old_bits = 0 ; + stop_i2c(regs, &address, &clock, old_bits, FALSE); + state = STATE_START ; + } + old_bits = 1 ; + start_i2c(regs, &address, &clock, old_bits); + old_bits = 0 ; + + // ޤɥ쥹 + for(bitpos = 0 ; bitpos < 7 ; bitpos++){ + bits = ((wblock->addr >> (6 - bitpos)) & 1); + writebits(regs, &address, old_bits, bits); + old_bits = bits ; + } + // סWRT + writebits(regs, &address, old_bits, 0); + // ACK/NACK(ɬ1) + writebits(regs, &address, 0, 1); + + old_bits = 1 ; + // ºݤΥǡ + for (lp = 0 ; lp < wblock->count ; lp++){ + for(bitpos = 0 ; bitpos < 8 ; bitpos++){ + bits = ((wblock->value[lp] >> (7 - bitpos)) & 1); + writebits(regs, &address, old_bits, bits); + old_bits = bits ; + } + // ACK/NACK(ɬ1) + writebits(regs, &address, old_bits, 1); + old_bits = 1 ; + } + + // Clock negedge + makei2c(regs, address, address + 1, 0, (old_bits ^ 1), 1, 1); + clock = TRUE ; + address += 1 ; + stop_i2c(regs, &address, &clock, old_bits, TRUE); + +} + +void blockread(void __iomem *regs, WBLOCK *wblock, int count) +{ + int lp ; + int bitpos ; + __u32 bits ; + __u32 old_bits = 1 ; + __u32 address = 0; + __u32 clock = 0; + + begin_i2c(regs, &address, &clock); + if(state == STATE_STOP){ + start_i2c(regs, &address, &clock, old_bits); + old_bits = 0 ; + stop_i2c(regs, &address, &clock, old_bits, FALSE); + state = STATE_START ; + } + old_bits = 1 ; + start_i2c(regs, &address, &clock, old_bits); + old_bits = 0 ; + + // ޤɥ쥹 + for(bitpos = 0 ; bitpos < 7 ; bitpos++){ + bits = ((wblock->addr >> (6 - bitpos)) & 1); + writebits(regs, &address, old_bits, bits); + old_bits = bits ; + } + // סWRT + writebits(regs, &address, old_bits, 0); + // ACK/NACK(ɬ1) + writebits(regs, &address, 0, 1); + + old_bits = 1 ; + // ºݤΥǡ + for (lp = 0 ; lp < wblock->count ; lp++){ + for(bitpos = 0 ; bitpos < 8 ; bitpos++){ + bits = ((wblock->value[lp] >> (7 - bitpos)) & 1); + writebits(regs, &address, old_bits, bits); + old_bits = bits ; + } + // ACK/NACK(ɬ1) + writebits(regs, &address, old_bits, 1); + old_bits = 1 ; + } + + // Clock negedge + makei2c(regs, address, address + 1, 0, (old_bits ^ 1), 1, 1); + clock = TRUE ; + address += 1 ; + + // Read + start_i2c(regs, &address, &clock, old_bits); + old_bits = 0 ; + // ޤɥ쥹 + for(bitpos = 0 ; bitpos < 7 ; bitpos++){ + bits = ((wblock->addr >> (6 - bitpos)) & 1); + writebits(regs, &address, old_bits, bits); + old_bits = bits ; + } + // סRD + writebits(regs, &address, old_bits, 1); + // ACK/NACK(ɬ1) + writebits(regs, &address, 1, 1); + + old_bits = 1 ; + // ºݤΥǡ + for (lp = 0 ; lp < count ; lp++){ + for(bitpos = 0 ; bitpos < 8 ; bitpos++){ + writebits(regs, &address, old_bits, 1); + // Read Mode Set + makei2c(regs, address, address + 1, 1, 0, 0, 1); + address += 1 ; + old_bits = 1 ; + } + if(lp >= (count - 1)){ + // ACK/NACK(ɬ1) + writebits(regs, &address, old_bits, 1); + old_bits = 0 ; + }else{ + // ACK/NACK(ɬ1) + writebits(regs, &address, old_bits, 0); + old_bits = 1 ; + } + } + + // Clock negedge + makei2c(regs, address, address + 1, 0, 0, 1, 1); + clock = TRUE ; + address += 1 ; + old_bits = 1 ; + stop_i2c(regs, &address, &clock, old_bits, TRUE); + +} +static void writebits(void __iomem *regs, __u32 *address, __u32 old_bits, __u32 bits) +{ + // CLOCK UP + makei2c(regs, *address, *address + 1, 0, (old_bits ^ 1), 1, 1); + *address += 1 ; + + // CLOCK UP + makei2c(regs, *address, *address + 1, 0, (bits ^ 1), 1, 1); + *address += 1 ; + + // CLOCK DOWN + makei2c(regs, *address, *address + 1, 0, (bits ^ 1), 0, 1); + *address += 1 ; + +} +static void begin_i2c(void __iomem *regs, __u32 *address, __u32 *clock) +{ + // bus FREE + makei2c(regs, *address, *address, 0, 0, 0, 0); + *address += 1 ; + + // bus busy + makei2c(regs, *address, *address + 1, 0, 0, 0, 1); + *address += 1 ; + *clock = FALSE ; +} + +static void start_i2c(void __iomem *regs, __u32 *address, __u32 *clock, __u32 data) +{ + // ǡĤäƤʤХǡ򲼤 + if(!data){ + // CLOCKCLOCK򲼤 + if(*clock != TRUE){ + *clock = TRUE ; + makei2c(regs, *address, *address + 1, 0, 1, 1, 1); + *address += 1 ; + } + makei2c(regs, *address, *address + 1, 0, 0, 1, 1); + *address += 1 ; + } + + if(*clock != FALSE){ + *clock = FALSE ; + makei2c(regs, *address, *address + 1, 0, 0, 0, 1); + *address += 1; + } + makei2c(regs, *address, *address + 1, 0, 1, 0, 1); + *address += 1; + *clock = FALSE ; +} + +static void stop_i2c(void __iomem *regs, __u32 *address, __u32 *clock, __u32 data, __u32 end) +{ + // ǡĤäƤ + if(data){ + // å + if(*clock != TRUE){ + *clock = TRUE ; + makei2c(regs, *address, *address + 1, 0, 0, 1, 1); + *address += 1; + } + makei2c(regs, *address, *address + 1, 0, 1, 1, 1); + *address += 1 ; + } + // åƤ + if(*clock){ + *clock = FALSE ; + makei2c(regs, *address, *address + 1, 0, 1, 0, 1); + *address += 1 ; + } + + if(end){ + makei2c(regs, *address, 0, 0, 0, 0, 1); + }else{ + makei2c(regs, *address, *address + 1, 0, 0, 0, 1); + *address += 1 ; + } +} + +void i2c_write(void __iomem *regs, struct mutex *lock, WBLOCK *wblock) +{ + + int lp; + __u32 val ; + + // å + mutex_lock(lock); +#if 0 + printk(KERN_INFO "Addr=%x(%d)\n", wblock->addr, wblock->count); + for(lp = 0 ; lp < wblock->count ; lp++){ + printk(KERN_INFO "%x\n", wblock->value[lp]); + } + printk(KERN_INFO "\n"); +#endif + + blockwrite(regs, wblock); + writel(FIFO_GO, regs + FIFO_GO_ADDR); + //Ȥꤢåʤ褦ˡ + for(lp = 0 ; lp < 100 ; lp++){ + val = readl(regs + FIFO_RESULT_ADDR); + if(!(val & FIFO_DONE)){ + break ; + } + schedule_timeout_interruptible(msecs_to_jiffies(1)); + } + mutex_unlock(lock); +} + +__u32 i2c_read(void __iomem *regs, struct mutex *lock, WBLOCK *wblock, int size) +{ + + int lp; + __u32 val ; + + // å + mutex_lock(lock); +#if 0 + printk(KERN_INFO "Addr=%x:%d:%d\n", wblock->addr, wblock->count, size); + for(lp = 0 ; lp < wblock->count ; lp++){ + printk(KERN_INFO "%x\n", wblock->value[lp]); + } + printk(KERN_INFO "\n"); +#endif + blockread(regs, wblock, size); + + writel(FIFO_GO, regs + FIFO_GO_ADDR); + + for(lp = 0 ; lp < 100 ; lp++){ + schedule_timeout_interruptible(msecs_to_jiffies(1)); + val = readl(regs + FIFO_RESULT_ADDR); + if(!(val & FIFO_DONE)){ + break ; + } + } + + val = readl(regs + I2C_RESULT_ADDR); + mutex_unlock(lock); + return val ; +} diff -r 000000000000 -r 67e8eca28a80 driver/pt1_i2c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_i2c.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,83 @@ +#ifndef __PT1_I2C_H__ +#define __PT1_I2C_H__ +#include +/***************************************************************************/ +/* I2Cǡ */ +/***************************************************************************/ +#define MAX_CHANNEL 4 // ͥ + +#define FALSE 0 +#define TRUE 1 + +/***************************************************************************/ +/* I2Cǡ */ +/***************************************************************************/ +#define I2C_ADDRESS 10 // I2Cɥ쥹(10ӥå) + +#define I2C_DATA_EN 10 +#define I2C_CLOCK 11 +#define I2C_WRIET_MODE 12 // I2C񤭹ߡɤ߹ +#define I2C_BUSY 13 +#define I2C_DATA 18 // I2Cǡ(18ӥå) +/***************************************************************************/ +/* I2C */ +/***************************************************************************/ +#define WRITE_EN 1 // 񤭹 +#define READ_EN 0 // ɤ߹ +#define DATA_EN 1 // ǡ +#define DATA_DIS 0 // ǡʤ +#define CLOCK_EN 1 // CLOCK +#define CLOCK_DIS 0 // CLOCKʤ +#define BUSY_EN 1 // BUSY +#define BUSY_DIS 0 // BUSYʤ + +/***************************************************************************/ +/* */ +/***************************************************************************/ +#define PCI_LOCKED 1 +#define RAM_LOCKED 2 +#define RAM_SHIFT 4 +/***************************************************************************/ +/* ӥå */ +/***************************************************************************/ +#define WRITE_PCI_RESET (1 << 16) +#define WRITE_PCI_RESET_ (1 << 24) +#define WRITE_RAM_RESET (1 << 17) +#define WRITE_RAM_RESET_ (1 << 25) +#define WRITE_RAM_ENABLE (1 << 1) + +#define WRITE_PULSE (1 << 3) +#define I2C_READ_SYNC (1 << 29) +#define READ_DATA (1 << 30) +#define READ_UNLOCK (1 << 31) + +#define XC3S_PCI_CLOCK (512 / 4) +/***************************************************************************/ +/* I2Cɥ쥹 */ +/***************************************************************************/ +#define T0_ISDB_S 0X1B // 塼0 ISDB-S +#define T1_ISDB_S 0X19 // 塼1 ISDB-S + +#define T0_ISDB_T 0X1A // 塼0 ISDB-T +#define T1_ISDB_T 0X18 // 塼1 ISDB-T + +/***************************************************************************/ +/* I2C񤭹ߥǡ */ +/***************************************************************************/ +typedef struct _WBLOCK{ + __u8 addr ; // I2CǥХɥ쥹 + __u32 count ; // žĿ + __u8 value[16]; // 񤭹 +}WBLOCK; + +/***************************************************************************/ +/* ؿ */ +/***************************************************************************/ +//extern __u32 makei2c(void __iomem *, __u32, __u32, __u32, __u32, __u32, __u32); +extern int xc3s_init(void __iomem *); +extern void SetStream(void __iomem *, __u32, __u32); +extern void blockwrite(void __iomem *, WBLOCK *); +extern void i2c_write(void __iomem *, struct mutex *, WBLOCK *); +extern __u32 i2c_read(void __iomem *, struct mutex *, WBLOCK *, int); + +#endif diff -r 000000000000 -r 67e8eca28a80 driver/pt1_ioctl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_ioctl.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,17 @@ +#ifndef __PT1_IOCTL_H__ +#define __PT1_IOCTL_H__ +/***************************************************************************/ +/* ͥȿ¤ */ +/***************************************************************************/ +typedef struct _frequency{ + int frequencyno ; // ȿơֹ֥ + int slot ; // åֹ桿ûȿ +}FREQUENCY; + +/***************************************************************************/ +/* IOCTL */ +/***************************************************************************/ +#define SET_CHANNEL _IOW(0x8D, 0x01, FREQUENCY) +#define START_REC _IO(0x8D, 0x02) +#define STOP_REC _IO(0x8D, 0x03) +#endif diff -r 000000000000 -r 67e8eca28a80 driver/pt1_pci.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_pci.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,801 @@ +/* pt1-pci.c: A PT1 on PCI bus driver for Linux. */ +#define DRV_NAME "pt1-pci" +#define DRV_VERSION "1.00" +#define DRV_RELDATE "11/28/2008" + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) +#include +#else +#define set_freezable() +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +typedef struct pm_message { + int event; +} pm_message_t; +#endif +#endif +#include +#include + +#include +#include + +#include + +#include "pt1_com.h" +#include "pt1_pci.h" +#include "pt1_tuner.h" +#include "pt1_i2c.h" +#include "pt1_tuner_data.h" +#include "pt1_ioctl.h" + +/* These identify the driver base version and may not be removed. */ +static char version[] __devinitdata = +KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " \n"; + +MODULE_AUTHOR("Tomoaki Ishikawa tomy@users.sourceforge.jp"); +#define DRIVER_DESC "PCI earthsoft PT1 driver" +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ +static int lnb = 0; /* LNB OFF:0 +11V:1 +15V:2 */ + +module_param(debug, int, 0); +module_param(lnb, int, 0); +MODULE_PARM_DESC(debug, "debug level (1-2)"); +MODULE_PARM_DESC(debug, "LNB level (0:OFF 1:+11V 2:+15V)"); + +static struct pci_device_id pt1_pci_tbl[] = { + { 0x10ee, 0x211a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, pt1_pci_tbl); +#define DEV_NAME "pt1video" + +#define MAX_READ_BLOCK 4 // 1٤ɤ߽ФDMAХåե +#define MAX_PCI_DEVICE 64 // 64 +#define DMA_SIZE 4096 // DMAХåե +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +#define DMA_RING_SIZE 64 // RING +#define DMA_RING_MAX 511 // 1RINGˤĵͤ뤫(1023NG511ޤ) +#define CHANEL_DMA_SIZE (1*1024*1024) // ϥǥ(16Mbps) +#define BS_CHANEL_DMA_SIZE (1*1024*1024) // BS(32Mbps) +#else +#define DMA_RING_SIZE 28 // RING +#define DMA_RING_MAX 511 // 1RINGˤĵͤ뤫(1023NG511ޤ) +#define CHANEL_DMA_SIZE (1*128*1024) // ϥǥ(16Mbps) +#define BS_CHANEL_DMA_SIZE (1*128*1024) // BS(32Mbps) +#endif + +typedef struct _DMA_CONTROL{ + dma_addr_t ring_dma[DMA_RING_MAX] ; // DMA + __u32 *data[DMA_RING_MAX]; +}DMA_CONTROL; + +typedef struct _PT1_CHANNEL PT1_CHANNEL; + +typedef struct _pt1_device{ + unsigned long mmio_start ; + __u32 mmio_len ; + void __iomem *regs; + struct mutex lock ; + dma_addr_t ring_dma[DMA_RING_SIZE] ; // DMA + void *dmaptr[DMA_RING_SIZE] ; + struct task_struct *kthread; + dev_t dev ; + __u32 base_minor ; + struct cdev cdev[MAX_CHANNEL]; + wait_queue_head_t dma_wait_q ;// for poll on reading + DMA_CONTROL dmactl[DMA_RING_SIZE]; + PT1_CHANNEL *channel[MAX_CHANNEL]; +}PT1_DEVICE; + +typedef struct _MICRO_PACKET{ + char data[3]; + char head ; +}MICRO_PACKET; + +struct _PT1_CHANNEL{ + __u32 valid ; // ե饰 + __u32 address ; // I2Cɥ쥹 + __u32 channel ; // ֹͥ + int type ; // ͥ륿 + __u32 drop ; // ѥåȥɥå׿ + struct mutex lock ; // CHmutex_lock + __u32 size ; // DMA줿 + __u32 maxsize ; // DMAѥХåե + __u32 bufsize ; // ͥ˳꿶줿 + __u32 overflow ; // Сե顼ȯ + __u32 counetererr ; // ž󥿣顼 + __u32 transerr ; // ž顼 + __u32 minor ; // ޥʡֹ + __u8 *buf; // CH̼ + __u8 req_dma ; // 줿ͥ + PT1_DEVICE *ptr ; // ̾ + wait_queue_head_t wait_q ; // for poll on reading +}; + +// I2Cɥ쥹(video0, 1 = ISDB-S) (video2, 3 = ISDB-T) +int i2c_address[MAX_CHANNEL] = {T0_ISDB_S, T1_ISDB_S, T0_ISDB_T, T1_ISDB_T}; +int real_chanel[MAX_CHANNEL] = {0, 2, 1, 3}; +int channeltype[MAX_CHANNEL] = {CHANNEL_TYPE_ISDB_S, CHANNEL_TYPE_ISDB_S, + CHANNEL_TYPE_ISDB_T, CHANNEL_TYPE_ISDB_T}; + +static PT1_DEVICE *device[MAX_PCI_DEVICE]; + +#define PT1MAJOR 251 +#define DRIVERNAME "pt1video" + +static void reset_dma(PT1_DEVICE *dev_conf) +{ + + int lp ; + __u32 addr ; + int ring_pos = 0; + int data_pos = 0 ; + __u32 *dataptr ; + + // ǡ + for(ring_pos = 0 ; ring_pos < DMA_RING_SIZE ; ring_pos++){ + for(data_pos = 0 ; data_pos < DMA_RING_MAX ; data_pos++){ + dataptr = dev_conf->dmactl[ring_pos].data[data_pos]; + // ǡꡩ + if(dataptr[(DMA_SIZE / sizeof(__u32)) - 2] == 0){ + break ; + } + } + } + // ž󥿤ꥻå + writel(0x00000010, dev_conf->regs); + // ž󥿤򥤥󥯥 + for(lp = 0 ; lp < DMA_RING_SIZE ; lp++){ + writel(0x00000020, dev_conf->regs); + } + + addr = (int)dev_conf->ring_dma[0] ; + addr >>= 12 ; + // DMAХåե + writel(addr, dev_conf->regs + DMA_ADDR); + // DMA + writel(0x0c000040, dev_conf->regs); + +} +static int pt1_thread(void *data) +{ + PT1_DEVICE *dev_conf = data ; + PT1_CHANNEL *channel ; + int ring_pos = 0; + int data_pos = 0 ; + int lp ; + int chno ; + int lp2 ; + __u32 addr ; + __u32 *dataptr ; + __u32 *curdataptr ; + __u32 val ; + union mpacket{ + __u32 val ; + MICRO_PACKET packet ; + }micro; + + set_freezable(); + reset_dma(dev_conf); + printk(KERN_INFO "pt1_thread run\n"); + + for(;;){ + if(kthread_should_stop()){ + break ; + } + + for(;;){ + dataptr = dev_conf->dmactl[ring_pos].data[data_pos]; + // ǡꡩ + if(dataptr[(DMA_SIZE / sizeof(__u32)) - 2] == 0){ + break ; + } + micro.val = *dataptr ; + curdataptr = dataptr ; + data_pos += 1 ; + for(lp = 0 ; lp < (DMA_SIZE / sizeof(__u32)) ; lp++, dataptr++){ + micro.val = *dataptr ; + chno = real_chanel[(((micro.packet.head >> 5) & 0x07) - 1)]; + channel = dev_conf->channel[chno] ; + // 顼å + if((micro.packet.head & MICROPACKET_ERROR)){ + val = readl(dev_conf->regs); + if((val & BIT_RAM_OVERFLOW)){ + channel->overflow += 1 ; + } + if((val & BIT_INITIATOR_ERROR)){ + channel->counetererr += 1 ; + } + if((val & BIT_INITIATOR_WARNING)){ + channel->transerr += 1 ; + } + // Ƭ + reset_dma(dev_conf); + ring_pos = data_pos = 0 ; + break ; + } + // ̤ѥͥϼΤƤ + if(channel->valid == FALSE){ + continue ; + } + mutex_lock(&channel->lock); + // դ줿ɤ߽ФޤԤ + while(1){ + if(channel->size >= (channel->maxsize - 4)){ + // ͥDMAɤߤԤˤ + wake_up(&channel->wait_q); + channel->req_dma = TRUE ; + mutex_unlock(&channel->lock); + // ˻֤Ϥ + wait_event_timeout(dev_conf->dma_wait_q, (channel->req_dma == FALSE), + msecs_to_jiffies(500)); + mutex_lock(&channel->lock); + channel->drop += 1 ; + }else{ + break ; + } + } + // ǡԡ + for(lp2 = 2 ; lp2 >= 0 ; lp2--){ + channel->buf[channel->size] = micro.packet.data[lp2]; + channel->size += 1 ; + } + mutex_unlock(&channel->lock); + } + curdataptr[(DMA_SIZE / sizeof(__u32)) - 2] = 0; + + if(data_pos >= DMA_RING_MAX){ + data_pos = 0; + ring_pos += 1 ; + // DMA󥰤Ѥäϥ󥯥 + writel(0x00000020, dev_conf->regs); + if(ring_pos >= DMA_RING_SIZE){ + ring_pos = 0 ; + } + } + + // ٤(4Kǵư) + for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ + channel = dev_conf->channel[real_chanel[lp]] ; + if((channel->size >= DMA_SIZE) && (channel->valid == TRUE)){ + wake_up(&channel->wait_q); + } + } + } + schedule_timeout_interruptible(msecs_to_jiffies(1)); + } + return 0 ; +} +static int pt1_open(struct inode *inode, struct file *file) +{ + + int minor = iminor(inode); + int lp ; + int lp2 ; + PT1_CHANNEL *channel ; + + for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){ + if(device[lp] == NULL){ + return -EIO ; + } + printk(KERN_INFO "(%d)base_minor=%d: MAX=%d(%d)\n", + lp, device[lp]->base_minor, + (device[lp]->base_minor + MAX_CHANNEL), minor); + if((device[lp]->base_minor <= minor) && + ((device[lp]->base_minor + MAX_CHANNEL) > minor)){ + mutex_lock(&device[lp]->lock); + for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){ + channel = device[lp]->channel[lp2] ; + printk(KERN_INFO "Minor(%d:%d)\n", channel->minor, minor); + if(channel->minor == minor){ + if(channel->valid == TRUE){ + mutex_unlock(&device[lp]->lock); + return -EIO ; + } + channel->drop = 0 ; + channel->valid = TRUE ; + channel->overflow = 0 ; + channel->counetererr = 0 ; + channel->transerr = 0 ; + file->private_data = channel; + mutex_lock(&channel->lock); + // ǡ + channel->size = 0 ; + mutex_unlock(&channel->lock); + mutex_unlock(&device[lp]->lock); + return 0 ; + } + } + } + } + return -EIO; +} +static int pt1_release(struct inode *inode, struct file *file) +{ + int minor = iminor(inode); + PT1_CHANNEL *channel = file->private_data; + + mutex_lock(&channel->ptr->lock); + SetStream(channel->ptr->regs, channel->channel, FALSE); + channel->valid = FALSE ; + printk(KERN_INFO "(%d)Drop=%08d:%08d:%08d:%08d\n", iminor(inode), channel->drop, + channel->overflow, channel->counetererr, channel->transerr); + channel->overflow = 0 ; + channel->counetererr = 0 ; + channel->transerr = 0 ; + channel->drop = 0 ; + // ߤƤϵ + if(channel->req_dma == TRUE){ + channel->req_dma = FALSE ; + wake_up(&channel->ptr->dma_wait_q); + } + mutex_unlock(&channel->ptr->lock); + return 0; +} + +static ssize_t pt1_read(struct file *file, char __user *buf, size_t cnt, loff_t * ppos) +{ + PT1_CHANNEL *channel = file->private_data; + __u32 size ; + + + // 4Kñ̤ǵΤԤ(CPUк) + if(channel->size < DMA_SIZE){ + wait_event_timeout(channel->wait_q, (channel->size >= DMA_SIZE), + msecs_to_jiffies(500)); + } + mutex_lock(&channel->lock); + if(!channel->size){ + size = 0 ; + }else{ + if(cnt < channel->size){ + // Хåե­ʤϻĤư + size = cnt ; + copy_to_user(buf, channel->buf, cnt); + memmove(channel->buf, &channel->buf[cnt], (channel->size - cnt)); + channel->size -= cnt ; + }else{ + size = channel->size ; + copy_to_user(buf, channel->buf, size); + channel->size = 0 ; + } + } + // ɤ߽äĻѤƤΤ4Kʲ + if((channel->req_dma == TRUE) && (channel->size < DMA_SIZE)){ + channel->req_dma = FALSE ; + wake_up(&channel->ptr->dma_wait_q); + } + mutex_unlock(&channel->lock); + return size ; +} +static int SetFreq(PT1_CHANNEL *channel, FREQUENCY *freq) +{ + + switch(channel->type){ + case CHANNEL_TYPE_ISDB_S: + { + ISDB_S_TMCC tmcc ; + int lp ; + + if(bs_tune(channel->ptr->regs, + &channel->ptr->lock, + channel->address, + freq->frequencyno, + &tmcc) < 0){ + return -EIO ; + } + printk(KERN_INFO "cn = (%x:%x)\n", (tmcc.cn[0] & 0xFF), + (tmcc.cn[1] & 0xFF)); + printk(KERN_INFO "agc = (%x)\n", (tmcc.agc & 0xFF)); + +#if 0 + printk(KERN_INFO "clockmargin = (%x)\n", (tmcc.clockmargin & 0xFF)); + printk(KERN_INFO "carriermargin = (%x)\n", (tmcc.carriermargin & 0xFF)); + + for(lp = 0 ; lp < MAX_BS_TS_ID ; lp++){ + if(tmcc.ts_id[lp].ts_id == 0xFFFF){ + continue ; + } + printk(KERN_INFO "Slot(%d:%x)\n", lp, tmcc.ts_id[lp].ts_id); + printk(KERN_INFO "mode (low/high) = (%x:%x)\n", + tmcc.ts_id[lp].low_mode, tmcc.ts_id[lp].high_mode); + printk(KERN_INFO "slot (low/high) = (%x:%x)\n", + tmcc.ts_id[lp].low_slot, + tmcc.ts_id[lp].high_slot); + } +#endif + ts_lock(channel->ptr->regs, + &channel->ptr->lock, + channel->address, + tmcc.ts_id[freq->slot].ts_id); + } + break ; + case CHANNEL_TYPE_ISDB_T: + { + if(isdb_t_frequency(channel->ptr->regs, + &channel->ptr->lock, + channel->address, + freq->frequencyno, freq->slot) < 0){ + return -EINVAL ; + } + } + } + return 0 ; +} +static int pt1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) +{ + PT1_CHANNEL *channel = file->private_data; + + switch(cmd){ + case SET_CHANNEL: + { + FREQUENCY freq ; + copy_from_user(&freq, arg, sizeof(FREQUENCY)); + return SetFreq(channel, &freq); + } + case START_REC: + SetStream(channel->ptr->regs, channel->channel, TRUE); + return 0 ; + case STOP_REC: + SetStream(channel->ptr->regs, channel->channel, FALSE); + return 0 ; + } + return -EINVAL; +} + +/* +*/ +static const struct file_operations pt1_fops = { + .owner = THIS_MODULE, + .open = pt1_open, + .release = pt1_release, + .read = pt1_read, + .ioctl = pt1_ioctl, + .llseek = no_llseek, +}; + +int pt1_makering(struct pci_dev *pdev, PT1_DEVICE *dev_conf) +{ + int lp ; + int lp2 ; + DMA_CONTROL *dmactl; + __u32 *dmaptr ; + __u32 addr ; + __u32 *ptr ; + + //DMA󥰺 + for(lp = 0 ; lp < DMA_RING_SIZE ; lp++){ + ptr = dev_conf->dmaptr[lp]; + if(lp == (DMA_RING_SIZE - 1)){ + addr = (__u32)dev_conf->ring_dma[0]; + }else{ + addr = (__u32)dev_conf->ring_dma[(lp + 1)]; + } + addr >>= 12 ; + memcpy(ptr, &addr, sizeof(__u32)); + ptr += 1 ; + + dmactl = &dev_conf->dmactl[lp]; + for(lp2 = 0 ; lp2 < DMA_RING_MAX ; lp2++){ + dmaptr = pci_alloc_consistent(pdev, DMA_SIZE, &dmactl->ring_dma[lp2]); + if(dmaptr == NULL){ + printk(KERN_INFO "PT1:DMA ALLOC ERROR\n"); + return -1 ; + } + dmactl->data[lp2] = dmaptr ; + // DMAǡꥢ + dmaptr[(DMA_SIZE / sizeof(__u32)) - 2] = 0 ; + addr = (__u32)dmactl->ring_dma[lp2]; + addr >>= 12 ; + memcpy(ptr, &addr, sizeof(__u32)); + ptr += 1 ; + } + } + return 0 ; +} +int pt1_dma_init(struct pci_dev *pdev, PT1_DEVICE *dev_conf) +{ + int lp ; + void *ptr ; + + for(lp = 0 ; lp < DMA_RING_SIZE ; lp++){ + ptr = pci_alloc_consistent(pdev, DMA_SIZE, &dev_conf->ring_dma[lp]); + if(ptr == NULL){ + printk(KERN_INFO "PT1:DMA ALLOC ERROR\n"); + return -1 ; + } + dev_conf->dmaptr[lp] = ptr ; + } + + return pt1_makering(pdev, dev_conf); +} +int pt1_dma_free(struct pci_dev *pdev, PT1_DEVICE *dev_conf) +{ + + int lp ; + int lp2 ; + + for(lp = 0 ; lp < DMA_RING_SIZE ; lp++){ + if(dev_conf->dmaptr[lp] != NULL){ + pci_free_consistent(pdev, DMA_SIZE, + dev_conf->dmaptr[lp], dev_conf->ring_dma[lp]); + for(lp2 = 0 ; lp2 < DMA_RING_MAX ; lp2++){ + if(dev_conf->dmactl[lp].data[lp2] != NULL){ + pci_free_consistent(pdev, DMA_SIZE, + dev_conf->dmactl[lp].data[lp2], + dev_conf->dmactl[lp].ring_dma[lp2]); + } + } + } + } + return 0 ; +} +static int __devinit pt1_pci_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int rc ; + int lp ; + int minor ; + u16 cmd ; + PT1_DEVICE *dev_conf ; + PT1_CHANNEL *channel ; + + rc = pci_enable_device(pdev); + if (rc) + return rc; + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + printk(KERN_ERR "PT1:DMA MASK ERROR"); + return rc; + } + + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if (!(cmd & PCI_COMMAND_MASTER)) { + printk(KERN_INFO "Attempting to enable Bus Mastering\n"); + pci_set_master(pdev); + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if (!(cmd & PCI_COMMAND_MASTER)) { + printk(KERN_ERR "Bus Mastering is not enabled\n"); + return -EIO; + } + } + printk(KERN_INFO "Bus Mastering Enabled.\n"); + + dev_conf = kzalloc(sizeof(PT1_DEVICE), GFP_KERNEL); + if(!dev_conf){ + printk(KERN_ERR "PT1:out of memory !"); + return -ENOMEM ; + } + // PCIɥ쥹ޥåפ + dev_conf->mmio_start = pci_resource_start(pdev, 0); + dev_conf->mmio_len = pci_resource_len(pdev, 0); + rc = request_mem_region(dev_conf->mmio_start, dev_conf->mmio_len, DEV_NAME); + if (!rc) { + printk(KERN_ERR "PT1: cannot request iomem (0x%llx).\n", (unsigned long long) dev_conf->mmio_start); + goto out_err_regbase; + } + + dev_conf->regs = ioremap(dev_conf->mmio_start, dev_conf->mmio_len); + if (!dev_conf->regs){ + printk(KERN_ERR "pt1: Can't remap register area.\n"); + goto out_err_regbase; + } + // + if(xc3s_init(dev_conf->regs)){ + printk(KERN_ERR "Error xc3s_init\n"); + goto out_err_fpga; + } + // 塼ʥꥻå + settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_ON_RESET_ENABLE); + schedule_timeout_interruptible(msecs_to_jiffies(50)); + + settuner_reset(dev_conf->regs, lnb, TUNER_POWER_ON_RESET_DISABLE); + schedule_timeout_interruptible(msecs_to_jiffies(10)); + mutex_init(&dev_conf->lock); + + // Tuner + for(lp = 0 ; lp < MAX_TUNER ; lp++){ + rc = tuner_init(dev_conf->regs, &dev_conf->lock, lp); + if(rc < 0){ + printk(KERN_ERR "Error tuner_init\n"); + goto out_err_fpga; + } + } + // λ + for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ + set_sleepmode(dev_conf->regs, &dev_conf->lock, + i2c_address[lp], channeltype[lp], TYPE_SLEEP); + + schedule_timeout_interruptible(msecs_to_jiffies(50)); + } + rc = alloc_chrdev_region(&dev_conf->dev, 0, MAX_CHANNEL, DEV_NAME); + if(rc < 0){ + goto out_err_fpga; + } + + // + init_waitqueue_head(&dev_conf->dma_wait_q); + + minor = MINOR(dev_conf->dev) ; + dev_conf->base_minor = minor ; + for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){ + if(device[lp] == NULL){ + device[lp] = dev_conf ; + printk(KERN_INFO "Alloc[%d]\n", lp); + break ; + } + } + for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ + cdev_init(&dev_conf->cdev[lp], &pt1_fops); + cdev_add(&dev_conf->cdev[lp], MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)), 1); + channel = kzalloc(sizeof(PT1_CHANNEL), GFP_KERNEL); + if(!channel){ + printk(KERN_ERR "PT1:out of memory !"); + return -ENOMEM ; + } + + // ̾ + mutex_init(&channel->lock); + // Ԥ֤ + channel->req_dma = FALSE ; + // ޥʡֹ + channel->minor = MINOR(dev_conf->dev) + lp ; + printk(KERN_INFO "Minor[%d]\n", channel->minor); + // оݤI2CǥХ + channel->address = i2c_address[lp] ; + channel->type = channeltype[lp] ; + // ºݤΥ塼ֹ + channel->channel = real_chanel[lp] ; + channel->ptr = dev_conf ; + channel->size = 0 ; + dev_conf->channel[lp] = channel ; + + init_waitqueue_head(&channel->wait_q); + + switch(channel->type){ + case CHANNEL_TYPE_ISDB_T: + channel->maxsize = CHANEL_DMA_SIZE ; + channel->buf = kzalloc(CHANEL_DMA_SIZE, GFP_KERNEL); + break ; + case CHANNEL_TYPE_ISDB_S: + channel->maxsize = BS_CHANEL_DMA_SIZE ; + channel->buf = kzalloc(BS_CHANEL_DMA_SIZE, GFP_KERNEL); + break ; + } + if(channel->buf == NULL){ + goto out_err_v4l; + } +#if 0 + dev_conf->vdev[lp] = video_device_alloc(); + memcpy(dev_conf->vdev[lp], &pt1_template, sizeof(pt1_template)); + video_set_drvdata(dev_conf->vdev[lp], channel); + video_register_device(dev_conf->vdev[lp], VFL_TYPE_GRABBER, -1); +#endif + } + if(pt1_dma_init(pdev, dev_conf) < 0){ + goto out_err_dma; + } + dev_conf->kthread = kthread_run(pt1_thread, dev_conf, "pt1"); + pci_set_drvdata(pdev, dev_conf); + return 0; + +out_err_dma: + pt1_dma_free(pdev, dev_conf); +out_err_v4l: + for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ + if(dev_conf->channel[lp] != NULL){ + if(dev_conf->channel[lp]->buf != NULL){ + kfree(dev_conf->channel[lp]->buf); + } + kfree(dev_conf->channel[lp]); + } + } +out_err_fpga: + writel(0xb0b0000, dev_conf->regs); + writel(0, dev_conf->regs + 4); + iounmap(dev_conf->regs); + release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len); + kfree(dev_conf); +out_err_regbase: + return -EIO; + +} + +static void __devexit pt1_pci_remove_one(struct pci_dev *pdev) +{ + + int lp ; + __u32 val ; + PT1_DEVICE *dev_conf = (PT1_DEVICE *)pci_get_drvdata(pdev); + + if(dev_conf){ + if(dev_conf->kthread) { + kthread_stop(dev_conf->kthread); + dev_conf->kthread = NULL; + } + + // DMAλ + writel(0x08080000, dev_conf->regs); + for(lp = 0 ; lp < 10 ; lp++){ + val = readl(dev_conf->regs); + if(!(val & (1 << 6))){ + break ; + } + schedule_timeout_interruptible(msecs_to_jiffies(1)); + } + pt1_dma_free(pdev, dev_conf); + for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ + if(dev_conf->channel[lp] != NULL){ + cdev_del(&dev_conf->cdev[lp]); + kfree(dev_conf->channel[lp]->buf); + kfree(dev_conf->channel[lp]); + } + } + unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL); + writel(0xb0b0000, dev_conf->regs); + writel(0, dev_conf->regs + 4); + settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF); + release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len); + iounmap(dev_conf->regs); + kfree(dev_conf); + } + pci_set_drvdata(pdev, NULL); +} +#ifdef CONFIG_PM + +static int pt1_pci_suspend (struct pci_dev *pdev, pm_message_t state) +{ + return 0; +} + +static int pt1_pci_resume (struct pci_dev *pdev) +{ + return 0; +} + +#endif /* CONFIG_PM */ + + +static struct pci_driver pt1_driver = { + .name = DRV_NAME, + .probe = pt1_pci_init_one, + .remove = __devexit_p(pt1_pci_remove_one), + .id_table = pt1_pci_tbl, +#ifdef CONFIG_PM + .suspend = pt1_pci_suspend, + .resume = pt1_pci_resume, +#endif /* CONFIG_PM */ + +}; + + +static int __init pt1_pci_init(void) +{ + return pci_register_driver(&pt1_driver); +} + + +static void __exit pt1_pci_cleanup(void) +{ + pci_unregister_driver (&pt1_driver); +} + +module_init(pt1_pci_init); +module_exit(pt1_pci_cleanup); diff -r 000000000000 -r 67e8eca28a80 driver/pt1_pci.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_pci.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,25 @@ +#ifndef __PT1_PCI_H__ +#define __PT1_PCI_H__ +/***************************************************************************/ +/* PCIɥ쥹 */ +/***************************************************************************/ +#define FIFO_GO 0x04 // FIFO¹ +#define FIFO_DONE 0x80 // FIFO ¹ӥå +/***************************************************************************/ +/* PCIɥ쥹 */ +/***************************************************************************/ +#define FIFO_GO_ADDR 0x00 // FIFO ¹ԥɥ쥹 +#define FIFO_RESULT_ADDR 0x00 // FIFO ̾ +#define I2C_RESULT_ADDR 0x08 // I2C +#define FIFO_ADDR 0x10 // FIFO˽񤯥ɥ쥹 +#define DMA_ADDR 0x14 // DMA˽񤯥ɥ쥹 +#define TS_TEST_ENABLE_ADDR 0x08 // + +/***************************************************************************/ +/* DMA顼 */ +/***************************************************************************/ +#define MICROPACKET_ERROR 1 // Micro Packet顼 +#define BIT_RAM_OVERFLOW (1 << 3) // +#define BIT_INITIATOR_ERROR (1 << 4) // +#define BIT_INITIATOR_WARNING (1 << 5) // +#endif diff -r 000000000000 -r 67e8eca28a80 driver/pt1_tuner.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_tuner.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,508 @@ +/* pt1-tuner.c: A PT1 on Tuner driver for Linux. */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pt1_com.h" +#include "pt1_pci.h" +#include "pt1_i2c.h" +#include "pt1_tuner.h" +#include "pt1_tuner_data.h" +/* + LNB : BIT 2 1 + OFF : 0 0 + +15V: 1 1 + +11V: 1 0 + + TUNER: BIT 3 0 + POWER-OFF : 0 0 + POWER-ON RESET : 0 1 + POWER-ON ONLY : 1 1 +*/ +typedef struct _TUNER_INFO{ + int isdb_s ; + int isdb_t ; +}TUNER_INFO; + +TUNER_INFO tuner_info[2] = { + {T0_ISDB_S, T0_ISDB_T}, + {T1_ISDB_S, T1_ISDB_T} +}; + +typedef struct _isdb_t_freq_add_table{ + __u16 pos ; // ɲäͥݥ + __u16 add_freq ; // ɲä +}isdb_t_freq_add_table; + +isdb_t_freq_add_table isdb_t_freq_add[10] = { + { 7, 0x8081}, // 07 + { 12, 0x80A1}, // 812 + { 21, 0x8062}, // 1321 + { 39, 0x80A2}, // 2239 + { 51, 0x80E2}, // 4051 + { 59, 0x8064}, // 5259 + { 75, 0x8084}, // 6075 + { 84, 0x80a4}, // 7684 + {100, 0x80C4}, // 85100 + {112, 0x80E4} // 101112 +}; + +void settuner_reset(void __iomem *regs, __u32 lnb, __u32 tuner) +{ + __u32 val = 0; + switch(lnb){ + case LNB_11V: val = (1 << BIT_LNB_DOWN); break ; + case LNB_15V: val = (1 << BIT_LNB_UP) | (1 << BIT_LNB_DOWN) ; break ; + } + + switch(tuner){ + case TUNER_POWER_ON_RESET_ENABLE: val |= (1 << BIT_TUNER) ; break ; + case TUNER_POWER_ON_RESET_DISABLE: val = (1 << BIT_TUNER) | (1 << BIT_RESET) ; break ; + } + + writel(val, (regs + 4)); +} +static int init_isdb_s(void __iomem *regs, struct mutex *lock, __u32 addr) +{ + + WBLOCK wk; + int lp ; + __u32 val ; + + // ISDB-S/T + memcpy(&wk, &com_initdata, sizeof(WBLOCK)); + + // (ʤREADʤΤ) + memcpy(&wk, &isdb_s_init1, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + if((val & 0xff) != 0x41){ + printk(KERN_INFO "PT1:ISDB-S Read(%x)\n", val); + return -EIO ; + } + for(lp = 0 ; lp < MAX_ISDB_S_INIT ; lp++){ + memcpy(&wk, isdb_s_initial[lp], sizeof(WBLOCK)); + wk.addr = addr; + i2c_write(regs, lock, &wk); + } + + return 0 ; +} +static void init_isdb_t(void __iomem *regs, struct mutex *lock, __u32 addr) +{ + int lp ; + WBLOCK wk; + + // ISDB-S/T + for(lp = 0 ; lp < MAX_ISDB_T_INIT ; lp++){ + memcpy(&wk, isdb_t_initial[lp], sizeof(WBLOCK)); + wk.addr = addr; + i2c_write(regs, lock, &wk); + } + + +} +int tuner_init(void __iomem *regs, struct mutex *lock, int tuner_no) +{ + + int rc ; + WBLOCK wk; + + // ISDB-S/T + memcpy(&wk, &com_initdata, sizeof(WBLOCK)); + + // () + wk.addr = tuner_info[tuner_no].isdb_t ; + i2c_write(regs, lock, &wk); + wk.addr = tuner_info[tuner_no].isdb_s ; + i2c_write(regs, lock, &wk); + + rc = init_isdb_s(regs, lock, tuner_info[tuner_no].isdb_s); + if(rc < 0){ + return rc ; + } + init_isdb_t(regs, lock, tuner_info[tuner_no].isdb_t); + + memcpy(&wk, &isdb_s_init21, sizeof(WBLOCK)); + wk.addr = tuner_info[tuner_no].isdb_s ; + i2c_write(regs, lock, &wk); + + memcpy(&wk, &isdb_t_init17, sizeof(WBLOCK)); + wk.addr = tuner_info[tuner_no].isdb_t ; + i2c_write(regs, lock, &wk); + + return 0 ; +} +void set_sleepmode(void __iomem *regs, struct mutex *lock, int address, int tuner_type, int type) +{ + WBLOCK wk; + + if(type == TYPE_WAKEUP){ + switch(tuner_type){ + case CHANNEL_TYPE_ISDB_S:memcpy(&wk, &isdb_s_wake, sizeof(WBLOCK));break ; + case CHANNEL_TYPE_ISDB_T:memcpy(&wk, &isdb_t_wake, sizeof(WBLOCK));break ; + } + wk.addr = address ; + i2c_write(regs, lock, &wk); + } + switch(tuner_type){ + case CHANNEL_TYPE_ISDB_S: + printk(KERN_INFO "PT1:ISDB-S Sleep\n"); + memcpy(&wk, &isdb_s_sleep, sizeof(WBLOCK)); + if(type == TYPE_WAKEUP){ + wk.value[1] = 0x01 ; + } + break ; + case CHANNEL_TYPE_ISDB_T: + printk(KERN_INFO "PT1:ISDB-T Sleep\n"); + memcpy(&wk, &isdb_t_sleep, sizeof(WBLOCK)); + if(type == TYPE_WAKEUP){ + wk.value[1] = 0x90 ; + } + break ; + } + wk.addr = address; + i2c_write(regs, lock, &wk); +} + +int bs_frequency(void __iomem *regs, struct mutex *lock, int addr, int channel) +{ + int lp ; + int tmcclock = FALSE ; + WBLOCK wk; + __u32 val ; + + if(channel >= MAX_BS_CHANNEL){ + return -EIO ; + } + // ISDB-S PLLå + for(lp = 0 ; lp < MAX_BS_CHANNEL_PLL_COMMAND ; lp++){ + memcpy(&wk, bs_pll[channel].wblock[lp], sizeof(WBLOCK)); + wk.addr = addr ; + i2c_write(regs, lock, &wk); + } + + // PLLåǧ + // å + for(lp = 0 ; lp < 200 ; lp++){ + memcpy(&wk, &bs_pll_lock, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + if(((val & 0xFF) != 0) && ((val & 0XFF) != 0XFF)){ + tmcclock = TRUE ; + break ; + } + } + + if(tmcclock == FALSE){ + printk(KERN_INFO "PLL LOCK ERROR\n"); + return -EIO; + } + + memcpy(&wk, &bs_tmcc_get_1, sizeof(WBLOCK)); + wk.addr = addr; + i2c_write(regs, lock, &wk); + + tmcclock = FALSE ; + + for(lp = 0 ; lp < 200 ; lp++){ + memcpy(&wk, &bs_tmcc_get_2, sizeof(WBLOCK)); + wk.addr = addr; + + val = i2c_read(regs, lock, &wk, 1); + if(((val & 0XFF) != 0XFF) && (!(val & 0x10))){ + tmcclock = TRUE ; + break ; + } + } + + if(tmcclock == FALSE){ + printk(KERN_INFO "TMCC LOCK ERROR\n"); + return -EIO; + } + + return 0 ; +} +int ts_lock(void __iomem *regs, struct mutex *lock, int addr, __u16 ts_id) +{ + + int lp ; + WBLOCK wk; + __u32 val ; + union{ + __u8 ts[2]; + __u16 tsid; + }uts_id ; + + uts_id.tsid = ts_id ; + memcpy(&wk, &bs_set_ts_lock, sizeof(WBLOCK)); + wk.addr = addr; + // TS-ID + wk.value[1] = uts_id.ts[1]; + wk.value[2] = uts_id.ts[0]; + i2c_write(regs, lock, &wk); + + for(lp = 0 ; lp < 100 ; lp++){ + memcpy(&wk, &bs_get_ts_lock, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 2); + if((val & 0xFFFF) == ts_id){ + return 0 ; + } + } + printk(KERN_INFO "PT1:ERROR TS-LOCK(%x)\n", ts_id); + return -EIO ; +} +int bs_tune(void __iomem *regs, struct mutex *lock, int addr, int channel, ISDB_S_TMCC *tmcc) +{ + + int lp ; + int lp2; + WBLOCK wk; + __u32 val ; + ISDB_S_TS_ID *tsid ; + union{ + __u8 slot[4]; + __u32 u32slot; + }ts_slot ; + union{ + __u16 ts[2]; + __u32 tsid; + }ts_id ; + + if(channel >= MAX_BS_CHANNEL){ + printk(KERN_INFO "Invalid Channel(%d)\n", channel); + return -EIO ; + } + val = bs_frequency(regs, lock, addr, channel); + if(val == -EIO){ + return val ; + } + + tsid = &tmcc->ts_id[0] ; + // ȿTS-ID + for(lp = 0 ; lp < (MAX_BS_TS_ID / 2) ; lp++){ + for(lp2 = 0 ; lp2 < 100 ; lp2++){ + memcpy(&wk, bs_get_ts_id[lp], sizeof(WBLOCK)); + wk.addr = addr; + ts_id.tsid = i2c_read(regs, lock, &wk, 4); + // TS-ID0ξϺƼ + if((ts_id.ts[0] != 0) && (ts_id.ts[1] != 0)){ + break ; + } + } + tsid->ts_id = ts_id.ts[1] ; + tsid += 1; + tsid->ts_id = ts_id.ts[0] ; + tsid += 1; + } + + memcpy(&wk, &bs_get_cn, sizeof(WBLOCK)); + wk.addr = addr; + tmcc->cn[0] = i2c_read(regs, lock, &wk, 1); + + memcpy(&wk, &bs_get_agc, sizeof(WBLOCK)); + wk.addr = addr; + tmcc->cn[1] = i2c_read(regs, lock, &wk, 1); + + memcpy(&wk, &bs_get_maxagc, sizeof(WBLOCK)); + wk.addr = addr; + tmcc->agc = i2c_read(regs, lock, &wk, 1); + + // TS-ID̤ξ + tsid = &tmcc->ts_id[0] ; + for(lp = 0 ; lp < MAX_BS_TS_ID ; lp++, tsid += 1){ + // TS-IDʤ=0XFFFF + if(tsid->ts_id == 0xFFFF){ + continue ; + } + ts_lock(regs, lock, addr, tsid->ts_id); + + //åȼ + memcpy(&wk, &bs_get_slot, sizeof(WBLOCK)); + wk.addr = addr; + ts_slot.u32slot = i2c_read(regs, lock, &wk, 3); + tsid->high_mode = 0; + tsid->low_slot = ts_slot.slot[0] ; + tsid->high_slot = ts_slot.slot[1] ; + tsid->low_mode = ts_slot.slot[2] ; + } + + memcpy(&wk, &bs_get_clock, sizeof(WBLOCK)); + wk.addr = addr; + tmcc->clockmargin = i2c_read(regs, lock, &wk, 1); + + memcpy(&wk, &bs_get_carrir, sizeof(WBLOCK)); + wk.addr = addr; + tmcc->carriermargin = i2c_read(regs, lock, &wk, 1); + return 0 ; +} +__u32 getfrequency_add(__u32 channel) +{ + int lp ; + + for(lp = 0 ; lp < 10 ; lp++){ + if(channel <= isdb_t_freq_add[lp].pos){ + return isdb_t_freq_add[lp].add_freq ; + } + } + return 0 ; +} +__u32 getfrequency(__u32 channel, int addfreq) +{ + __u32 frequencyoffset = 0; + __u32 frequencyOffset = 0; + + if (12 <= channel){ + frequencyoffset += 2; + }else if (17 <= channel){ + frequencyoffset = 0; + }else if (63 <= channel){ + frequencyoffset += 2; + } +#if 0 + return (((93 + channel * 6 + frequencyOffset) + addfreq) * 7) + 400; +#endif + frequencyOffset = 93 + channel * 6 + frequencyoffset; + frequencyOffset = 7 * (frequencyOffset + addfreq); + return frequencyOffset + 400; + +} +int isdb_t_frequency(void __iomem *regs, struct mutex *lock, int addr, int channel, int addfreq) +{ + + int lp ; + WBLOCK wk; + __u32 val ; + int tmcclock = FALSE ; + union{ + __u8 charfreq[2]; + __u16 freq; + }freq[2] ; + + if(channel >= MAX_ISDB_T_CHANNEL){ + return -EIO ; + } + + freq[0].freq = getfrequency(channel, addfreq); + freq[1].freq = getfrequency_add(channel); + //ȿ + memcpy(&wk, &isdb_t_pll_base, sizeof(WBLOCK)); + wk.addr = addr ; + // ׻ȿ + wk.value[wk.count] = freq[0].charfreq[1]; + wk.count += 1 ; + wk.value[wk.count] = freq[0].charfreq[0]; + wk.count += 1 ; + + // ׻ȿղþ + wk.value[wk.count] = freq[1].charfreq[1]; + wk.count += 1 ; + wk.value[wk.count] = freq[1].charfreq[0]; + wk.count += 1 ; + + i2c_write(regs, lock, &wk); + + for(lp = 0 ; lp < 100 ; lp++){ + memcpy(&wk, &isdb_t_pll_lock, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + if(((val & 0xFF) != 0XFF) && ((val & 0X50) == 0x50)){ + tmcclock = TRUE ; + break ; + } + } + if(tmcclock != TRUE){ + printk(KERN_INFO "PT1:ISDB-T LOCK NG(%08x)\n", val); + return -EIO ; + } + + memcpy(&wk, &isdb_t_check_tune, sizeof(WBLOCK)); + wk.addr = addr ; + i2c_write(regs, lock, &wk); + + tmcclock = FALSE ; + for(lp = 0 ; lp < 1000 ; lp++){ + memcpy(&wk, &isdb_t_tune_read, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + if(((val & 0xFF) != 0XFF) && ((val & 0X8) != 8)){ + tmcclock = TRUE ; + break ; + } + } + if(tmcclock != TRUE){ + return -EIO ; + } + return 0 ; +} +#if 0 +int isdb_t_tune(void __iomem *regs, struct mutex *lock, int addr, int channel, ISDB_T_TMCC *tmcc) +{ + + int lp ; + int rc ; + int lp2 ; + WBLOCK wk; + __u32 val ; + + printk(KERN_INFO "Channel(%d) Start\n", channel); + if(channel >= MAX_ISDB_T_CHANNEL){ + return -EIO ; + } + rc = isdb_t_frequency(regs, lock, addr, channel); + if(rc < 0){ + return -EIO ; + } + for(lp = 0 ; lp < 100 ; lp++){ + memcpy(&wk, &isdb_t_tmcc_read_1, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 4); + if((val & 0xFF) != 0){ + break ; + } + } + printk(KERN_INFO "TMCC(1)Val(%x)\n", val); + + for(lp = 0 ; lp < 100 ; lp++){ + memcpy(&wk, &isdb_t_tmcc_read_2, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 4); + if((val & 0xFF) != 0){ + break ; + } + } + printk(KERN_INFO "TMCC(2)Val(%x)\n", val); + + memcpy(&wk, &isdb_t_cn_1, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + printk(KERN_INFO "CN(1)Val(%x)\n", val); + + memcpy(&wk, &isdb_t_cn_2, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + printk(KERN_INFO "CN(2)Val(%x)\n", val); + + memcpy(&wk, &isdb_t_agc_1, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + printk(KERN_INFO "AGC(1)Val(%x)\n", val); + + memcpy(&wk, &isdb_t_agc_2, sizeof(WBLOCK)); + wk.addr = addr; + val = i2c_read(regs, lock, &wk, 1); + printk(KERN_INFO "AGC(2)Val(%x)\n", val); + return 0; +} +#endif diff -r 000000000000 -r 67e8eca28a80 driver/pt1_tuner.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_tuner.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,111 @@ +#ifndef __PT1_TUNER_H__ +#define __PT1_TUNER_H__ +/***************************************************************************/ +/* 塼ʾ */ +/***************************************************************************/ +// SLEEP⡼ +enum { + TYPE_SLEEP, + TYPE_WAKEUP +}; + +// 塼ʥѥ⡼ +enum { + BIT_TUNER, + BIT_LNB_UP, + BIT_LNB_DOWN, + BIT_RESET +}; + +// LNBѥ +enum{ + LNB_OFF, // LNB OFF + LNB_11V, // +11 V + LNB_15V // +15 V + +}; +enum{ // Ÿϡɥꥻå + TUNER_POWER_OFF, // ա֥͡ + TUNER_POWER_ON_RESET_ENABLE, // 󡿥֥͡ + TUNER_POWER_ON_RESET_DISABLE // 󡿥ǥ֥ +}; +/***************************************************************************/ +/* 塼ʾ */ +/***************************************************************************/ +#define MAX_BS_TS_ID 8 // TS-ID +#define MAX_ISDB_T_INFO 3 // ϥǥؾ +#define MAX_ISDB_T_INFO_LEN 2 // ϥǥؾ +/***************************************************************************/ +/* ISDB-S */ +/***************************************************************************/ +typedef struct _ISDB_S_CH_TABLE{ + int channel ; // ϥֹͥ + int real_chno ; // ºݤΥơֹ֥ + int slotno ; // åֹ +}ISDB_S_CH_TABLE ; + +/***************************************************************************/ +/* ISDB-S */ +/***************************************************************************/ +typedef struct _ISDB_S_TS_ID{ + __u16 ts_id ; // TS-ID + __u16 dmy ; // PAD + __u8 low_mode ; // 㳬 ⡼ + __u8 low_slot ; // 㳬 åȿ + __u8 high_mode ; // ⳬ ⡼ + __u8 high_slot ; // ⳬ åȿ +}ISDB_S_TS_ID; +typedef struct _ISDB_S_TMCC{ + ISDB_S_TS_ID ts_id[MAX_BS_TS_ID]; // TSֹnФTS ID +#if 0 + __u32 indicator; // ѹؼ (5ӥå) + __u32 emergency; // ư濮 (1ӥå) + __u32 uplink; // åץ (4ӥå) + __u32 ext; // ĥե饰 (1ӥå) + __u32 extdata[2]; // ĥΰ (61ӥå) +#endif + __u32 cn[2] ; // CN + __u32 agc ; // AGC + __u32 clockmargin ; // åȿ + __u32 carriermargin ; // ꥢȿ +}ISDB_S_TMCC; + +// ؾ +typedef struct _ISDB_T_INFO{ + __u32 mode; // ꥢĴ (3ӥå) + __u32 rate; // 沽Ψ (3ӥå) + __u32 interleave; // 󥿡꡼Ĺ (3ӥå) + __u32 segment; // ȿ (4ӥå) +}ISDB_T_INFO; + +typedef struct _ISDB_T_TMCC { +#if 0 + __u32 sysid; // ƥ༱ (2ӥå) + __u32 indicator; // ѥ᡼ڤؤɸ (4ӥå) + __u32 emergency; // ۵޷ѵưե饰 (1ӥå) +#endif + ISDB_T_INFO info[MAX_ISDB_T_INFO]; +#if 0 + // Ⱦ + __u32 partial; // ʬե饰 (1ӥå) + __u32 Phase; // Ϣ (3ӥå) + __u32 Reserved; // ꥶ (12ӥå) +#endif + __u32 cn[2] ; // CN + __u32 agc ; // AGC + __u32 clockmargin ; // åȿ + __u32 carriermargin ; // ꥢȿ +}ISDB_T_TMCC; +/***************************************************************************/ +/* 塼ʾ */ +/***************************************************************************/ +extern void settuner_reset(void __iomem *, __u32, __u32); +extern int tuner_init(void __iomem *, struct mutex *, int); +extern void set_sleepmode(void __iomem *, struct mutex *, int, int, int); + +extern int bs_tune(void __iomem *, struct mutex *, int, int, ISDB_S_TMCC *); +extern int ts_lock(void __iomem *, struct mutex *, int, __u16); + +extern int isdb_t_tune(void __iomem *, struct mutex *, int, int, ISDB_T_TMCC *); +extern int isdb_t_frequency(void __iomem *, struct mutex *, int, int, int); +#endif diff -r 000000000000 -r 67e8eca28a80 driver/pt1_tuner_data.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_tuner_data.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,1080 @@ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pt1_com.h" +#include "pt1_pci.h" +#include "pt1_i2c.h" +#include "pt1_tuner.h" +#include "pt1_tuner_data.h" + +/***************************************************************************/ +/* ϥơ֥ */ +/***************************************************************************/ +/* +ISDB-Sξ + C0 C1 +:7Bit Address Mode(1b/19):17:00 +ISDB-Sξ̵(ޥ) + C0 C1 +:7Bit Address Mode(1B/19):fe:c0:f0:04 +:7Bit Address Mode(1B/19):17:01 +*/ +WBLOCK isdb_s_wake = { + 0, + 4, + {0xFE, 0xC0, 0xF0, 0x04} +}; +WBLOCK isdb_s_sleep = { + 0, + 2, + {0x17, 0x00} +}; +/* +ISDB-Tξ + C0 C1 +:7Bit Address Mode(1A/18):03:80 + +ISDB-Tξ̵(ޥ) + C0 C1 +:7Bit Address Mode(1A/18):fe:c2 +:7Bit Address Mode(1A/18):03:90 +*/ + +WBLOCK isdb_t_wake = { + 0, + 2, + {0xFE, 0xC2} +}; +WBLOCK isdb_t_sleep = { + 0, + 2, + {0x03, 0x80} +}; + +/***************************************************************************/ +/* ǡ() */ +/***************************************************************************/ +WBLOCK com_initdata = { + 0, + 2, + {0x01, 0x80} +}; + +/***************************************************************************/ +/* ǡ(ISDB-S) */ +/***************************************************************************/ +// ISDB-Sͣ +WBLOCK isdb_s_init1 ={ + 0, + 1, + {0x07} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init2 ={ + 0, + 2, + {0x04, 0x02} +}; + +// ISDB-Sͣ +WBLOCK isdb_s_init3 ={ + 0, + 2, + {0x0D, 0x55} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init4 ={ + 0, + 2, + {0x11, 0x40} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init5 ={ + 0, + 2, + {0x13, 0x80} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init6 ={ + 0, + 2, + {0x17, 0x01} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init7 ={ + 0, + 2, + {0x1C, 0x0A} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init8 ={ + 0, + 2, + {0x1D, 0xAA} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init9 ={ + 0, + 2, + {0x1E, 0x20} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init10 ={ + 0, + 2, + {0x1F, 0x88} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init11 ={ + 0, + 2, + {0x51, 0xB0} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init12 ={ + 0, + 2, + {0x52, 0x89} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init13 ={ + 0, + 2, + {0x53, 0xB3} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init14 ={ + 0, + 2, + {0x5A, 0x2D} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init15 ={ + 0, + 2, + {0x5B, 0xD3} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init16 ={ + 0, + 2, + {0x85, 0x69} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init17 ={ + 0, + 2, + {0x87, 0x04} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init18 ={ + 0, + 2, + {0x8E, 0x02} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init19 ={ + 0, + 2, + {0xA3, 0xF7} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init20 ={ + 0, + 2, + {0xA5, 0xC0} +}; +// ISDB-Sͣ +WBLOCK isdb_s_init21 ={ + 0, + 4, + {0xFE, 0xC0, 0xF0, 0x04} +}; +/***************************************************************************/ +/* ǡ(ISDB-T) */ +/***************************************************************************/ +// ISDB-Tͣ +WBLOCK isdb_t_init1 ={ + 0, + 2, + {0x03, 0x90} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init2 ={ + 0, + 2, + {0x14, 0x8F} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init3 ={ + 0, + 2, + {0x1C, 0x2A} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init4 ={ + 0, + 2, + {0x1D, 0xA8} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init5 ={ + 0, + 2, + {0x1E, 0xA2} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init6 ={ + 0, + 2, + {0x22, 0x83} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init7 ={ + 0, + 2, + {0x31, 0x0D} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init8 ={ + 0, + 2, + {0x32, 0xE0} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init9 ={ + 0, + 2, + {0x39, 0xD3} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init10 ={ + 0, + 2, + {0x3A, 0x00} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init11 ={ + 0, + 2, + {0x5C, 0x40} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init12 ={ + 0, + 2, + {0x5F, 0x80} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init13 ={ + 0, + 2, + {0x75, 0x02} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init14 ={ + 0, + 2, + {0x76, 0x4E} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init15 ={ + 0, + 2, + {0x77, 0x03} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init16 ={ + 0, + 2, + {0xEF, 0x01} +}; +// ISDB-Tͣ +WBLOCK isdb_t_init17 ={ + 0, + 7, + {0xFE, 0xC2, 0x01, 0x8F, 0xC1, 0x80, 0x80} +}; + +/***************************************************************************/ +/* ǡ֥å(ISDB-S) */ +/***************************************************************************/ +WBLOCK *isdb_s_initial[MAX_ISDB_S_INIT] = +{ + &isdb_s_init2, &isdb_s_init3, &isdb_s_init4, &isdb_s_init5, + &isdb_s_init6, &isdb_s_init7, &isdb_s_init8, &isdb_s_init9, + &isdb_s_init10, &isdb_s_init11, &isdb_s_init12, &isdb_s_init13, + &isdb_s_init14, &isdb_s_init15, &isdb_s_init16, &isdb_s_init17, + &isdb_s_init18, &isdb_s_init19, &isdb_s_init20 +}; +/***************************************************************************/ +/* ǡ֥å(ISDB-T) */ +/***************************************************************************/ +WBLOCK *isdb_t_initial[MAX_ISDB_T_INIT] = +{ + &isdb_t_init1, &isdb_t_init2, &isdb_t_init3, &isdb_t_init4, + &isdb_t_init5, &isdb_t_init6, &isdb_t_init7, &isdb_t_init8, + &isdb_t_init9, &isdb_t_init10, &isdb_t_init11, &isdb_t_init12, + &isdb_t_init13, &isdb_t_init14, &isdb_t_init15, &isdb_t_init16 +}; +/***************************************************************************/ +/* Ͼǥѥǡ */ +/***************************************************************************/ +/***************************************************************************/ +/* ȿܥơ֥ */ +/* 01: */ +/* 23: ׻ */ +/* 45: ɲ÷׻ */ +/***************************************************************************/ + +WBLOCK isdb_t_pll_base = { + 0, + 2, + {0xFE, 0xC2, 0, 0, 0, 0, 0, 0} +}; +/***************************************************************************/ +/* ϥǥȿåå */ +/***************************************************************************/ +WBLOCK isdb_t_pll_lock = { + 0, + 2, + {0xFE, 0xC3} +}; + +WBLOCK isdb_t_check_tune = { + 0, + 2, + {0x01, 0x40} +}; + +WBLOCK isdb_t_tune_read = { + 0, + 1, + {0x80} +}; +WBLOCK isdb_t_tmcc_read_1 = { + 0, + 1, + {0xB2} +}; +WBLOCK isdb_t_tmcc_read_2 = { + 0, + 1, + {0xB6} +}; +/***************************************************************************/ +/* ϥǥȿåå */ +/***************************************************************************/ +WBLOCK isdb_t_cn_1 = { + 0, + 1, + {0x8B} +}; +WBLOCK isdb_t_cn_2 = { + 0, + 1, + {0x8C} +}; +WBLOCK isdb_t_agc1 = { + 0, + 1, + {0x8D} +}; +WBLOCK isdb_t_agc2 = { + 0, + 1, + {0x82} +}; +WBLOCK isdb_t_lockedt1 = { + 0, + 1, + {0x96} +}; +WBLOCK isdb_t_lockedt2 = { + 0, + 1, + {0xB0} +}; +WBLOCK isdb_t_get_clock = { + 0, + 1, + {0x86} +}; +WBLOCK isdb_t_get_carrir = { + 0, + 1, + {0x84} +}; + +/***************************************************************************/ +/* ϥǥѥǡ */ +/***************************************************************************/ + +/***************************************************************************/ +/* £ѥǡ */ +/***************************************************************************/ +/***************************************************************************/ +/* £Ӽȿåå */ +/***************************************************************************/ +WBLOCK bs_pll_lock = { + 0, + 2, + {0xFE, 0xC1} +}; +/***************************************************************************/ +/* TMCC */ +/***************************************************************************/ +WBLOCK bs_tmcc_get_1 = { + 0, + 2, + {0x03, 0x01} +}; +WBLOCK bs_tmcc_get_2 = { + 0, + 1, + {0xC3} +}; +/***************************************************************************/ +/* TMCC */ +/***************************************************************************/ +WBLOCK bs_get_slot_ts_id_1 = { + 0, + 1, + {0xCE} +}; +WBLOCK bs_get_slot_ts_id_2 = { + 0, + 1, + {0xD2} +}; +WBLOCK bs_get_slot_ts_id_3 = { + 0, + 1, + {0xD6} +}; +WBLOCK bs_get_slot_ts_id_4 = { + 0, + 1, + {0xDA} +}; +/***************************************************************************/ +/* TS-IDå */ +/***************************************************************************/ +WBLOCK bs_set_ts_lock = { + 0, + 3, + {0x8F, 0x00, 0x00} +}; +/***************************************************************************/ +/* TS-ID */ +/***************************************************************************/ +WBLOCK bs_get_ts_lock = { + 0, + 1, + {0xE6} +}; +/***************************************************************************/ +/* åȼ */ +/***************************************************************************/ +WBLOCK bs_get_slot = { + 0, + 1, + {0xE8} +}; +/***************************************************************************/ +/* CN/AGC/MAXAGC */ +/***************************************************************************/ +WBLOCK bs_get_cn = { + 0, + 1, + {0xBC} +}; +WBLOCK bs_get_agc = { + 0, + 1, + {0xBD} +}; +WBLOCK bs_get_maxagc = { + 0, + 1, + {0xBA} +}; +/***************************************************************************/ +/* åȿ */ +/***************************************************************************/ +WBLOCK bs_get_clock = { + 0, + 1, + {0xBE} +}; +/***************************************************************************/ +/* ꥢȿ */ +/***************************************************************************/ +WBLOCK bs_get_carrir = { + 0, + 1, + {0xBB} +}; +/***************************************************************************/ +/* ȿơ֥ */ +/* £Ӥ˴ؤƤΤߡȤꤢơ֥Ȥ׻ǻнʤ */ +/* ׻ǻФ롣 */ +/***************************************************************************/ +/***************************************************************************/ +/* BS̥ơ֥ */ +/***************************************************************************/ +WBLOCK bs_com_step2 = { + 0, + 3, + {0xFE, 0xC0, 0xE4} +}; +/***************************************************************************/ +/* BS-1 */ +/***************************************************************************/ +WBLOCK bs_1_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x48, 0x29, 0xE0, 0xD2} +}; +WBLOCK bs_1_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xD6} +}; +/***************************************************************************/ +/* BS-3 */ +/***************************************************************************/ +WBLOCK bs_3_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x44, 0x40, 0xE0, 0xE2} +}; +WBLOCK bs_3_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xE6} +}; +/***************************************************************************/ +/* BS-5 */ +/***************************************************************************/ +WBLOCK bs_5_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x44, 0x66, 0xE0, 0xE2} +}; +WBLOCK bs_5_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xE6} +}; +/***************************************************************************/ +/* BS-7 */ +/***************************************************************************/ +WBLOCK bs_7_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x44, 0x8D, 0xE0, 0x20} +}; +WBLOCK bs_7_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x24} +}; +/***************************************************************************/ +/* BS-9 */ +/***************************************************************************/ +WBLOCK bs_9_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x44, 0xB3, 0xE0, 0x20} +}; +WBLOCK bs_9_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x24} +}; +/***************************************************************************/ +/* BS-11 */ +/***************************************************************************/ +WBLOCK bs_11_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x44, 0xD9, 0xE0, 0x20} +}; +WBLOCK bs_11_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x24} +}; +/***************************************************************************/ +/* BS-13 */ +/***************************************************************************/ +WBLOCK bs_13_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x45, 0x00, 0xE0, 0x20} +}; +WBLOCK bs_13_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x24} +}; +/***************************************************************************/ +/* BS-15 */ +/***************************************************************************/ +WBLOCK bs_15_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x45, 0x26, 0xE0, 0x40} +}; +WBLOCK bs_15_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x44} +}; +/***************************************************************************/ +/* BS-17 */ +/***************************************************************************/ +WBLOCK bs_17_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x45, 0x73, 0xE0, 0x40} +}; +WBLOCK bs_17_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0X44} +}; +/***************************************************************************/ +/* BS-19 */ +/***************************************************************************/ +WBLOCK bs_19_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x45, 0x73, 0xE0, 0x40} +}; +WBLOCK bs_19_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x44} +}; +/***************************************************************************/ +/* BS-21 */ +/***************************************************************************/ +WBLOCK bs_21_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x45, 0x99, 0xE0, 0x40} +}; +WBLOCK bs_21_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x44} +}; +/***************************************************************************/ +/* BS-23 */ +/***************************************************************************/ +WBLOCK bs_23_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x45, 0xBF, 0xE0, 0x60} +}; +WBLOCK bs_23_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x64} +}; + +/***************************************************************************/ +/* ND 2 */ +/***************************************************************************/ +WBLOCK nd_2_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0x4D, 0xE0, 0x60} +}; +WBLOCK nd_2_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x64} +}; + +/***************************************************************************/ +/* ND 4 */ +/***************************************************************************/ +WBLOCK nd_4_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0x75, 0xE0, 0x80} +}; +WBLOCK nd_4_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 6 */ +/***************************************************************************/ +WBLOCK nd_6_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0x9D, 0xE0, 0x80} +}; +WBLOCK nd_6_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 8 */ +/***************************************************************************/ +WBLOCK nd_8_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0xC5, 0xE0, 0x80} +}; +WBLOCK nd_8_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 10 */ +/***************************************************************************/ +WBLOCK nd_10_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0xED, 0xE0, 0x80} +}; +WBLOCK nd_10_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 12 */ +/***************************************************************************/ +WBLOCK nd_12_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x15, 0xE0, 0xA0} +}; +WBLOCK nd_12_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 14 */ +/***************************************************************************/ +WBLOCK nd_14_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x3D, 0xE0, 0xA0} +}; +WBLOCK nd_14_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 16 */ +/***************************************************************************/ +WBLOCK nd_16_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x65, 0xE0, 0xA0} +}; +WBLOCK nd_16_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 18 */ +/***************************************************************************/ +WBLOCK nd_18_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x8D, 0xE0, 0xA0} +}; +WBLOCK nd_18_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 20 */ +/***************************************************************************/ +WBLOCK nd_20_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0xB5, 0xE0, 0xC0} +}; +WBLOCK nd_20_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xC4} +}; + +/***************************************************************************/ +/* ND 22 */ +/***************************************************************************/ +WBLOCK nd_22_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0xDD, 0xE0, 0xC0} +}; +WBLOCK nd_22_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xC4} +}; + +/***************************************************************************/ +/* ND 24 */ +/***************************************************************************/ +WBLOCK nd_24_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x48, 0x05, 0xE0, 0xC0} +}; +WBLOCK nd_24_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xC4} +}; + +/***************************************************************************/ +/* ND 1 */ +/***************************************************************************/ +WBLOCK nd_1_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0x39, 0xE0, 0x60} +}; +WBLOCK nd_1_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x64} +}; + +/***************************************************************************/ +/* ND 3 */ +/***************************************************************************/ +WBLOCK nd_3_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0x61, 0xE0, 0x80} +}; +WBLOCK nd_3_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 5 */ +/***************************************************************************/ +WBLOCK nd_5_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0x89, 0xE0, 0x80} +}; +WBLOCK nd_5_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 7 */ +/***************************************************************************/ +WBLOCK nd_7_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0xB1, 0xE0, 0x80} +}; +WBLOCK nd_7_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 9 */ +/***************************************************************************/ +WBLOCK nd_9_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x46, 0xD9, 0xE0, 0x80} +}; +WBLOCK nd_9_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0x84} +}; + +/***************************************************************************/ +/* ND 11 */ +/***************************************************************************/ +WBLOCK nd_11_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x01, 0xE0, 0xA0} +}; +WBLOCK nd_11_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 13 */ +/***************************************************************************/ +WBLOCK nd_13_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x29, 0xE0, 0xA0} +}; +WBLOCK nd_13_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 15 */ +/***************************************************************************/ +WBLOCK nd_15_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x51, 0xE0, 0xA0} +}; +WBLOCK nd_15_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 17 */ +/***************************************************************************/ +WBLOCK nd_17_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0x79, 0xE0, 0xA0} +}; +WBLOCK nd_17_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 19 */ +/***************************************************************************/ +WBLOCK nd_19_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0xA1, 0xE0, 0xA0} +}; +WBLOCK nd_19_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xA4} +}; + +/***************************************************************************/ +/* ND 21 */ +/***************************************************************************/ +WBLOCK nd_21_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0xC9, 0xE0, 0xC0} +}; +WBLOCK nd_21_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xC4} +}; + +/***************************************************************************/ +/* ND 23 */ +/***************************************************************************/ +WBLOCK nd_23_step1 = { + 0, + 6, + {0xFE, 0xC0, 0x47, 0xF1, 0xE0, 0xC0} +}; +WBLOCK nd_23_step3 = { + 0, + 4, + {0xFE, 0xC0, 0xF4, 0xC4} +}; + +/***************************************************************************/ +/* BS-ȿơ֥ */ +/***************************************************************************/ +WBLOCK_BS_PLL bs_pll[MAX_BS_CHANNEL] = { + {&bs_1_step1, &bs_com_step2, &bs_1_step3}, + {&bs_3_step1, &bs_com_step2, &bs_3_step3}, + {&bs_5_step1, &bs_com_step2, &bs_5_step3}, + {&bs_7_step1, &bs_com_step2, &bs_7_step3}, + {&bs_9_step1, &bs_com_step2, &bs_9_step3}, + {&bs_11_step1, &bs_com_step2, &bs_11_step3}, + {&bs_13_step1, &bs_com_step2, &bs_13_step3}, + {&bs_15_step1, &bs_com_step2, &bs_15_step3}, + {&bs_17_step1, &bs_com_step2, &bs_17_step3}, + {&bs_19_step1, &bs_com_step2, &bs_19_step3}, + {&bs_21_step1, &bs_com_step2, &bs_21_step3}, + {&bs_23_step1, &bs_com_step2, &bs_21_step3}, + {&nd_2_step1, &bs_com_step2, &nd_2_step3}, + {&nd_4_step1, &bs_com_step2, &nd_4_step3}, + {&nd_6_step1, &bs_com_step2, &nd_6_step3}, + {&nd_8_step1, &bs_com_step2, &nd_8_step3}, + {&nd_10_step1, &bs_com_step2, &nd_10_step3}, + {&nd_12_step1, &bs_com_step2, &nd_12_step3}, + {&nd_14_step1, &bs_com_step2, &nd_14_step3}, + {&nd_16_step1, &bs_com_step2, &nd_16_step3}, + {&nd_18_step1, &bs_com_step2, &nd_18_step3}, + {&nd_20_step1, &bs_com_step2, &nd_20_step3}, + {&nd_22_step1, &bs_com_step2, &nd_22_step3}, + {&nd_24_step1, &bs_com_step2, &nd_24_step3}, + {&nd_1_step1, &bs_com_step2, &nd_1_step3}, + {&nd_3_step1, &bs_com_step2, &nd_3_step3}, + {&nd_5_step1, &bs_com_step2, &nd_5_step3}, + {&nd_7_step1, &bs_com_step2, &nd_7_step3}, + {&nd_9_step1, &bs_com_step2, &nd_9_step3}, + {&nd_11_step1, &bs_com_step2, &nd_11_step3}, + {&nd_13_step1, &bs_com_step2, &nd_13_step3}, + {&nd_15_step1, &bs_com_step2, &nd_15_step3}, + {&nd_17_step1, &bs_com_step2, &nd_17_step3}, + {&nd_19_step1, &bs_com_step2, &nd_19_step3}, + {&nd_21_step1, &bs_com_step2, &nd_21_step3}, + {&nd_23_step1, &bs_com_step2, &nd_23_step3} +}; +WBLOCK *bs_get_ts_id[(MAX_BS_TS_ID / 2)] = { + &bs_get_slot_ts_id_1, + &bs_get_slot_ts_id_2, + &bs_get_slot_ts_id_3, + &bs_get_slot_ts_id_4 +}; diff -r 000000000000 -r 67e8eca28a80 driver/pt1_tuner_data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/driver/pt1_tuner_data.h Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,76 @@ +#ifndef __PT1_TUNER_DATA_H__ +#define __PT1_TUNER_DATA_H__ +/***************************************************************************/ +/* */ +/***************************************************************************/ +#define MAX_ISDB_S_INIT 19 // ISDB-S ǡ +#define MAX_ISDB_T_INIT 16 // ISDB-S ǡ +#define MAX_BS_CHANNEL 36 // ȿơ֥ +#define MAX_ISDB_T_CHANNEL 113 // ȿơ֥(ϥǥ) +#define MAX_BS_CHANNEL_PLL_COMMAND 3 // PLLå뤿Υޥɿ +/***************************************************************************/ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/***************************************************************************/ +typedef struct _WBLOCK_BS_PLL{ + WBLOCK *wblock[MAX_BS_CHANNEL_PLL_COMMAND] ; +}WBLOCK_BS_PLL; + +/***************************************************************************/ +/* */ +/***************************************************************************/ +extern WBLOCK com_initdata; //() +extern WBLOCK isdb_s_init1; //ISDB-SƬ +extern WBLOCK isdb_s_init21; //ISDB-Sǽ +extern WBLOCK isdb_t_init17; //ISDB-Tǽ +extern WBLOCK bs_pll_lock; //ISDB-S PLLåǧ +extern WBLOCK *isdb_s_initial[MAX_ISDB_S_INIT]; +extern WBLOCK *isdb_t_initial[MAX_ISDB_T_INIT]; +/***************************************************************************/ +/* BSѥǡ */ +/***************************************************************************/ +extern WBLOCK_BS_PLL bs_pll[MAX_BS_CHANNEL] ; // ȿơ֥ +extern WBLOCK *bs_get_ts_id[(MAX_BS_TS_ID / 2)] ; // TS-IDơ֥ +extern WBLOCK bs_tmcc_get_1; // TMCCơ֥ +extern WBLOCK bs_tmcc_get_2; // TMCCơ֥ +extern WBLOCK bs_get_ts_lock; +extern WBLOCK bs_set_ts_lock; +extern WBLOCK bs_get_slot; +extern WBLOCK bs_get_clock; +extern WBLOCK bs_get_carrir; +extern WBLOCK bs_get_cn; +extern WBLOCK bs_get_agc; +extern WBLOCK bs_get_maxagc; +/***************************************************************************/ +/* ϥǥѥǡ */ +/***************************************************************************/ +extern WBLOCK isdb_t_pll_base; // ϥǥѼȿơ֥base +extern WBLOCK isdb_t_pll_lock; +extern WBLOCK_BS_PLL isdb_t_info[MAX_ISDB_T_INFO_LEN]; +extern WBLOCK isdb_t_check_tune; +extern WBLOCK isdb_t_tune_read; +extern WBLOCK isdb_t_tmcc_read_1; +extern WBLOCK isdb_t_tmcc_read_1; +extern WBLOCK isdb_t_cn_1; +extern WBLOCK isdb_t_cn_2; +extern WBLOCK isdb_t_agc_1; +extern WBLOCK isdb_t_agc_2; + +extern WBLOCK isdb_t_get_clock; +extern WBLOCK isdb_t_get_carrir; + +/***************************************************************************/ +/* ѥǡ */ +/***************************************************************************/ +extern WBLOCK isdb_s_wake; +extern WBLOCK isdb_t_wake; + +extern WBLOCK isdb_s_sleep; +extern WBLOCK isdb_t_sleep; + +extern ISDB_S_CH_TABLE isdb_t_table[11]; + +#endif diff -r 000000000000 -r 67e8eca28a80 recpt1/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/recpt1/Makefile Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,51 @@ +#!/usr/bin/make -f +# $Id: Makefile 5663 2008-09-15 17:53:59Z clworld $ + +# options +B25 = -DB25 + +ifdef B25 + B25_PATH = ../arib25v021/arib25/src + B25_CLEAN = clean_b25 +# B25_OBJS = B25Decoder.o + B25_OBJS_EXT = $(B25_PATH)/arib_std_b25.o $(B25_PATH)/b_cas_card.o $(B25_PATH)/multi2.o $(B25_PATH)/ts_section_parser.o + PCSC_LDLIBS ?= `pkg-config libpcsclite --libs` + B25_LIBS = $(PCSC_LDLIBS) -lm +endif + +DIST = . +CC = gcc +CFLAGS = -O2 -g -Wall -pthread -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(B25) -I../driver +LDFLAGS = + +OBJS = test.o $(B25_OBJS_EXT) +LIBS = -lpthread +TARGET = $(DIST)/recpt1 + +all: $(TARGET) + +clean: $(B25_CLEAN) + rm -f $(OBJS) $(TARGET) + +ifdef B25 +clean_b25: + cd $(B25_PATH); make clean +endif + +$(TARGET): $(OBJS) + $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) $(B25_LIBS) + +depend: + $(CC) -MM $(OBJS:.o=.cpp) > Makefile.dep + +# B25_OBJS_EXT +$(B25_PATH)/arib_std_b25.o: + cd $(B25_PATH); make all +$(B25_PATH)/b_cas_card.o: + cd $(B25_PATH); make all +$(B25_PATH)/multi2.o: + cd $(B25_PATH); make all +$(B25_PATH)/ts_section_parser.o: + cd $(B25_PATH); make all + +-include Makefile.dep diff -r 000000000000 -r 67e8eca28a80 recpt1/Makefile.dep diff -r 000000000000 -r 67e8eca28a80 recpt1/test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/recpt1/test.c Mon Feb 16 15:41:49 2009 +0900 @@ -0,0 +1,400 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "pt1_ioctl.h" + +char *bsdev[2] = { + "/dev/pt1video1", + "/dev/pt1video0" +}; +char *isdb_t_dev[2] = { + "/dev/pt1video2", + "/dev/pt1video3" +}; + +#define CHTYPE_SATELLITE 0 // ǥ +#define CHTYPE_GROUND 1 // Ͼǥ +#define MAX_QUEUE 8192 + +#define MAX_READ_SIZE (1024 * 16) +#define WRITE_SIZE (1024 * 1024 * 2) +#define TRUE 1 +#define FALSE 0 + +typedef struct _BUFSZ{ + int size ; + u_char buffer[MAX_READ_SIZE]; +}BUFSZ; + +typedef struct _QUEUE_T{ + unsigned int in; // 륤ǥå + unsigned int out; // ˽Фǥå + unsigned int size; // 塼Υ + unsigned int no_full; // ˤʤ 0 ˤʤ + unsigned int no_empty; // äݤˤʤ 0 ˤʤ + pthread_mutex_t mutex; + pthread_cond_t cond_full; // ǡΤȤԤĤ cond + pthread_cond_t cond_empty; // ǡΤȤԤĤ cond + BUFSZ *buffer[1]; // Хåեݥ +}QUEUE_T; + +int wfd; // ե񤭹 +int f_exit = FALSE ; + +typedef struct _ISDB_T_FREQ_CONV_TABLE { + int set_freq ; // ºݤioctl()Ԥ + int type ; // ͥ륿 + int add_freq ; // ɲäȿ(BS/CSξϥåֹ) + char *parm_freq ; // ѥ᡼Ǽ +}ISDB_T_FREQ_CONV_TABLE; + +// Ѵơ֥(ISDB-T) +#define MAX_CHANNEL_SELECT 123 +// ºݤioctl()ԤͤʬREADME򻲾Ȥλ +// BS/CSͤӥåֹ +// http://www5e.biglobe.ne.jp/~kazu_f/digital-sat/index.html +// + +ISDB_T_FREQ_CONV_TABLE isdb_t_conv_table[MAX_CHANNEL_SELECT] = { + { 0, CHTYPE_SATELLITE, 0, "151"}, // 151chBSī + { 0, CHTYPE_SATELLITE, 1, "161"}, // 161chBS-i + { 1, CHTYPE_SATELLITE, 1, "171"}, // 171chBSѥ + { 4, CHTYPE_SATELLITE, 0, "211"}, // 211chBS11ǥ + { 4, CHTYPE_SATELLITE, 2, "222"}, // 222chTwellV + { 6, CHTYPE_SATELLITE, 0, "141"}, // 141chBSƥ + { 6, CHTYPE_SATELLITE, 1, "181"}, // 181chBSե + { 7, CHTYPE_SATELLITE, 0, "101"}, // 101chNHK1(BS1) + { 7, CHTYPE_SATELLITE, 0, "102"}, // 102chNHK2(BS2) + { 7, CHTYPE_SATELLITE, 1, "103"}, // 103chNHKϥӥ(BShi) + { 0, CHTYPE_GROUND, 0, "1"}, { 1, CHTYPE_GROUND, 0, "2"}, + { 2, CHTYPE_GROUND, 0, "3"}, { 3, CHTYPE_GROUND, 0, "C13"}, + { 4, CHTYPE_GROUND, 0, "C14"}, { 5, CHTYPE_GROUND, 0, "C15"}, + { 6, CHTYPE_GROUND, 0, "C16"}, { 7, CHTYPE_GROUND, 0, "C17"}, + { 8, CHTYPE_GROUND, 0, "C18"}, { 9, CHTYPE_GROUND, 0, "C19"}, + { 10, CHTYPE_GROUND, 0, "C20"}, { 11, CHTYPE_GROUND, 0, "C21"}, + { 12, CHTYPE_GROUND, 0, "C22"}, { 13, CHTYPE_GROUND, 0, "4"}, + { 14, CHTYPE_GROUND, 0, "5"}, { 15, CHTYPE_GROUND, 0, "6"}, + { 16, CHTYPE_GROUND, 0, "7"}, { 17, CHTYPE_GROUND, 0, "8"}, + { 18, CHTYPE_GROUND, 0, "9"}, { 19, CHTYPE_GROUND, 0, "10"}, + { 20, CHTYPE_GROUND, 0, "11"}, { 21, CHTYPE_GROUND, 0, "12"}, + { 22, CHTYPE_GROUND, 0, "C23"}, { 23, CHTYPE_GROUND, 0, "C24"}, + { 24, CHTYPE_GROUND, 0, "C25"}, { 25, CHTYPE_GROUND, 0, "C26"}, + { 26, CHTYPE_GROUND, 0, "C27"}, { 27, CHTYPE_GROUND, 0, "C28"}, + { 28, CHTYPE_GROUND, 0, "C29"}, { 29, CHTYPE_GROUND, 0, "C30"}, + { 30, CHTYPE_GROUND, 0, "C31"}, { 31, CHTYPE_GROUND, 0, "C32"}, + { 32, CHTYPE_GROUND, 0, "C33"}, { 33, CHTYPE_GROUND, 0, "C34"}, + { 34, CHTYPE_GROUND, 0, "C35"}, { 35, CHTYPE_GROUND, 0, "C36"}, + { 36, CHTYPE_GROUND, 0, "C37"}, { 37, CHTYPE_GROUND, 0, "C38"}, + { 38, CHTYPE_GROUND, 0, "C39"}, { 39, CHTYPE_GROUND, 0, "C40"}, + { 40, CHTYPE_GROUND, 0, "C41"}, { 41, CHTYPE_GROUND, 0, "C42"}, + { 42, CHTYPE_GROUND, 0, "C43"}, { 43, CHTYPE_GROUND, 0, "C44"}, + { 44, CHTYPE_GROUND, 0, "C45"}, { 45, CHTYPE_GROUND, 0, "C46"}, + { 46, CHTYPE_GROUND, 0, "C47"}, { 47, CHTYPE_GROUND, 0, "C48"}, + { 48, CHTYPE_GROUND, 0, "C49"}, { 49, CHTYPE_GROUND, 0, "C50"}, + { 50, CHTYPE_GROUND, 0, "C51"}, { 51, CHTYPE_GROUND, 0, "C52"}, + { 52, CHTYPE_GROUND, 0, "C53"}, { 53, CHTYPE_GROUND, 0, "C54"}, + { 54, CHTYPE_GROUND, 0, "C55"}, { 55, CHTYPE_GROUND, 0, "C56"}, + { 56, CHTYPE_GROUND, 0, "C57"}, { 57, CHTYPE_GROUND, 0, "C58"}, + { 58, CHTYPE_GROUND, 0, "C59"}, { 59, CHTYPE_GROUND, 0, "C60"}, + { 60, CHTYPE_GROUND, 0, "C61"}, { 61, CHTYPE_GROUND, 0, "C62"}, + { 62, CHTYPE_GROUND, 0, "C63"}, { 63, CHTYPE_GROUND, 0, "13"}, + { 64, CHTYPE_GROUND, 0, "14"}, { 65, CHTYPE_GROUND, 0, "15"}, + { 66, CHTYPE_GROUND, 0, "16"}, { 67, CHTYPE_GROUND, 0, "17"}, + { 68, CHTYPE_GROUND, 0, "18"}, { 69, CHTYPE_GROUND, 0, "19"}, + { 70, CHTYPE_GROUND, 0, "20"}, { 71, CHTYPE_GROUND, 0, "21"}, + { 72, CHTYPE_GROUND, 0, "22"}, { 73, CHTYPE_GROUND, 0, "23"}, + { 74, CHTYPE_GROUND, 0, "24"}, { 75, CHTYPE_GROUND, 0, "25"}, + { 76, CHTYPE_GROUND, 0, "26"}, { 77, CHTYPE_GROUND, 0, "27"}, + { 78, CHTYPE_GROUND, 0, "28"}, { 79, CHTYPE_GROUND, 0, "29"}, + { 80, CHTYPE_GROUND, 0, "30"}, { 81, CHTYPE_GROUND, 0, "31"}, + { 82, CHTYPE_GROUND, 0, "32"}, { 83, CHTYPE_GROUND, 0, "33"}, + { 84, CHTYPE_GROUND, 0, "34"}, { 85, CHTYPE_GROUND, 0, "35"}, + { 86, CHTYPE_GROUND, 0, "36"}, { 87, CHTYPE_GROUND, 0, "37"}, + { 88, CHTYPE_GROUND, 0, "38"}, { 89, CHTYPE_GROUND, 0, "39"}, + { 90, CHTYPE_GROUND, 0, "40"}, { 91, CHTYPE_GROUND, 0, "41"}, + { 92, CHTYPE_GROUND, 0, "42"}, { 93, CHTYPE_GROUND, 0, "43"}, + { 94, CHTYPE_GROUND, 0, "44"}, { 95, CHTYPE_GROUND, 0, "45"}, + { 96, CHTYPE_GROUND, 0, "46"}, { 97, CHTYPE_GROUND, 0, "47"}, + { 98, CHTYPE_GROUND, 0, "48"}, { 99, CHTYPE_GROUND, 0, "49"}, + { 100, CHTYPE_GROUND, 0, "50"}, { 101, CHTYPE_GROUND, 0, "51"}, + { 102, CHTYPE_GROUND, 0, "52"}, { 103, CHTYPE_GROUND, 0, "53"}, + { 104, CHTYPE_GROUND, 0, "54"}, { 105, CHTYPE_GROUND, 0, "55"}, + { 106, CHTYPE_GROUND, 0, "56"}, { 107, CHTYPE_GROUND, 0, "57"}, + { 108, CHTYPE_GROUND, 0, "58"}, { 109, CHTYPE_GROUND, 0, "59"}, + { 110, CHTYPE_GROUND, 0, "60"}, { 111, CHTYPE_GROUND, 0, "61"}, + { 112, CHTYPE_GROUND, 0, "62"} +}; + +// ȿơ֥Ѵ +ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel) +{ + int lp ; + + for(lp = 0 ; lp < 113 ; lp++){ + // ʸĹפȿơֵֹ֥Ѥ + if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, strlen(channel)) == 0) && + (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){ + return &isdb_t_conv_table[lp] ; + } + } + return NULL ; +} + +QUEUE_T* create_queue(size_t size) +{ + QUEUE_T* p_queue; + int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ)); + + p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); + + if(p_queue != NULL){ + p_queue->size = size; + p_queue->no_full = size; + p_queue->no_empty = 0; + pthread_mutex_init(&p_queue->mutex, NULL); + pthread_cond_init(&p_queue->cond_full, NULL); + pthread_cond_init(&p_queue->cond_empty, NULL); + } + + return p_queue; +} + +void destroy_queue(QUEUE_T *p_queue) +{ + if(p_queue != NULL){ + pthread_mutex_destroy(&p_queue->mutex); + pthread_cond_destroy(&p_queue->cond_full); + pthread_cond_destroy(&p_queue->cond_empty); + free(p_queue); + } +} + +// ؿ̾: enqueue +// 塼˥ǡ +// ǡʾϡ֥åޤ +void enqueue(QUEUE_T *p_queue, BUFSZ *data) +{ + pthread_mutex_lock(&p_queue->mutex); + // -- 顢ƥ륻 -- + + // 󤸤ʤʤޤԤ + while(!p_queue->no_full) { + pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); + printf("Full\n"); + } + + p_queue->buffer[p_queue->in] = data; + + p_queue->in++; + p_queue->in %= p_queue->size; + + p_queue->no_full--; + p_queue->no_empty++; + + pthread_mutex_unlock(&p_queue->mutex); + pthread_cond_signal(&p_queue->cond_empty); +} + +// ؿ̾: dequeue +// 塼˥ǡ +// ǡʾϡ֥åޤ +BUFSZ *dequeue(QUEUE_T *p_queue) +{ + void *result; + + pthread_mutex_lock(&p_queue->mutex); + // -- 顢ƥ륻 -- + + // äݤʤʤޤԤ + while (!p_queue->no_empty) { + pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); + } + + // ǡФ + result = p_queue->buffer[p_queue->out]; + + // ˥ǡФ򥤥󥯥 + p_queue->out++; + p_queue->out %= p_queue->size; + + // ե饰ι + p_queue->no_full++; + p_queue->no_empty--; + + // -- ޤǡƥ륻 -- + pthread_mutex_unlock(&p_queue->mutex); + pthread_cond_signal(&p_queue->cond_full); + + return result; +} + + +void *write_func(void *p) +{ + QUEUE_T *p_queue = (QUEUE_T*)p; + int size = 0 ; + BUFSZ *ptr ; +#if 0 + u_char *buffer ; + + buffer = calloc(WRITE_SIZE, sizeof(char)); + if(buffer == NULL){ + return NULL ; + } +#endif + + while(1){ + ptr = dequeue(p_queue); + if(ptr == NULL){ + close(wfd); + break ; + } +#if 0 + if((size + ptr->size) < WRITE_SIZE){ + memcpy((buffer + size) , ptr->buffer, ptr->size); + size += ptr->size ; + }else{ + write(wfd, buffer, size); + size = ptr->size ; + } +#endif + write(wfd, ptr->buffer, ptr->size); + free(ptr); + if((f_exit) && (!p_queue->no_empty)){ +#if 0 + if(size){ + write(wfd, buffer, size); + } +#endif + close(wfd); + break ; + } + } + return NULL; +} + +int main(int argc, char **argv) +{ + int fd ; + int rc ; + int lp ; + int channel ; + int recsec ; + time_t start_time ; + time_t cur_time ; + FREQUENCY freq; + ISDB_T_FREQ_CONV_TABLE *ptr ; + pthread_t dequeue_threads; + QUEUE_T *p_queue = create_queue(MAX_QUEUE); + BUFSZ *bufptr ; + + if(argc < 4){ + printf("Usage %s: channel recsec destfile\n", argv[0]); + printf("channel =\n"); + printf("151chBSī\n"); + printf("161chBS-i\n"); + printf("171chBSѥ\n"); + printf("211chBS11ǥ\n"); + printf("222chTwellV\n"); + printf("141chBSƥ\n"); + printf("181chBSե\n"); + printf("101chNHK1(BS1)\n"); + printf("102chNHK2(BS2)\n"); + printf("103chNHKϥӥ(BShi)\n"); + return 1; + } + ptr = searchrecoff(argv[1]); + if(ptr == NULL){ + printf("Channel Select Error(%s)\n", argv[1]); + return 1 ; + } + + freq.frequencyno = ptr->set_freq ; + freq.slot = ptr->add_freq ; + + if(ptr->type == CHTYPE_SATELLITE){ + for(lp = 0 ; lp < 2 ; lp++){ + fd = open(bsdev[lp], O_RDONLY); + if(fd >= 0){ + break ; + } + } + if(fd < 0){ + printf("Device Open Error\n"); + return 1; + } + }else{ + for(lp = 0 ; lp < 2 ; lp++){ + fd = open(isdb_t_dev[lp], O_RDONLY); + if(fd >= 0){ + break ; + } + } + if(fd < 0){ + printf("Device Open Error\n"); + return 1; + } + } + recsec = atoi(argv[2]); + + wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); + if(wfd < 0){ + printf("Output File Open Error(%s)\n", argv[3]); + return 0; + } + + if(ioctl(fd, SET_CHANNEL, &freq) < 0){ + printf("Tuner Select Error\n"); + return 0 ; + } + pthread_create(&dequeue_threads, NULL, write_func, p_queue); + if(ioctl(fd, START_REC, 0) < 0){ + printf("Tuner Start Error\n"); + return 0 ; + } + + time(&start_time); + while(1){ + time(&cur_time); + bufptr = calloc(1, sizeof(BUFSZ)); + bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); + if(bufptr->size <= 0){ + if((cur_time - start_time) >= recsec){ + f_exit = TRUE ; + enqueue(p_queue, NULL); + break ; + }else{ + continue ; + } + } + enqueue(p_queue, bufptr); + + if((cur_time - start_time) >= recsec){ + ioctl(fd, STOP_REC, 0); + //ʤʤޤǥǡɤ߽Ф + while(1){ + bufptr = calloc(1, sizeof(BUFSZ)); + bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); + if(bufptr->size <= 0){ + f_exit = TRUE ; + enqueue(p_queue, NULL); + break ; + } + enqueue(p_queue, bufptr); + } + break ; + } + } + close(fd); + pthread_join(dequeue_threads, NULL); + destroy_queue(p_queue); + return 0 ; +}