| /* |
| * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| /* |
| * qmidev: internal interface to the top-level QMI device object. |
| * |
| * (Also see ../include/qmidev.h for the public interface.) |
| */ |
| |
| #ifndef LIBQMI_QMIDEV_H |
| #define LIBQMI_QMIDEV_H |
| |
| #include <libqmi.h> |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| struct qmidev; |
| struct qmimsg; |
| struct callback; |
| |
| struct client; |
| |
| typedef void (*client_create_fn)(struct qmidev *qmidev, |
| struct client *client); |
| |
| typedef void (*client_destroy_fn)(struct qmidev *qmidev, |
| struct client *client); |
| |
| typedef int (*request_fn)(void *context, |
| struct qmimsg *message); |
| |
| typedef void (*response_fn)(struct qmidev *qmidev, |
| void *context, |
| int status, |
| struct qmimsg *message); |
| |
| typedef void (*event_fn)(struct qmidev *qmidev, |
| void *user_callback, |
| void *user_context, |
| uint16_t length, |
| void *value); |
| |
| struct event { |
| uint8_t type; |
| struct listener *listener; |
| event_fn callback; |
| void *user_callback; |
| void *user_context; |
| }; |
| |
| struct service { |
| uint8_t service_id; |
| uint16_t event_msg_id; |
| |
| client_create_fn create_fn; |
| client_destroy_fn destroy_fn; |
| }; |
| |
| #define INIT_SERVICE(id, event_msg_id) { (id), (event_msg_id), NULL, NULL } |
| |
| void *client_priv(struct client *client); |
| |
| void client_set_priv(struct client *client, void *priv); |
| |
| /** |
| * Fills in a struct event. |
| * |
| * @event: the struct event to fill in |
| * @type: the type of the TLV element representing the event |
| * @callback: the callback used to call the user's callback when the event |
| * happens |
| */ |
| void event_init(struct event *event, uint8_t type, event_fn callback); |
| |
| /** Callback type for qmidev_get_client */ |
| typedef void (*qmidev_client_fn)(struct qmidev *qmidev, |
| void *context, |
| int status, |
| struct client *client); |
| |
| /** |
| * Allocates a client for a particular service on the card. |
| */ |
| int qmidev_get_client(struct qmidev *qmidev, |
| struct service *service, |
| qmidev_client_fn callback, |
| void *context); |
| |
| |
| /** |
| * Releases an allocated client. |
| */ |
| int qmidev_release_client(struct qmidev *qmidev, |
| struct client *client, |
| qmidev_response_fn callback, |
| void *context); |
| |
| /** |
| * Returns the default client for a given service. |
| */ |
| struct client *qmidev_default_client(struct qmidev *qmidev, |
| struct service *service); |
| |
| /* |
| * General request structure: |
| * |
| * Most requests will have four declarations: |
| * |
| * 1. a context struct to be passed to the response handler. This stores the |
| * callback and context passed to the main request function, so the |
| * response handler can call the callback after extracting any returned |
| * data from the response message. |
| * |
| * 2. (optional) a make_request function. If the request requires any TLVs to |
| * be included in the request message, this function takes a QMI message |
| * and a context pointer and adds the data to the message. (This is a |
| * separate function because it makes things neater for requests that don't |
| * have any parameter -- a NULL make_request function simply isn't called.) |
| * |
| * 3. a handle_response function. This is called when a response to the |
| * request is received, and is responsible for getting any returned data |
| * from the response message, calling the original callback, and freeing |
| * the context. |
| * |
| * 4. the main request function. This allocates a context and calls |
| * qmidev_request with pointers to the request and response functions and |
| * associated contexts. |
| */ |
| |
| /** |
| * Makes a request on a particular client (as opposed to the default one) of a |
| * service. |
| * |
| * @qmidev: the QMI device |
| * @client: the client on which to make the request |
| * @msg_id: the message ID of the request and response messages |
| * @make_request_fn: a function to be called to fill in the request message, |
| * if it requires a payload (otherwise NULL). Will be |
| * called before qmidev_client_request returns. |
| * @request_context: the context for make_request_fn |
| * @handle_response_fn: the function to call when the response is received |
| * @response_context: the context for handle_response_fn |
| */ |
| int qmidev_client_request(struct qmidev *qmidev, |
| struct client *client, |
| uint16_t msg_id, |
| request_fn make_request_fn, |
| void *request_context, |
| response_fn handle_response_fn, |
| void *response_context); |
| |
| /** |
| * Makes a request on the default client of a service. |
| * |
| * Arguments are otherwise the same as qmidev_client_request. |
| */ |
| int qmidev_request(struct qmidev *qmidev, |
| struct service *service, |
| uint16_t msg_id, |
| request_fn make_request_fn, |
| void *request_context, |
| response_fn handle_response_fn, |
| void *response_context); |
| |
| /** |
| * Makes a void request on the default client of a service. |
| * |
| * Immediately calls the response function without doing anything with the |
| * response message besides getting the result code. |
| * |
| * Arguments are otherwise the same as qmidev_request. |
| */ |
| int qmidev_void_request(struct qmidev *qmidev, |
| struct service *service, |
| uint16_t msg_id, |
| request_fn make_request_fn, |
| void *request_context, |
| qmidev_response_fn handle_response_fn, |
| void *response_context); |
| |
| /** |
| * Sets or clears a callback. |
| * |
| * @qmidev: the QMI device |
| * @client: the client on which to set/clear the callback |
| * @event: the event structure representing the event whose callback we are |
| * setting or clearing |
| * @new_callback: the new callback to set, or NULL if clearing |
| * @new_context: the context for new_callback |
| * @caller_callback: the callback to call once new_callback is set |
| * @caller_context: the context for caller_callback |
| */ |
| int qmidev_set_callback(struct qmidev *qmidev, |
| struct client *client, |
| struct event *event, |
| void *new_callback, |
| void *new_context, |
| qmidev_response_fn caller_callback, |
| void *caller_context); |
| |
| /* TODO: These should be replaced by qmidev_poll. */ |
| |
| /** |
| * Sets a file descriptor belonging to the dev underlying this qmidev. |
| * The qmidev will read from the dev when this filehandle is ready to read. |
| * Returns zero on success, errno on failure. |
| */ |
| int qmidev_set_dev_fd(struct qmidev *qmidev, int fd); |
| |
| /** |
| * Clears the file descriptor set by qmidev_set_dev_fd. |
| * Returns zero on success, errno on failure. |
| */ |
| int qmidev_clear_dev_fd(struct qmidev *qmidev); |
| |
| /** |
| * Adds a file descriptor to the poller in this qmidev. |
| * Returns the new struct polled * on success, NULL on failure. |
| */ |
| struct polled *qmidev_poll(struct qmidev *qmidev, int fd); |
| |
| /** |
| * Callback type for QMI requests made with qmidev_send_request. |
| * |
| * @resp_msg: The response message received, or NULL if none. |
| */ |
| typedef void (*qmidev_request_fn)(struct qmidev *qmidev, |
| void *context, |
| int status, |
| struct qmimsg *resp_msg); |
| |
| enum { |
| LISTEN_MATCH_QMI_FLAGS = 0x1, |
| LISTEN_MATCH_TRANSACTION = 0x2, |
| LISTEN_MATCH_MESSAGE = 0x4 |
| }; |
| |
| struct listen_criteria { |
| int flags; |
| uint8_t qmi_flags; |
| uint16_t transaction; |
| uint16_t message; |
| }; |
| |
| /** |
| * Callback type for qmidev_listen. |
| * |
| * Will be called when a message matching the listen criteria is received. |
| * |
| * @qmidev: the QMI device on which a message was received |
| * @context: the context passed to qmidev_listen |
| * @message: the message received |
| * |
| * The callback should return zero to continue listening for such messages, |
| * or non-zero to remove the listener. |
| */ |
| typedef int (*qmidev_listen_callback_fn)(struct qmidev *qmidev, |
| void *context, |
| struct qmimsg *message); |
| |
| struct listener *qmidev_listen(struct qmidev *qmidev, |
| struct client *client, |
| struct listen_criteria *criteria, |
| qmidev_listen_callback_fn callback, |
| void *context); |
| |
| void qmidev_cancel_listen(struct qmidev *qmidev, struct listener *listener); |
| |
| /** |
| * Sends a QMI message. |
| * Returns zero on success, errno on failure. |
| */ |
| int qmidev_send(struct qmidev *qmidev, struct qmimsg *msg); |
| |
| typedef void (*callback_fn)(struct qmidev *qmidev, void *context); |
| |
| /** |
| * Calls a callback from qmidev_process instead of the current call stack. |
| */ |
| void qmidev_call_later(struct qmidev *qmidev, callback_fn func, |
| void *context); |
| |
| /* Mock qmidev functions: */ |
| |
| /* Create a new mock QMI device (backed by pipes instead of a real file.) */ |
| struct qmidev *qmidev_new_mock(void); |
| |
| /* Check if the mock device os open. */ |
| int qmidev_mock_is_open(struct qmidev *qmidev); |
| |
| /* Inject a message "received from" the mock device. */ |
| int qmidev_mock_inject(struct qmidev *qmidev, const void *buf, size_t len); |
| |
| /* Extract a message "sent to" the mock device. |
| * |
| * @len: A pointer to the length of buf; it will be replaced with the size of |
| * the message read. Cannot be NULL. |
| * |
| * Returns 0 on success, |
| * ENOSPC if len is too small for the next message. |
| */ |
| int qmidev_mock_extract(struct qmidev *qmidev, void *buf, size_t *len); |
| |
| #endif /* LIBQMI_QMIDEV_H */ |