* Runs a JSON-RPC command (request or notification) * Params: * dst: destination of the command * cmd: comand to send * id: if present, unique ID of the command, otherwise this is a notification * ret: value returned in case of a request * * Returns: * -2: communication error * -3: reply error * 1: success */
| 257 | * 1: success |
| 258 | */ |
| 259 | static int jsonrpc_handle_cmd(union sockaddr_union *dst, char *cmd, int *id, |
| 260 | pv_value_t *vret) |
| 261 | { |
| 262 | int r, fd, ret = -2; |
| 263 | unsigned int cmd_len; |
| 264 | struct timeval begin; |
| 265 | struct pollfd pf; |
| 266 | int tout_left, total; |
| 267 | cJSON *obj = NULL, *aux; |
| 268 | |
| 269 | char buffer[JSONRPC_DEFAULT_BUFFER_SIZE + 1/* null terminate */]; |
| 270 | |
| 271 | /* connect to the destination */ |
| 272 | fd = jsonrpc_get_fd(dst); |
| 273 | if (fd < 0) { |
| 274 | LM_ERR("cannot get a connection to %s:%hu\n", JSONRPC_PRINT(dst)); |
| 275 | return -2; |
| 276 | } |
| 277 | |
| 278 | /* we have a connection - send the command now */ |
| 279 | cmd_len = strlen(cmd); |
| 280 | |
| 281 | if (tsend_stream(fd, cmd, cmd_len, jrpc_write_timeout) < 0) { |
| 282 | LM_ERR("cannot send stream to %s:%hu\n", JSONRPC_PRINT(dst)); |
| 283 | goto end; |
| 284 | } |
| 285 | |
| 286 | /* notification - no need to wait for a reply */ |
| 287 | if (!id) { |
| 288 | ret = 1; |
| 289 | goto end; |
| 290 | } |
| 291 | |
| 292 | /* read the reply */ |
| 293 | pf.fd = fd; |
| 294 | pf.events = POLLIN; |
| 295 | |
| 296 | total = 0; |
| 297 | gettimeofday(&begin, NULL); |
| 298 | while (1) { |
| 299 | /* compute how long we are allowed to block */ |
| 300 | tout_left = jrpc_read_timeout - (get_time_diff(&begin) / 1000); |
| 301 | if (tout_left <= 0) { |
| 302 | LM_ERR("read timeout reached (%s:%hu)\n", JSONRPC_PRINT(dst)); |
| 303 | goto end; |
| 304 | } |
| 305 | r = poll(&pf, 1, tout_left); |
| 306 | if (r < 0) { |
| 307 | if (errno == EINTR) |
| 308 | continue; |
| 309 | LM_ERR("poll failed: %s [%d\n", strerror(errno), errno); |
| 310 | goto end; |
| 311 | } |
| 312 | if (pf.revents & POLLIN) { |
| 313 | /* now we can read */ |
| 314 | r = read(fd, buffer + total, JSONRPC_DEFAULT_BUFFER_SIZE - total); |
| 315 | if (r < 0) { |
| 316 | if (errno == EINTR) |
no test coverage detected