0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-25 23:14:13 +01:00

ircd: Add utility to beep the pcspeaker.

This commit is contained in:
Jason Volk 2021-10-06 13:07:21 -07:00
parent 422c4da624
commit 31431d32c5
6 changed files with 232 additions and 0 deletions

View file

@ -1129,6 +1129,7 @@ RB_CHK_SYSHEADER(linux/perf_event.h, [LINUX_PERF_EVENT_H])
RB_CHK_SYSHEADER(linux/hw_breakpoint.h, [LINUX_HW_BREAKPOINT_H])
RB_CHK_SYSHEADER(linux/io_uring.h, [LINUX_IO_URING_H])
RB_CHK_SYSHEADER(linux/icmp.h, [LINUX_ICMP_H])
RB_CHK_SYSHEADER(linux/input-event-codes.h, [LINUX_INPUT_EVENT_CODES_H])
dnl windows platform
RB_CHK_SYSHEADER(windows.h, [WINDOWS_H])

44
include/ircd/beep.h Normal file
View file

@ -0,0 +1,44 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2021 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_BEEP_H
/// pcspkr-event-spkr
namespace ircd
{
struct beep;
}
/// Transmits audible tone through the pcspkr for the object's duration. The
/// tone starts at construction and continues until terminated by destruction.
///
class ircd::beep
{
struct ctrl;
static ctx::mutex mutex;
static conf::item<std::string> path;
static conf::item<bool> debug;
std::unique_lock<ctx::mutex> lock;
fs::fd fd;
public:
beep(const float tone = 2600.0f);
beep(beep &&) noexcept;
beep(const beep &) = delete;
beep &operator=(beep &&) noexcept;
beep &operator=(const beep &) = delete;
~beep() noexcept;
static bool available() noexcept;
static bool busy() noexcept;
};

View file

@ -110,6 +110,7 @@
#include "net/net.h"
#include "server/server.h"
#include "png.h"
#include "beep.h"
#include "magick.h"
#include "resource/resource.h"
#include "client.h"

View file

@ -229,6 +229,7 @@ endif
if IMAGEMAGICK
libircd_la_SOURCES += magick.cc
endif
libircd_la_SOURCES += beep.cc
libircd_la_SOURCES += png.cc
if OPENCL
libircd_la_SOURCES += cl.cc

158
ircd/beep.cc Normal file
View file

@ -0,0 +1,158 @@
// The Construct
//
// Copyright (C) The Construct Developers, Authors & Contributors
// Copyright (C) 2016-2021 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#if __has_include(<linux/input-event-codes.h>)
#include <linux/input-event-codes.h>
#endif
#ifndef EV_SND
#define EV_SND 0
#endif
#ifndef SND_TONE
#define SND_TONE 0
#endif
/// Event device file structure.
struct ircd::beep::ctrl
{
struct timeval tv {0};
uint16_t type {EV_SND};
uint16_t code {SND_TONE};
int32_t tone {0};
};
decltype(ircd::beep::mutex)
ircd::beep::mutex;
decltype(ircd::beep::path)
ircd::beep::path
{
{ "name", "ircd.beep.path" },
{ "default", "/dev/input/by-path/platform-pcspkr-event-spkr" },
};
decltype(ircd::beep::debug)
ircd::beep::debug
{
{ "name", "ircd.beep.debug" },
{ "default", false },
};
/// Is another ircd::ctx currently beeping?
bool
ircd::beep::busy()
noexcept
{
return mutex.locked();
}
/// Is beeping at all possible for this platform?
bool
ircd::beep::available()
noexcept try
{
return path && fs::exists(path);
}
catch(const std::exception &e)
{
log::derror
{
"Failed to detect PC Speaker event availability :%s",
e.what()
};
return false;
}
//
// beep::beep
//
ircd::beep::beep(const float tone)
try
:lock
{
tone > 0.0f?
std::unique_lock<ctx::mutex>{mutex}:
std::unique_lock<ctx::mutex>{mutex, std::defer_lock}
}
,fd
{
tone > 0.0f?
fs::fd{string_view{path}, std::ios::out}:
fs::fd{-1}
}
{
if(!fd)
return;
beep::ctrl c;
c.tone = tone;
syscall(::write, int(fd), &c, sizeof(c));
if(debug)
log::debug
{
"PC Speaker audible tone active @ %-1.1f Hz",
tone,
};
}
catch(const std::exception &e)
{
log::error
{
"Failed to activate audible alarm :%s",
e.what(),
};
throw;
}
ircd::beep::beep(beep &&other)
noexcept
:lock{std::move(other.lock)}
,fd{std::move(other.fd)}
{
}
ircd::beep &
ircd::beep::operator=(beep &&other)
noexcept
{
this->~beep();
lock = std::move(other.lock);
fd = std::move(other.fd);
return *this;
}
ircd::beep::~beep()
noexcept try
{
if(!fd)
return;
assert(mutex.locked());
assert(this->lock.owns_lock());
beep::ctrl c;
c.tone = 0;
syscall(::write, int(fd), &c, sizeof(c));
}
catch(const std::exception &e)
{
log::derror
{
"Failed to clear pcspkr event (%p)",
this,
};
return;
}

View file

@ -619,6 +619,33 @@ console_cmd__sync(opt &out, const string_view &line)
return true;
}
bool
console_cmd__beep(opt &out, const string_view &line)
{
const params param{line, " ",
{
"frequency", "duration"
}};
const auto tone
{
param.at("frequency", 2600.0f)
};
const auto duration
{
param.at("duration", 250ms)
};
beep beep
{
tone
};
ctx::sleep(duration);
return true;
}
//
// log
//