GIO example for opening a server port? - gtk

Can you please tell me if there is any example for using GIO Server Socket
(the one which I can open a port and listen on socket requests)?
I would like to use it to 'remote-control' my GTK+ application.

I think you should do something like this:
#define MY_PORT 47110
/* Listener callback, this gets called by GTK+ when
* there's socket activity to handle.
*/
static gboolean cb_listener(GIOChannel *source, GIOCondition condition, gpointer data
{
switch(condition)
{
case G_IO_IN:
/* There's data to be read. */
break;
default:
/* An error has occured, or socket is closed. */
return FALSE; /* This tells GIO to remove the source, might be drastic. */
}
return TRUE; /* This tells GIO that all is fine. */
}
Then elsewhere (in a function, maybe main()):
GSocketListener *listener;
listener = g_socket_listener_new();
g_socket_listener_add_inet_port(listener, MY_PORT, NULL, NULL);
g_io_add_watch(G_IO_CHANNEL(listener), G_IO_IN | G_IO_ERR | G_IO_HUP, cb_listener, NULL);

Related

STM32 FreeRTOS - UART Deferred Interrupt Problem

I am trying to read data with unkown size using UART Receive Interrupt. In the call back function, I enabled Rx interrupt in order to read characters until \n is gotten. If \n is get, then higher priority task which is deferred interrupt handler is woken. The problem is that I tried to read one by one byte via call back function and I tried to put each character into a buffer, but unfortunately buffer could not get any character. Moreover, deferred interrupt handler could not be woken.
My STM32 board is STM32F767ZI, and my IDE is KEIL.
Some Important notes before sharing the code:
1. rxIndex and gpsBuffer are declared as global.
2. Periodic function works without any problem.
Here is my code:
Periodic Function, Priority = 1
void vPeriodicTask(void *pvParameters)
{
const TickType_t xDelay500ms = pdMS_TO_TICKS(500UL);
while (1) {
vTaskDelay(xDelay500ms);
HAL_UART_Transmit(&huart3,(uint8_t*)"Imu\r\n",sizeof("Imu\r\n"),1000);
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);
}
}
Deferred Interrupt, Priority = 3
void vHandlerTask(void *pvParameters)
{
const TickType_t xMaxExpectedBlockTime = pdMS_TO_TICKS(1000);
while(1) {
if (xSemaphoreTake(xBinarySemaphore,xMaxExpectedBlockTime) == pdPASS) {
HAL_UART_Transmit(&huart3,(uint8_t*)"Semaphore Acquired\r\n",sizeof("Semaphore
Acquired\r\n"),1000);
// Some important processes will be added here
rxIndex = 0;
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
}
}
}
Call back function:
void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)
{
gpsBuffer[rxIndex++] = rData;
if (rData == 0x0A) {
BaseType_t xHigherPriorityTaskWoken;
xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);
}
Main function
HAL_UART_Receive_IT(&huart3,&rData,1);
xBinarySemaphore = xSemaphoreCreateBinary();
if (xBinarySemaphore != NULL) {
//success
xTaskCreate(vHandlerTask,"Handler",128,NULL,1,&vHandlerTaskHandler);
xTaskCreate(vPeriodicTask,"Periodic",128,NULL,3,&vPeriodicTaskHandler);
vTaskStartScheduler();
}
Using HAL for it is a best way to get into the troubles. It uses HAL_Delay which is systick dependant and you should rewrite this function to read RTOS tick instead.
I use queues to pass the data (the references to data) but it should work. There is always a big question mark when using the HAL functions.
void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
gpsBuffer[rxIndex++] = rData;
if (rData == 0x0A) {
if(xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken) == pdFALSE)
{
/* some error handling */
}
}
HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
Concluding if I use HAL & RTOS I always modify the way HAL handles timeouts.

GTK GIO How to read reply sent by server

I wanted to write a client server thing using gio socket in gtk and I found a sample code to send data to server but, the more thing i want is to read the data/reply sent by the server. The below is sample code
#include <glib.h>
#include <gio/gio.h>
int main (int argc, char *argv[])
{
/* initialize glib */
g_type_init ();
GError * error = NULL;
/* create a new connection */
GSocketConnection * connection = NULL;
GSocketClient * client = g_socket_client_new();
/* connect to the host */
connection = g_socket_client_connect_to_host (client,
(gchar*)"localhost",
1500, /* your port goes here */
NULL,
&error);
/* don't forget to check for errors */
if (error != NULL)
{
g_error (error->message);
}
else
{
g_print ("Connection successful!\n");
}
/* use the connection */
GInputStream * istream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
GOutputStream * ostream = g_io_stream_get_output_stream (G_IO_STREAM (connection));
g_output_stream_write (ostream,
"Hello server!", /* your message goes here */
13, /* length of your message */
NULL,
&error);
/* don't forget to check for errors */
if (error != NULL)
{
g_error (error->message);
}
return 0;
}
The above code works fine for the sending data to server but when i try to read it form input stream it goes in to block state. My read message function look like this
void readMessage()
{
char buffer[2048];
GInputStream * istream = g_io_stream_get_input_stream (G_IO_STREAM(connection));
gssize bytes;
bytes = g_input_stream_read(istream, buffer, sizeof buffer, NULL, NULL);
buffer[bytes] = '\0';
g_print ("%"G_GSSIZE_FORMAT" bytes read: %s\n", bytes, buffer);
}
g_input_stream_read() is documented as blocking until it receives as many bytes as you request (in this case, 2048), or until the connection is closed. Presumably, neither of those things are happening. How big is the reply from the server? Does it close the connection after sending its reply?
Bear in mind that g_socket_client_connect_to_host() opens a TCP connection, so you should expect to be doing stream-based I/O here, rather than message-based I/O. If you expect to be sending messages to and from the server, you will need a framing protocol within TCP.

GIO socket client server for multiple clients

I want to implement a GIO socket client server program where the server can serve up to say 5 clients at the same time. Is this even possible? How can I modify the following standard server to allow multiple clients to connect in a thread safe way? The incoming_callback() function will receive data from a client and do some processing and respond an acknowledgement and this will continue till the client sends an "exit" message at which point the server will close the client connection. I want to do this for a max of say 5 connections at a time for the server. Is it possible and if so how?
int
main (int argc, char **argv)
{
/* initialize glib */
g_type_init();
GError * error = NULL;
/* create the new socketservice */
GSocketService * service = g_socket_service_new ();
/* connect to the port */
g_socket_listener_add_inet_port ((GSocketListener*)service,
1500, /* your port goes here */
NULL,
&error);
/* don't forget to check for errors */
if (error != NULL)
{
g_error (error->message);
}
/* listen to the 'incoming' signal */
g_signal_connect (service,
"incoming",
G_CALLBACK (incoming_callback),
NULL);
/* start the socket service */
g_socket_service_start (service);
/* enter mainloop */
g_print ("Waiting for client!\n");
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
return 0;
}
The magic should happen within your incoming_callback, returning as fast as possible and pushing the work into another GThread (or even better, a GThreadPool)

fetching text messages from sip header or msg body

I am trying to get server text response that sent after i make the dial
am getting the log like this
From: ;tag=as121b5ca6
To: "me" ;tag=FP0KRz3fkxBtR6q19Er1ykMXhHCqtqOU
Call-ID: ltPywl5Qkt5JwdG47.U0K2J.R.YZN0my
CSeq: 103 MESSAGE
User-Agent: Asterisk PBX 1.6.2.18
Content-Type: text/plain;charset=UTF-8
Content-Length: 137
ResultHead=STARS1STARSText=STARS 2764 6053 2778 7089 7541 7156 4997 3457 4438 3666 2246 1307 3666 2246 300 4838 7230 4577 4216 3811 STARS
i want to fetch the 'ResultHead'
knowing that i get many like these messages ..is there any function (am sure there is but i cant see it ) to fetch this messages only or at least the header as string ..
i think i need to use this function but i dunno how!!
static pjsip_rx_data *get_rx_data(pjsip_event *e)
{
if (e->type == PJSIP_EVENT_RX_MSG)
return e->body.rx_msg.rdata;
if (e->type == PJSIP_EVENT_TSX_STATE && e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
return e->body.tsx_state.src.rdata;
// There's no rdata on this eevnt
return NULL;
}
*I use siphon on top of Pjsip ..thnx
i hope my question is clear
looks i ended up answering my question
since its hard to find the answer at least it was for me .. I'll post it in hope that somebody will make use of it ..
first you need to create new module and register it ,
fisrt create the pjsip_module
pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata);
static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata);
static pjsip_module my_pjsua_msg_logger =
{
NULL, NULL, /* prev, next. */
{ "my_mod-pjsua-log", 13 }, /* Name. */
-1, /* Id */
PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */
NULL, /* load() */
NULL, /* start() */
NULL, /* stop() */
NULL, /* unload() */
&logging_on_rx_msg, /* on_rx_request() */
&logging_on_rx_msg, /* on_rx_response() */
&logging_on_tx_msg, /* on_tx_request. */
&logging_on_tx_msg, /* on_tx_response() */
NULL, /* on_tsx_state() */
};
in the sip_connect function use
pjsip_endpt_register_module(pjsua_get_pjsip_endpt(), &my_pjsua_msg_logger);
and now the implementation of the reciepient functions
static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
{
/* Important note:
* tp_info field is only valid after outgoing messages has passed
* transport layer. So don't try to access tp_info when the module
* has lower priority than transport layer.
*/
/* Always return success, otherwise message will not get sent! */
return PJ_SUCCESS;
}
pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
{
NSLog(#"\n recieving rx msg %s--end my joy",rdata->msg_info.msg_buf);
if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG)
{
do something
}
return PJ_FALSE;
}

GetQueuedCompletionStatus blocks forever

I'm writing a server application and I want to use IOCompletion ports, so I wrote a prototype for the server, but I'm facing a problem with GetQueuedCompletionStatus that it never returns(it blocks). Below is my code:
bool CreateSocketOverlappedServer()
{
WSADATA wsaData;
SOCKADDR_IN sockaddr;
if(WSAStartup(MAKEWORD(2,2,),&wsaData)){
_tprintf(_T("Unable to start up\n"));
return false;
}
SrvSocket = WSASocket(AF_INET,SOCK_STREAM,0,NULL,NULL,WSA_FLAG_OVERLAPPED);
if(SrvSocket==INVALID_SOCKET){
_tprintf(_T("Unable to start socket\n"));
return false;
}
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(10000);
sockaddr.sin_addr.s_addr = INADDR_ANY;
/* now bind the socket */
if(bind(SrvSocket, (SOCKADDR *)&sockaddr, sizeof(SOCKADDR_IN))==SOCKET_ERROR){
_tprintf(_T("Unable to bind socket\n"));
return false;
}
if(listen(SrvSocket, 5)==SOCKET_ERROR){
_tprintf(_T("Error listening\n"));
return false;
}
return true;
}
void WorkerThread(void *arg)
{
bool bret= false;
DWORD dwTransferedBytes=0;
CLIENTS *client;
PPER_IO_OPERATION_DATA data;
/* Just sleep for now */
while(true){
_tprintf(_T("Entering while\n"));
bret = GetQueuedCompletionStatus(hIocp,&dwTransferedBytes,(PULONG_PTR)&client,(LPOVERLAPPED *) &data,INFINITE);
if(!bret){
_tprintf(_T("Unable to process completion port\n"));
}
}
//Sleep(10000);
}
void AcceptClientConnections(void *arg)
{
SOCKET ClientSocket;
CLIENTS *c;
_tprintf(_T("Start accepting client connections\n"));
while(true){
ClientSocket = accept(SrvSocket, NULL,NULL);
if(ClientSocket==INVALID_SOCKET){
_tprintf(_T("Unable to accept connection\n"));
continue;
}
/* do an association with completion port */
c = (CLIENTS *)malloc(sizeof(CLIENTS));
c->sock = ClientSocket;
/* associate with completion port */
if(!CreateIoCompletionPort((HANDLE)ClientSocket, hIocp, (ULONG_PTR)c,0)){
_tprintf(_T("Unable to associate with completion port\n: %d"),GetLastError());
}
}
}
Any idea?
thanks in advance.
You are not using the Completion Port correctly, so it has nothing to do, and thus no status to report. Using a Completion Port with sockets is a two-step process, but you are only doing half of the steps.
Read the following MSDN article for details:
Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports
ONe possibility: Check if you have associated the listener socket with the completion port (made this mistake myself). If you haven't the GetQueuedCompletionStatus() will block forever.