* GNU General Public License for more details.
*/
+#include <linux/usb/cdc-wdm.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "mbim.h"
-uint8_t mbim_buffer[MBIM_BUFFER_SIZE];
+size_t mbim_bufsize = 0;
+uint8_t *mbim_buffer = NULL;
static struct uloop_fd mbim_fd;
static uint32_t expected;
int no_close;
static void mbim_msg_tout_cb(struct uloop_timeout *t)
{
fprintf(stderr, "ERROR: mbim message timeout\n");
- uloop_end();
+ mbim_end();
}
static struct uloop_timeout tout = {
struct mbim_message_header *hdr = (struct mbim_message_header *) mbim_buffer;
int ret = 0;
- if (le32toh(hdr->length) > MBIM_BUFFER_SIZE) {
+ if (le32toh(hdr->length) > mbim_bufsize) {
fprintf(stderr, "message too big %d\n", le32toh(hdr->length));
return -1;
}
static void
mbim_recv(struct uloop_fd *u, unsigned int events)
{
- ssize_t cnt = read(u->fd, mbim_buffer, MBIM_BUFFER_SIZE);
+ ssize_t cnt = read(u->fd, mbim_buffer, mbim_bufsize);
struct mbim_message_header *hdr = (struct mbim_message_header *) mbim_buffer;
- struct command_message *msg = (struct command_message *) mbim_buffer;
+ struct command_done_message *msg = (struct command_done_message *) (hdr + 1);
int i;
if (cnt < 0)
mbim_send_close_msg();
break;
case MBIM_MESSAGE_TYPE_COMMAND_DONE:
- return_code = current_handler->response(msg->buffer, le32toh(msg->buffer_length));
+ if (verbose) {
+ printf(" command_id: %04X\n", le32toh(msg->command_id));
+ printf(" status_code: %04X\n", le32toh(msg->status_code));
+ }
+ if (msg->status_code && !msg->buffer_length)
+ return_code = -le32toh(msg->status_code);
+ else
+ return_code = current_handler->response(msg->buffer, le32toh(msg->buffer_length));
if (return_code < 0)
no_close = 0;
mbim_send_close_msg();
break;
case MBIM_MESSAGE_TYPE_CLOSE_DONE:
- uloop_end();
+ mbim_end();
break;
case MBIM_MESSAGE_TYPE_FUNCTION_ERROR:
no_close = 0;
void
mbim_open(const char *path)
{
+ __u16 max;
+ int rc;
+
mbim_fd.cb = mbim_recv;
mbim_fd.fd = open(path, O_RDWR);
if (mbim_fd.fd < 1) {
perror("open failed: ");
exit(-1);
}
+ rc = ioctl(mbim_fd.fd, IOCTL_WDM_MAX_COMMAND, &max);
+ if (!rc)
+ mbim_bufsize = max;
+ else
+ mbim_bufsize = 512;
+ mbim_buffer = malloc(mbim_bufsize);
uloop_fd_add(&mbim_fd, ULOOP_READ);
}
+
+void
+mbim_end(void)
+{
+ if (mbim_buffer) {
+ free(mbim_buffer);
+ mbim_bufsize = 0;
+ mbim_buffer = NULL;
+ }
+ uloop_end();
+}