Home | History | Annotate | Download | only in rbug
      1 /*
      2  * Copyright 2009 VMware, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * on the rights to use, copy, modify, merge, publish, distribute, sub
      9  * license, and/or sell copies of the Software, and to permit persons to whom
     10  * the Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
     19  * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 /*
     26  * This file holds the function implementation for one of the rbug extensions.
     27  * Prototypes and declerations of functions and structs is in the same folder
     28  * in the header file matching this file's name.
     29  *
     30  * The functions starting rbug_send_* encodes a call to the write format and
     31  * sends that to the supplied connection, while functions starting with
     32  * rbug_demarshal_* demarshal data in the wire protocol.
     33  *
     34  * Functions ending with _reply are replies to requests.
     35  */
     36 
     37 #include "rbug_internal.h"
     38 #include "rbug_core.h"
     39 
     40 int rbug_send_noop(struct rbug_connection *__con,
     41                    uint32_t *__serial)
     42 {
     43 	uint32_t __len = 0;
     44 	uint32_t __pos = 0;
     45 	uint8_t *__data = NULL;
     46 	int __ret = 0;
     47 
     48 	LEN(8); /* header */
     49 
     50 	/* align */
     51 	PAD(__len, 8);
     52 
     53 	__data = (uint8_t*)MALLOC(__len);
     54 	if (!__data)
     55 		return -ENOMEM;
     56 
     57 	WRITE(4, int32_t, ((int32_t)RBUG_OP_NOOP));
     58 	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
     59 
     60 	/* final pad */
     61 	PAD(__pos, 8);
     62 
     63 	if (__pos != __len) {
     64 		__ret = -EINVAL;
     65 	} else {
     66 		rbug_connection_send_start(__con, RBUG_OP_NOOP, __len);
     67 		rbug_connection_write(__con, __data, __len);
     68 		__ret = rbug_connection_send_finish(__con, __serial);
     69 	}
     70 
     71 	FREE(__data);
     72 	return __ret;
     73 }
     74 
     75 int rbug_send_ping(struct rbug_connection *__con,
     76                    uint32_t *__serial)
     77 {
     78 	uint32_t __len = 0;
     79 	uint32_t __pos = 0;
     80 	uint8_t *__data = NULL;
     81 	int __ret = 0;
     82 
     83 	LEN(8); /* header */
     84 
     85 	/* align */
     86 	PAD(__len, 8);
     87 
     88 	__data = (uint8_t*)MALLOC(__len);
     89 	if (!__data)
     90 		return -ENOMEM;
     91 
     92 	WRITE(4, int32_t, ((int32_t)RBUG_OP_PING));
     93 	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
     94 
     95 	/* final pad */
     96 	PAD(__pos, 8);
     97 
     98 	if (__pos != __len) {
     99 		__ret = -EINVAL;
    100 	} else {
    101 		rbug_connection_send_start(__con, RBUG_OP_PING, __len);
    102 		rbug_connection_write(__con, __data, __len);
    103 		__ret = rbug_connection_send_finish(__con, __serial);
    104 	}
    105 
    106 	FREE(__data);
    107 	return __ret;
    108 }
    109 
    110 int rbug_send_error(struct rbug_connection *__con,
    111                     uint32_t error,
    112                     uint32_t *__serial)
    113 {
    114 	uint32_t __len = 0;
    115 	uint32_t __pos = 0;
    116 	uint8_t *__data = NULL;
    117 	int __ret = 0;
    118 
    119 	LEN(8); /* header */
    120 	LEN(4); /* error */
    121 
    122 	/* align */
    123 	PAD(__len, 8);
    124 
    125 	__data = (uint8_t*)MALLOC(__len);
    126 	if (!__data)
    127 		return -ENOMEM;
    128 
    129 	WRITE(4, int32_t, ((int32_t)RBUG_OP_ERROR));
    130 	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
    131 	WRITE(4, uint32_t, error); /* error */
    132 
    133 	/* final pad */
    134 	PAD(__pos, 8);
    135 
    136 	if (__pos != __len) {
    137 		__ret = -EINVAL;
    138 	} else {
    139 		rbug_connection_send_start(__con, RBUG_OP_ERROR, __len);
    140 		rbug_connection_write(__con, __data, __len);
    141 		__ret = rbug_connection_send_finish(__con, __serial);
    142 	}
    143 
    144 	FREE(__data);
    145 	return __ret;
    146 }
    147 
    148 int rbug_send_ping_reply(struct rbug_connection *__con,
    149                          uint32_t serial,
    150                          uint32_t *__serial)
    151 {
    152 	uint32_t __len = 0;
    153 	uint32_t __pos = 0;
    154 	uint8_t *__data = NULL;
    155 	int __ret = 0;
    156 
    157 	LEN(8); /* header */
    158 	LEN(4); /* serial */
    159 
    160 	/* align */
    161 	PAD(__len, 8);
    162 
    163 	__data = (uint8_t*)MALLOC(__len);
    164 	if (!__data)
    165 		return -ENOMEM;
    166 
    167 	WRITE(4, int32_t, ((int32_t)RBUG_OP_PING_REPLY));
    168 	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
    169 	WRITE(4, uint32_t, serial); /* serial */
    170 
    171 	/* final pad */
    172 	PAD(__pos, 8);
    173 
    174 	if (__pos != __len) {
    175 		__ret = -EINVAL;
    176 	} else {
    177 		rbug_connection_send_start(__con, RBUG_OP_PING_REPLY, __len);
    178 		rbug_connection_write(__con, __data, __len);
    179 		__ret = rbug_connection_send_finish(__con, __serial);
    180 	}
    181 
    182 	FREE(__data);
    183 	return __ret;
    184 }
    185 
    186 int rbug_send_error_reply(struct rbug_connection *__con,
    187                           uint32_t serial,
    188                           uint32_t error,
    189                           uint32_t *__serial)
    190 {
    191 	uint32_t __len = 0;
    192 	uint32_t __pos = 0;
    193 	uint8_t *__data = NULL;
    194 	int __ret = 0;
    195 
    196 	LEN(8); /* header */
    197 	LEN(4); /* serial */
    198 	LEN(4); /* error */
    199 
    200 	/* align */
    201 	PAD(__len, 8);
    202 
    203 	__data = (uint8_t*)MALLOC(__len);
    204 	if (!__data)
    205 		return -ENOMEM;
    206 
    207 	WRITE(4, int32_t, ((int32_t)RBUG_OP_ERROR_REPLY));
    208 	WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
    209 	WRITE(4, uint32_t, serial); /* serial */
    210 	WRITE(4, uint32_t, error); /* error */
    211 
    212 	/* final pad */
    213 	PAD(__pos, 8);
    214 
    215 	if (__pos != __len) {
    216 		__ret = -EINVAL;
    217 	} else {
    218 		rbug_connection_send_start(__con, RBUG_OP_ERROR_REPLY, __len);
    219 		rbug_connection_write(__con, __data, __len);
    220 		__ret = rbug_connection_send_finish(__con, __serial);
    221 	}
    222 
    223 	FREE(__data);
    224 	return __ret;
    225 }
    226 
    227 struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header)
    228 {
    229 	struct rbug_proto_noop *ret;
    230 
    231 	if (!header)
    232 		return NULL;
    233 	if (header->opcode != (int32_t)RBUG_OP_NOOP)
    234 		return NULL;
    235 
    236 	ret = MALLOC(sizeof(*ret));
    237 	if (!ret)
    238 		return NULL;
    239 
    240 	ret->header.__message = header;
    241 	ret->header.opcode = header->opcode;
    242 
    243 	return ret;
    244 }
    245 
    246 struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header)
    247 {
    248 	struct rbug_proto_ping *ret;
    249 
    250 	if (!header)
    251 		return NULL;
    252 	if (header->opcode != (int32_t)RBUG_OP_PING)
    253 		return NULL;
    254 
    255 	ret = MALLOC(sizeof(*ret));
    256 	if (!ret)
    257 		return NULL;
    258 
    259 	ret->header.__message = header;
    260 	ret->header.opcode = header->opcode;
    261 
    262 	return ret;
    263 }
    264 
    265 struct rbug_proto_error * rbug_demarshal_error(struct rbug_proto_header *header)
    266 {
    267 	uint32_t len = 0;
    268 	uint32_t pos = 0;
    269 	uint8_t *data =  NULL;
    270 	struct rbug_proto_error *ret;
    271 
    272 	if (!header)
    273 		return NULL;
    274 	if (header->opcode != (int32_t)RBUG_OP_ERROR)
    275 		return NULL;
    276 
    277 	pos = 0;
    278 	len = header->length * 4;
    279 	data = (uint8_t*)&header[1];
    280 	ret = MALLOC(sizeof(*ret));
    281 	if (!ret)
    282 		return NULL;
    283 
    284 	ret->header.__message = header;
    285 	ret->header.opcode = header->opcode;
    286 
    287 	READ(4, uint32_t, error); /* error */
    288 
    289 	return ret;
    290 }
    291 
    292 struct rbug_proto_ping_reply * rbug_demarshal_ping_reply(struct rbug_proto_header *header)
    293 {
    294 	uint32_t len = 0;
    295 	uint32_t pos = 0;
    296 	uint8_t *data =  NULL;
    297 	struct rbug_proto_ping_reply *ret;
    298 
    299 	if (!header)
    300 		return NULL;
    301 	if (header->opcode != (int32_t)RBUG_OP_PING_REPLY)
    302 		return NULL;
    303 
    304 	pos = 0;
    305 	len = header->length * 4;
    306 	data = (uint8_t*)&header[1];
    307 	ret = MALLOC(sizeof(*ret));
    308 	if (!ret)
    309 		return NULL;
    310 
    311 	ret->header.__message = header;
    312 	ret->header.opcode = header->opcode;
    313 
    314 	READ(4, uint32_t, serial); /* serial */
    315 
    316 	return ret;
    317 }
    318 
    319 struct rbug_proto_error_reply * rbug_demarshal_error_reply(struct rbug_proto_header *header)
    320 {
    321 	uint32_t len = 0;
    322 	uint32_t pos = 0;
    323 	uint8_t *data =  NULL;
    324 	struct rbug_proto_error_reply *ret;
    325 
    326 	if (!header)
    327 		return NULL;
    328 	if (header->opcode != (int32_t)RBUG_OP_ERROR_REPLY)
    329 		return NULL;
    330 
    331 	pos = 0;
    332 	len = header->length * 4;
    333 	data = (uint8_t*)&header[1];
    334 	ret = MALLOC(sizeof(*ret));
    335 	if (!ret)
    336 		return NULL;
    337 
    338 	ret->header.__message = header;
    339 	ret->header.opcode = header->opcode;
    340 
    341 	READ(4, uint32_t, serial); /* serial */
    342 	READ(4, uint32_t, error); /* error */
    343 
    344 	return ret;
    345 }
    346