Пример #1
0
/**
 * Handles incoming data on a client connection.
 * @param socket_server Socket server
 * @param conn Client connection
 */
static void handle_connection(struct lwpb_transport_socket_server *socket_server,
        struct lwpb_socket_server_conn *conn)
{
    void *res_buf;
    size_t res_len;
    ssize_t len;
    size_t used;
    struct protocol_header_info info;
    lwpb_err_t ret;
    
    used = conn->pos - conn->buf;
    
    len = recv(conn->socket, conn->pos, conn->len - used, 0);
    if (len <= 0) {
        close_connection(socket_server, conn);
        return;
    }
    
    conn->pos += len;
    used = conn->pos - conn->buf;
    
    LWPB_DEBUG("Client(%d) received %d bytes", conn->index, len);
    
    // Try to decode the request
    ret = parse_request(conn->buf, used, &info, socket_server->server->service_list);
    if (ret != PARSE_ERR_OK)
        return;
    
    LWPB_DEBUG("Client(%d) received request header", conn->index);
    LWPB_DEBUG("type = %d, service = %p, method = %p, header_len = %d, msg_len = %d",
               info.msg_type, info.service_desc, info.method_desc,
               info.header_len, info.msg_len);
    
    if (!info.service_desc) {
        // TODO unknown service
    }
    
    if (!info.method_desc) {
        // TODO unknown method
    }
    
    // Allocate response buffer
    ret = lwpb_transport_alloc_buf(&socket_server->super, &res_buf, &res_len);
    if (ret != LWPB_ERR_OK) {
        // TODO handle memory error
    }
    
    ret = socket_server->server->call_handler(
        socket_server->server, info.method_desc,
        info.method_desc->req_desc,conn->buf + info.header_len, info.msg_len,
        info.method_desc->res_desc, res_buf, &res_len,
        socket_server->server->arg);
    
    // Send response back to server
    send_response(conn->socket, info.method_desc, res_buf, res_len);
    
    lwpb_transport_free_buf(&socket_server->super, res_buf);
}
Пример #2
0
/**
 * Closes the socket client.
 * @param transport Transport handle
 */
void lwpb_transport_socket_client_close(lwpb_transport_t transport)
{
    struct lwpb_transport_socket_client *socket_client =
        (struct lwpb_transport_socket_client *) transport;
    int i;
    
    if (socket_client->socket == -1)
        return;
    
    // Free receive buffer
    lwpb_transport_free_buf(transport, socket_client->buf);
    
    // Close socket
    close(socket_client->socket);
    socket_client->socket == -1;
}
Пример #3
0
/**
 * This method is called from the client to start an RPC call.
 * @param transport Transport implementation
 * @param client Client
 * @param method_desc Method descriptor
 * @return Returns LWPB_ERR_OK if successful.
 */
static lwpb_err_t transport_call(lwpb_transport_t transport,
                                 struct lwpb_client *client,
                                 const struct lwpb_method_desc *method_desc)
{
    struct lwpb_transport_socket_client *socket_client =
        (struct lwpb_transport_socket_client *) transport;
    lwpb_err_t ret = LWPB_ERR_OK;
    void *req_buf = NULL;
    size_t req_len;
    
    // Only continue if connected to server
    if (socket_client->socket == -1) {
        client->done_handler(client, method_desc,
                             LWPB_RPC_NOT_CONNECTED, client->arg);
        goto out;
    }
    
    // Allocate a buffer for the request message
    ret = lwpb_transport_alloc_buf(transport, &req_buf, &req_len);
    if (ret != LWPB_ERR_OK)
        goto out;
    
    // Encode the request message
    ret = client->request_handler(client, method_desc, method_desc->req_desc,
                                  req_buf, &req_len, client->arg);
    if (ret != LWPB_ERR_OK)
        goto out;

    
    socket_client->last_method = method_desc;
    
    // Send the request to the server
    // TODO check result
    send_request(socket_client->socket, method_desc, req_buf, req_len);
    
out:
    // Free allocated requiest message buffer
    if (req_buf)
        lwpb_transport_free_buf(transport, req_buf);
    
    return ret;
}
Пример #4
0
/**
 * This method is called from the client to start an RPC call.
 * @param transport Transport implementation
 * @param client Client
 * @param method_desc Method descriptor
 * @return Returns LWPB_ERR_OK if successful.
 */
static lwpb_err_t transport_call(lwpb_transport_t transport,
                                 struct lwpb_client *client,
                                 const struct lwpb_method_desc *method_desc)
{
    struct lwpb_transport_socket_server *socket_server =
        (struct lwpb_transport_socket_server *) transport;
    lwpb_err_t ret = LWPB_ERR_OK;
    void *req_buf = NULL;
    size_t req_len;
    void *res_buf = NULL;
    size_t res_len;
    
    // Allocate a buffer for the request message
    ret = lwpb_transport_alloc_buf(transport, &req_buf, &req_len);
    if (ret != LWPB_ERR_OK)
        goto out;
    
    // Allocate a buffer for the response message
    ret = lwpb_transport_alloc_buf(transport, &res_buf, &res_len);
    if (ret != LWPB_ERR_OK)
        goto out;

    // Encode the request message
    ret = client->request_handler(client, method_desc, method_desc->req_desc,
                                  req_buf, &req_len, client->arg);
    if (ret != LWPB_ERR_OK)
        goto out;
    
    // We need a registered server to continue
    if (!socket_server->server) {
        client->done_handler(client, method_desc,
                             LWPB_RPC_NOT_CONNECTED, client->arg);
        goto out;
    }
    
    // Process the call on the server
    ret = socket_server->server->call_handler(socket_server->server, method_desc,
                                              method_desc->req_desc, req_buf, req_len,
                                              method_desc->res_desc, res_buf, &res_len,
                                              socket_server->server->arg);
    if (ret != LWPB_ERR_OK) {
        client->done_handler(client, method_desc,
                             LWPB_RPC_FAILED, client->arg);
        goto out;
    }
    
    // Process the response in the client
    ret = client->response_handler(client, method_desc,
                                   method_desc->res_desc, res_buf, res_len,
                                   client->arg);
    
    client->done_handler(client, method_desc, LWPB_RPC_OK, client->arg);
    
out:
    // Free allocated message buffers
    if (req_buf)
        lwpb_transport_free_buf(transport, req_buf);
    if (res_buf)
        lwpb_transport_free_buf(transport, res_buf);
    
    return ret;
}