From 0572164d65422eacd543c3f59248a2a8aba15409 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 10 Sep 2015 13:01:22 +0200 Subject: wip --- src/embim/embim-context.c | 11 ++++---- src/libembim/embim-device.c | 62 ++++++++++++++++++++++++++++++++++++++++++++- src/libembim/embim-device.h | 43 +++++++++++++++++++++++++++++-- src/libembim/embim-enums.h | 2 ++ 4 files changed, 109 insertions(+), 9 deletions(-) diff --git a/src/embim/embim-context.c b/src/embim/embim-context.c index ddbd74b..66d8227 100644 --- a/src/embim/embim-context.c +++ b/src/embim/embim-context.c @@ -84,7 +84,7 @@ embim_context_init (int *argc, char ***argv) { static const struct option longopts[] = { { "device", required_argument, 0, 'd' }, - { "noop", no_argument, 0, '1' }, + { "noop", no_argument, 0, '1' }, { "version", no_argument, 0, 'V' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } @@ -97,9 +97,9 @@ embim_context_init (int *argc, char ***argv) while (iarg != -1) { iarg = getopt_long (*argc, *argv, "d:hV", longopts, &idx); switch (iarg) { - case '1': - noop = true; - break; + case '1': + noop = true; + break; case 'd': if (device_path) { fprintf (stderr, "error: device path redefined.\n"); @@ -118,13 +118,12 @@ embim_context_init (int *argc, char ***argv) if (!device_path) { fprintf (stderr, "error: device path not given.\n"); - return -2; + return -2; } return 0; } - void embim_context_shutdown (void) { diff --git a/src/libembim/embim-device.c b/src/libembim/embim-device.c index 68852cf..740b84e 100644 --- a/src/libembim/embim-device.c +++ b/src/libembim/embim-device.c @@ -32,6 +32,10 @@ #include #include +#include +#define IOCTL_WDM_MAX_COMMAND _IOR('H', 0xA0, uint16_t) +#define FALLBACK_MAX_CONTROL_TRANSFER 4096 + #include "embim-device.h" /*****************************************************************************/ @@ -42,6 +46,8 @@ struct embim_device_s { char *path; /* Open device FD */ int fd; + /* Transaction ID */ + uint32_t transaction_id; /* Registered indication callbacks */ struct indication_s *indications; size_t indications_n; @@ -54,6 +60,7 @@ static void notify_indication (embim_device_t *self, const uint8_t *indication); /*****************************************************************************/ +/* Basic device creation/destruction */ embim_device_t * embim_device_new (const char *path) @@ -96,6 +103,18 @@ embim_device_free (embim_device_t *self) free (self); } +/*****************************************************************************/ +/* MBIM write */ + +embim_status_e +embim_device_write (embim_device_t *self, + const uint8_t *message, + size_t message_size) +{ + + +} + /*****************************************************************************/ /* MBIM open */ @@ -107,14 +126,35 @@ embim_device_open (embim_device_t *self) return EMBIM_STATUS_SUCCESS; self->fd = open (self->path, O_RDWR | FD_CLOEXEC); - if (self->fd < 0) + if (self->fd < 0) { + /* Not having enough privileges is a very common error here. */ + if (errno == EACCESS) + return EMBIM_STATUS_ERROR_UNAUTHORIZED; return EMBIM_STATUS_ERROR_GENERIC; + } + + /* Query message size */ + if (ioctl (self->fd, IOCTL_WDM_MAX_COMMAND, &self->max_control_transfer) < 0) + /* Fallback to a default value */ + self->max_control_transfer = FALLBACK_MAX_CONTROL_TRANSFER; notify_indication (self, NULL); return EMBIM_STATUS_SUCCESS; } +int +embim_device_get_fd (embim_device_t *self) +{ + return self->fd; +} + +uint16_t +embim_device_get_max_control_transfer (embim_device_t *self) +{ + return self->max_control_transfer; +} + /*****************************************************************************/ /* MBIM close */ @@ -125,9 +165,29 @@ embim_device_close (embim_device_t *self) close (self->fd); self->fd = -1; } + return EMBIM_STATUS_SUCCESS; } +/*****************************************************************************/ +/* Transaction ID management */ + +static uint32_t +get_next_transaction_id (embim_device_t *self) +{ + uint32_t next; + + next = self->transaction_id; + + if (self->transaction_id == (uint32_t) 0xFFFFFFFF) + /* Reset! */ + self->priv->transaction_id = 0x01; + else + self->priv->transaction_id++; + + return next; +} + /*****************************************************************************/ /* Registered callbacks for indications */ diff --git a/src/libembim/embim-device.h b/src/libembim/embim-device.h index c351fda..19e1d3c 100644 --- a/src/libembim/embim-device.h +++ b/src/libembim/embim-device.h @@ -67,9 +67,48 @@ embim_device_t *embim_device_new (const char *path); */ void embim_device_free (embim_device_t *self); -embim_status_e embim_device_open (embim_device_t *self); +/** + * embim_device_open: + * @self: a #embim_device_t. + * + * Opens the MBIM device for reading and writing. + * + * Note that this method does not send the MBIM Open message to the device. + * + * Operation may finish with the following status values: + * - %EMBIM_STATUS_SUCCESS: Operation succeeded. + * - %EMBIM_STATUS_ERROR_UNAUTHORIZED: Not enough privileges to open the control device. + * - %EMBIM_STATUS_ERROR_GENERIC: Generic filesystem I/O error. + * + * Returns: a #embim_status_e. + */ +embim_status_e embim_device_open (embim_device_t *self); + +/** + * embim_device_get_fd: + * @self: a #embim_device_t. + * + * Gets the internal file descriptor of the #embim_device_t, which the user + * should setup for polling. + * + * Returns: the file descriptor. + */ +int embim_device_get_fd (embim_device_t *self); -embim_status_e embim_device_close (embim_device_t *self); +/** + * embim_device_close: + * @self: a #embim_device_t. + * + * Closes the MBIM device. + * + * Note that this method does not send the MBIM Close message to the device. + * + * Operation may finish with the following status values: + * - %EMBIM_STATUS_SUCCESS: Operation succeeded. + * + * Returns: a #embim_status_e. + */ +embim_status_e embim_device_close (embim_device_t *self); /** * embim_device_indication_cb: diff --git a/src/libembim/embim-enums.h b/src/libembim/embim-enums.h index 0177c3c..fc35d92 100644 --- a/src/libembim/embim-enums.h +++ b/src/libembim/embim-enums.h @@ -118,6 +118,7 @@ const char *embim_message_command_type_to_string (embim_message_command_type_e t * @EMBIM_STATUS_ERROR_NOT_FOUND: Item not found. * @EMBIM_STATUS_ERROR_EXISTS: Item already exists. * @EMBIM_STATUS_ERROR_WRONG_STATE: Operation not allowed in current state. + * @EMBIM_STATUS_ERROR_UNAUTHORIZED: Operation not allowed. * * Status of the operation. */ @@ -137,6 +138,7 @@ typedef enum { EMBIM_STATUS_ERROR_NOT_FOUND = 12, EMBIM_STATUS_ERROR_EXISTS = 13, EMBIM_STATUS_ERROR_WRONG_STATE = 14, + EMBIM_STATUS_ERROR_UNAUTHORIZED = 15, } embim_status_e; /** -- cgit v1.2.1