summaryrefslogtreecommitdiff
path: root/src/libembim/embim-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libembim/embim-device.c')
-rw-r--r--src/libembim/embim-device.c62
1 files changed, 61 insertions, 1 deletions
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 {