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>
25 #include <libubox/utils.h>
26 #include <libubox/uloop.h>
30 #include "data/mbim-service-basic-connect.h"
32 int transaction_id
= 1;
33 uint8_t basic_connect
[16] = { 0xa2, 0x89, 0xcc, 0x33, 0xbc, 0xbb, 0x8b, 0x4f,
34 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6,0xdf };
35 static int payload_offset
, payload_free
, payload_len
;
36 static uint8_t *payload_buffer
;
39 mbim_add_payload(uint8_t len
)
41 uint32_t offset
= payload_offset
;
43 if (payload_free
< len
)
47 payload_offset
+= len
;
54 mbim_encode_string(struct mbim_string
*str
, char *in
)
56 const int l
= strlen(in
);
57 const int utf16_len
= l
* 2;
58 const int pad_len
= utf16_len
% 4;
59 const int s
= mbim_add_payload(utf16_len
+ pad_len
);
60 uint8_t *p
= &payload_buffer
[s
];
66 str
->offset
= htole32(s
);
67 str
->length
= htole32(utf16_len
);
69 for (i
= 0; i
< l
; i
++)
76 mbim_get_string(struct mbim_string
*str
, char *in
)
78 char *p
= &in
[le32toh(str
->offset
)];
81 if (!le32toh(str
->offset
))
84 if (le32toh(str
->length
)) {
85 for (i
= 0; i
< le32toh(str
->length
) / 2; i
++)
95 mbim_get_ipv4(void *buffer
, char *out
, uint32_t offset
)
97 uint8_t *b
= buffer
+ offset
;
99 snprintf(out
, 16, "%d.%d.%d.%d", b
[0], b
[1], b
[2], b
[3]);
103 mbim_get_ipv6(void *buffer
, char *out
, uint32_t offset
)
105 uint8_t *b
= buffer
+ offset
;
107 snprintf(out
, 40, "%x:%x:%x:%x:%x:%x:%x:%x", b
[0] << 8 | b
[1],
108 b
[2] << 8 | b
[3], b
[4] << 8 | b
[5], b
[6] << 8 | b
[7],
109 b
[8] << 8 | b
[9], b
[10] << 8 | b
[11], b
[12] << 8 | b
[13],
114 mbim_get_int(void *buffer
, uint32_t offset
)
116 uint32_t *i
= buffer
+ offset
;
122 mbim_enum_string(struct mbim_enum
*e
, uint32_t key
)
133 mbim_setup_header(struct mbim_message_header
*hdr
, MbimMessageType type
, int length
)
138 hdr
->transaction_id
= htole32(transaction_id
++);
139 hdr
->type
= htole32(type
);
140 hdr
->length
= htole32(length
);
144 mbim_setup_command_msg(uint8_t *uuid
, uint32_t type
, uint32_t command_id
, int len
)
146 struct command_message
*cmd
= (struct command_message
*) mbim_buffer
;
150 memset(mbim_buffer
, 0, mbim_bufsize
);
152 cmd
->fragment_header
.total
= htole32(1);
153 cmd
->fragment_header
.current
= htole32(0);
154 memcpy(cmd
->service_id
, uuid
, 16);
155 cmd
->command_id
= htole32(command_id
);
156 cmd
->command_type
= htole32(type
);
157 cmd
->buffer_length
= htole32(len
);
159 payload_offset
= len
;
160 payload_free
= mbim_bufsize
- (sizeof(*cmd
) + len
);
162 payload_buffer
= cmd
->buffer
;
168 mbim_send_command_msg(void)
170 struct command_message
*cmd
= (struct command_message
*) mbim_buffer
;
174 if (payload_len
& 0x3) {
179 cmd
->buffer_length
= htole32(le32toh(cmd
->buffer_length
) + payload_len
);
180 mbim_setup_header(&cmd
->header
, MBIM_MESSAGE_TYPE_COMMAND
, sizeof(*cmd
) + le32toh(cmd
->buffer_length
));
186 mbim_send_open_msg(void)
188 struct mbim_open_message
*msg
= (struct mbim_open_message
*) mbim_buffer
;
190 mbim_setup_header(&msg
->header
, MBIM_MESSAGE_TYPE_OPEN
, sizeof(*msg
));
191 msg
->max_control_transfer
= htole32(mbim_bufsize
);
197 mbim_send_close_msg(void)
199 struct mbim_message_header
*hdr
= (struct mbim_message_header
*) mbim_buffer
;
201 if (no_close
|| !mbim_buffer
) {
205 mbim_setup_header(hdr
, MBIM_MESSAGE_TYPE_CLOSE
, sizeof(*hdr
));