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 40int 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 75int 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 110int 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 148int 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 186int 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 227struct 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 246struct 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 265struct 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 292struct 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 319struct 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