function main()
    freeswitch.consoleLog("INFO", "start clear dirty calls.\n");
    local dbh=freeswitch.Dbh("sqlite://core");
    assert(dbh:connected())
    local count = 0;
    local calls = {};
    local time = os.time();
    local gap = 60*60*4 - 10; -- 4个小时
    dbh:query("Select uuid, direction, state, callstate, cid_num, dest, created, created_epoch From channels", function(row)
        if time - row.created_epoch > gap then -- 4小时前的通话
            local call = {};
            call.uuid = row.uuid;
            call.log = "<"..count..">clearing ["..row.uuid.."]".." d:"..row.direction..", c:"..row.created..", s:"..row.state..", caller:"..row.cid_num..", callee:"..row.dest;
            table.insert(calls, call);
        end
    end)

    for i,v in ipairs(calls) do
        local res = "fail";
        local a = dbh:query("Delete From channels where uuid = '"..v.uuid.."'");
        if a then
            res = "succ";
        end

        freeswitch.consoleLog("NOTICE", v.log.." "..res..".\n");
    end
    dbh:release()
    freeswitch.consoleLog("INFO", "clear dirty calls end.\n")
end
main()