summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2015-09-10 13:01:22 +0200
committerAleksander Morgado <aleksander@aleksander.es>2015-09-10 13:01:22 +0200
commit0572164d65422eacd543c3f59248a2a8aba15409 (patch)
tree2735a942af007b3682fc73d53ad32cb33dab3ea5
parent19c90472f3f6c29767844f671a2d8453ff449e88 (diff)
downloadlibmbim-libembim.tar.gz
-rw-r--r--src/embim/embim-context.c11
-rw-r--r--src/libembim/embim-device.c62
-rw-r--r--src/libembim/embim-device.h43
-rw-r--r--src/libembim/embim-enums.h2
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 <fcntl.h>
#include <unistd.h>
+#include <sys/ioctl.h>
+#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)
@@ -97,6 +104,18 @@ embim_device_free (embim_device_t *self)
}
/*****************************************************************************/
+/* MBIM write */
+
+embim_status_e
+embim_device_write (embim_device_t *self,
+ const uint8_t *message,
+ size_t message_size)
+{
+
+
+}
+
+/*****************************************************************************/
/* MBIM open */
embim_status_e
@@ -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,10 +165,30 @@ 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 */
struct indication_s {
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;
/**