1 /* 2 * umbim 3 * Copyright (C) 2014 John Crispin <blogic@openwrt.org> 4 * 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 8 * 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. 13 */ 14 15 #define __STDC_FORMAT_MACROS 16 #include <inttypes.h> 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 21 #include <alloca.h> 22 #include <fcntl.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 #include <ctype.h> 28 29 #include <libubox/utils.h> 30 #include <libubox/uloop.h> 31 32 #include "mbim.h" 33 34 #include "data/mbim-service-basic-connect.h" 35 36 int return_code = -1; 37 int verbose; 38 39 struct mbim_handler *current_handler; 40 static uint8_t uuid_context_type_internet[16] = { 0x7E, 0x5E, 0x2A, 0x7E, 0x4E, 0x6F, 0x72, 0x72, 0x73, 0x6B, 0x65, 0x6E, 0x7E, 0x5E, 0x2A, 0x7E }; 41 static int _argc; 42 static char **_argv; 43 44 static int 45 mbim_device_caps_response(void *buffer, size_t len) 46 { 47 struct mbim_basic_connect_device_caps_r *caps = (struct mbim_basic_connect_device_caps_r *) buffer; 48 char *deviceid, *firmwareinfo, *hardwareinfo; 49 50 if (len < sizeof(struct mbim_basic_connect_device_caps_r)) { 51 fprintf(stderr, "message not long enough\n"); 52 return -1; 53 } 54 55 deviceid = mbim_get_string(&caps->deviceid, buffer); 56 firmwareinfo = mbim_get_string(&caps->firmwareinfo, buffer); 57 hardwareinfo = mbim_get_string(&caps->hardwareinfo, buffer); 58 59 printf(" devicetype: %04X - %s\n", le32toh(caps->devicetype), 60 mbim_enum_string(mbim_device_type_values, le32toh(caps->devicetype))); 61 printf(" cellularclass: %04X\n", le32toh(caps->cellularclass)); 62 printf(" voiceclass: %04X - %s\n", le32toh(caps->voiceclass), 63 mbim_enum_string(mbim_voice_class_values, le32toh(caps->voiceclass))); 64 printf(" simclass: %04X\n", le32toh(caps->simclass)); 65 printf(" dataclass: %04X\n", le32toh(caps->dataclass)); 66 printf(" smscaps: %04X\n", le32toh(caps->smscaps)); 67 printf(" controlcaps: %04X\n", le32toh(caps->controlcaps)); 68 printf(" maxsessions: %04X\n", le32toh(caps->maxsessions)); 69 printf(" deviceid: %s\n", deviceid); 70 printf(" firmwareinfo: %s\n", firmwareinfo); 71 printf(" hardwareinfo: %s\n", hardwareinfo); 72 73 return 0; 74 } 75 76 static int 77 mbim_pin_state_response(void *buffer, size_t len) 78 { 79 struct mbim_basic_connect_pin_r *pin = (struct mbim_basic_connect_pin_r *) buffer; 80 81 if (len < sizeof(struct mbim_basic_connect_pin_r)) { 82 fprintf(stderr, "message not long enough\n"); 83 return -1; 84 } 85 86 if (le32toh(pin->pinstate) != MBIM_PIN_STATE_UNLOCKED) { 87 fprintf(stderr, "required pin: %d - %s\n", 88 le32toh(pin->pintype), mbim_enum_string(mbim_pin_type_values, le32toh(pin->pintype))); 89 fprintf(stderr, "remaining attempts: %d\n", le32toh(pin->remainingattempts)); 90 return le32toh(pin->pintype); 91 } 92 93 fprintf(stderr, "Pin Unlocked\n"); 94 95 return 0; 96 } 97 98 static int 99 mbim_home_provider_response(void *buffer, size_t len) 100 { 101 struct mbim_basic_connect_home_provider_r *state = (struct mbim_basic_connect_home_provider_r *) buffer; 102 struct mbimprovider *provider; 103 char *provider_id, *provider_name; 104 105 if (len < sizeof(struct mbim_basic_connect_home_provider_r)) { 106 fprintf(stderr, "message not long enough\n"); 107 return -1; 108 } 109 110 provider = &state->provider; 111 provider_id = mbim_get_string(&provider->providerid, buffer); 112 provider_name = mbim_get_string(&provider->providername, buffer); 113 114 printf(" provider_id: %s\n", provider_id); 115 printf(" provider_name: %s\n", provider_name); 116 printf(" cellularclass: %04X - %s\n", le32toh(provider->cellularclass), 117 mbim_enum_string(mbim_cellular_class_values, le32toh(provider->cellularclass))); 118 printf(" rssi: %04X\n", le32toh(provider->rssi)); 119 printf(" errorrate: %04X\n", le32toh(provider->errorrate)); 120 121 return 0; 122 } 123 124 static int 125 mbim_registration_response(void *buffer, size_t len) 126 { 127 struct mbim_basic_connect_register_state_r *state = (struct mbim_basic_connect_register_state_r *) buffer; 128 char *provider_id, *provider_name, *roamingtext; 129 130 if (len < sizeof(struct mbim_basic_connect_register_state_r)) { 131 fprintf(stderr, "message not long enough\n"); 132 return -1; 133 } 134 135 provider_id = mbim_get_string(&state->providerid, buffer); 136 provider_name = mbim_get_string(&state->providername, buffer); 137 roamingtext = mbim_get_string(&state->roamingtext, buffer); 138 139 printf(" nwerror: %04X - %s\n", le32toh(state->nwerror), 140 mbim_enum_string(mbim_nw_error_values, le32toh(state->nwerror))); 141 printf(" registerstate: %04X - %s\n", le32toh(state->registerstate), 142 mbim_enum_string(mbim_register_state_values, le32toh(state->registerstate))); 143 printf(" registermode: %04X - %s\n", le32toh(state->registermode), 144 mbim_enum_string(mbim_register_mode_values, le32toh(state->registermode))); 145 printf(" availabledataclasses: %04X - %s\n", le32toh(state->availabledataclasses), 146 mbim_enum_string(mbim_data_class_values, le32toh(state->availabledataclasses))); 147 printf(" currentcellularclass: %04X - %s\n", le32toh(state->currentcellularclass), 148 mbim_enum_string(mbim_cellular_class_values, le32toh(state->currentcellularclass))); 149 printf(" provider_id: %s\n", provider_id); 150 printf(" provider_name: %s\n", provider_name); 151 printf(" roamingtext: %s\n", roamingtext); 152 153 if (le32toh(state->registerstate) == MBIM_REGISTER_STATE_HOME) 154 return 0; 155 156 return le32toh(state->registerstate); 157 } 158 159 static int 160 mbim_subscriber_response(void *buffer, size_t len) 161 { 162 struct mbim_basic_connect_subscriber_ready_status_r *state = (struct mbim_basic_connect_subscriber_ready_status_r *) buffer; 163 char *subscriberid, *simiccid; 164 unsigned int nr; 165 166 if (len < sizeof(struct mbim_basic_connect_subscriber_ready_status_r)) { 167 fprintf(stderr, "message not long enough\n"); 168 return -1; 169 } 170 171 subscriberid = mbim_get_string(&state->subscriberid, buffer); 172 simiccid = mbim_get_string(&state->simiccid, buffer); 173 174 printf(" readystate: %04X - %s\n", le32toh(state->readystate), 175 mbim_enum_string(mbim_subscriber_ready_state_values, le32toh(state->readystate))); 176 printf(" simiccid: %s\n", simiccid); 177 printf(" subscriberid: %s\n", subscriberid); 178 if (le32toh(state->readyinfo) & MBIM_READY_INFO_FLAG_PROTECT_UNIQUE_ID) 179 printf(" dont display subscriberID: 1\n"); 180 for (nr = 0; nr < le32toh(state->telephonenumberscount); nr++) { 181 struct mbim_string *str = (void *)&state->telephonenumbers + (nr * sizeof(struct mbim_string)); 182 char *number = mbim_get_string(str, buffer); 183 printf(" number: %s\n", number); 184 } 185 186 if (MBIM_SUBSCRIBER_READY_STATE_INITIALIZED == le32toh(state->readystate)) 187 return 0; 188 189 return le32toh(state->readystate); 190 } 191 192 static int 193 mbim_attach_response(void *buffer, size_t len) 194 { 195 struct mbim_basic_connect_packet_service_r *ps = (struct mbim_basic_connect_packet_service_r *) buffer; 196 197 if (len < sizeof(struct mbim_basic_connect_packet_service_r)) { 198 fprintf(stderr, "message not long enough\n"); 199 return -1; 200 } 201 202 printf(" nwerror: %04X - %s\n", le32toh(ps->nwerror), 203 mbim_enum_string(mbim_nw_error_values, le32toh(ps->nwerror))); 204 printf(" packetservicestate: %04X - %s\n", le32toh(ps->packetservicestate), 205 mbim_enum_string(mbim_packet_service_state_values, le32toh(ps->packetservicestate))); 206 printf(" uplinkspeed: %"PRIu64"\n", (uint64_t) le64toh(ps->uplinkspeed)); 207 printf(" downlinkspeed: %"PRIu64"\n", (uint64_t) le64toh(ps->downlinkspeed)); 208 209 if (MBIM_PACKET_SERVICE_STATE_ATTACHED == le32toh(ps->packetservicestate)) 210 return 0; 211 212 return le32toh(ps->packetservicestate); 213 } 214 215 static int 216 mbim_connect_response(void *buffer, size_t len) 217 { 218 struct mbim_basic_connect_connect_r *c = (struct mbim_basic_connect_connect_r *) buffer; 219 220 if (len < sizeof(struct mbim_basic_connect_connect_r)) { 221 fprintf(stderr, "message not long enough\n"); 222 return -1; 223 } 224 225 printf(" sessionid: %d\n", le32toh(c->sessionid)); 226 printf(" activationstate: %04X - %s\n", le32toh(c->activationstate), 227 mbim_enum_string(mbim_activation_state_values, le32toh(c->activationstate))); 228 printf(" voicecallstate: %04X - %s\n", le32toh(c->voicecallstate), 229 mbim_enum_string(mbim_voice_call_state_values, le32toh(c->voicecallstate))); 230 printf(" nwerror: %04X - %s\n", le32toh(c->nwerror), 231 mbim_enum_string(mbim_nw_error_values, le32toh(c->nwerror))); 232 printf(" iptype: %04X - %s\n", le32toh(c->iptype), 233 mbim_enum_string(mbim_context_ip_type_values, le32toh(c->iptype))); 234 235 if (MBIM_ACTIVATION_STATE_ACTIVATED == le32toh(c->activationstate)) 236 return 0; 237 238 return le32toh(c->activationstate); 239 } 240 241 static int 242 mbim_config_response(void *buffer, size_t len) 243 { 244 struct mbim_basic_connect_ip_configuration_r *ip = (struct mbim_basic_connect_ip_configuration_r *) buffer; 245 char out[40]; 246 unsigned int i; 247 uint32_t offset; 248 249 if (len < sizeof(struct mbim_basic_connect_ip_configuration_r)) { 250 fprintf(stderr, "message not long enough\n"); 251 return -1; 252 } 253 254 if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS) 255 for (i = 0; i < le32toh(ip->ipv4addresscount); i++) { 256 offset = le32toh(ip->ipv4address) + (i * 4); 257 mbim_get_ipv4(buffer, out, 4 + offset); 258 printf(" ipv4address: %s/%d\n", out, mbim_get_int(buffer, offset)); 259 } 260 if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) { 261 mbim_get_ipv4(buffer, out, le32toh(ip->ipv4gateway)); 262 printf(" ipv4gateway: %s\n", out); 263 } 264 if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU) 265 printf(" ipv4mtu: %d\n", le32toh(ip->ipv4mtu)); 266 if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) 267 for (i = 0; i < le32toh(ip->ipv4dnsservercount); i++) { 268 mbim_get_ipv4(buffer, out, le32toh(ip->ipv4dnsserver) + (i * 4)); 269 printf(" ipv4dnsserver: %s\n", out); 270 } 271 272 if (le32toh(ip->ipv6configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS) 273 for (i = 0; i < le32toh(ip->ipv6addresscount); i++) { 274 offset = le32toh(ip->ipv6address) + (i * 16); 275 mbim_get_ipv6(buffer, out, 4 + offset); 276 printf(" ipv6address: %s/%d\n", out, mbim_get_int(buffer, offset)); 277 } 278 if (le32toh(ip->ipv6configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) { 279 mbim_get_ipv6(buffer, out, le32toh(ip->ipv6gateway)); 280 printf(" ipv6gateway: %s\n", out); 281 } 282 if (le32toh(ip->ipv6configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU) 283 printf(" ipv6mtu: %d\n", le32toh(ip->ipv6mtu)); 284 if (le32toh(ip->ipv6configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) 285 for (i = 0; i < le32toh(ip->ipv6dnsservercount); i++) { 286 mbim_get_ipv6(buffer, out, le32toh(ip->ipv6dnsserver) + (i * 16)); 287 printf(" ipv6dnsserver: %s\n", out); 288 } 289 290 return 0; 291 } 292 293 static int 294 mbim_radio_response(void *buffer, size_t len) 295 { 296 struct mbim_basic_connect_radio_state_r *r = (struct mbim_basic_connect_radio_state_r *) buffer; 297 298 if (len < sizeof(struct mbim_basic_connect_radio_state_r)) { 299 fprintf(stderr, "message not long enough\n"); 300 return -1; 301 } 302 printf(" hwradiostate: %s\n", r->hwradiostate ? "on" : "off"); 303 printf(" swradiostate: %s\n", r->swradiostate ? "on" : "off"); 304 return 0; 305 } 306 307 static int 308 mbim_device_caps_request(void) 309 { 310 mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_DEVICE_CAPS, 0); 311 312 return mbim_send_command_msg(); 313 } 314 315 static int 316 mbim_pin_state_request(void) 317 { 318 mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_PIN, 0); 319 320 return mbim_send_command_msg(); 321 } 322 323 static int 324 mbim_home_provider_request(void) 325 { 326 mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CID_BASIC_CONNECT_HOME_PROVIDER, 0); 327 328 return mbim_send_command_msg(); 329 } 330 331 static int 332 mbim_registration_request(void) 333 { 334 if (_argc > 0) { 335 struct mbim_basic_connect_register_state_s *rs = 336 (struct mbim_basic_connect_register_state_s *) mbim_setup_command_msg(basic_connect, 337 MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_REGISTER_STATE, 338 sizeof(struct mbim_basic_connect_register_state_s)); 339 340 rs->registeraction = htole32(MBIM_REGISTER_ACTION_AUTOMATIC); 341 } else { 342 mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_REGISTER_STATE, 0); 343 } 344 345 return mbim_send_command_msg(); 346 } 347 348 static int 349 mbim_subscriber_request(void) 350 { 351 mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_SUBSCRIBER_READY_STATUS, 0); 352 353 return mbim_send_command_msg(); 354 } 355 356 static int 357 _mbim_attach_request(int action) 358 { 359 struct mbim_basic_connect_packet_service_s *ps = 360 (struct mbim_basic_connect_packet_service_s *) mbim_setup_command_msg(basic_connect, 361 MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_PACKET_SERVICE, 362 sizeof(struct mbim_basic_connect_packet_service_s)); 363 364 ps->packetserviceaction = htole32(action); 365 366 return mbim_send_command_msg(); 367 } 368 369 static int 370 mbim_attach_request(void) 371 { 372 return _mbim_attach_request(MBIM_PACKET_SERVICE_ACTION_ATTACH); 373 } 374 375 static int 376 mbim_detach_request(void) 377 { 378 return _mbim_attach_request(MBIM_PACKET_SERVICE_ACTION_DETACH); 379 } 380 381 static int 382 mbim_connect_request(void) 383 { 384 char *apn; 385 struct mbim_basic_connect_connect_s *c = 386 (struct mbim_basic_connect_connect_s *) mbim_setup_command_msg(basic_connect, 387 MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_CONNECT, 388 sizeof(struct mbim_basic_connect_connect_s)); 389 390 c->activationcommand = htole32(MBIM_ACTIVATION_COMMAND_ACTIVATE); 391 c->iptype = htole32(MBIM_CONTEXT_IP_TYPE_DEFAULT); 392 memcpy(c->contexttype, uuid_context_type_internet, 16); 393 if (_argc > 0) { 394 apn = index(*_argv, ':'); 395 if (!apn) { 396 apn = *_argv; 397 } else { 398 apn[0] = 0; 399 apn++; 400 if (!strcmp(*_argv, "ipv4")) 401 c->iptype = htole32(MBIM_CONTEXT_IP_TYPE_IPV4); 402 else if (!strcmp(*_argv, "ipv6")) 403 c->iptype = htole32(MBIM_CONTEXT_IP_TYPE_IPV6); 404 else if (!strcmp(*_argv, "ipv4v6")) 405 c->iptype = htole32(MBIM_CONTEXT_IP_TYPE_IPV4V6); 406 } 407 mbim_encode_string(&c->accessstring, apn); 408 } 409 if (_argc > 3) { 410 if (!strcmp(_argv[1], "pap")) 411 c->authprotocol = htole32(MBIM_AUTH_PROTOCOL_PAP); 412 else if (!strcmp(_argv[1], "chap")) 413 c->authprotocol = htole32(MBIM_AUTH_PROTOCOL_CHAP); 414 else if (!strcmp(_argv[1], "mschapv2")) 415 c->authprotocol = htole32(MBIM_AUTH_PROTOCOL_MSCHAPV2); 416 417 if (c->authprotocol) { 418 mbim_encode_string(&c->username, _argv[2]); 419 mbim_encode_string(&c->password, _argv[3]); 420 } 421 } 422 return mbim_send_command_msg(); 423 } 424 425 static int 426 mbim_disconnect_request(void) 427 { 428 struct mbim_basic_connect_connect_s *c = 429 (struct mbim_basic_connect_connect_s *) mbim_setup_command_msg(basic_connect, 430 MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_CONNECT, 431 sizeof(struct mbim_basic_connect_connect_s)); 432 433 c->activationcommand = htole32(MBIM_ACTIVATION_COMMAND_DEACTIVATE); 434 memcpy(c->contexttype, uuid_context_type_internet, 16); 435 436 no_close = 0; 437 438 return mbim_send_command_msg(); 439 } 440 441 static char* 442 mbim_pin_sanitize(char *pin) 443 { 444 char *p; 445 446 while (*pin && !isdigit(*pin)) 447 pin++; 448 p = pin; 449 if (!*p) 450 return NULL; 451 while (*pin && isdigit(*pin)) 452 pin++; 453 if (*pin) 454 *pin = '\0'; 455 456 return p; 457 } 458 459 static int 460 mbim_pin_unlock_request(void) 461 { 462 struct mbim_basic_connect_pin_s *p = 463 (struct mbim_basic_connect_pin_s *) mbim_setup_command_msg(basic_connect, 464 MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_PIN, 465 sizeof(struct mbim_basic_connect_pin_s)); 466 char *pin = mbim_pin_sanitize(_argv[0]); 467 468 if (!pin || !strlen(pin)) { 469 fprintf(stderr, "failed to sanitize the pincode\n"); 470 return -1; 471 } 472 473 p->pintype = htole32(MBIM_PIN_TYPE_PIN1); 474 p->pinoperation = htole32(MBIM_PIN_OPERATION_ENTER); 475 mbim_encode_string(&p->pin, _argv[0]); 476 477 return mbim_send_command_msg(); 478 } 479 480 static int 481 mbim_config_request(void) 482 { 483 mbim_setup_command_msg(basic_connect, 484 MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_IP_CONFIGURATION, 485 sizeof(struct mbim_basic_connect_ip_configuration_q)); 486 487 return mbim_send_command_msg(); 488 } 489 490 static int 491 mbim_radio_request(void) 492 { 493 if (_argc > 0) { 494 struct mbim_basic_connect_radio_state_s *rs = 495 (struct mbim_basic_connect_radio_state_s *) mbim_setup_command_msg(basic_connect, 496 MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_RADIO_STATE, 497 sizeof(struct mbim_basic_connect_radio_state_r)); 498 499 if (!strcmp(_argv[0], "off")) 500 rs->radiostate = htole32(MBIM_RADIO_SWITCH_STATE_OFF); 501 else 502 rs->radiostate = htole32(MBIM_RADIO_SWITCH_STATE_ON); 503 } else { 504 mbim_setup_command_msg(basic_connect, 505 MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_RADIO_STATE, 506 sizeof(struct mbim_basic_connect_radio_state_r)); 507 } 508 return mbim_send_command_msg(); 509 } 510 511 static struct mbim_handler handlers[] = { 512 { "caps", 0, mbim_device_caps_request, mbim_device_caps_response }, 513 { "pinstate", 0, mbim_pin_state_request, mbim_pin_state_response }, 514 { "unlock", 1, mbim_pin_unlock_request, mbim_pin_state_response }, 515 { "home", 0, mbim_home_provider_request, mbim_home_provider_response }, 516 { "registration", 0, mbim_registration_request, mbim_registration_response }, 517 { "subscriber", 0, mbim_subscriber_request, mbim_subscriber_response }, 518 { "attach", 0, mbim_attach_request, mbim_attach_response }, 519 { "detach", 0, mbim_detach_request, mbim_attach_response }, 520 { "connect", 0, mbim_connect_request, mbim_connect_response }, 521 { "disconnect", 0, mbim_disconnect_request, mbim_connect_response }, 522 { "config", 0, mbim_config_request, mbim_config_response }, 523 { "radio", 0, mbim_radio_request, mbim_radio_response }, 524 }; 525 526 static int 527 usage(void) 528 { 529 fprintf(stderr, "Usage: umbim <caps|pinstate|unlock|home|registration|subscriber|attach|detach|connect|disconnect|config|radio> [options]\n" 530 "Options:\n" 531 #ifdef LIBQMI_MBIM_PROXY 532 " -p use mbim-proxy\n" 533 #endif 534 " -d <device> the device (/dev/cdc-wdmX)\n" 535 " -t <transaction> the transaction id\n" 536 " -n no close\n\n" 537 " -v verbose\n\n"); 538 return 1; 539 } 540 541 int 542 main(int argc, char **argv) 543 { 544 char *cmd, *device = NULL; 545 int no_open = 0, ch; 546 unsigned int i; 547 #ifdef LIBQMI_MBIM_PROXY 548 int proxy = 0; 549 #endif 550 551 while ((ch = getopt(argc, argv, "pnvd:t:")) != -1) { 552 switch (ch) { 553 case 'v': 554 verbose = 1; 555 break; 556 case 'n': 557 no_close = 1; 558 break; 559 case 'd': 560 device = optarg; 561 break; 562 case 't': 563 no_open = 1; 564 transaction_id = atoi(optarg); 565 break; 566 #ifdef LIBQMI_MBIM_PROXY 567 case 'p': 568 proxy = 1; 569 break; 570 #endif 571 default: 572 return usage(); 573 } 574 } 575 576 if (!device || optind == argc) 577 return usage(); 578 579 cmd = argv[optind]; 580 optind++; 581 582 _argc = argc - optind; 583 _argv = &argv[optind]; 584 585 for (i = 0; i < ARRAY_SIZE(handlers); i++) 586 if (!strcmp(cmd, handlers[i].name)) 587 current_handler = &handlers[i]; 588 589 if (!current_handler || (optind + current_handler->argc > argc)) 590 return usage(); 591 592 uloop_init(); 593 594 #ifdef LIBQMI_MBIM_PROXY 595 if (proxy) 596 mbim_proxy_open(device); 597 else 598 #endif 599 mbim_open(device); 600 if (!no_open) 601 mbim_send_open_msg(); 602 else if (current_handler->request() < 0) 603 return -1; 604 605 uloop_run(); 606 uloop_done(); 607 608 return return_code; 609 } 610
This page was automatically generated by LXR 0.3.1. • OpenWrt