bidirectional messages implemented, updated the example code
[profile/ivi/message-port.git] / daemon / server-socket.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * Copyright (C) 2013 Intel Corporation.
5  *
6  * Contact: Amarnath Valluri <amarnath.valluri@linux.intel.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23
24 #include "server-socket.h"
25 #include "libwebsockets.h"
26 #include "priv-libwebsockets.h"
27
28 G_DEFINE_TYPE (MsgPortServerSocket, msgport_server_socket, G_TYPE_OBJECT)
29
30 #define MSGPORT_SERVER_SOCKET_GET_PRIV(obj) \
31     G_TYPE_INSTANCE_GET_PRIVATE ((obj), MSGPORT_TYPE_SERVER_SOCKET, MsgPortServerSocketPrivate)
32
33 struct _MsgPortServerSocketPrivate {
34     GMainLoop *ml;
35     struct libwebsocket_context *context;
36 };
37
38
39 static void
40 _server_socket_finalize (GObject *self)
41 {
42     MsgPortServerSocket *socket = MSGPORT_SERVER_SOCKET (self);
43
44     if (socket->priv->context) {
45         libwebsocket_context_destroy (socket->priv->context);
46         socket->priv->context = NULL;
47     }
48
49     G_OBJECT_CLASS (msgport_server_socket_parent_class)->finalize (self);
50 }
51
52 static void
53 _server_socket_dispose (GObject *self)
54 {
55     G_OBJECT_CLASS (msgport_server_socket_parent_class)->dispose (self);
56 }
57
58 static void
59 msgport_server_socket_init (MsgPortServerSocket *self)
60 {
61     MsgPortServerSocketPrivate *priv = MSGPORT_SERVER_SOCKET_GET_PRIV (self);
62
63     self->priv = priv;
64 }
65
66 static void
67 msgport_server_socket_class_init (MsgPortServerSocketClass *klass)
68 {
69     GObjectClass *gklass = G_OBJECT_CLASS(klass);
70
71     g_type_class_add_private (klass, sizeof(MsgPortServerSocketPrivate));
72
73     gklass->finalize = _server_socket_finalize;
74     gklass->dispose = _server_socket_dispose;
75 }
76
77 struct MsgPortCallbackData {
78     MsgPortServerSocket *self;
79     struct libwebsocket_context *wsctx;
80 };
81
82 static gboolean 
83 _fd_event (
84     GIOChannel *source,
85     GIOCondition condition,
86     gpointer data)
87 {
88     struct pollfd pollfd ;
89     static libwebsocket_context *wsctx = (struct libwebsocket_context *)data;
90
91     pollfd.fd = g_io_channel_get_unix_fd (source);
92     pollfd.events = condition; // FIXME: convert to poll events ??
93     pollfd.revents = ; // FIXME: what it should ?? 
94
95     libwebsocket_service_fd (wsctx, pollfd);
96 };
97
98 static void
99 _add_fd_to_main_loop (
100     MsgPortServerSocket *socket,
101     int fd,
102     int events)
103 {
104     if (socket->priv->ml) {
105         GIOChannel *io = g_io_channel_unix_new (fd);
106         g_io_add_watch (io, events, _fd_event, socket);
107     }
108
109
110 static int
111 _http_callback (
112     struct libwebsocket_context       *context,
113     struct libwebsocket               *wsi,
114     enum libwebsocket_callback_reasons reason,
115     void  *user,
116     void  *in, 
117     size_t len)
118 {
119     switch (reason) {
120         case LWS_CALLBACK_HTTP:
121         /* client connected */
122         break;
123
124         default:
125         g_print ("%s reason %d\n", __FUNCTION_NAME__, reason);
126     }
127
128     return 0;
129 }
130
131 static int
132 _msgport_callback (
133     struct libwebsocket_context       *context,
134     struct libwebsocket               *wsi,
135     enum libwebsocket_callback_reasons reason,
136     void  *user,
137     void  *in, 
138     size_t len)
139 {
140     switch (reason) {
141         case LWS_CALLBACK_ESTABLISHED:
142         break;
143
144         default;
145         g_print ("%s reason %d\n", __FUNCTION_NAME__, reason);
146     }
147
148     return 0;
149 }
150
151
152
153 MsgPortServerSocket *
154 msgport_server_socket_new (GMainLoop *ml)
155 {
156     struct lws_context_creation_info info;
157     static struct libwebsocket_protocols protocols[] = {
158         /* first protocol must always be HTTP handler */
159         { "http-only",   _http_callback,    sizeof (void *), 0, },
160         { "messge-port", _msgport_callback, sizeof (void *), 0, },
161         { NULL, NULL, 0, 0 }
162     };
163
164     MsgPortServerSocket *socket = NULL;
165
166     socket = MSGPORT_SERVER_SOCKET (g_object_new (MSGPORT_TYPE_SERVER_SOCKET, NULL));
167     if (!socket) return NULL;
168
169     info.port = 9000;
170     info.iface = NULL;
171     info.protocols = protocols;
172     info.extensions = libwebsocket_get_internal_extensions();
173     info.ssl_cert_filepath = NULL;
174     info.ssl_private_key_filepath = NULL;
175     info.ssl_cipher_list = NULL;
176     /* FIXME: set socket permessions */
177     info.gid = -1; info.uid = -1;
178     info.options = 0;
179     info.user = socket;
180     info.ka_time = 0;
181     info.ka_probes = 0;
182     info.ka_interval = 0;
183
184     socket->priv->context = libwebsocket_create_context (&info);
185     socket->priv->ml = g_main_loop_ref (ml);
186 }
187
188 gboolean
189 msgport_server_socket_start (MsgPortServerSocket *socket)
190 {
191     g_return_val_if_fail (socket && MSGPORT_IS_SERVER_SOCKET (socket), FALSE);
192
193     if (!socket->priv->ml) {
194         /* run libwesocket loop if no super mainloop */
195         while (1) {
196             libwebsocket_service (socket->priv.>context, 50);
197         }
198     }
199     else {
200         /* integrate to super mainloop */
201     }
202
203     return TRUE;
204 }
205