...
- マイコン
- Raspberry Pi(モデルは何でもOK)
- Raspberry Piでi2cを使えるように設定しておくこと。(raspi-configで可能)
- i2c-toolsを入れておくこと。
- Raspberry Pi(モデルは何でもOK)
- SFPスロット
Cisco TwinGig Converter CVR-X2-SFP
これらを以下のように接続する。プルアップ抵抗はCVR-X2-SFPに内蔵されているため直結でOK!I
以下書きかけ
接続の確認
上記手順の通りSFPスロットとRaspberry Piを接続した後、電源を起動し、SFPスロットにSFPを挿入する。以下のコマンドで、SFPが正しく認識されることを確認する。
コード ブロック | ||
---|---|---|
| ||
$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- |
正しく認識されていると、上記のように0x50番地に何かが接続されていると表示される。0x51については前述の通りDDM用であるが、デバイスによっては表示されないこともある(1000BASE-TのSFPや中華製の安物等)。
データの吸い出し
SFPが正しく認識されていることを確認できたら、続いてデータの吸い出しを行う。I2C EEPROMは非常に単純なプロトコルなので、以下のコマンドで容易に吸い出しが可能である。
コード ブロック | ||
---|---|---|
| ||
$ sudo i2cdump -y 1 0x50
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 03 04 07 00 00 00 01 20 40 0c 01 01 0c 00 00 00 ???...? @????...
10: 37 1e 00 00 46 49 4e 49 53 41 52 20 43 4f 52 50 7?..FINISAR CORP
20: 2e 20 20 20 00 00 90 65 46 54 52 4a 2d 38 35 31 . ..?eFTRJ-851
30: 39 2d 37 44 2d 4a 55 4e 00 00 00 00 03 52 00 12 9-7D-JUN....?R.?
40: 00 12 00 00 48 35 46 30 51 30 35 20 20 20 20 20 .?..H5F0Q05
50: 20 20 20 20 30 34 30 34 31 39 20 20 68 10 00 c5 040419 h?.?
60: 37 34 30 2d 30 30 37 33 32 36 20 52 45 56 20 30 740-007326 REV 0
70: 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1...............
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ |
さて、吸い出したこのデータ、そのままでは読みにくいのでHuman-readableな形に変換したいところであるが、手で行うのは非常に面倒である。
そこで作成したParserがあるので、こちらを使ってみると、以下のようになる。このプログラムにはI2Cの読込/書込のプログラムも含まれているため、もはやi2ctoolsは用済みである。
コード ブロック | ||
---|---|---|
| ||
$ cd ruby-libsfp/examples
$ ruby read.rb
raw data:
0304070000000120400c01010c000000371e000046494e4953415220434f52502e202020000090654654524a2d383531392d37442d4a554e000000000352001200120000483546305130352020202020202020203034303431392020681000c53734302d30303733323620524556203031000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
#<SFP::EEPROM:0x6504f0
@br=:BR_1200M,
@br_max=0,
@br_min=0,
@cc_base=18,
@cc_ext=197,
@connector=:LC,
@date_code="040419",
@diagnostic_monitoring_type=
[:DDM, :INTERNAL_CALIBRATED, :RECEIVED_POWER_MEASUREMENT_AVERAGE],
@encoding=:ENC_8B10B,
@enhanced_options=[:SOFT_RX_LOS],
@ext_identifier=4,
@identifier=:SFP,
@length_copper=0,
@length_mm500_10m=55,
@length_mm500_om3_10m=0,
@length_mm625_10m=30,
@length_sm_100m=0,
@length_sm_km=0,
@options=[:TX_DISABLE, :LOSS_OF_SIGNAL],
@rate_identifier=0,
@sff_8472_compliance=0,
@transciever=
[:GE_SX, :FC_LINK_I, :FC_TXT_SN, :FC_TXM_M6, :FC_TXM_M5, :FC_SPEED_100M],
@transciever2=0,
@used_for_dwdm_modules=0,
@vendor_name="FINISAR CORP.",
@vendor_oui=[0, 144, 101],
@vendor_pn="FTRJ-8519-7D-JUN",
@vendor_rev="",
@vendor_sn="H5F0Q05",
@vendor_specific=
"740-007326 REV 01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
@wavelength=850>
Base CC is valid? : false
Ext CC is valid? : true
Expected Base CC: 146
Expected Ext CC: 197 |
非常に読みすい(?)ですね。
raw data: 0304...というところが生データになるので、ここはバックアップしておきましょう。
書き換え
さて、読み込んだならば書き換えねばなるまい。ということで、実際に書き換えてみましょう。
irbで上記のライブラリを読み込み、OUIとベンダ名を書き換えてみます。
新しいベンダ名は"JITAKURACK", OUIはC0-A8-FE(192, 168, 254)とします。特に意味は無いです。
コード ブロック | ||
---|---|---|
| ||
$ cd ruby-libsfp
$ irb
# ライブラリの読み込み
irb(main):001:0> require './lib/sfp/rw.rb'
=> true
irb(main):002:0> require './lib/sfp/eeprom.rb'
=> true
# SFP R/Wライブラリの初期化
irb(main):003:0> rw = SFP::RW.new
=> #<SFP::RW:0xca85a0 @path="/dev/i2c-1", @addr=80>
# SFP R/Wで読み込んだ情報を元にSFP EEPROMライブラリのインスタンスを生成
irb(main):004:0> sfp = SFP::EEPROM.new(rw.read)
=> #<SFP::EEPROM:0xf92328 @identifier=:SFP, @ext_identifier=4, @connector=:LC, @transciever=[:GE_SX, :FC_LINK_I, :FC_TXT_SN, :FC_TXM_M6, :FC_TXM_M5, :FC_SPEED_100M], @encoding=:ENC_8B10B, @br=:BR_1200M, @rate_identifier=0, @length_sm_km=0, @length_sm_100m=0, @length_mm500_10m=55, @length_mm625_10m=30, @length_copper=0, @length_mm500_om3_10m=0, @vendor_name="FINISAR CORP.", @transciever2=0, @vendor_oui=[0, 144, 101], @vendor_pn="FTRJ-8519-7D-JUN", @vendor_rev="", @wavelength=850, @used_for_dwdm_modules=0, @options=[:TX_DISABLE, :LOSS_OF_SIGNAL], @br_max=0, @br_min=0, @vendor_sn="H5F0Q05", @date_code="040419", @diagnostic_monitoring_type=[:DDM, :INTERNAL_CALIBRATED, :RECEIVED_POWER_MEASUREMENT_AVERAGE], @enhanced_options=[:SOFT_RX_LOS], @sff_8472_compliance=0, @vendor_specific="740-007326 REV 01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", @cc_base=18, @cc_ext=197>
# オリジナルのベンダ名とOUIを確認
irb(main):005:0> sfp.vendor_name
=> "FINISAR CORP."
irb(main):006:0> sfp.vendor_oui
=> [0, 144, 101]
# ベンダ名とOUIの書き換え
irb(main):007:0> sfp.vendor_name = "JITAKURACK"
=> "JITAKURACK"
irb(main):008:0> sfp.vendor_oui = [ 0xC0, 0xA8, 0xFE ]
=> [192, 168, 254]
# 書き換え後の情報確認
irb(main):009:0> sfp
=> #<SFP::EEPROM:0xf92328 @identifier=:SFP, @ext_identifier=4, @connector=:LC, @transciever=[:GE_SX, :FC_LINK_I, :FC_TXT_SN, :FC_TXM_M6, :FC_TXM_M5, :FC_SPEED_100M], @encoding=:ENC_8B10B, @br=:BR_1200M, @rate_identifier=0, @length_sm_km=0, @length_sm_100m=0, @length_mm500_10m=55, @length_mm625_10m=30, @length_copper=0, @length_mm500_om3_10m=0, @vendor_name="JITAKURACK", @transciever2=0, @vendor_oui=[192, 168, 254], @vendor_pn="FTRJ-8519-7D-JUN", @vendor_rev="", @wavelength=850, @used_for_dwdm_modules=0, @options=[:TX_DISABLE, :LOSS_OF_SIGNAL], @br_max=0, @br_min=0, @vendor_sn="H5F0Q05", @date_code="040419", @diagnostic_monitoring_type=[:DDM, :INTERNAL_CALIBRATED, :RECEIVED_POWER_MEASUREMENT_AVERAGE], @enhanced_options=[:SOFT_RX_LOS], @sff_8472_compliance=0, @vendor_specific="740-007326 REV 01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", @cc_base=18, @cc_ext=197>
# 書き換え後のデータをSFPに書き込み
irb(main):010:0> rw.write(sfp.to_hex)
=> 9
# 比較用に再度SFPの情報を読み込み
irb(main):011:0> sfp2 = SFP::EEPROM.new(rw.read)
=> #<SFP::EEPROM:0xf41fb8 @identifier=:SFP, @ext_identifier=4, @connector=:LC, @transciever=[:GE_SX, :FC_LINK_I, :FC_TXT_SN, :FC_TXM_M6, :FC_TXM_M5, :FC_SPEED_100M], @encoding=:ENC_8B10B, @br=:BR_1200M, @rate_identifier=0, @length_sm_km=0, @length_sm_100m=0, @length_mm500_10m=55, @length_mm625_10m=30, @length_copper=0, @length_mm500_om3_10m=0, @vendor_name="JITAKURACK", @transciever2=0, @vendor_oui=[192, 168, 254], @vendor_pn="FTRJ-8519-7D-JUN", @vendor_rev="", @wavelength=850, @used_for_dwdm_modules=0, @options=[:TX_DISABLE, :LOSS_OF_SIGNAL], @br_max=0, @br_min=0, @vendor_sn="H5F0Q05", @date_code="040419", @diagnostic_monitoring_type=[:DDM, :INTERNAL_CALIBRATED, :RECEIVED_POWER_MEASUREMENT_AVERAGE], @enhanced_options=[:SOFT_RX_LOS], @sff_8472_compliance=0, @vendor_specific="740-007326 REV 01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", @cc_base=190, @cc_ext=197>
# 作成したデータとSFPのEEPROMの内容が一致していることを確認
irb(main):012:0> sfp.to_hex == sfp2.to_hex
=> true
irb(main):013:0> |
こんな感じです。ライブラリの使い方はexamples/以下のファイルを見ていただけると大体分かるかと思います。
それでは、Let's enjoy hack life!