How to run SRT server on local? - c

I want to create a streaming application which is responsible for send and receive live audio/video stream.
But this audio/video stream must be equipped with FEC client server error mechanism. I have done some R&D and found that Haivision has provided open source SRT solution.
I have setup project as suggested here https://github.com/Haivision/srt but no idea how to run this server.
Please guide me how can i start this server. Reply me as soon as possible.

The SRT library is provided with API guides to allow you build it into your own applications and 'hubs', rather than a ready to go 'server' that you configure and run.
The API includes information on how to 'start' SRT and on how to set up a socket to listen for traffic - e.g.:
Setup and teardown
Before any part of the SRT C API can be used, the user should call srt_startup() function. Likewise, before the application exits, the srt_cleanup() function should be called. Note that one of the things the startup function does is to create a new thread, so choose the point of execution for these functions carefully.
SRT Usage - listener (server)
sockaddr_in sa = { ... }; // set local listening port and possibly interface's IP
int st = srt_bind(sock, (sockaddr*)&sa, sizeof sa);
srt_listen(sock, 5);
while ( !finish ) {
socklen_t sa_len = sizeof sa;
newsocket = srt_accept(sock, (sockaddr*)&sa, &sa_len);
HandleNewClient(newsocket, sa);
}
The info is all in the API section of the link you highlighted: https://github.com/Haivision/srt/blob/master/docs/API.md
There is (at the time of writing) a guide to using the SRT library with ffmpeg to send and receive data - this may be what you are looking for: https://medium.com/#eyevinntechnology/using-ffmpeg-and-srt-to-transport-video-signal-to-the-cloud-7160960f846a

Related

change file descriptor without re-initializing the handle of uv_poll_t type

I have an application project running on Linux environment, which includes libuv and another third-party library, the third-party library provides APIs for starting a TCP connection to remote server (say xxx_connect()) and getting file descriptor of the active connection (say xxx_get_socket()) . So far I managed to get valid file descriptor from xxx_get_socket() after xxx_connect() completed successfully, and initialize uv_poll_t handle with that file descriptor in my program.
Currently I am working on reconnecting function, after reconnecting the same server (by running xxx_connect() again), xxx_get_socket() returns different file descriptor, that means it is necessary to update io_watcher.fd member of a uv_poll_t handle to receive data in the new active connection.
AFAIK uv_poll_init() internally invokes uv__io_check_fd() , uv__nonblock() and uv__io_init() , it seems possible to modify io_watcher.fd of a uv_poll_t handle without closing the handle and then initializing it again (see sample code below), which has extra latency. However I'm not sure if it is safe to do so, I don't know whether io_watcher.fd member of a uv_poll_t handle is referenced elsewhere in libuv (e.g. uv_run()) which makes thing more complex. Is my approach feasible or should I re-initialize the uv_poll_t handle in such case ? Appreciate any feedback.
Possible approach , simplified sample code :
int uv_poll_change_fd( uv_poll_t *handle, int new_fd ) {
if (uv__fd_exists(handle->loop, new_fd))
// ..... some code ....
err = uv__io_check_fd(handle->loop, new_fd);
if(err)
// ..... some code ....
err = uv__nonblock(new_fd, 1);
// ..... some code ....
handle->io_watcher.fd = new_fd;
}

Get signal level of the connected WiFi network

Using wpa_supplicant 2.4 on ARM Debian.
Is there a way to get signal level, in decibels or percents, of the wireless network I’m currently connected to?
STATUS command only returns the following set of values: bssid, freq, ssid, id, mode, pairwise_cipher, group_cipher, key_mgmt, wpa_state, ip_address, p2p_device_address, address, uuid
I can run SCAN afterwards, wait for results and search by SSID. But that’s slow and error-prone, I'd like to do better.
The driver should already know that information (because connected, and adjusting transmit levels for energy saving), is there a way to just query for that?
This question is not about general computing hardware and software. I'm using wpa_supplicant through a C API defined in wpa_ctrl.h header, interacting with the service through a pair of unix domain sockets (one for commands, another one for unsolicited events).
One reason I don’t like my current SCAN + SCAN_RESULT solution, it doesn’t work for hidden SSID networks. Scan doesn’t find the network, therefore I’m not getting signal level this way. Another issue is minor visual glitch at application startup. My app is launched by systemd, After=multi-user.target. Unless it’s the very first launch, Linux is already connected to Wi-Fi by then. In my app’s GUI (the product will feature a touch screen), I render a phone-like status bar, that includes WiFi signal strength icon. Currently, it initially shows minimal level (I know it's connected because STATUS command shows SSID), only after ~1 second I’m getting CTRL-EVENT-SCAN-RESULTS event from wpa_supplicant, run SCAN_RESULT command and update signal strength to the correct value.
On the API level my code is straightforward. I have two threads for that, both call wpa_ctrl_open, the command thread calls wpa_ctrl_request, the event thread has an endless loop that calls poll passing wpa_ctrl_get_fd() descriptor and POLLIN event mask, followed by wpa_ctrl_pending and wpa_ctrl_recv.
And here's the list of files in /sys/class/net/wlan0:
./mtu
./type
./phys_port_name
./netdev_group
./flags
./power/control
./power/async
./power/runtime_enabled
./power/runtime_active_kids
./power/runtime_active_time
./power/autosuspend_delay_ms
./power/runtime_status
./power/runtime_usage
./power/runtime_suspended_time
./speed
./dormant
./name_assign_type
./proto_down
./addr_assign_type
./phys_switch_id
./dev_id
./duplex
./gro_flush_timeout
./iflink
./phys_port_id
./addr_len
./address
./operstate
./carrier_changes
./broadcast
./queues/rx-0/rps_flow_cnt
./queues/rx-0/rps_cpus
./queues/rx-1/rps_flow_cnt
./queues/rx-1/rps_cpus
./queues/rx-2/rps_flow_cnt
./queues/rx-2/rps_cpus
./queues/rx-3/rps_flow_cnt
./queues/rx-3/rps_cpus
./queues/tx-0/xps_cpus
./queues/tx-0/tx_maxrate
./queues/tx-0/tx_timeout
./queues/tx-0/byte_queue_limits/limit
./queues/tx-0/byte_queue_limits/limit_max
./queues/tx-0/byte_queue_limits/limit_min
./queues/tx-0/byte_queue_limits/hold_time
./queues/tx-0/byte_queue_limits/inflight
./queues/tx-1/xps_cpus
./queues/tx-1/tx_maxrate
./queues/tx-1/tx_timeout
./queues/tx-1/byte_queue_limits/limit
./queues/tx-1/byte_queue_limits/limit_max
./queues/tx-1/byte_queue_limits/limit_min
./queues/tx-1/byte_queue_limits/hold_time
./queues/tx-1/byte_queue_limits/inflight
./queues/tx-2/xps_cpus
./queues/tx-2/tx_maxrate
./queues/tx-2/tx_timeout
./queues/tx-2/byte_queue_limits/limit
./queues/tx-2/byte_queue_limits/limit_max
./queues/tx-2/byte_queue_limits/limit_min
./queues/tx-2/byte_queue_limits/hold_time
./queues/tx-2/byte_queue_limits/inflight
./queues/tx-3/xps_cpus
./queues/tx-3/tx_maxrate
./queues/tx-3/tx_timeout
./queues/tx-3/byte_queue_limits/limit
./queues/tx-3/byte_queue_limits/limit_max
./queues/tx-3/byte_queue_limits/limit_min
./queues/tx-3/byte_queue_limits/hold_time
./queues/tx-3/byte_queue_limits/inflight
./tx_queue_len
./uevent
./statistics/rx_fifo_errors
./statistics/collisions
./statistics/rx_errors
./statistics/rx_compressed
./statistics/rx_dropped
./statistics/tx_packets
./statistics/tx_errors
./statistics/rx_missed_errors
./statistics/rx_over_errors
./statistics/tx_carrier_errors
./statistics/tx_heartbeat_errors
./statistics/rx_crc_errors
./statistics/multicast
./statistics/tx_fifo_errors
./statistics/tx_aborted_errors
./statistics/rx_bytes
./statistics/tx_compressed
./statistics/tx_dropped
./statistics/rx_packets
./statistics/tx_bytes
./statistics/tx_window_errors
./statistics/rx_frame_errors
./statistics/rx_length_errors
./dev_port
./ifalias
./ifindex
./link_mode
./carrier
You can get the signal level of the connected wifi by wpa_supplicant cmd SIGNAL_POLL
The wpa_supplicant would return:
RSSI=-60
LINKSPEED=867
NOISE=9999
FREQUENCY=5745
The value of the RSSI is the signal level.
You can get the signal level of the connected wifi by wpa_supplicant cmd BSS <bssid>.
About the bssid of the connected wifi, you can get from wpa_supplicant cmd STATUS.
https://android.googlesource.com/platform/external/wpa_supplicant_8/+/622b66d6efd0cccfeb8623184fadf2f76e7e8206/wpa_supplicant/ctrl_iface.c#1986
For iw compatible devices:
Following command gives the current station(aka AP) signal strength:
iw dev wlp2s0 station dump -v
If you need C API, just dig the source code of iw.
After a quick glance, the function you need is here
For broadcom devices, try search broadcom wl. It is close source, don't know if C API is provided.

How to execute net.exe from Windows Runtime in C?

To introduce my problem, I'm currently working on a project to remotely shut down stationary PCs via Siemens S7 PLC. Those PCs are used for an experimental manufactoring line for relays at my university. The principle is quiet simple, the PLC sends the IP of a computer via UDP to a special "always on" PC with monitoring functions on which a UDP server listens for packets (this PC starts up together with the manufactoring line; OS is Windows 10; the server is written in C). If it receives an UDP packet, it triggers a net use command followed by a shutdown command to that specific IP. This works just fine, if the server.exe is started manually. The goal is to get the server working when it's automatically started with e.g. the taskplaner. Exactly this is the main issue here, it's not working as background task. It receives the packets (I tested it) but then nothing happens, no computer shuts down. So I guessed it must be the net use or the shutdown command. At first I tried to set up the net use with a system()call:
char command[100] = { 0 };
snprintf(command, sizeof(command), "#NET USE \\\\%s\\IPC$ %s /USER:%s", ip, pw, usr);
system(command);
As this won't work I found following statement for system()on the Windows API reference page:
This API cannot be used in applications that execute in the Windows Runtime.
So I figured I had to find an alternative, which leads me to my next try with the ShellExecute() function. It seemed like there are no problems concerning the execution out of the runtime, cause I could't find any word about it at the reference page. I tried:
char programpath[100] = "C:\\Windows\\System32\\net.exe";
char cmdline[100] = { 0 };
snprintf(cmdline, sizeof(cmdline), "Use \\\\%s\\IPC$ %s /USER:%s", ip, pw, usr);
ShellExecute(NULL, "open", programpath, cmdline, NULL, SW_HIDE);
But nope, won't work either from the background. When I asked my prof about it, he said he is more into Linux, so he could only guess that there might be a problem with the permissions. He meant that my server has possibly no rights to open those two programs, when calling them as background process. But even after a long time of investigating through the internet, I can't find a proper solution which fits to my problem.

how to find pulseaudio dbus server when using system-instance

I'm trying to use org.PulseAudio1 and org.PulseAudio.ServerLookup1 to find the unix path to the pulseaudio dbus server exposed from module-dbus-protocol.
I'm enabling system mode via 'system-instance = yes'. I'm also enabling module-dbus-protocol. I've verified that both of these are enabled.
The trouble is that with 'system-instance = yes' there isn't a org.PulseAudio1 exposed on the system dbus bus, apparently due to this code in daemon/main.c:
if (!conf->system_instance) {
if ((server_lookup = pa_dbusobj_server_lookup_new(c))) {
if (!(lookup_service_bus = register_dbus_name(c, DBUS_BUS_SESSION, "org.PulseAudio1")))
goto finish;
}
}
How is one supposed to find the unix path to the dbus server when running as a system instance?

libssh2 session cleanup without blocking?

My app uses libssh2 to communicate over SSH, and generally works fine. One problem I have is when the remote host dies unexpectedly -- the remote host in this case is an embedded device that can lose power at any time, so this isn't uncommon.
When that happens, my app detects that the remote computer has stopped responding to pings, and tears down the local end of the SSH connection like this:
void SSHSession :: CleanupSession()
{
if (_uploadFileChannel)
{
libssh2_channel_free(_uploadFileChannel);
_uploadFileChannel = NULL;
}
if (_sendCommandsChannel)
{
libssh2_channel_free(_sendCommandsChannel);
_sendCommandsChannel = NULL;
}
if (_session)
{
libssh2_session_disconnect(_session, "bye bye");
libssh2_session_free(_session);
_session = NULL;
}
}
Pretty straightforward, but the problem is that the libssh2_channel_free() calls can block for a long time waiting for the remote end to respond to the "I'm going away now" message, which it will never do because it's powered off... but in the meantime, my app is frozen (blocked in the cleanup-routine), which isn't good.
Is there any way (short of hacking libssh2) to avoid this? I'd like to just tear down the local SSH data structures, and never block during this tear-down. (I suppose I could simply leak the SSH session memory, or delegate it to a different thread, but those seem like ugly hacks rather than proper solutions)
I'm not experienced with libssh2, but perhaps we can get different behavior out of libssh2 by using libssh2_session_disconnect_ex and a different disconnect reason: SSH_DISCONNECT_CONNECTION_LOST.
libssh2_session_disconnect is equivalent to using libssh2_session_disconnect_ex with the reason SSH_DISCONNECT_BY_APPLICATION. If libssh2 knows that the connection is lost, maybe it won't try to talk to the other side.
http://libssh2.sourceforge.net/doc/#libssh2sessiondisconnectex
http://libssh2.sourceforge.net/doc/#sshdisconnectcodes
Set to non-blocking mode and take the control of reading data from the socket to your hand by setting callback function to read data from the soket using libssh2_session_callback_set with LIBSSH2_CALLBACK_RECV for cbtype
void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);
If you can't read data from the socket due to error ENOTCONN that means remote end has closed the socket or connection failed, then return -ENOTCONN in your callback function

Resources