{"id":21651827,"url":"https://github.com/hoytech/sdr-radio-hackrf","last_synced_at":"2025-03-20T04:06:44.621Z","repository":{"id":35275707,"uuid":"39536500","full_name":"hoytech/SDR-Radio-HackRF","owner":"hoytech","description":"Perl interface to libhackrf","archived":false,"fork":false,"pushed_at":"2015-10-08T04:50:57.000Z","size":176,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-25T05:43:06.496Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"XS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoytech.png","metadata":{"files":{"readme":"README.pod","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-23T00:11:55.000Z","updated_at":"2024-06-27T02:01:51.000Z","dependencies_parsed_at":"2022-09-06T15:02:19.434Z","dependency_job_id":null,"html_url":"https://github.com/hoytech/SDR-Radio-HackRF","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FSDR-Radio-HackRF","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FSDR-Radio-HackRF/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FSDR-Radio-HackRF/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoytech%2FSDR-Radio-HackRF/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoytech","download_url":"https://codeload.github.com/hoytech/SDR-Radio-HackRF/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244547606,"owners_count":20470103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T07:49:46.088Z","updated_at":"2025-03-20T04:06:44.594Z","avatar_url":"https://github.com/hoytech.png","language":"XS","funding_links":[],"categories":[],"sub_categories":[],"readme":"package SDR::Radio::HackRF;\n\nour $VERSION = '0.100';\n\nrequire XSLoader;\nXSLoader::load('SDR::Radio::HackRF', $VERSION);\n\nuse common::sense;\nuse AnyEvent;\nuse AnyEvent::Util;\n\n\nsub new {\n  my ($class, %args) = @_;\n\n  my $self = {};\n  bless $self, $class;\n\n  $self-\u003e{ctx} = new_context();\n  $self-\u003e{state} = 'IDLE';\n\n  ($self-\u003e{perl_side_signalling_fh}, $self-\u003e{c_side_signalling_fh}) = AnyEvent::Util::portable_socketpair();\n\n  die \"couldn't create signalling socketpair: $!\" if !$self-\u003e{perl_side_signalling_fh};\n\n  _set_signalling_fd($self-\u003e{ctx}, fileno($self-\u003e{c_side_signalling_fh}));\n\n  ## always turn amp off -- keep off as much as possible so it doesn't accidentally fry\n  _set_amp_enable($self-\u003e{ctx}, 0);\n\n  if (!$args{dont_handle_sigint}) {\n    $SIG{INT} = sub {\n      $self-\u003estop;\n      exit;\n    };\n  }\n\n  return $self;\n}\n\n\nsub tx {\n  my ($self, $cb) = @_;\n\n  die \"already in $self-\u003e{state} state\" if $self-\u003e{state} ne 'IDLE';\n  $self-\u003e{state} = 'TX';\n\n  $self-\u003e{pipe_watcher} = AE::io $self-\u003e{perl_side_signalling_fh}, 0, sub {\n    sysread $self-\u003e{perl_side_signalling_fh}, my $junk, 1; ## FIXME: non-blocking\n\n    my $buffer_size = _get_buffer_size($self-\u003e{ctx});\n\n    my $bytes = $cb-\u003e($buffer_size);\n\n    if (!defined $bytes) {\n      $self-\u003estop;\n      return;\n    }\n\n    _copy_to_buffer($self-\u003e{ctx}, $$bytes);\n\n    syswrite $self-\u003e{perl_side_signalling_fh}, \"\\x00\";\n  };\n\n  _start_tx($self-\u003e{ctx});\n}\n\nsub rx {\n  my ($self, $cb) = @_;\n\n  die \"already in $self-\u003e{state} state\" if $self-\u003e{state} ne 'IDLE';\n  $self-\u003e{state} = 'RX';\n\n  $self-\u003e{pipe_watcher} = AE::io $self-\u003e{perl_side_signalling_fh}, 0, sub {\n    sysread $self-\u003e{perl_side_signalling_fh}, my $junk, 1; ## FIXME: non-blocking\n\n    my $buffer = _copy_from_buffer($self-\u003e{ctx});\n\n    $cb-\u003e($buffer);\n\n    syswrite $self-\u003e{perl_side_signalling_fh}, \"\\x00\";\n  };\n\n  _start_rx($self-\u003e{ctx});\n}\n\n\n\nsub frequency {\n  my ($self, $freq) = @_;\n\n  die \"getter not implemented yet\" if !defined $freq;\n\n  _set_freq($self-\u003e{ctx}, $freq);\n}\n\nsub sample_rate {\n  my ($self, $sample_rate) = @_;\n\n  die \"getter not implemented yet\" if !defined $sample_rate;\n\n  _set_sample_rate($self-\u003e{ctx}, $sample_rate);\n}\n\nsub amp_enable {\n  my ($self, $amp_enable) = @_;\n\n  die \"getter not implemented yet\" if !defined $amp_enable;\n\n  $amp_enable = $amp_enable ? 1 : 0;\n\n  _set_amp_enable($self-\u003e{ctx}, $amp_enable);\n}\n\n\n\nsub stop {\n  my ($self) = @_;\n\n  if ($self-\u003e{state} eq 'TX') {\n    $self-\u003e_stop_callback();\n    _stop_tx($self-\u003e{ctx});\n  } elsif ($self-\u003e{state} eq 'RX') {\n    $self-\u003e_stop_callback();\n    _stop_rx($self-\u003e{ctx});\n  } else {\n    warn \"called stop but in state '$self-\u003e{state}'\";\n  }\n}\n\n\nsub _stop_callback {\n  my ($self) = @_;\n\n  _set_terminate_callback_flag($self-\u003e{ctx});\n\n  $self-\u003e{state} = 'TERM';\n\n  syswrite $self-\u003e{perl_side_signalling_fh}, \"\\x00\";\n\n  $self-\u003e{pipe_watcher} = AE::io $self-\u003e{perl_side_signalling_fh}, 0, sub {\n    sysread $self-\u003e{perl_side_signalling_fh}, my $junk, 1; ## FIXME: non-blocking\n\n    delete $self-\u003e{pipe_watcher};\n    delete $self-\u003e{state};\n  };\n}\n\n\n\nsub run {\n  my ($self) = @_;\n\n  $self-\u003e{cv} = AE::cv;\n\n  $self-\u003e{cv}-\u003erecv;\n}\n\n\n\n1;\n\n\n\n__END__\n\n=encoding utf-8\n\n=head1 NAME\n\nSDR::Radio::HackRF - Control HackRF software defined radio\n\n=head1 SYNOPSIS\n\nTX:\n\n    my $radio = SDR::Radio::HackRF-\u003enew;\n\n    $radio-\u003efrequency(35_000_000);\n    $radio-\u003esample_rate(8_000_000);\n\n    $radio-\u003etx(sub {\n        my $block_size = shift;\n\n        my $output = \"\\x00\" x $block_size;\n\n        return \\$output;\n    });\n\n    $radio-\u003erun;\n\nRX:\n\n    my $radio = SDR::Radio::HackRF-\u003enew;\n\n    $radio-\u003efrequency(35_000_000);\n    $radio-\u003esample_rate(8_000_000);\n\n    $radio-\u003erx(sub {\n        ## Process data in $_[0]\n    });\n\n    $radio-\u003erun;\n\n=head1 DESCRIPTION\n\nThis is the L\u003cSDR\u003e driver for L\u003cHackRF|http://greatscottgadgets.com/hackrf/\u003e devices.\n\nAlthough you can use it by itself, see the L\u003cSDR\u003e docs for more generic usage.\n\nIn order to install this module you will need C\u003clibhackrf\u003e installed. On Ubuntu/Debian you can run:\n\n    sudo apt-get install libhackrf-dev\n\nNOTE: This module creates background threads so you should not fork after creating C\u003cSDR::Radio::HackRF\u003e objects.\n\n=head1 SEE ALSO\n\nL\u003cSDR-Radio-HackRF github repo|https://github.com/hoytech/SDR-Radio-HackRF\u003e\n\nL\u003cSDR\u003e - The main module, includes examples\n\n=head1 AUTHOR\n\nDoug Hoyte, C\u003c\u003c \u003cdoug@hcsw.org\u003e \u003e\u003e\n\n=head1 COPYRIGHT \u0026 LICENSE\n\nCopyright 2015 Doug Hoyte.\n\nThis module is licensed under the same terms as perl itself.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoytech%2Fsdr-radio-hackrf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoytech%2Fsdr-radio-hackrf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoytech%2Fsdr-radio-hackrf/lists"}