Пример #1
0
/*  
 *   Code to Send AMP message
 */
void do_sum_call(AMP_Proto_T *proto, Sum_State_T sum_state)
{
    int ret;
    AMP_Box_T *box = amp_new_box();
    amp_put_long_long(box, "a", sum_state->operands[sum_state->idx]);
    amp_put_long_long(box, "b", sum_state->operands[sum_state->idx+1]);

    sum_state->idx++;

    ret = amp_call(proto, "Sum", box, resp_cb, sum_state,
                   &(sum_state->lastAskKey));
    if (ret)
    {
        fprintf(stderr, "amp_call() failed: %s\n", amp_strerror(ret));
        exit(1);
    }
}
Пример #2
0
/*  
 *   Code to Get reply
 */
void resp_cb(AMP_Proto_T *proto, AMP_Result_T *result, void *callback_arg)
{
    Sum_State_T sum_state = callback_arg;
    int ret;
    long long total;

    switch (result->reason)
    {
    case AMP_SUCCESS:
        /* Decode reply keyword value 'total' */
        if ( (ret = amp_get_long_long((result->response)->args,
                                      "total", &total)) != 0) {
            fprintf(stderr, "Couldn't get total key: %s\n", amp_strerror(ret));
            exit(1);
        }
        amp_free_result(result);

        if (sum_state->idx == sum_state->max_idx)
        {
            printf("Finished sums. Total: %lld\n", total);
            exit(0);
        }
        else
        {
            sum_state->operands[sum_state->idx] = total;
            do_sum_call(proto, sum_state);
        }
        break;
    case AMP_ERROR:
        fprintf(stderr, "Got AMP error from remote peer.\n");
        if ((result->error)->error_code)
            fprintf(stderr, "Code: %s\n", (result->error)->error_code->value);
            fprintf(stderr, "Description: %s\n",
                    (result->error)->error_descr->value);

        amp_free_result(result);
        exit(1);
        break;
    }
}
Пример #3
0
int _amp_process_full_packet(AMP_Proto_T *proto, AMP_Box_T *box)
{
    /* Dispatch the box that has been accumulated by the given AMP_Proto .
     *
     * Returns 0 on success or an AMP_* code on failure.
     *
     * TODO - do we check for insane boxes that have e.g.
     *        an _answer and an _error key? */
    amp_error_t ret = 0;

    if (amp_num_keys(box) == 0)
        return AMP_BOX_EMPTY;

    if (amp_has_key(box, COMMAND))
    {
        debug_print("Received %s box.\n", COMMAND);

        AMP_Request_T *request;
        if ( (ret = _amp_new_request_from_box(box, &request)) != 0)
            return ret;

        proto->box = NULL; /* forget the box that is now held by the
                              request object */

        _AMP_Responder_p responder;
        if ( (responder = _amp_get_responder(proto->responders,
                                             request->command->value)) != NULL)
        {
            /* Fire off user-supplied responder */
            (responder->func)(proto, request, responder->arg);
        }
        else
        {
            amp_log("No handler for command: %s", request->command->value);

            /* send error to remote peer if _ask key present.
             * (ret == 0 before this point) */
            if (request->ask_key != NULL)
            {
                ret = _amp_send_unhandled_command_error(proto, request);
            }

            /* This free's the box too */
            amp_free_request(request);
            return ret;
        }
    }
    else if (amp_has_key(box, ANSWER))
    {
        debug_print("Received %s box.\n", ANSWER);

        AMP_Response_T *response;
        if ( (ret = _amp_new_response_from_box(box, &response)) != 0)
            return ret;

        proto->box = NULL; /* forget the box that is now held by the newly
                              created response object */

        _AMP_Callback_p cb;
        if ((cb = _amp_pop_callback(proto->outstanding_requests,
                                    response->answer_key)) != NULL) {
            AMP_Result_T *result;
            if ( (ret = _amp_new_result_with_response(response, &result)) != 0)
            {
                amp_free_response(response);
                _amp_free_callback(cb);
                return ret;
            }

            (cb->func)(proto, result, cb->arg);
            _amp_free_callback(cb);

        }
        else
        {
            amp_log("Got unknown _answer key: %u", response->answer_key);
            amp_free_response(response); /* free's the box too */
            return 0;
        }

    }
    else if (amp_has_key(box, _ERROR))
    {
        debug_print("Received %s box.\n", _ERROR);

        AMP_Error_T *error;
        if ( (ret = _amp_new_error_from_box(box, &error)) != 0)
            return ret;

        /* _amp_new_error_from_box was successful which means the box has
         * been free'd - so forget it to avoid a potential double-free() */
        proto->box = NULL;

        _AMP_Callback_p cb;
        if ((cb = _amp_pop_callback(proto->outstanding_requests,
                                    error->answer_key)) != NULL) {

            AMP_Result_T *result;
            if ( (ret = _amp_new_result_with_error(error, &result)) != 0)
            {
                amp_free_error(error);
                _amp_free_callback(cb);
                return ret;
            }

            (cb->func)(proto, result, cb->arg);
            _amp_free_callback(cb);

        }
        else
        {
            amp_log("Got unknown _error key: %u", error->answer_key);
            amp_free_error(error);
            return 0;
        }


    }
    else
    {
        amp_log("Invalid protocol data: %s", amp_strerror(AMP_REQ_KEY_MISSING));
        return AMP_REQ_KEY_MISSING;
    }

    return 0;
}
Пример #4
0
int main(int argc, char *argv[])
{
    if (argc < 4)
        usage();

    char buf[256];
    int ret;

    char server_hostname[NI_MAXHOST];
    int server_port;
    int client_sock;

    Sum_State_T sum_state;
    if ( (sum_state = malloc(sizeof(*sum_state))) == NULL)
    {
        fprintf(stderr, "ERROR allocating Sum_State_T: %s\n", strerror(errno));
        exit(1);
    }

    sum_state->idx = 0;

    /* first operand begins at argv[2] */
    sum_state->max_idx = argc - 3;

    /* do we have too many operands? */
    if (sum_state->max_idx >= MAX_OPERANDS)
        usage();

    /* Convert operand arguments to numbers */
    const char *errstr;
    int i;
    for (i = 0; i <= sum_state->max_idx; i++)
    {
        sum_state->operands[i] = strtonum(argv[i+2], LLONG_MIN, LLONG_MAX, &errstr);
        if (errstr != NULL)
            usage();
    }

    /* split IP from port number */
    if (parse_host_port(argv[1], server_hostname, NI_MAXHOST, &server_port) != 0)
        usage();

/* Windows is dumb */
#ifdef WIN32
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        fprintf(stderr, "WSAStartup() failed.\n");
        exit(1);
    }
#endif

    fprintf(stderr, "Connecting to server...");
    /* Connect to server */
    if ((client_sock = connect_tcp(server_hostname, server_port, &errstr)) == -1)
    {
        fprintf(stderr, "Failed to connect: %s\n", errstr);
        return 1;
    }
    fprintf(stderr, "Done.\n");

    /* Done connecting... set up AMP Protocol */

    AMP_Proto_T *proto;
    if ( (proto = amp_new_proto()) == NULL)
    {
        fprintf(stderr, "Couldn't allocate AMP_Proto.\n");
        return 1;
    };

    amp_set_write_handler(proto, do_write, &client_sock);

    /* Set up libamp logging to stderr for any error messages that
     * it wishes to report */
    amp_set_log_handler(amp_stderr_logger);

    /* Make first call... */

    do_sum_call(proto, sum_state);

    /* Start reading loop */

    int bytesRead;
    while ( (bytesRead = recv(client_sock, buf, sizeof(buf), 0)) >= 0)
    {
        if ( (ret = amp_consume_bytes(proto, buf, bytesRead)) != 0)
        {
            fprintf(stderr, "ERROR detected by amp_consume_bytes(): %s\n", amp_strerror(ret));
            return 1;
        };
    }

    return 0;
}