Skip to content

Commit

Permalink
blocks/sources/rtlsdr: add sigterm handler to allow device close
Browse files Browse the repository at this point in the history
the sigterm handlers cancel's the async read, allowing device close
after rtlsdr_read_async() returns.

also rename read_async_callback to read_callback for less ambiguity
between it and the async.callback() helper function.

resolves #8.
  • Loading branch information
vsergeev committed Jul 17, 2016
1 parent 29ad3b2 commit 86b64c9
Showing 1 changed file with 33 additions and 4 deletions.
37 changes: 33 additions & 4 deletions radio/blocks/sources/rtlsdr.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ local block = require('radio.core.block')
local platform = require('radio.core.platform')
local types = require('radio.types')
local debug = require('radio.core.debug')
local async = require('radio.core.async')

local RtlSdrSource = block.factory("RtlSdrSource")

Expand Down Expand Up @@ -175,10 +176,26 @@ function RtlSdrSource:initialize_rtlsdr()
end
end

local function read_async_callback_factory(pipes)
local function sigterm_handler_factory(dev)
local ffi = require('ffi')

ffi.cdef[[
typedef struct rtlsdr_dev rtlsdr_dev_t;
int rtlsdr_cancel_async(rtlsdr_dev_t *dev);
]]
local librtlsdr = ffi.load('rtlsdr')

local function sigterm_handler(sig)
librtlsdr.rtlsdr_cancel_async(ffi.cast('rtlsdr_dev_t *', dev))
end

return ffi.cast('void (*)(int)', sigterm_handler)
end

local function read_callback_factory(pipes)
local out = types.ComplexFloat32.vector()

local function read_async_callback(buf, len, ctx)
local function read_callback(buf, len, ctx)
-- Resize output vector
out:resize(len/2)

Expand All @@ -194,18 +211,30 @@ local function read_async_callback_factory(pipes)
end
end

return read_async_callback
return read_callback
end

function RtlSdrSource:run()
-- Initialize the rtlsdr in our own running process
self:initialize_rtlsdr()

-- Register SIGTERM signal handler
local handler, handler_state = async.callback(sigterm_handler_factory, tonumber(ffi.cast("intptr_t", self.dev[0])))
ffi.C.signal(ffi.C.SIGTERM, handler)

local ret

-- Start asynchronous read
local ret = librtlsdr.rtlsdr_read_async(self.dev[0], read_async_callback_factory(self.outputs[1].pipes), nil, 0, 32768)
ret = librtlsdr.rtlsdr_read_async(self.dev[0], read_callback_factory(self.outputs[1].pipes), nil, 0, 32768)
if ret ~= 0 then
error("rtlsdr_read_async(): " .. tostring(ret))
end

-- Close rtlsdr
ret = librtlsdr.rtlsdr_close(self.dev[0])
if ret ~= 0 then
error("rtlsdr_close(): " .. tostring(ret))
end
end

return RtlSdrSource

0 comments on commit 86b64c9

Please sign in to comment.