当前位置:网站首页>Tempest HDMI leak receive 2
Tempest HDMI leak receive 2
2022-06-25 07:24:00 【Lao Shao's open source world】
I found it later gr-tempest package , It's based on gnuradio Reset tempestsdr, Because it is gnuradio, It is convenient for me to install locally , So I ran , It didn't work out , Maybe because it defaults to usrp, I'm using hackrf+ Resampling , The hardware is different . But there's another one in it simulate The flow chart of , You can import the picture and re solve it . I succeeded in this game , By debugging , I found that in different sample correction when , There will be something like the first article , There will also be decent pictures . So my confidence greatly increased .
Later, I decided to be in my former c++/hackrf Implementation of the analog video demodulation program to try . Sure enough, it worked , The main secret is to get rid of all kinds of synchronization in analog video demodulation , Remove interlacing , Then patiently adjust the row width , Finally, in order to get better results , Don't jump , It is recommended to artificially limit the refresh interval .
Here is my code :
#include <iostream>
#include <signal.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <libhackrf/hackrf.h>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <sstream>
using namespace std;
using namespace cv;
int decimate_rate = 1;
//#define original_width_x_height 65100
static volatile bool do_exit = false;
int result;
static hackrf_device* device = NULL;
double sample_rate_hz = 6e6/decimate_rate * 1.951047 ;
double baseband_filter_bw_hz = 1e6 ;
double freq_hz = 395.991*1000000;
Mat frame;
int x = 0;
int y = 0;
int correctX = 0;
int correctY = 0;
int autoCorrectX = 0;
int autoCorrectY = 0;
int width = 2081; //multiple of 347 like 2081 or 1387
int height = 800;
int original_width = width / decimate_rate;
int original_width_x_height = original_width * height;
int inverseVideo = 1;
double maxSignalLevel = 0;
double blackLevel = 0;
double coeff = 0;
double agcSignalLevel = 0;
int pixelCounter = 0;
double contrast = 40;
double bright = 40;
int delay_count = 0;
bool bufferIsFull = false;
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
//double grayScaleValues[original_width_x_height];
double grayScaleValues[2000000];
void sigint_callback_handler(int signum)
{
cout << "Caught signal" << endl;
do_exit = true;
}
void draw_pixel(double mag)
{
if (x >= original_width)
{
y += 1;
x = 0;
}
if (y >= height)
{
y = 0;
delay_count++;
if (delay_count > 3)
{
bufferIsFull = true;
delay_count = 0;
}
}
double num2 = (blackLevel - mag) * coeff * contrast;
num2 += bright;
if (num2 > 255)
{
num2 = 255;
}
if (num2 < 0)
{
num2 = 0;
}
int num = y % height * original_width + x % original_width;
grayScaleValues[num] = num2;
x = x + 1;
}
int rx_callback(hackrf_transfer* transfer)
{
double im, re, mag;
double num = 0;
double num2 = 0;
double compare_re;
for( uint32_t i = 0; i < transfer->valid_length; i += 2)
{
// int8_t(transfer->buffer[i]) -128~127
im = (int8_t(transfer->buffer[i]))/128.0;
re = (int8_t(transfer->buffer[i + 1]))/128.0;
compare_re = abs(int8_t(transfer->buffer[i+1])) ;
if (compare_re > num)
{
num = compare_re;
}
double mag = sqrt( im * im + re * re); //mag 0~1.414
if (mag > num2)
{
num2 = mag;
}
if (inverseVideo)
{
mag = maxSignalLevel - mag;
}
pthread_mutex_lock(&mtx);
draw_pixel(mag);
pthread_mutex_unlock(&mtx);
//grey of opencv is 0~255
//0 is black 255 is white
}
maxSignalLevel = maxSignalLevel * 0.9 + num2 * 0.1;
blackLevel = maxSignalLevel * 0.4;
coeff = 255 / blackLevel;
agcSignalLevel = num;
return 0;
}
void *receiving_function(void *arg)
{
while (do_exit == false)
{
sleep(1);
}
cout << "Thread Exiting..." << endl;
pthread_exit(NULL);
}
int main()
{
pthread_t recv_th;
signal(SIGINT, &sigint_callback_handler);
frame = Mat::zeros(height, width, CV_8UC1);
result = hackrf_init();
if( result != HACKRF_SUCCESS )
{
cout << "hackrf_init() failed" << endl;
return EXIT_FAILURE;
}
result = hackrf_open(&device);
if( result != HACKRF_SUCCESS )
{
cout << "hackrf_open() failed" << endl;
return EXIT_FAILURE;
}
result = hackrf_set_sample_rate(device, sample_rate_hz);
if( result != HACKRF_SUCCESS )
{
cout << "hackrf_set_sample_rate() failed" << endl;
return EXIT_FAILURE;
}
result = hackrf_set_baseband_filter_bandwidth(device, baseband_filter_bw_hz);
if( result != HACKRF_SUCCESS )
{
cout << "hackrf_baseband_filter_bandwidth_set() failed" << endl;
return EXIT_FAILURE;
}
result = hackrf_set_freq(device, freq_hz);
if( result != HACKRF_SUCCESS )
{
cout << "hackrf_set_freq() failed" << endl;
return EXIT_FAILURE;
}
result = hackrf_set_lna_gain(device, 40);
if( result != HACKRF_SUCCESS )
{
cout << "hackrf_set_lna_gain() failed" << endl;
return EXIT_FAILURE;
}
result = hackrf_set_vga_gain(device, 26);
if( result != HACKRF_SUCCESS )
{
cout << "hackrf_set_vga_gain() failed" << endl;
return EXIT_FAILURE;
}
int err = pthread_create(&recv_th, NULL, receiving_function, NULL);
if (err != 0)
{
cout << "Create thread failed" << endl;
}
result = hackrf_start_rx(device, rx_callback, NULL);
while( (hackrf_is_streaming(device) == HACKRF_TRUE) && (do_exit == false) )
{
if (bufferIsFull)
{
pthread_mutex_lock(&mtx);
for (int counter = 0; counter < original_width_x_height; counter++)
{
int new_x = counter % original_width;
int new_y = counter / original_width;
for (int c = 0; c < decimate_rate; c++)
{
frame.at<uchar>(new_y, new_x*decimate_rate + c) = grayScaleValues[counter];
}
grayScaleValues[counter] = 0;
}
bufferIsFull = false;
pthread_mutex_unlock(&mtx);
}
imshow("frame", frame);
if (waitKey(5) == 'q')
{
do_exit = true;
break;
}
}
if (do_exit)
{
cout << "Exiting..." << endl;
}
result = hackrf_close(device);
if(result != HACKRF_SUCCESS)
{
cout << "hackrf_close() failed" << endl;
}
else
{
cout << "hackrf_close() done" << endl;
}
hackrf_exit();
cout << "hackrf_exit() done" << endl;
pthread_join(recv_th,NULL);
return 0;
}
The following is the command for compiling :
g++ hackrf_tv_hdmi.cpp -o hackrf_tv_hdmi `pkg-config --cflags --libs opencv` -lhackrf -pthreadInterested friends can try , My monitor is set to 1920x1080 60Hz. Your frequency is different from mine .
Now this c++ The version code must be tempestsdr It's much simpler , But it is still not the simplest , There are many redundant codes when I do analog video demodulation . When I have time, I'll sort it out as python edition .
边栏推荐
- Cocos学习日记3——api获取节点、组件
- TEMPEST HDMI泄漏接收 2
- Google extender address
- Blue Bridge Cup SCM module code (nixie tube) (code + comments)
- From perceptron to transformer, a brief history of deep learning
- MySQL - definition and assignment of variables
- [introduction to UVM== > episode_9] ~ register model, integration of register model, general methods of register model, application scenarios of register model
- Jameswebb Space Telescope goes into operation to help study interstellar objects
- 【UVM入門 ===> Episode_9 】~ 寄存器模型、寄存器模型的集成、寄存器模型的常規方法、寄存器模型的應用場景
- 鸿蒙页面菜单的选择
猜你喜欢

正版photoshop2022购买体验经历分享

LabVIEW jump to web page

Practice of hierarchical management based on kubesphere

Reading sensor data with GPIO analog SPI interface

Advanced mathematics foundation_ Parity of functions

Harmony美食菜单界面

太上老君的炼丹炉之分布式 Quorum NWR

活动报名|Apache Pulsar x KubeSphere 在线 Meetup 火热来袭

What is the new business model of Taishan crowdfunding in 2022?

Pratique de gestion hiérarchique basée sur kubesphere
随机推荐
活动报名|Apache Pulsar x KubeSphere 在线 Meetup 火热报名中
Omni toolbox direct download
【一起上水硕系列】Day 5
Orcad Schematic常用功能
Alphassl wildcard certificate for one month
Finally, when you open source the applet ~
Change the current count of auto increment values in MySQL- Changing the current count of an Auto Increment value in MySQL?
正版photoshop2022购买体验经历分享
1W字|40 图|硬核 ES 实战
我与CSDN的一年时光及大学经验分享
【xxl-job】池塘水绿风微暖,记得玉真初见面
威迈斯新能源冲刺科创板:年营收17亿 应收账款账面价值近4亿
Pratique de gestion hiérarchique basée sur kubesphere
【一起上水硕系列】Day 4
全局变量&局部变量
[Shangshui Shuo series] day 4
Authentique Photoshop 2022 expérience d'achat partage
Chang Wei (variables and constants) is easy to understand
Reading sensor data with GPIO analog SPI interface
MySQL(十二)——更改表的备注