1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2009 VMware, Inc.
3bf215546Sopenharmony_ci * All Rights Reserved.
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
9bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
10bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include "rbug.h"
26bf215546Sopenharmony_ci#include "rbug_internal.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "util/u_network.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_cistruct rbug_connection
31bf215546Sopenharmony_ci{
32bf215546Sopenharmony_ci   int socket;
33bf215546Sopenharmony_ci   uint32_t send_serial;
34bf215546Sopenharmony_ci   uint32_t recv_serial;
35bf215546Sopenharmony_ci   enum rbug_opcode opcode;
36bf215546Sopenharmony_ci};
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci/**
39bf215546Sopenharmony_ci * Create a rbug connection from a socket created with u_socket.
40bf215546Sopenharmony_ci *
41bf215546Sopenharmony_ci * Result:
42bf215546Sopenharmony_ci *    A new allocated connection using socket as communication path
43bf215546Sopenharmony_ci */
44bf215546Sopenharmony_cistruct rbug_connection *
45bf215546Sopenharmony_cirbug_from_socket(int socket)
46bf215546Sopenharmony_ci{
47bf215546Sopenharmony_ci   struct rbug_connection *c = CALLOC_STRUCT(rbug_connection);
48bf215546Sopenharmony_ci   c->socket = socket;
49bf215546Sopenharmony_ci   return c;
50bf215546Sopenharmony_ci}
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci/**
53bf215546Sopenharmony_ci * Free a connection, also closes socket.
54bf215546Sopenharmony_ci */
55bf215546Sopenharmony_civoid
56bf215546Sopenharmony_cirbug_disconnect(struct rbug_connection *c)
57bf215546Sopenharmony_ci{
58bf215546Sopenharmony_ci   u_socket_close(c->socket);
59bf215546Sopenharmony_ci   FREE(c);
60bf215546Sopenharmony_ci}
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci/**
63bf215546Sopenharmony_ci * Waits for a message to be fully received.
64bf215546Sopenharmony_ci * Also returns the serial for the message, serial is not touched for replys.
65bf215546Sopenharmony_ci *
66bf215546Sopenharmony_ci * Result:
67bf215546Sopenharmony_ci *    demarshaled message on success, NULL on connection error
68bf215546Sopenharmony_ci */
69bf215546Sopenharmony_cistruct rbug_header *
70bf215546Sopenharmony_cirbug_get_message(struct rbug_connection *c, uint32_t *serial)
71bf215546Sopenharmony_ci{
72bf215546Sopenharmony_ci   struct rbug_proto_header header;
73bf215546Sopenharmony_ci   struct rbug_header *out;
74bf215546Sopenharmony_ci   struct rbug_proto_header *data;
75bf215546Sopenharmony_ci   size_t length = 0;
76bf215546Sopenharmony_ci   size_t read = 0;
77bf215546Sopenharmony_ci   int ret;
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci   ret = u_socket_peek(c->socket, &header, sizeof(header));
81bf215546Sopenharmony_ci   if (ret <= 0) {
82bf215546Sopenharmony_ci      return NULL;
83bf215546Sopenharmony_ci   }
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci   length = (size_t)header.length * 4;
86bf215546Sopenharmony_ci   data = MALLOC(length);
87bf215546Sopenharmony_ci   if (!data) {
88bf215546Sopenharmony_ci      return NULL;
89bf215546Sopenharmony_ci   }
90bf215546Sopenharmony_ci   data->opcode = 0;
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   do {
93bf215546Sopenharmony_ci      uint8_t *ptr = ((uint8_t*)data) + read;
94bf215546Sopenharmony_ci      ret = u_socket_recv(c->socket, ptr, length - read);
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci      if (ret <= 0) {
97bf215546Sopenharmony_ci         FREE(data);
98bf215546Sopenharmony_ci         return NULL;
99bf215546Sopenharmony_ci      }
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci      read += ret;
102bf215546Sopenharmony_ci   } while(read < length);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   out = rbug_demarshal(data);
105bf215546Sopenharmony_ci   if (!out)
106bf215546Sopenharmony_ci      FREE(data);
107bf215546Sopenharmony_ci   else if (serial)
108bf215546Sopenharmony_ci      *serial = c->recv_serial++;
109bf215546Sopenharmony_ci   else
110bf215546Sopenharmony_ci      c->recv_serial++;
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   return out;
113bf215546Sopenharmony_ci}
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci/**
116bf215546Sopenharmony_ci * Frees a message and associated data.
117bf215546Sopenharmony_ci */
118bf215546Sopenharmony_civoid
119bf215546Sopenharmony_cirbug_free_header(struct rbug_header *header)
120bf215546Sopenharmony_ci{
121bf215546Sopenharmony_ci   if (!header)
122bf215546Sopenharmony_ci      return;
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   FREE(header->__message);
125bf215546Sopenharmony_ci   FREE(header);
126bf215546Sopenharmony_ci}
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci/**
129bf215546Sopenharmony_ci * Internal function used by rbug_send_* functions.
130bf215546Sopenharmony_ci *
131bf215546Sopenharmony_ci * Start sending a message.
132bf215546Sopenharmony_ci */
133bf215546Sopenharmony_ciint
134bf215546Sopenharmony_cirbug_connection_send_start(struct rbug_connection *c, enum rbug_opcode opcode, uint32_t length)
135bf215546Sopenharmony_ci{
136bf215546Sopenharmony_ci   c->opcode = opcode;
137bf215546Sopenharmony_ci   return 0;
138bf215546Sopenharmony_ci}
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci/**
141bf215546Sopenharmony_ci * Internal function used by rbug_send_* functions.
142bf215546Sopenharmony_ci *
143bf215546Sopenharmony_ci * Write data to the socket.
144bf215546Sopenharmony_ci */
145bf215546Sopenharmony_ciint
146bf215546Sopenharmony_cirbug_connection_write(struct rbug_connection *c, void *to, uint32_t size)
147bf215546Sopenharmony_ci{
148bf215546Sopenharmony_ci   int ret = u_socket_send(c->socket, to, size);
149bf215546Sopenharmony_ci   return ret;
150bf215546Sopenharmony_ci}
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci/**
153bf215546Sopenharmony_ci * Internal function used by rbug_send_* functions.
154bf215546Sopenharmony_ci *
155bf215546Sopenharmony_ci * Finish writing data to the socket.
156bf215546Sopenharmony_ci * Ups the send_serial and sets the serial argument if supplied.
157bf215546Sopenharmony_ci */
158bf215546Sopenharmony_ciint rbug_connection_send_finish(struct rbug_connection *c, uint32_t *serial)
159bf215546Sopenharmony_ci{
160bf215546Sopenharmony_ci   if (c->opcode < 0)
161bf215546Sopenharmony_ci      return 0;
162bf215546Sopenharmony_ci   else if (serial)
163bf215546Sopenharmony_ci      *serial = c->send_serial++;
164bf215546Sopenharmony_ci   else
165bf215546Sopenharmony_ci      c->send_serial++;
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci   return 0;
168bf215546Sopenharmony_ci}
169