GStreamer connection to VLC using GstRTSP library - gstreamer

I am trying to write a C application to connect with VLC RTSP (via RTP) stream and save frames as images.
I use the GStreamer RTSP library: https://gstreamer.freedesktop.org/documentation/gst-plugins-base-rtsp-1.0/index.html?gi-language=c
I have written some simple code presented below, but the app wait for the message from the VLC. I am not sure if it is a good way to connect but I am in stuck now. Maybe I should send something first to VLC but I do not know what and how to do this. Could anyone help or point some resources/examples how to use GStreamer RTSP?
#include <gstreamer-1.0/gst/rtsp/rtsp.h>
#include <stdio.h>
int main()
{
GstRTSPUrl *gstUrl = NULL;
const char* url = "rtsp://10.30.1.163:8554/test.sdp";
if(gst_rtsp_url_parse(url, &gstUrl) == GST_RTSP_OK) {
printf("URL PARSE");
GstRTSPConnection *gstRTSPConnection = NULL;
if(gst_rtsp_connection_create(gstUrl, &gstRTSPConnection) == GST_RTSP_OK) {
printf("Connection created\n");
GstRTSPMessage *message = NULL;
gst_rtsp_message_new(&message);
GstRTSPResult result = gst_rtsp_connection_connect_with_response(gstRTSPConnection, NULL, message);
if(result == GST_RTSP_ETIMEOUT){
printf("Timeout\n");
} else if(result == GST_RTSP_OK) {
printf("Connected\n");
printf("%s\n", gst_rtsp_connection_get_ip(gstRTSPConnection));
printf("Is tunelled: %d\n", gst_rtsp_connection_is_tunneled(gstRTSPConnection));
gst_rtsp_connection_receive(gstRTSPConnection, message, NULL);
}
}
}
return 0;
}

Ok. I will handle this. The issue was I need to first send some message to the server according to RTSP protocol. The solution below (with some dump messages):
#include <gstreamer-1.0/gst/rtsp/rtsp.h>
#include <stdio.h>
int main()
{
GstRTSPUrl *gstUrl = NULL;
const char* url = "rtsp://10.30.1.163:8554";
if(gst_rtsp_url_parse(url, &gstUrl) == GST_RTSP_OK) {
printf("URL PARSE");
GstRTSPConnection *gstRTSPConnection = NULL;
if(gst_rtsp_connection_create(gstUrl, &gstRTSPConnection) == GST_RTSP_OK) {
printf("Connection created\n");
GstRTSPMessage *message = NULL;
gst_rtsp_message_new(&message);
GstRTSPResult result = gst_rtsp_connection_connect_with_response(gstRTSPConnection, NULL, message);
if(result == GST_RTSP_ETIMEOUT){
printf("Timeout\n");
} else if(result == GST_RTSP_OK) {
printf("Connected\n");
printf("%s\n", gst_rtsp_connection_get_ip(gstRTSPConnection));
printf("Is tunelled: %d\n", gst_rtsp_connection_is_tunneled(gstRTSPConnection));
gst_rtsp_message_new(&message);
gst_rtsp_message_init_request(message, GST_RTSP_DESCRIBE, "rtsp://10.30.1.163:8554/test.sdp");
gst_rtsp_message_add_header(message, GST_RTSP_HDR_CSEQ, "1");
printf("Message Type %d", gst_rtsp_message_get_type(message));
gst_rtsp_message_dump(message);
if(gst_rtsp_connection_send(gstRTSPConnection, message, NULL) == GST_RTSP_OK){
printf("Message sent");
}else {
printf("Message not sent");
}
gst_rtsp_connection_receive(gstRTSPConnection, message, NULL);
gst_rtsp_message_dump(message);
}
}
}
return 0;
}

Related

Filtering by TCP SYN packets with npcap not working

I'm trying to sniff all TCP SYN packets received by any of my network adapters and I treid doing so by using the free npcap library available online.
You can see my code below
pcap_if_t* allNetworkDevices;
std::vector<pcap_t*> networkInterfacesHandles;
std::vector<WSAEVENT> sniffEvents;
void packet_handler(u_char* user, const struct pcap_pkthdr* header, const u_char* packet) {
cout << "here" << endl;
}
BOOL openAllInterfaceHandles()
{
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* curNetworkHandle;
if (pcap_findalldevs(&allNetworkDevices, errbuf) == -1) {
printf("Error in pcap_findalldevs: %s\n", errbuf);
return FALSE;
}
for (pcap_if_t* d = allNetworkDevices; d != NULL; d = d->next) {
//curNetworkHandle = pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf);
printf("%s\n", d->description);
curNetworkHandle = pcap_open_live(d->name, BUFSIZ, 1, 1000, errbuf);
if (curNetworkHandle == NULL) {
printf("Couldn't open device %s: %s\n", d->name, errbuf);
continue;
}
networkInterfacesHandles.push_back(curNetworkHandle);
// Compile and set the filter
struct bpf_program fp;
char filter_exp[] = "(tcp[tcpflags] & tcp-syn) != 0";
if (pcap_compile(curNetworkHandle, &fp, filter_exp, 1, PCAP_NETMASK_UNKNOWN) < 0) {
printf("Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(curNetworkHandle));
continue;
}
if (pcap_setfilter(curNetworkHandle, &fp) == -1) {
printf("Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(curNetworkHandle));
continue;
}
// Create an event for the handle
sniffEvents.push_back(pcap_getevent(curNetworkHandle));
}
}
int main()
{
openAllInterfaceHandles();
while (TRUE)
{
DWORD result = WaitForMultipleObjects(sniffEvents.size(), sniffEvents.data(), FALSE, INFINITE);
if (result == WAIT_FAILED) {
printf("Error in WaitForMultipleObjects: %d\n", GetLastError());
break;
}
// Dispatch packets for the handle associated with the triggered event
int index = result - WAIT_OBJECT_0;
pcap_dispatch(networkInterfacesHandles[index], -1, &packet_handler, NULL);
if (cond)
{
cout << "done" << endl;
break;
}
}
while (!networkInterfacesHandles.empty())
{
pcap_close(networkInterfacesHandles.back());
networkInterfacesHandles.pop_back();
}
pcap_freealldevs(allNetworkDevices);
return 0;
}
cond is some condition I'm using which is irrelevant to the problem.
For some reason it won't go into the packet_handler even when I receive TCP SYN packets (which I check by using Wireshark) and I tried sending them either via the loopback and also from another PC in the same LAN.
Any help to find the problem would be greatly appreciated.

Why does PIP_ADAPTER_INFO->LeaseExpires contain a different value after each call to GetAdaptersInfo

I am trying to create a program that achieves the same functionality as running the command ipconfg /all in Windows. I have managed to implement pretty much all the functionality however I am having difficulty getting the correct date and time for when the lease will expire. I am attempting to get this information by calling GetAdapterInfo and getting the value of LeaseExpires from the PIP_ADAPTER_INFO object that is returned. However not only does the value for lease expires not match that shown by ipconfig /all but it also changes on every run of the program. Can anyone spot why this would be happening?
#include <WinSock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma comment(lib, "Iphlpapi.lib")
PIP_ADAPTER_INFO getAdaptersInfo();
void outputFormatedTime(time_t * ttp);
int main()
{
PIP_ADAPTER_INFO pai = getAdaptersInfo();
if (pai)
{
for (; pai != NULL; pai = pai->Next)
{
if (pai->DhcpEnabled && pai->LeaseObtained)
{
printf("Lease Obtained: %llu - ", pai->LeaseObtained);
outputFormatedTime(&pai->LeaseObtained);
printf("Lease Expires: %llu - ", pai->LeaseExpires);
outputFormatedTime(&pai->LeaseExpires);
}
}
HeapFree(GetProcessHeap(), 0, pai);
pai = NULL;
}
return 0;
}
PIP_ADAPTER_INFO getAdaptersInfo()
{
PIP_ADAPTER_INFO paiResult;
ULONG ulOutputBufferLength = sizeof(IP_ADAPTER_INFO);
paiResult = (IP_ADAPTER_INFO *)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
if (paiResult == NULL)
{
printf("Error allocating memory needed to call GetAdaptersInfo\n");
return paiResult;
}
if (GetAdaptersInfo(paiResult, &ulOutputBufferLength) == ERROR_BUFFER_OVERFLOW)
{
HeapFree(GetProcessHeap(), 0, paiResult);
paiResult = (IP_ADAPTER_INFO *)HeapAlloc(GetProcessHeap(), 0, ulOutputBufferLength);
if (paiResult == NULL)
{
printf("Error allocating memory needed to call GetAdaptersInfo\n");
return paiResult;
}
}
if (!GetAdaptersInfo(paiResult, &ulOutputBufferLength) == NO_ERROR)
{
printf("Error calling GetAdaptersInfo\n");
HeapFree(GetProcessHeap(), 0, paiResult);
paiResult = NULL;
return paiResult;
}
return paiResult;
}
void outputFormatedTime(time_t * ttp)
{
struct tm newtime;
char buffer[32];
errno_t error;
error = _localtime32_s(&newtime, (__time32_t *)ttp);
if (error)
{
printf("Invalid Argument to _localtime32_s\n");
}
else
{
error = asctime_s(buffer, 32, &newtime);
if (error)
{
printf("Invalid Argument to asctime_s\n");
}
else
{
printf("%s", buffer);
}
}
}

Why a ZeroMQ PGM multicast is not receiving a Multicast message? ( C++, Windows )

Environment setup:
- Both a multicast send & receive applications are running in the same machine
I am integrating ZeroMQ multicast with OpenPGM support, but facing problem in below my sample code.
i.e. "Multicast message is not received" in receiver application. Kindly correct me if I am doing wrong. Also not able to find proper examples on ZeroMQ PGM multicast requirement.
// ZMQ_pgm_receive.cpp :
//
//Headers
#include "stdafx.h"
#include "zmq.h"
#include <iostream>
#include <windows.h>
std::string fullurl = "pgm://eth0;239.255.0.1:30001";
static int roundtrip_count = 50;
static size_t message_size = 4;
int _tmain(int argc, _TCHAR* argv[])
{
void *ctx = NULL,
*s = NULL;
int con;
int i;
ctx = zmq_init (1);
if (!ctx) {
printf ("error in zmq_init: %s\n", zmq_strerror (errno));
return -1;
}
s = zmq_socket (ctx, ZMQ_SUB);
if (!s) {
printf ("error in zmq_socket: %s\n", zmq_strerror (errno));
return -1;
}
con = zmq_bind(socket, fullurl.c_str());
if (con == 0) {
printf ("error in zmq_bind: %s\n", zmq_strerror (errno));
return -1;
}
zmq_msg_t msg;
int rc = zmq_msg_init (&msg);
if (rc != 0) {
printf ("error in zmq_msg_init: %s\n", zmq_strerror (errno));
return -1;
}
for (i = 0; i != roundtrip_count; i++) {
rc = zmq_recvmsg (s, &msg, 0);
if (rc < 0) {
printf ("error in zmq_recvmsg: %s\n", zmq_strerror (errno));
return -1;
}
printf("message received\n");
if (zmq_msg_size (&msg) != message_size) {
printf ("message of incorrect size received\n");
return -1;
}
Sleep(1000);
}
rc = zmq_msg_close (&msg);
if (rc != 0) {
printf ("error in zmq_msg_close: %s\n", zmq_strerror (errno));
return -1;
}
rc = zmq_close (s);
if (rc != 0) {
printf ("error in zmq_close: %s\n", zmq_strerror (errno));
return -1;
}
/*rc = zmq_ctx_term (ctx);
if (rc != 0) {
printf ("error in zmq_ctx_term: %s\n", zmq_strerror (errno));
return -1;
}
ctx = NULL;
*/
return 0;
}
// ZMQ_pgm_send.cpp :
//
#include "stdafx.h"
#include "zmq.h"
#include <iostream>
#include <windows.h>
std::string fullurl = "pgm://eth0;239.255.0.1:30001";
static int roundtrip_count = 50;
static size_t message_size = 4;
int _tmain(int argc, _TCHAR* argv[])
{
void *ctx = NULL,
*s = NULL;
int con;
int i;
ctx = zmq_init (1);
if (!ctx) {
printf ("error in zmq_init: %s\n", zmq_strerror (errno));
return -1;
}
s = zmq_socket (ctx, ZMQ_PUB);
if (!s) {
printf ("error in zmq_socket: %s\n", zmq_strerror (errno));
return -1;
}
con = zmq_connect(socket, fullurl.c_str());
if (con == 0) {
printf ("error in zmq_connect: %s\n", zmq_strerror (errno));
return -1;
}
zmq_msg_t msg;
int rc = zmq_msg_init_size (&msg,message_size);
if (rc != 0) {
printf ("error in zmq_msg_init: %s\n", zmq_strerror (errno));
return -1;
}
memset(zmq_msg_data (&msg),'A', message_size );
for (i = 0; i != roundtrip_count; i++) {
rc = zmq_sendmsg (s, &msg, 0);
if (rc < 0) {
printf ("error in zmq_sendmsg: %s\n", zmq_strerror (errno));
return -1;
}
}
rc = zmq_msg_close (&msg);
if (rc != 0) {
printf ("error in zmq_msg_close: %s\n", zmq_strerror (errno));
return -1;
}
rc = zmq_close (s);
if (rc != 0) {
printf ("error in zmq_close: %s\n", zmq_strerror (errno));
return -1;
}
/*rc = zmq_ctx_term (ctx);
if (rc != 0) {
printf ("error in zmq_ctx_term: %s\n", zmq_strerror (errno));
return -1;
}
ctx = NULL;
*/
return 0;
}
Please correct me if I am doing wrong.
Having solved the [Step 0], proposed above in the comment,
one ought
detect
a Missing ZMQ_SUBSCRIBE setup, thus SUB-side filters all traffic
ZMQ_SUBSCRIBE: Establish message filter
The ZMQ_SUBSCRIBE option shall establish a new message filter on a ZMQ_SUB socket. Newly created ZMQ_SUB sockets shall filter out all incoming messages, therefore you should call this option to establish an initial message filter.
An empty option_value of length zero shall subscribe to all incoming messages. A non-empty option_value shall subscribe to all messages beginning with the specified prefix. Multiple filters may be attached to a single ZMQ_SUB socket, in which case a message shall be accepted if it matches at least one filter.
Anyway, welcome & enjoy these smart tools for distributed systems computing!

WSARecv() receives less bytes than sent

I'm trying to send an image through WinSock. I'm reading the image in blocks of fixed size. The WSASend() sends the right amount of information, but when i'm receiving it, i'm having smaller pieces than the regular blocks.
char* TCPClient::ReadSocket()
{
Flags = 0;
if ((WSARecv(Info->GetSocket(), &(Info->GetWSABufForRead()), 1, &RecvBytes, &Flags, NULL, NULL)) == SOCKET_ERROR) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
sprintf(exceptBuf, "WSARecv() failed with error %d\n", WSAGetLastError());
throw new CException(exceptBuf);
}
else
{
printf("WSARecv() is OK!\n");
}
}
else {
if (RecvBytes == 0) {
return nullptr;
}
Info->SetRecvBytes(RecvBytes);
return Info->ReadBuffer();
}
return nullptr;
}
EDIT: What I actually want to know is how to get the entire block of information.

libssh not return command results

I am using libssh to send a remote command to a computer. This command is real time so I am trying to get databack as it is generated. Basically I am hexdumping a mouse event and I want that data as it comes in. How can I make this return realtime results from my command?
#include <libssh/libssh.h>
#include <stdio.h>
#include <stdlib.h>
/*
* 1) Set ssh options
* 2) Connect
* 3) Authenticate
* 4) Set channels
* 5) Execute command
* */
int main()
{
//Initilization
ssh_session session;
int verbosity = SSH_LOG_PROTOCOL;
int port = 22;
char* password ="root";
int rc;
session = ssh_new();
if (session == NULL)
return(-1);
//Set options for SSH connection
ssh_options_set(session,SSH_OPTIONS_HOST,"90.12.34.44");
ssh_options_set(session,SSH_OPTIONS_LOG_VERBOSITY,&verbosity);
ssh_options_set(session,SSH_OPTIONS_PORT,&port);
ssh_options_set(session,SSH_OPTIONS_USER,"root");
//Connect to server
rc = ssh_connect(session);
if (rc != SSH_OK)
{
fprintf(stderr,"Error connecting to host %s\n",ssh_get_error(session));
ssh_free(session);
return(-1);
}
rc = ssh_userauth_password(session,NULL,password);
if ( rc == SSH_AUTH_SUCCESS)
{
printf("Authenticated correctly");
}
ssh_channel channel;
channel = ssh_channel_new(session);
if(channel == NULL) return SSH_ERROR;
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK)
{
ssh_channel_free(channel);
return rc;
}
rc = ssh_channel_request_exec(channel,"hd /dev/input/event0");
if (rc != SSH_OK)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
char buffer[30];
unsigned int nbytes;
nbytes = ssh_channel_read(channel,buffer,sizeof(buffer),0);
while(nbytes > 0)
{
if(fwrite(buffer,1,nbytes,stdout));
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
nbytes = ssh_channel_read(channel,buffer,sizeof(buffer),0);
if (nbytes < 0)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
return 0;
}
}
If you want to get asynchronous real-time responses from remote file being changed, you'd better try some special async I/O API, like libevent. You will have to write your own client and server, but it's quite simple.
Are you sure you need an encrypted connection? If you are, openSSL is supported by libevent too.
The Problem is in this line my friend
nbytes = ssh_channel_read(channel,buffer,sizeof(buffer),0);
The last parameters is (0) Zero . If you Change it to (1) one , function will fill the buffer with the result of your Command . :D That's it