fl2kでgps-sdr-sim

osmo-fl2kで生成したGPS信号の周波数補正

osmo-fl2kには、fl2k_testコマンドが用意されていて、実行すると10秒間隔でPPMエラーを表示します。

$ fl2k_test
Kernel mass storage driver is attached, detaching driver. This may take more than 10 seconds!
Reporting PPM error measurement every 10 seconds...
Press ^C after a few minutes.
real sample rate: 99647567 current PPM: -3524 cumulative PPM: -3524
real sample rate: 99909730 current PPM: -903 cumulative PPM: -2187
real sample rate: 99976679 current PPM: -233 cumulative PPM: -1527
real sample rate: 99994151 current PPM: -58 cumulative PPM: -1156
real sample rate: 100001137 current PPM: 11 cumulative PPM: -921
real sample rate: 100003392 current PPM: 34 cumulative PPM: -761
real sample rate: 100007238 current PPM: 72 cumulative PPM: -641


これは、USB-VGAデバイスを接続した直後の実行例ですが、かなり変動しています。しばらくして試すと、次のように安定してきます。(ただし、CPUの負荷による影響もあるようなので、テスト中は、負荷の重いプロセスの起動は避けたほうがよさそう、、、)

$ fl2k_test
Reporting PPM error measurement every 10 seconds...
Press ^C after a few minutes.
real sample rate: 100006806 current PPM: 68 cumulative PPM: 68
real sample rate: 100006831 current PPM: 68 cumulative PPM: 68
real sample rate: 100007186 current PPM: 72 cumulative PPM: 69
real sample rate: 100005995 current PPM: 60 cumulative PPM: 67

この値を(平均値など)、フローグラフの変数 ID:ppmへセットし、ID:out_rateに表示される(この例では138.01e6)を fl2k_fileで送信する際のサンプルング周波数にセットしたところ、GSP受信機でfixできました。

$fl2k_file -s 138.01e6  ファイル名
安定度などの問題があるかもしれませんが、GPS-SDR-SIMとUSB-VGAアダプタの組み合わせで、超安価なGPS信号シミュレータが実現できそうです。

実行中の動画

osmo-fl2kの実験メモ

2018年04月24日21:58カテゴリSDR

RTL-SDR.COMで紹介されていたosmo-fl2kを試してみました。

基本波としてHF~約157MHzまでの周波数を生成することができ、その高調波でさらに1.7GHz程度まで利用できるらしい、、、
osmo-fl2kのWikiはこちら:SDR (Software Defined Radio) osmo-fl2k
https://osmocom.org/projects/osmo-fl2k/wiki

Patech USB3.0 to VGA変換アダプター ビデオグラフィックカード。アマゾンで1780円で購入。

VGAコネクタの①端子へアンテナ用の短いリード線を接続

実験環境
VirtualBOX内のUbuntu16.04で実験(ホストWindows10)
仮想マシンのUSBデバイスとして接続すると、不明なデバイスDevice 002: ID 1d5c:2000 として検出される。

$ lsusb
Bus 002 Device 002: ID 1d5c:2000

次の手順でosmo-fl2kをインストール

$ git clone git://git.osmocom.org/osmo-fl2k
$ cd osmo-fl2k/
$ mkdir build
$ cd build
$ cmake .. -DINSTALL_UDEV_RULES=ON
$ make
$ sudo make install

デバイス名の確認

$ pacmd list-sources | grep name | grep monitor
name:

この時に、permission errorなどとなったら、インストールしたユーザのディレクトリのパーミッションをチェックし、必要に応じて次を実行(ユーザ名 user1の場合)
 $sudo chown  -R user1:user1 /home/user1

サンプルのWBFM信号の生成に必要なpv, soxをインストール

$ sudo apt install pv sox

WBFM信号生成のテスト;
例えばRhymbox(ミュージックプレイヤー)などで音楽を再生すると、その音声で変調された信号が生成される。簡単なshell scriptを作る

$ cat start.sh #!/bin/bashpacat -r -d alsa_output.pci-0000_00_05.0.analog-stereo.monitor | \pv -B 256k | \sox -t raw -r 44100 -e signed-integer -L -b 16 -c 2 - -c 1 -e signed-integer -b 16 -t raw - \biquad 4.76963 -2.98129 0 1 0.78833 0 sinc -15k loudness 5 | \fl2k_fm - -s 130e6 -c 35e6 -i 44100

$ ./start.sh./start.sh Samplerate: 130.00 MHzCarrier: 35.00 MHzFrequencies: 95.00 MHz, 165.00 MHz

この例ではキャリアー周波数を -c 35e6(=35MHz)としているが、試してみると多数の他の周波数でも受信できてしまう。スプリアスが多いようなので実験には注意が必要。(アンテナは5cm程度のリード線で十分)
スペクトラムを観測した動画 (youtube)

VirtualBOXの中で実験している影響のせいか、他のプロセスの起動や操作を行うと、buffer underrunが
発生することがあり、buffer underrunが発生すると信号の生成が停止するようだ。

 wavファイルがあれば、次のように実行するこもできる。


$ fl2k_fm strings.wavSamplerate:     100.00 MHzCarrier:        97.00 MHzFrequencies:    3.00 MHz, 197.00 MHz


他に用意されているコマンドのhelpを表示

$ fl2k_test -helpfl2k_test, clock accuracy test for FL2K VGA dongles,also outputs a square wave at fs/2
Usage: [-d device_index (default: 0)] [-s samplerate (default: 100 MS/s)]
$ fl2k_fm --fl2k_fm, an FM modulator for FL2K VGA dongles
Usage: [-d device index (default: 0)] [-c carrier frequency (default: 9.7 MHz)] [-f FM deviation (default: 75000 Hz, WBFM)] [-i input audio sample rate (default: 44100 Hz for mono FM)] [-s samplerate in Hz (default: 100 MS/s)] filename (use '-' to read from stdin)
$ fl2k_file --fl2k_file, a sample player for FL2K VGA dongles
Usage: [-d device_index (default: 0)] [-r repeat file (default: 1)] [-s samplerate (default: 100 MS/s)] filename (use '-' to read from stdin)


fl2k_file コマンドを利用してGPS信号なども生成できるようなので試してみたが、周波数がずれてしまう。 (https://youtu.be/Xh6Xl3mB0c8)

無線でAirGapを超える

無線でAirGapを超える実験(その1 Raspberry Pi)

イスラエスのベン・グリオン大学の研究チームが様々な手段でAirGapを超える実験を発表していて、これまでに、電波、音波、熱などの例が紹介されています。
かねてから、ネタの一つとして無線で実験してみたいと思っていたのですが、最近になってようやく実験を開始しました。

最初は、GPIOを備え、敷居が低そうなRaspberry Piで実験を試みました。RaspberrPiでは、FM変調で音楽などを流す試みが発表されています。手始めに、これを実験してみましたが、githubからダウンロードして、簡単に再現することができました。このソフトはあらかじめ用意したwavファイルの音楽を流したり、マイクロフォンやLINE入力からのオーディオ信号をFM変調で送信できるようになっています。調べてみると、RaspberryPiには3個のGPCLKポートが備わっていて、このポートから、内蔵のクロックを基にしてプログラマブルに周波数を設定可能なハードウェアとなっています。

GPCLK General Purpose CLock https://pinout.xyz/pinout/gpclk

GPIO端子に出力される信号は、基本的には矩形波なので、RF信号の振幅が変化するような変調は、外部のハードウェアなしには実装できません。FM電波とした理由も、そこにあるものと思われます。プログラマブルにクロックを設定できる仕組みを利用し、GPCLK端子へ出力する周波数をうまく制御してFM変調を実現しているようです。クロック生成の詳細は、この記事などが参考になります

RaspberryPiのFM送信機のソフトを利用してデジタルデータを送信するには、データからQPSKなどの信号を音声データとして生成し、wavファイルに落として変調用のファイルとすれば、比較的簡単に実現できそうな気がします(APSK変調)。もっと安直な方法として、GPCLK端子から、あるの周波数の信号を断続して出力すれば、搬送波の断続による原始的なCW変調が実現できそうなので、こちらの方式で実験をしてみました。クロックの生成で、参考にた記事は、こちらの Miscellaneous related code セクションにあるMinimal Clock Accessのコードです。

クロックの制御部分だけをC言語で記述し、残りの部分は、これまた安直にPHPで記述しています。

無線でAirGapを超える実験(その2 Windows10 RS-232CポートのON/OFF)

PCには、Raspberry Piと違ってGPIOのような物理的にアクセス可能なデバイスは用意されていない。そこで、最近のPCの標準装備からはほとんど姿を消したものの、RS232C(特に法人向けのPCには、数年前まで、標準装備されていたように記憶していますが、、、?)ポートには、ハードウェアによるフロー制御に利用可能なRTS端子があることを思い出した。

この端子を、高速でON/OFFすることで、電波として放射できないか、実験をしてみた。RTS端子をオシロで観測した様子。46KHz程度で、周期がかなり変動している。

電波のスペクトラムを観測した様子のyoutube動画はこちら https://youtu.be/YtIuUOOOiLs
動画の左側は、Raspberry Pi3のGPIO端子をソフトウエアでOn/Offした時のスペクトラム波形。右側がPCのRS-232C端子をOn/Offした際の、スペクトラム波形。WindowsではOn/Off周期の変動が大きく、スペクトラムが大きく広がっている。

プログラム例


#include
#include
int main()
{
HANDLE hComm;
int Status;
int n;
unsigned clockDivisor = 0;
hComm = CreateFile(“COM1”, //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write
0, // No Sharing
NULL, // No Security
OPEN_EXISTING,// Open existing port only
0, // Non Overlapped I/O
NULL); // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
printf(“Error in opening serial port”);
else {
printf(“opening serial port successful”);
for(n=0;n<100000;n++){  // ここのループでRF信号を放射 Status = EscapeCommFunction(hComm, SETRTS); // RTS ON Status = EscapeCommFunction(hComm, CLRRTS); // RTS OFF } printf("Done...\n"); uSleep(5000000); } CloseHandle(hComm);//Closing the Serial Port return 0; }

無線でAirGapを超える実験(その1 Raspberry Pi)

イスラエスのベン・グリオン大学の研究チームが様々な手段でAirGapを超える実験を発表していて、これまでに、電波、音波、熱などの例が紹介されています。
かねてから、ネタの一つとして無線で実験してみたいと思っていたのですが、最近になってようやく実験を開始しました。
最初は、GPIOを備え、敷居が低そうなRaspberry Piで実験を試みました。RaspberrPiでは、FM変調で音楽などを流す試みが発表されています。手始めに、これを実験してみましたが、githubからダウンロードして、簡単に再現することができました。このソフトはあらかじめ用意したwavファイルの音楽を流したり、マイクロフォンやLINE入力からのオーディオ信号をFM変調で送信できるようになっています。調べてみると、RaspberryPiには3個のGPCLKポートが備わっていて、このポートから、内蔵のクロックを基にしてプログラマブルに周波数を設定可能なハードウェアとなっています。

GPCLK General Purpose CLock https://pinout.xyz/pinout/gpclk
GPIO端子に出力される信号は、基本的には矩形波なので、RF信号の振幅が変化するような変調は、外部のハードウェアなしには実装できません。FM電波とした理由も、そこにあるものと思われます。プログラマブルにクロックを設定できる仕組みを利用し、GPCLK端子へ出力する周波数をうまく制御してFM変調を実現しているようです。クロック生成の詳細は、この記事などが参考になります
RaspberryPiのFM送信機のソフトを利用してデジタルデータを送信するには、データからQPSKなどの信号を音声データとして生成し、wavファイルに落として変調用のファイルとすれば、比較的簡単に実現できそうな気がします(APSK変調)。もっと安直な方法として、GPCLK端子から、あるの周波数の信号を断続して出力すれば、搬送波の断続による原始的なCW変調が実現できそうなので、こちらの方式で実験をしてみました。クロックの生成で、参考にた記事は、こちらの Miscellaneous related code セクションにあるMinimal Clock Accessのコードです。

クロックの制御部分だけをC言語で記述し、残りの部分は、これまた安直にPHPで記述しています。

無線でAirGapを超える

(その2 Windows10 RS-232CポートのON/OFF)

PCには、Raspberry Piと違ってGPIOのような物理的にアクセス可能なデバイスは用意されていない。そこで、最近のPCの標準装備からはほとんど姿を消したものの、RS232C(特に法人向けのPCには、数年前まで、標準装備されていたように記憶していますが、、、?)ポートには、ハードウェアによるフロー制御に利用可能なRTS端子があることを思い出した。

この端子を、高速でON/OFFすることで、電波として放射できないか、実験をしてみた。RTS端子をオシロで観測した様子。46KHz程度で、周期がかなり変動している。

動画の左側は、Raspberry Pi3のGPIO端子をソフトウエアでOn/Offした時のスペクトラム波形。右側がPCのRS-232C端子をOn/Offした際の、スペクトラム波形。WindowsではOn/Off周期の変動が大きく、スペクトラムが大きく広がっている。

プログラム例


#include <windows.h>
#include<stdio.h>
int main()
{
  HANDLE hComm;
  int Status;
  int n;
  unsigned clockDivisor = 0;
  hComm = CreateFile("COM1",                //port name
                      GENERIC_READ | GENERIC_WRITE, //Read/Write
                      0,                            // No Sharing
                      NULL,                         // No Security
                      OPEN_EXISTING,// Open existing port only
                      0,            // Non Overlapped I/O
                      NULL);        // Null for Comm Devices
  if (hComm == INVALID_HANDLE_VALUE)
      printf("Error in opening serial port");
  else {
      printf("opening serial port successful");
      for(n=0;n<100000;n++){                         // ここのループでRF信号を放射
     	Status = EscapeCommFunction(hComm, SETRTS);  // RTS ON
      	Status = EscapeCommFunction(hComm, CLRRTS);  // RTS OFF
      }
      printf("Done...\n");
      uSleep(5000000);
      }
  CloseHandle(hComm);//Closing the Serial Port
  return 0;
}

LANのパケット監視

WannaCryは、LANの中ではsmb(445/TCP)で感染するということなので、簡易な監視のツールを作ってみました。
ミラーしたセグメントのパケットをtcpdumpでキャプチャし、PHPのスクリプトで観測したパケットの数を可視化します。
使い方は、次のような感じ、、、
#tcpdump -ntttti eth0 port 445 | visualize.php
visualize.php は、定期的にhtmlファイルを生成ます
利用者はブラウザでhtmlファイルを閲覧します。
htmlファイルは (例えば10秒毎に)自身をrefreshします。
表示される、画像の1マスは、ノード(PCやサーバ)間のパケット数を色で表現しています。
通信がまったく観測されない場合は濃い青色で観測されたパケット数が多いと黄色~赤に変化します。
また、マスの中の1文字は、観測したパケットの数に応じて、0-9,A-Z…..と表示しています。


#!/usr/bin/php
$MIN_TH) {
MkHTML($buf,$date);
$prev_min = $min;
}
}
fclose($fp);
MkHTML($buf,$date);
echo “Finished!!!\n”;
function MkHTML($buf,$date){
$date=”

$date

“;
$header=”“;
$msg=”

$date

\n\n”;
for($i=1;$i<255;$i++){ $sum=0; for($j=1;$j<255;$j++){ $sum+=$buf[$j][$i]; } $iSum[$i]=$sum; // echo "$i,$iSum[$i]\n"; } for($i=1;$i<255;$i++){ $tmp="“;$sum=0;
for($j=1;$j<255;$j++){ $var=$buf[$i][$j]; $pt="."; if($var<63) { if($var<10) { $pt=$var; } else { $pt=chr(ord('A')+$var-10); } } $sum+=$var; $var=20*log($var+1); $color=set_color($var); if($iSum[$j]!=0) $tmp.= "“;
}
if($sum !=0 ) {
$msg.=$tmp;
$msg.=”\n”;
}
}
$msg.=”
$i10.8.0.$j\”>$pt
\n

$date

\n”;
$fw=fopen(“/var/www/html/cross.html”,”w”);
fputs($fw,$header);
fputs($fw,$msg);
fclose($fw);
}
function set_color($x){
if ($x<64) { $r=0; $g= $x*4 ; $b=255; } else { if ($x<128){ $r=4*( $x -64 );$g=255;$b=255-$r; } else { if ($x<192){ $b=4*( $x - 128 );$r=255;$g=255-$b; } else { $r=255;$g=0;$b=255-4*( $x -192); } } } return "#".sprintf("%02x%02x%02x",$r,$g,$b); } ?>

LANのパケット監視

WannaCryは、LANの中ではsmb(445/TCP)で感染するということなので、簡易な監視のツールを作ってみました。
ミラーしたセグメントのパケットをtcpdumpでキャプチャし、PHPのスクリプトで観測したパケットの数を可視化します。
使い方は、次のような感じ、、、

#tcpdump -ntttti eth0 port 445 | visualize.php

visualize.php は、定期的にhtmlファイルを生成ます
利用者はブラウザでhtmlファイルを閲覧します。
htmlファイルは (例えば10秒毎に)自身をrefreshします。

表示される、画像の1マスは、ノード(PCやサーバ)間のパケット数を色で表現しています。
通信がまったく観測されない場合は濃い青色で観測されたパケット数が多いと黄色~赤に変化します。
また、マスの中の1文字は、観測したパケットの数に応じて、0-9,A-Z…..と表示しています。

#!/usr/bin/php
<?php
/*
        Usage:
        tcpdump -nttttr xxxxx.pcap port 445 | ./p445.php
*/

$MIN_TH = 5;
$fp=fopen("php://stdin","r");
for($i=1;$i<255;$i++){
        for($j=1;$j<255;$j++){
                $buf[$i][$j]=0;
        }
}
$n=0;$prev_min=0;
while($in=fgets($fp)){
        $t=explode(" ",$in);
        $date=$t[0]." ".$t[1];
        $tmp =explode(":",$t[1]);       // hh:mm:ss.xxxxx
        $min =$tmp[1];                  // min
        if(isset($t[3])){
                $s=explode(".",$t[3]);
                if(isset($s[3])) {
                        $ip1=$s[3];
                        $d=explode(".",$t[5]);
                        $ip2=$d[3];
//                      echo "$ip1,$ip2\n";
                        $buf[$ip1][$ip2]++;
                }
        }

        $n++;
        if(($n % 2000)==0 || ($min - $prev_min) > $MIN_TH) {
                MkHTML($buf,$date);
                $prev_min = $min;
        }
}

fclose($fp);
MkHTML($buf,$date);
echo "Finished!!!\n";


function MkHTML($buf,$date){

        $date="<H3>$date</H3>";
        $header="<!DOCTYPE HTML><HTML><HEAD><meta http-equiv=\"refresh\" content=\"10\"></HEAD><BODY>";
        $msg="<H3>$date</H3>\n<TABLE>\n";
        for($i=1;$i<255;$i++){
                $sum=0;
                for($j=1;$j<255;$j++){
                        $sum+=$buf[$j][$i];
                }
                $iSum[$i]=$sum;
//              echo "$i,$iSum[$i]\n";
        }

        for($i=1;$i<255;$i++){
                $tmp="<TR><TD>$i</TD>";$sum=0;
                for($j=1;$j<255;$j++){
                        $var=$buf[$i][$j];
                        $pt=".";
                        if($var<63) {
                                if($var<10) {
                                        $pt=$var;
                                } else {
                                        $pt=chr(ord('A')+$var-10);
                                }
                        }
                        $sum+=$var;
                        $var=20*log($var+1);
                        $color=set_color($var);
                        if($iSum[$j]!=0) $tmp.= "<TD BGCOLOR=$color>10.8.0.$j\">$pt</TD>";

                }
                if($sum !=0 ) {
                        $msg.=$tmp;
                        $msg.="</TR>\n";
                }
        }

        $msg.="</TABLE>\n<H3>$date</H3></BODY></HTML>\n";
        $fw=fopen("/var/www/html/cross.html","w");
        fputs($fw,$header);
        fputs($fw,$msg);
        fclose($fw);
}


function set_color($x){
   if ($x<64) {
       $r=0; $g= $x*4 ; $b=255;
   } else {
       if ($x<128){
           $r=4*( $x -64 );$g=255;$b=255-$r;
       } else {
           if ($x<192){
               $b=4*( $x - 128 );$r=255;$g=255-$b;
           } else {
               $r=255;$g=0;$b=255-4*( $x -192);
           }
       }
   }
   return "#".sprintf("%02x%02x%02x",$r,$g,$b);
}
?>