Gstreamer: How to change RTSP port? - gstreamer

I'm trying to create RTSP server by test-mp4 usage from gst-rtsp-server example.
The example works, but I need to change basic 8554 port to another.
I checked the test-record.c example, where we can see:
#define DEFAULT_RTSP_PORT "8554"
static char *port = (char *) DEFAULT_RTSP_PORT;
...
static GOptionEntry entries[] = {
{"port", 'p', 0, G_OPTION_ARG_STRING, &port,
"Port to listen on (default: " DEFAULT_RTSP_PORT ")", "PORT"},
{NULL}
};
optctx = g_option_context_new ("<launch line> - Test RTSP Server, Launch\n\n"
"Example: \"( decodebin name=depay0 ! autovideosink )\"");
g_option_context_add_main_entries (optctx, entries, NULL);
But finally I can't understand how to change the port in test-mp4 example. I'll be appreciated if you tell me a way for the solution..
Thanks in advance!

Finally I found the solution:
It's necessary to add these lines:
.....
char *port = (char *) argv[2]; //argv[<X>] is a port - an input argument
g_object_set (server, "service", port, NULL);
....

Related

RabbitMQ closes socket while amqp_login call

I am using an example code from ..\rabbitmq-c\examples in order to create a connection to my http://localhost:15672.
From the following code block I get: Logging in: socket is closed output
amqp_socket_t *socket = NULL;
amqp_connection_state_t conn;
hostname = "localhost";
port = 131072; // 15672 // 131072
username = "guest";
password = "guest";
exchange = "testExchange";
bindingKey = "testMessage";
queueName = "testQueue";
routingKey = "testMessage";
messageBody = "testMessageBody";
conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if (!socket)
{
die("Creating TCP socket ERROR");
}
status = amqp_socket_open(socket, hostname, port);
if (!status)
{
die("Opening TCP socket ERROR");
}
die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN,
"guest", "guest"),
"Logging in");
amqp_channel_open(conn, 1);
die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
rabbitmq-c is compiled with VS2015 and I have rabbitmq-server 3.7.6, which is already running.
RabbitMQ runs on port 5672, and you are trying to connect to port 131072. Considering the maximum port allowed by TCP is 65535, there's no way that is going to work.
Change you code to use 5672.
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.

Why can't I see UDP on ncat after closing the initial program?

I have a short program to send UDP data to a local socket like so.
const char *i = "localhost";
const char *p = "8980";
struct addrinfo h;
struct addrinfo *res = 0;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_ADDRCONFIG;
if (getaddrinfo(i, p, &hints, &res) != 0)
{
printf("ERROR: getaddinfo\n");
}
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (fd == -1)
{
printf("ERROR: socket\n");
freeaddrinfo(res);
}
if (sendto(fd, "hello", 5, 0, res->ai_addr, res->ai_addrlen) == -1)
{
printf("ERROR: Sending\n");
}
freeaddrinfo(res);
close(fd);
I have launched ncat in a different terminal window with ncat -ul localhost 8980 and I can see "hello" on it when I subsequently launch the above program. I can also perform repeated calls to sendto and see hello multiple times. The program terminates but I cannot see an additional "hello" message on ncat when I relaunch the sending program. Why is this?
I've also tried not calling close at the end of the program as well.
The issue is that every time you run your program it will send its data from a different port, and thus be seen as a different network endpoint. When ncat
first receives a packet, it will bind to the remote endpoint and stop listening for packets coming from any other endpoint.
You can work around this with ncat by using the -k option. Sadly, ncat's -k option can only be used with the -e or -c options when doing UDP. You can make it work with:
ncat -ulkc "cat > $(tty)" localhost 8980
It will still bind to each remote endpoint it gets anything from though, so there's a limit to the number of times it will work (default 100, configurable via the -m option).
It's a bit easier if you use nc instead. It's -k option works normally with -u:
nc -ulk localhost 8980
That will prevent nc from binding to the remote endpoint at all, so it doesn't have the same limit as ncat.

Capturing packets on loopback

This code works perfectly fine on Ubuntu 16.04 and prints correct value (ETHERTYPE_IP) when I toss around UDP bytes via loopback interface:
#include <pcap.h>
#include <iostream>
#include <net/ethernet.h>
int main(int argc,char **argv)
{
char errbuf[PCAP_ERRBUF_SIZE];
auto pcap = pcap_open_live("lo0", BUFSIZ, 0, 1000, errbuf);
pcap_loop(pcap,0, [] (u_char *self, const struct pcap_pkthdr *header,
const u_char *packet) {
auto eth = (struct ether_header *) packet;
auto eth_type = ntohs(eth->ether_type);
std::cout << "eth_type: " << std::hex << eth_type << std::endl;
}, nullptr);
return 0;
}
netcat:
➜ ~ nc -uv -l 54321
Listening on [0.0.0.0] (family 0, port 54321)
➜ ~ nc -4u localhost 54321
hello
Program output:
➜ ~ sudo ./a.out
eth_type: 800
However on OS X 10.11.5 it prints eth_type: 4011. Interesting that it works fine with en1 adapter.
Why there is such a difference between loopback and non-loopback adapters and what is the correct way to capture packets on both?
Update:
tcpdump also works:
➜ ~ sudo tcpdump -i lo0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
15:09:00.160664 IP localhost.54321 > localhost.63543: UDP, length 4
As the link type is not ethernet, the header does not contain suitable data for ether_header.
Add this code after fetching the handle with pcap_open_live to see the link-layer header type:
if (pcap_datalink(pcap) != DLT_EN10MB) {
fprintf(stderr, "Device doesn't provide Ethernet headers - link type was %d\n", pcap_datalink(pcap));
return 1;
}
Running this indicates that the linktype value for lo0 is 0, DLT_NULL. The documentation states that this means "BSD loopback encapsulation; the link layer header is a 4-byte field, in host byte order, containing a PF_ value from socket.h for the network-layer protocol of the packet."
Indeed, when I look at the the first 4 bytes of the ether_dhost field I see the value 2, corresponding to PF_INET. In the end, this doesn't help you much if you are trying to distinguish UDP packets.
You can find more documentation here: http://www.tcpdump.org/linktypes.html

Bluetooth can receive data but cannot transmit it (socket programming in C++ to communicate Matlab)

I am using Raspberry Pi 3's internal bluetooth and I am writing a c++ code to connect the bluetooth of my windows PC. On the PC side, I use Matlab and I am able to send bytes to raspberry. However when I try to send bytes from raspberry to PC, I get the following error:
"Transport endpoint is not connected"
and Matlab says "Unsuccessful read: the specified amount of data was not returned within the timeout period".
Another interesting thing is that, when I try to send more than three bytes from Matlab, raspberry only receives the first three as if the rest did not exist. If I use two reads in a row, I am able to get 6 bytes and so on. Just pointing this odd fact since I thought it might be connected with my main problem and be a clue.
I have also tried to send a file manually, using the bluetooth symbol on menubar and it worked. So c++ code should be doing something different to cause this problem.
What is likely to be the cause of my problem? How can I send data from raspberry to my computer using c++?
My code is as follows:
(Referred website: http://people.csail.mit.edu/albert/bluez-intro/index.html)
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv)
{
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read;
socklen_t opt = sizeof(rem_addr);
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
bdaddr_t tempBDADDR = {0};
// bind socket to port 1 of the first available
// local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = tempBDADDR;
loc_addr.rc_channel = (uint8_t) 1;
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
ba2str( &rem_addr.rc_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
memset(buf, 0, sizeof(buf));
// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
printf("received [%s]\n", buf);
}
int status = 0;
// send a message
if( status == 0 ) {
status = write(s, "hello!", 6);
}
if( status < 0 ) perror("uh oh");
// close connection
close(client);
close(s);
return 0;
}
Matlab side is as straight forward as:
b = Bluetooth('raspberrypi', 1);
fopen(b);
fwrite(b, uint('1234'));
input = fread(b,6)
fclose(b);
clear('b');
EDIT:
Just figured that I do not get the "Transport endpoint is not connected" when I use the following line. However this only allows me to connect as client, whereas matlab only has a client type of connection. So now, I am able to send data to my computer from another socket without getting any errors, but cannot read it with matlab.
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
Just figured it out. Leaving this here in case it helps someone else as well.
When a connection is accepted, a new descriptor is returned (along with a new socket). This is a significant difference from connect(). So I was wrong at the following line.
status = write(s, "hello!", 6);
changing it to
status = write(client, "hello!", 6);
worked like a charm.
(Reference: http://users.pja.edu.pl/~jms/qnx/help/tcpip_4.25_en/prog_guide/sock_advanced_tut.html)

Child commands in popen telnet

I am trying to establish a local telnet session in C++ and send commands/receive data. Right now I have:
const char *cmd = "telnet 127.0.0.1 2006";
char buffer[256];
FILE *pipe = popen(cmd, "rw");
//if( !pipe ) { perror("popen"); exit(-1); }
while( fgets(buffer, sizeof(buffer), pipe) != NULL &&
!feof(pipe) )
{
if( ferror(pipe) ) { perror("fgets"); break; }
/* Here you do whatever you want with the data. */
printf("%s", buffer);
}
pclose(pipe);
Which is opening the telnet connection. I need to send a command like: "/neighbors" and then receive the data it would return. Ideally, the session would remain open and I would re-query "/neighbors" every 20 seconds or so.
I think I need to create a child process with fork(), but I am very new to this process.
Using telnet seems like a rather roundabout way to do this. Have you considered using regular sockets to talk to the remote process? For example, try this guide to socket programming.