3 * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <sys/types.h>
24 #include <libubox/uloop.h>
28 size_t mbim_bufsize
= 0;
29 uint8_t *mbim_buffer
= NULL
;
30 static struct uloop_fd mbim_fd
;
31 static uint32_t expected
;
34 static void mbim_msg_tout_cb(struct uloop_timeout
*t
)
36 fprintf(stderr
, "ERROR: mbim message timeout\n");
40 static struct uloop_timeout tout
= {
41 .cb
= mbim_msg_tout_cb
,
47 struct mbim_message_header
*hdr
= (struct mbim_message_header
*) mbim_buffer
;
50 if (le32toh(hdr
->length
) > mbim_bufsize
) {
51 fprintf(stderr
, "message too big %d\n", le32toh(hdr
->length
));
56 fprintf(stderr
, "sending (%d): ", le32toh(hdr
->length
));
57 for (ret
= 0; ret
< le32toh(hdr
->length
); ret
++)
58 printf("%02x ", ((uint8_t *) mbim_buffer
)[ret
]);
60 printf(" header_type: %04X\n", le32toh(hdr
->type
));
61 printf(" header_length: %04X\n", le32toh(hdr
->length
));
62 printf(" header_transaction: %04X\n", le32toh(hdr
->transaction_id
));
65 ret
= write(mbim_fd
.fd
, mbim_buffer
, le32toh(hdr
->length
));
67 perror("writing data failed: ");
69 expected
= le32toh(hdr
->type
) | 0x80000000;
70 uloop_timeout_set(&tout
, 15000);
76 mbim_recv(struct uloop_fd
*u
, unsigned int events
)
78 ssize_t cnt
= read(u
->fd
, mbim_buffer
, mbim_bufsize
);
79 struct mbim_message_header
*hdr
= (struct mbim_message_header
*) mbim_buffer
;
80 struct command_done_message
*msg
= (struct command_done_message
*) (hdr
+ 1);
86 if (cnt
< sizeof(struct mbim_message_header
)) {
87 perror("failed to read() data: ");
91 printf("reading (%zu): ", cnt
);
92 for (i
= 0; i
< cnt
; i
++)
93 printf("%02x ", mbim_buffer
[i
]);
95 printf(" header_type: %04X\n", le32toh(hdr
->type
));
96 printf(" header_length: %04X\n", le32toh(hdr
->length
));
97 printf(" header_transaction: %04X\n", le32toh(hdr
->transaction_id
));
100 if (le32toh(hdr
->type
) == expected
)
101 uloop_timeout_cancel(&tout
);
103 switch(le32toh(hdr
->type
)) {
104 case MBIM_MESSAGE_TYPE_OPEN_DONE
:
105 if (current_handler
->request() < 0)
106 mbim_send_close_msg();
108 case MBIM_MESSAGE_TYPE_COMMAND_DONE
:
110 printf(" command_id: %04X\n", le32toh(msg
->command_id
));
111 printf(" status_code: %04X\n", le32toh(msg
->status_code
));
113 if (msg
->status_code
&& !msg
->buffer_length
)
114 return_code
= -le32toh(msg
->status_code
);
116 return_code
= current_handler
->response(msg
->buffer
, le32toh(msg
->buffer_length
));
119 mbim_send_close_msg();
121 case MBIM_MESSAGE_TYPE_CLOSE_DONE
:
124 case MBIM_MESSAGE_TYPE_FUNCTION_ERROR
:
126 mbim_send_close_msg();
133 mbim_open(const char *path
)
135 mbim_fd
.cb
= mbim_recv
;
136 mbim_fd
.fd
= open(path
, O_RDWR
);
137 if (mbim_fd
.fd
< 1) {
138 perror("open failed: ");
141 mbim_bufsize
= MBIM_BUFFER_SIZE
;
142 mbim_buffer
= malloc(mbim_bufsize
);
143 uloop_fd_add(&mbim_fd
, ULOOP_READ
);