1 #define __STDC_FORMAT_MACROS
14 #include <libubox/utils.h>
15 #include <libubox/uloop.h>
19 #include "data/mbim-service-basic-connect.h"
24 struct mbim_handler
*current_handler
;
25 static uint8_t uuid_context_type_internet
[16] = { 0x7E, 0x5E, 0x2A, 0x7E, 0x4E, 0x6F, 0x72, 0x72, 0x73, 0x6B, 0x65, 0x6E, 0x7E, 0x5E, 0x2A, 0x7E };
30 mbim_device_caps_response(void *buffer
, int len
)
32 struct mbim_basic_connect_device_caps_r
*caps
= (struct mbim_basic_connect_device_caps_r
*) buffer
;
33 char *deviceid
, *firmwareinfo
, *hardwareinfo
;
35 if (len
< sizeof(struct mbim_basic_connect_device_caps_r
)) {
36 fprintf(stderr
, "message not long enough\n");
40 deviceid
= mbim_get_string(&caps
->deviceid
, buffer
);
41 firmwareinfo
= mbim_get_string(&caps
->firmwareinfo
, buffer
);
42 hardwareinfo
= mbim_get_string(&caps
->hardwareinfo
, buffer
);
44 printf(" devicetype: %04X - %s\n", le32toh(caps
->devicetype
),
45 mbim_enum_string(mbim_device_type_values
, le32toh(caps
->devicetype
)));
46 printf(" cellularclass: %04X\n", le32toh(caps
->cellularclass
));
47 printf(" voiceclass: %04X - %s\n", le32toh(caps
->voiceclass
),
48 mbim_enum_string(mbim_voice_class_values
, le32toh(caps
->voiceclass
)));
49 printf(" simclass: %04X\n", le32toh(caps
->simclass
));
50 printf(" dataclass: %04X\n", le32toh(caps
->dataclass
));
51 printf(" smscaps: %04X\n", le32toh(caps
->smscaps
));
52 printf(" controlcaps: %04X\n", le32toh(caps
->controlcaps
));
53 printf(" maxsessions: %04X\n", le32toh(caps
->maxsessions
));
54 printf(" deviceid: %s\n", deviceid
);
55 printf(" firmwareinfo: %s\n", firmwareinfo
);
56 printf(" hardwareinfo: %s\n", hardwareinfo
);
62 mbim_pin_state_response(void *buffer
, int len
)
64 struct mbim_basic_connect_pin_r
*pin
= (struct mbim_basic_connect_pin_r
*) buffer
;
66 if (len
< sizeof(struct mbim_basic_connect_pin_r
)) {
67 fprintf(stderr
, "message not long enough\n");
71 if (le32toh(pin
->pinstate
) != MBIM_PIN_STATE_UNLOCKED
) {
72 fprintf(stderr
, "required pin: %d - %s\n",
73 le32toh(pin
->pintype
), mbim_enum_string(mbim_pin_type_values
, le32toh(pin
->pintype
)));
74 fprintf(stderr
, "remaining attempts: %d\n", le32toh(pin
->remainingattempts
));
75 return le32toh(pin
->pintype
);
78 fprintf(stderr
, "Pin Unlocked\n");
84 mbim_registration_response(void *buffer
, int len
)
86 struct mbim_basic_connect_register_state_r
*state
= (struct mbim_basic_connect_register_state_r
*) buffer
;
87 char *provider_id
, *provider_name
, *roamingtext
;
89 if (len
< sizeof(struct mbim_basic_connect_register_state_r
)) {
90 fprintf(stderr
, "message not long enough\n");
94 provider_id
= mbim_get_string(&state
->providerid
, buffer
);
95 provider_name
= mbim_get_string(&state
->providername
, buffer
);
96 roamingtext
= mbim_get_string(&state
->roamingtext
, buffer
);
98 printf(" nwerror: %04X - %s\n", le32toh(state
->nwerror
),
99 mbim_enum_string(mbim_nw_error_values
, le32toh(state
->nwerror
)));
100 printf(" registerstate: %04X - %s\n", le32toh(state
->registerstate
),
101 mbim_enum_string(mbim_register_state_values
, le32toh(state
->registerstate
)));
102 printf(" registermode: %04X - %s\n", le32toh(state
->registermode
),
103 mbim_enum_string(mbim_register_mode_values
, le32toh(state
->registermode
)));
104 printf(" availabledataclasses: %04X - %s\n", le32toh(state
->availabledataclasses
),
105 mbim_enum_string(mbim_data_class_values
, le32toh(state
->availabledataclasses
)));
106 printf(" currentcellularclass: %04X - %s\n", le32toh(state
->currentcellularclass
),
107 mbim_enum_string(mbim_cellular_class_values
, le32toh(state
->currentcellularclass
)));
108 printf(" provider_id: %s\n", provider_id
);
109 printf(" provider_name: %s\n", provider_name
);
110 printf(" roamingtext: %s\n", roamingtext
);
112 if (le32toh(state
->registerstate
) == MBIM_REGISTER_STATE_HOME
)
115 return le32toh(state
->registerstate
);
119 mbim_subscriber_response(void *buffer
, int len
)
121 struct mbim_basic_connect_subscriber_ready_status_r
*state
= (struct mbim_basic_connect_subscriber_ready_status_r
*) buffer
;
122 char *subscriberid
, *simiccid
;
125 if (len
< sizeof(struct mbim_basic_connect_subscriber_ready_status_r
)) {
126 fprintf(stderr
, "message not long enough\n");
130 subscriberid
= mbim_get_string(&state
->subscriberid
, buffer
);
131 simiccid
= mbim_get_string(&state
->simiccid
, buffer
);
133 printf(" readystate: %04X - %s\n", le32toh(state
->readystate
),
134 mbim_enum_string(mbim_subscriber_ready_state_values
, le32toh(state
->readystate
)));
135 printf(" simiccid: %s\n", simiccid
);
136 printf(" subscriberid: %s\n", subscriberid
);
137 if (le32toh(state
->readyinfo
) & MBIM_READY_INFO_FLAG_PROTECT_UNIQUE_ID
)
138 printf(" dont display subscriberID: 1\n");
139 for (nr
= 0; nr
< le32toh(state
->telephonenumberscount
); nr
++) {
140 struct mbim_string
*str
= buffer
+ le32toh(state
->telephonenumbers
) + (nr
* sizeof(struct mbim_string
));
141 char *number
= mbim_get_string(str
, buffer
);
142 printf(" number: %s\n", number
);
145 if (MBIM_SUBSCRIBER_READY_STATE_INITIALIZED
== le32toh(state
->readystate
))
148 return le32toh(state
->readystate
);
152 mbim_attach_response(void *buffer
, int len
)
154 struct mbim_basic_connect_packet_service_r
*ps
= (struct mbim_basic_connect_packet_service_r
*) buffer
;
156 if (len
< sizeof(struct mbim_basic_connect_packet_service_r
)) {
157 fprintf(stderr
, "message not long enough\n");
161 printf(" nwerror: %04X - %s\n", le32toh(ps
->nwerror
),
162 mbim_enum_string(mbim_nw_error_values
, le32toh(ps
->nwerror
)));
163 printf(" packetservicestate: %04X - %s\n", le32toh(ps
->packetservicestate
),
164 mbim_enum_string(mbim_packet_service_state_values
, le32toh(ps
->packetservicestate
)));
165 printf(" uplinkspeed: %"PRIu64
"\n", le64toh(ps
->uplinkspeed
));
166 printf(" downlinkspeed: %"PRIu64
"\n", le64toh(ps
->downlinkspeed
));
168 if (MBIM_PACKET_SERVICE_STATE_ATTACHED
== le32toh(ps
->packetservicestate
))
171 return le32toh(ps
->packetservicestate
);
175 mbim_connect_response(void *buffer
, int len
)
177 struct mbim_basic_connect_connect_r
*c
= (struct mbim_basic_connect_connect_r
*) buffer
;
179 if (len
< sizeof(struct mbim_basic_connect_connect_r
)) {
180 fprintf(stderr
, "message not long enough\n");
184 printf(" sessionid: %d\n", le32toh(c
->sessionid
));
185 printf(" activationstate: %04X - %s\n", le32toh(c
->activationstate
),
186 mbim_enum_string(mbim_activation_state_values
, le32toh(c
->activationstate
)));
187 printf(" voicecallstate: %04X - %s\n", le32toh(c
->voicecallstate
),
188 mbim_enum_string(mbim_voice_call_state_values
, le32toh(c
->voicecallstate
)));
189 printf(" nwerror: %04X - %s\n", le32toh(c
->nwerror
),
190 mbim_enum_string(mbim_nw_error_values
, le32toh(c
->nwerror
)));
191 printf(" iptype: %04X - %s\n", le32toh(c
->iptype
),
192 mbim_enum_string(mbim_context_ip_type_values
, le32toh(c
->iptype
)));
194 if (MBIM_ACTIVATION_STATE_ACTIVATED
== le32toh(c
->activationstate
))
197 return le32toh(c
->activationstate
);
201 mbim_config_response(void *buffer
, int len
)
203 struct mbim_basic_connect_ip_configuration_r
*ip
= (struct mbim_basic_connect_ip_configuration_r
*) buffer
;
207 if (len
< sizeof(struct mbim_basic_connect_ip_configuration_r
)) {
208 fprintf(stderr
, "message not long enough\n");
212 if (le32toh(ip
->ipv4configurationavailable
) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS
)
213 for (i
= 0; i
< le32toh(ip
->ipv4addresscount
); i
++) {
214 mbim_get_ipv4(buffer
, ipv4
, ip
->ipv4address
+ (i
* 4));
215 printf(" ipv4address: %s\n", ipv4
);
217 if (le32toh(ip
->ipv4configurationavailable
) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS
) {
218 mbim_get_ipv4(buffer
, ipv4
, ip
->ipv4gateway
);
219 printf(" ipv4gateway: %s\n", ipv4
);
221 if (le32toh(ip
->ipv4configurationavailable
) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU
)
222 printf(" ipv4mtu: %d\n", le32toh(ip
->ipv4mtu
));
223 if (le32toh(ip
->ipv4configurationavailable
) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS
)
224 for (i
= 0; i
< le32toh(ip
->ipv4dnsservercount
); i
++) {
225 mbim_get_ipv4(buffer
, ipv4
, ip
->ipv4dnsserver
+ (i
* 4));
226 printf(" ipv4dnsserver: %s\n", ipv4
);
229 printf(" ipv6configurationavailable: %04X\n", le32toh(ip
->ipv6configurationavailable
));
235 mbim_device_caps_request(void)
237 mbim_setup_command_msg(basic_connect
, MBIM_MESSAGE_COMMAND_TYPE_QUERY
, MBIM_CMD_BASIC_CONNECT_DEVICE_CAPS
, 0);
239 return mbim_send_command_msg();
243 mbim_pin_state_request(void)
245 mbim_setup_command_msg(basic_connect
, MBIM_MESSAGE_COMMAND_TYPE_QUERY
, MBIM_CMD_BASIC_CONNECT_PIN
, 0);
247 return mbim_send_command_msg();
251 mbim_registration_request(void)
253 mbim_setup_command_msg(basic_connect
, MBIM_MESSAGE_COMMAND_TYPE_QUERY
, MBIM_CMD_BASIC_CONNECT_REGISTER_STATE
, 0);
255 return mbim_send_command_msg();
259 mbim_subscriber_request(void)
261 mbim_setup_command_msg(basic_connect
, MBIM_MESSAGE_COMMAND_TYPE_QUERY
, MBIM_CMD_BASIC_CONNECT_SUBSCRIBER_READY_STATUS
, 0);
263 return mbim_send_command_msg();
267 _mbim_attach_request(int action
)
269 struct mbim_basic_connect_packet_service_s
*ps
=
270 (struct mbim_basic_connect_packet_service_s
*) mbim_setup_command_msg(basic_connect
,
271 MBIM_MESSAGE_COMMAND_TYPE_SET
, MBIM_CMD_BASIC_CONNECT_PACKET_SERVICE
,
272 sizeof(struct mbim_basic_connect_packet_service_s
));
274 ps
->packetserviceaction
= htole32(action
);
276 return mbim_send_command_msg();
280 mbim_attach_request(void)
282 return _mbim_attach_request(MBIM_PACKET_SERVICE_ACTION_ATTACH
);
286 mbim_detach_request(void)
288 return _mbim_attach_request(MBIM_PACKET_SERVICE_ACTION_DETACH
);
292 mbim_connect_request(void)
294 struct mbim_basic_connect_connect_s
*c
=
295 (struct mbim_basic_connect_connect_s
*) mbim_setup_command_msg(basic_connect
,
296 MBIM_MESSAGE_COMMAND_TYPE_SET
, MBIM_CMD_BASIC_CONNECT_CONNECT
,
297 sizeof(struct mbim_basic_connect_connect_s
));
299 c
->activationcommand
= htole32(MBIM_ACTIVATION_COMMAND_ACTIVATE
);
300 c
->iptype
= htole32(MBIM_CONTEXT_IP_TYPE_DEFAULT
);
301 memcpy(c
->contexttype
, uuid_context_type_internet
, 16);
303 mbim_encode_string(&c
->accessstring
, *_argv
);
305 return mbim_send_command_msg();
309 mbim_disconnect_request(void)
311 struct mbim_basic_connect_connect_s
*c
=
312 (struct mbim_basic_connect_connect_s
*) mbim_setup_command_msg(basic_connect
,
313 MBIM_MESSAGE_COMMAND_TYPE_SET
, MBIM_CMD_BASIC_CONNECT_CONNECT
,
314 sizeof(struct mbim_basic_connect_connect_s
));
316 c
->activationcommand
= htole32(MBIM_ACTIVATION_COMMAND_DEACTIVATE
);
317 memcpy(c
->contexttype
, uuid_context_type_internet
, 16);
321 return mbim_send_command_msg();
325 mbim_pin_unlock_request(void)
327 struct mbim_basic_connect_pin_s
*p
=
328 (struct mbim_basic_connect_pin_s
*) mbim_setup_command_msg(basic_connect
,
329 MBIM_MESSAGE_COMMAND_TYPE_SET
, MBIM_CMD_BASIC_CONNECT_PIN
,
330 sizeof(struct mbim_basic_connect_pin_s
));
332 p
->pintype
= htole32(MBIM_PIN_TYPE_PIN1
);
333 p
->pinoperation
= htole32(MBIM_PIN_OPERATION_ENTER
);
334 mbim_encode_string(&p
->pin
, _argv
[0]);
336 return mbim_send_command_msg();
340 mbim_config_request(void)
342 mbim_setup_command_msg(basic_connect
,
343 MBIM_MESSAGE_COMMAND_TYPE_QUERY
, MBIM_CMD_BASIC_CONNECT_IP_CONFIGURATION
,
344 sizeof(struct mbim_basic_connect_ip_configuration_q
));
346 return mbim_send_command_msg();
349 static struct mbim_handler handlers
[] = {
350 { "caps", 0, mbim_device_caps_request
, mbim_device_caps_response
},
351 { "pinstate", 0, mbim_pin_state_request
, mbim_pin_state_response
},
352 { "unlock", 1, mbim_pin_unlock_request
, mbim_pin_state_response
},
353 { "registration", 0, mbim_registration_request
, mbim_registration_response
},
354 { "subscriber", 0, mbim_subscriber_request
, mbim_subscriber_response
},
355 { "attach", 0, mbim_attach_request
, mbim_attach_response
},
356 { "detach", 0, mbim_detach_request
, mbim_attach_response
},
357 { "connect", 0, mbim_connect_request
, mbim_connect_response
},
358 { "disconnect", 0, mbim_disconnect_request
, mbim_connect_response
},
359 { "config", 0, mbim_config_request
, mbim_config_response
},
365 fprintf(stderr
, "Usage: mbim <caps|pinstate|unlock|connect|disconnect> [options]\n"
367 " -d <device> the device (/dev/cdc-wdmX)\n"
368 " -t <transaction> the transaction id\n"
375 main(int argc
, char **argv
)
377 char *cmd
, *device
= NULL
;
378 int no_open
= 0, ch
, i
;
380 while ((ch
= getopt(argc
, argv
, "nvd:t:")) != -1) {
393 transaction_id
= atoi(optarg
);
400 if (!device
|| optind
== argc
)
406 _argc
= argc
- optind
;
407 _argv
= &argv
[optind
];
409 for (i
= 0; i
< ARRAY_SIZE(handlers
); i
++)
410 if (!strcmp(cmd
, handlers
[i
].name
))
411 current_handler
= &handlers
[i
];
413 if (!current_handler
|| (optind
+ current_handler
->argc
> argc
))
420 mbim_send_open_msg();
421 else if (current_handler
->request() < 0)