1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#include "response.h"
#include "socket-common.h"
#include "lcd.h"
#include "i2c.h"
#include <string.h>
#include <stdlib.h>
#include <glib.h>
//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 gssize writeOutput(GPollableOutputStream* stream, gchar* data, gssize size);
//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;
size=g_pollable_input_stream_read_nonblocking(inStream, buffer, 1024, NULL, NULL);
if(size == -1) {
g_print_debug("Got: %d\n", size);
return FALSE;
}
//emit a signal which calls the responseCb 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 gssize writeOutput(GPollableOutputStream* stream, gchar* data, gssize size)
{
return g_pollable_output_stream_write_nonblocking(stream, data, size, NULL, NULL);
}
//initialize the signals
void initSignals(guint *signal)
{
*signal = g_signal_new("runEchoService", 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, "runEchoService", G_CALLBACK (responseCb), NULL);
}
//send to client 3 times
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;
gssize len = data->size;
gssize written = 0;
// remove leading and trailing whitespace
g_strstrip (str);
// I2C/LCD test function
LCD_display_error_message(str);
guchar status = 0; // delete me, later - FIXME
// I2C test code
I2C_Write (PCF8574A + Upper_Encoder_Port, 0xff);
status = I2C_Read (PCF8574A + Upper_Encoder_Port);
// dummy response function
gchar* upper = g_ascii_strup(str, len);
gchar *out_string = g_strdup_printf("%s\n%s\n%s\n%x\n",upper,upper,upper,status);
gssize out_len = strlen (out_string);
//send response back to client
written = data->cb(stream, out_string, out_len);
if(written == -1) {
g_print_debug("Could not send message to client\n");
}
g_free(upper);
g_free(out_string);
g_static_mutex_unlock (&mutex);
}
|