#include "response.h" #include "socket-common.h" #include "lcd.h" #include "i2c.h" #include "signalobject.h" #include "parser.h" #include #include #include //RESPONSE related functions from the server extern guint signalMyCb; //signal id extern GAsyncQueue* stdinQueue; //our queue SignalObject* signalObject; //the signal object which registered the signal id //write output to client static void writeOutput(GPollableOutputStream* stream, gchar* data); //callback for client output, this is where the queue messages are sent to the client gboolean cbClientOutput(gpointer data, gpointer additional) { GPollableOutputStream* outStream = (GPollableOutputStream*)data; GAsyncQueue* queue = (GAsyncQueue*)additional; if(g_async_queue_length(queue) <= 0) { return FALSE; } gpointer elem; g_print_debug("Try pop\n"); //try to pop an element from the queue elem=g_async_queue_try_pop(queue); g_print_debug("after pop\n"); if(elem) { char* buf = (char*)elem; g_print_debug("Extracted %s\n", buf); gssize size = strlen(buf); gssize written = 0; written=g_pollable_output_stream_write_nonblocking(outStream, buf, size+1, NULL, NULL); if(written==-1) { g_printerr("Could not write to client\n"); } //free the alloc'ed memory free(buf); } return FALSE; } //the client input callback gboolean cbClientInput(gpointer data, gpointer additional) { char buffer[1024]; gssize size=0; memset(buffer,0,1024); GPollableInputStream* inStream = (GPollableInputStream*)data; GPollableOutputStream* outStream = (GPollableOutputStream*)additional; GError* error = NULL; if(!g_pollable_input_stream_is_readable(inStream)) { return FALSE; } size=g_pollable_input_stream_read_nonblocking(inStream, buffer, 1024, NULL, &error); if(error && error->message) { g_print_debug("Error: %s\n",error->message); return FALSE; } if(size <= 0) { g_print_debug("Got: %d\n", size); return FALSE; } //emit a signal which calls the echoCb function SignalObjectClass myStruct; myStruct.instance = NULL; myStruct.cb = writeOutput; myStruct.data = buffer; myStruct.size = size; myStruct.inStream = inStream; myStruct.outStream = outStream; g_signal_emit(signalObject, signalMyCb, 0, &myStruct, NULL); return TRUE; } //write output to client static void writeOutput(GPollableOutputStream* stream, gchar* data) { gssize written_bytes = 0; gchar *terminated; if (data==NULL) { terminated = g_strdup("\r\n"); } else if (!strlen(data)) { terminated = g_strdup("> "); } else { terminated = g_strdup_printf ("%s\r\n", data); } written_bytes = g_pollable_output_stream_write_nonblocking(stream, terminated, strlen(terminated), NULL, NULL); if (written_bytes == -1) { g_print("Could not send message to client\n"); } g_free (terminated); return; } //initialize the signals void initSignals(guint *signal) { *signal = g_signal_new("runService", SIGNAL_OBJECT_TYPE, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER , G_TYPE_NONE, 1, G_TYPE_POINTER); signalObject = g_object_new(SIGNAL_OBJECT_TYPE, NULL); g_signal_connect (signalObject, "runService", G_CALLBACK (responseCb), NULL); } //parse message and send to client void responseCb(gpointer instance, GObject *arg1, gpointer user_data) { static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_static_mutex_lock (&mutex); SignalObjectClass *data = (SignalObjectClass*)arg1; GPollableOutputStream* stream = (GPollableOutputStream*)data->outStream; gchar* str = data->data; g_strstrip(str); // I2C/LCD test functions - start guchar status = I2C_Read (PCF8574A + Upper_Encoder_Port); gchar *lcd_str = g_strdup_printf ("%s %x",str,status); LCD_display_error_message(lcd_str); // I2C/LCD test functions - stop // FIXME - Parser_main may generate multiple responses Parser_main(str, 1, data->cb, stream); g_static_mutex_unlock (&mutex); }