00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdarg.h>
00018 #include <string.h>
00019 #include <stdlib.h>
00020
00021 #include <errno.h>
00022 #include <time.h>
00023 #include <assert.h>
00024
00025 #include "xmmspriv/xmms_list.h"
00026 #include "xmmsc/xmmsc_ipc_transport.h"
00027 #include "xmmsc/xmmsc_ipc_msg.h"
00028 #include "xmmsc/xmmsc_util.h"
00029 #include "xmmsc/xmmsc_sockets.h"
00030 #include "xmmsc/xmmsc_stdint.h"
00031 #include "xmmsc/xmmsv_coll.h"
00032
00033 struct xmms_ipc_msg_St {
00034 xmmsv_t *bb;
00035 uint32_t xfered;
00036 };
00037
00038
00039
00040 xmms_ipc_msg_t *
00041 xmms_ipc_msg_alloc (void)
00042 {
00043 xmms_ipc_msg_t *msg;
00044 static unsigned char empty[16] = {0,};
00045
00046 msg = x_new0 (xmms_ipc_msg_t, 1);
00047 msg->bb = xmmsv_bitbuffer_new ();
00048 xmmsv_bitbuffer_put_data (msg->bb, empty, 16);
00049
00050 return msg;
00051 }
00052
00053 void
00054 xmms_ipc_msg_destroy (xmms_ipc_msg_t *msg)
00055 {
00056 x_return_if_fail (msg);
00057
00058 xmmsv_unref (msg->bb);
00059 free (msg);
00060 }
00061
00062 static void
00063 xmms_ipc_msg_update_length (xmmsv_t *bb)
00064 {
00065 int len;
00066
00067 len = xmmsv_bitbuffer_len (bb);
00068
00069 len /= 8;
00070 len -= XMMS_IPC_MSG_HEAD_LEN;
00071
00072 xmmsv_bitbuffer_goto (bb, 12*8);
00073 xmmsv_bitbuffer_put_bits (bb, 32, len);
00074 xmmsv_bitbuffer_end (bb);
00075 }
00076
00077 static uint32_t
00078 xmms_ipc_msg_get_length (const xmms_ipc_msg_t *msg)
00079 {
00080 int len, p;
00081 x_return_val_if_fail (msg, 0);
00082
00083 p = xmmsv_bitbuffer_pos (msg->bb);
00084 xmmsv_bitbuffer_goto (msg->bb, 12*8);
00085 xmmsv_bitbuffer_get_bits (msg->bb, 32, &len);
00086 xmmsv_bitbuffer_goto (msg->bb, p);
00087 return len;
00088 }
00089
00090 uint32_t
00091 xmms_ipc_msg_get_object (const xmms_ipc_msg_t *msg)
00092 {
00093 int obj, p;
00094 x_return_val_if_fail (msg, 0);
00095
00096 p = xmmsv_bitbuffer_pos (msg->bb);
00097 xmmsv_bitbuffer_goto (msg->bb, 0);
00098 xmmsv_bitbuffer_get_bits (msg->bb, 32, &obj);
00099 xmmsv_bitbuffer_goto (msg->bb, p);
00100 return obj;
00101 }
00102
00103 static void
00104 xmms_ipc_msg_set_object (xmms_ipc_msg_t *msg, uint32_t object)
00105 {
00106 x_return_if_fail (msg);
00107
00108 xmmsv_bitbuffer_goto (msg->bb, 0);
00109 xmmsv_bitbuffer_put_bits (msg->bb, 32, object);
00110 xmmsv_bitbuffer_end (msg->bb);
00111 }
00112
00113 uint32_t
00114 xmms_ipc_msg_get_cmd (const xmms_ipc_msg_t *msg)
00115 {
00116 int cmd, p;
00117 x_return_val_if_fail (msg, 0);
00118
00119 p = xmmsv_bitbuffer_pos (msg->bb);
00120 xmmsv_bitbuffer_goto (msg->bb, 4 * 8);
00121 xmmsv_bitbuffer_get_bits (msg->bb, 32, &cmd);
00122 xmmsv_bitbuffer_goto (msg->bb, p);
00123 return cmd;
00124 }
00125
00126 static void
00127 xmms_ipc_msg_set_cmd (xmms_ipc_msg_t *msg, uint32_t cmd)
00128 {
00129 x_return_if_fail (msg);
00130
00131 xmmsv_bitbuffer_goto (msg->bb, 4 * 8);
00132 xmmsv_bitbuffer_put_bits (msg->bb, 32, cmd);
00133 xmmsv_bitbuffer_end (msg->bb);
00134 }
00135
00136 void
00137 xmms_ipc_msg_set_cookie (xmms_ipc_msg_t *msg, uint32_t cookie)
00138 {
00139 xmmsv_bitbuffer_goto (msg->bb, 8 * 8);
00140 xmmsv_bitbuffer_put_bits (msg->bb, 32, cookie);
00141 xmmsv_bitbuffer_end (msg->bb);
00142 }
00143
00144 uint32_t
00145 xmms_ipc_msg_get_cookie (const xmms_ipc_msg_t *msg)
00146 {
00147 int cookie, p;
00148 x_return_val_if_fail (msg, 0);
00149
00150 p = xmmsv_bitbuffer_pos (msg->bb);
00151 xmmsv_bitbuffer_goto (msg->bb, 8 * 8);
00152 xmmsv_bitbuffer_get_bits (msg->bb, 32, &cookie);
00153 xmmsv_bitbuffer_goto (msg->bb, p);
00154 return cookie;
00155 }
00156
00157 xmms_ipc_msg_t *
00158 xmms_ipc_msg_new (uint32_t object, uint32_t cmd)
00159 {
00160 xmms_ipc_msg_t *msg;
00161
00162 msg = xmms_ipc_msg_alloc ();
00163
00164 xmms_ipc_msg_set_cmd (msg, cmd);
00165 xmms_ipc_msg_set_object (msg, object);
00166
00167 return msg;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 bool
00180 xmms_ipc_msg_write_transport (xmms_ipc_msg_t *msg,
00181 xmms_ipc_transport_t *transport,
00182 bool *disconnected)
00183 {
00184 char *buf;
00185 unsigned int ret, len;
00186
00187 x_return_val_if_fail (msg, false);
00188 x_return_val_if_fail (transport, false);
00189
00190 xmmsv_bitbuffer_align (msg->bb);
00191
00192 len = xmmsv_bitbuffer_len (msg->bb) / 8;
00193
00194 x_return_val_if_fail (len > msg->xfered, true);
00195
00196 buf = (char *) (xmmsv_bitbuffer_buffer (msg->bb) + msg->xfered);
00197 ret = xmms_ipc_transport_write (transport, buf, len - msg->xfered);
00198
00199 if (ret == SOCKET_ERROR) {
00200 if (xmms_socket_error_recoverable ()) {
00201 return false;
00202 }
00203
00204 if (disconnected) {
00205 *disconnected = true;
00206 }
00207
00208 return false;
00209 } else if (!ret) {
00210 if (disconnected) {
00211 *disconnected = true;
00212 }
00213 } else {
00214 msg->xfered += ret;
00215 }
00216
00217 return (len == msg->xfered);
00218 }
00219
00220
00221
00222
00223
00224
00225 bool
00226 xmms_ipc_msg_read_transport (xmms_ipc_msg_t *msg,
00227 xmms_ipc_transport_t *transport,
00228 bool *disconnected)
00229 {
00230 char buf[512];
00231 unsigned int ret, len, rlen;
00232
00233 x_return_val_if_fail (msg, false);
00234 x_return_val_if_fail (transport, false);
00235
00236 while (true) {
00237 len = XMMS_IPC_MSG_HEAD_LEN;
00238
00239 if (msg->xfered >= XMMS_IPC_MSG_HEAD_LEN) {
00240 len += xmms_ipc_msg_get_length (msg);
00241
00242 if (msg->xfered == len) {
00243 return true;
00244 }
00245 }
00246
00247 x_return_val_if_fail (msg->xfered < len, false);
00248
00249 rlen = len - msg->xfered;
00250 if (rlen > sizeof (buf))
00251 rlen = sizeof (buf);
00252
00253 ret = xmms_ipc_transport_read (transport, buf, rlen);
00254
00255 if (ret == SOCKET_ERROR) {
00256 if (xmms_socket_error_recoverable ()) {
00257 return false;
00258 }
00259
00260 if (disconnected) {
00261 *disconnected = true;
00262 }
00263
00264 return false;
00265 } else if (ret == 0) {
00266 if (disconnected) {
00267 *disconnected = true;
00268 }
00269
00270 return false;
00271 } else {
00272 xmmsv_bitbuffer_goto (msg->bb, msg->xfered * 8);
00273 xmmsv_bitbuffer_put_data (msg->bb, (unsigned char *) buf, ret);
00274 msg->xfered += ret;
00275 xmmsv_bitbuffer_goto (msg->bb, XMMS_IPC_MSG_HEAD_LEN * 8);
00276 }
00277 }
00278 }
00279
00280 uint32_t
00281 xmms_ipc_msg_put_value (xmms_ipc_msg_t *msg, xmmsv_t *v)
00282 {
00283 if (!xmmsv_bitbuffer_serialize_value (msg->bb, v))
00284 return false;
00285 xmms_ipc_msg_update_length (msg->bb);
00286 return xmmsv_bitbuffer_pos (msg->bb);
00287 }
00288
00289
00290 bool
00291 xmms_ipc_msg_get_value (xmms_ipc_msg_t *msg, xmmsv_t **val)
00292 {
00293 return xmmsv_bitbuffer_deserialize_value (msg->bb, val);
00294 }