From b82f187ab204a56f5ed7cd6d4de64bfdc07a1a74 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 14 Aug 2014 15:32:11 +0200 Subject: [PATCH] initial import --- .gitignore | 7 + CMakeLists.txt | 22 + cli.c | 428 +++++ data/gen-header.pl | 137 ++ data/lib/JSON.pm | 2267 +++++++++++++++++++++++++ data/lib/JSON/backportPP.pm | 2797 +++++++++++++++++++++++++++++++ data/lib/JSON/backportPP/Boolean.pm | 26 + data/lib/JSON/backportPP/Compat5005.pm | 131 ++ data/lib/JSON/backportPP/Compat5006.pm | 173 ++ data/mbim-service-auth.h | 65 + data/mbim-service-auth.json | 89 + data/mbim-service-basic-connect.h | 704 ++++++++ data/mbim-service-basic-connect.json | 814 +++++++++ data/mbim-service-dss.h | 7 + data/mbim-service-dss.json | 20 + data/mbim-service-ms-firmware-id.h | 11 + data/mbim-service-ms-firmware-id.json | 13 + data/mbim-service-ms-host-shutdown.h | 7 + data/mbim-service-ms-host-shutdown.json | 11 + data/mbim-service-phonebook.h | 52 + data/mbim-service-phonebook.json | 89 + data/mbim-service-proxy-control.h | 7 + data/mbim-service-proxy-control.json | 17 + data/mbim-service-sms.h | 94 ++ data/mbim-service-sms.json | 181 ++ data/mbim-service-stk.h | 34 + data/mbim-service-stk.json | 47 + data/mbim-service-ussd.h | 14 + data/mbim-service-ussd.json | 38 + mbim-cid.h | 213 +++ mbim-dev.c | 120 ++ mbim-dev.h | 10 + mbim-enum.c | 576 +++++++ mbim-enum.h | 1062 ++++++++++++ mbim-enums.h | 68 + mbim-msg.c | 169 ++ mbim-msg.h | 84 + mbim-type.h | 15 + mbim.h | 28 + 39 files changed, 10647 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 cli.c create mode 100755 data/gen-header.pl create mode 100644 data/lib/JSON.pm create mode 100644 data/lib/JSON/backportPP.pm create mode 100644 data/lib/JSON/backportPP/Boolean.pm create mode 100644 data/lib/JSON/backportPP/Compat5005.pm create mode 100644 data/lib/JSON/backportPP/Compat5006.pm create mode 100644 data/mbim-service-auth.h create mode 100644 data/mbim-service-auth.json create mode 100644 data/mbim-service-basic-connect.h create mode 100644 data/mbim-service-basic-connect.json create mode 100644 data/mbim-service-dss.h create mode 100644 data/mbim-service-dss.json create mode 100644 data/mbim-service-ms-firmware-id.h create mode 100644 data/mbim-service-ms-firmware-id.json create mode 100644 data/mbim-service-ms-host-shutdown.h create mode 100644 data/mbim-service-ms-host-shutdown.json create mode 100644 data/mbim-service-phonebook.h create mode 100644 data/mbim-service-phonebook.json create mode 100644 data/mbim-service-proxy-control.h create mode 100644 data/mbim-service-proxy-control.json create mode 100644 data/mbim-service-sms.h create mode 100644 data/mbim-service-sms.json create mode 100644 data/mbim-service-stk.h create mode 100644 data/mbim-service-stk.json create mode 100644 data/mbim-service-ussd.h create mode 100644 data/mbim-service-ussd.json create mode 100644 mbim-cid.h create mode 100644 mbim-dev.c create mode 100644 mbim-dev.h create mode 100644 mbim-enum.c create mode 100644 mbim-enum.h create mode 100644 mbim-enums.h create mode 100644 mbim-msg.c create mode 100644 mbim-msg.h create mode 100644 mbim-type.h create mode 100644 mbim.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1134291 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +umbim +.* +Makefile +CMakeCache.txt +CMakeFiles +*.cmake +install_manifest.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c210d6f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.6) + +PROJECT(umbim C) +ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations) + +SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") + +SET(SOURCES cli.c mbim-enum.c mbim-dev.c mbim-msg.c ) + +SET(LIBS ubox) + +IF(DEBUG) + ADD_DEFINITIONS(-DDEBUG -g3) +ENDIF() + +ADD_EXECUTABLE(umbim ${SOURCES}) + +TARGET_LINK_LIBRARIES(umbim ${LIBS}) + +INSTALL(TARGETS umbim + RUNTIME DESTINATION sbin +) diff --git a/cli.c b/cli.c new file mode 100644 index 0000000..328804d --- /dev/null +++ b/cli.c @@ -0,0 +1,428 @@ +#define __STDC_FORMAT_MACROS +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mbim.h" + +#include "data/mbim-service-basic-connect.h" + +int return_code = -1; +int verbose; + +struct mbim_handler *current_handler; +static uint8_t uuid_context_type_internet[16] = { 0x7E, 0x5E, 0x2A, 0x7E, 0x4E, 0x6F, 0x72, 0x72, 0x73, 0x6B, 0x65, 0x6E, 0x7E, 0x5E, 0x2A, 0x7E }; +static int _argc; +static char **_argv; + +static int +mbim_device_caps_response(void *buffer, int len) +{ + struct mbim_basic_connect_device_caps_r *caps = (struct mbim_basic_connect_device_caps_r *) buffer; + char *deviceid, *firmwareinfo, *hardwareinfo; + + if (len < sizeof(struct mbim_basic_connect_device_caps_r)) { + fprintf(stderr, "message not long enough\n"); + return -1; + } + + deviceid = mbim_get_string(&caps->deviceid, buffer); + firmwareinfo = mbim_get_string(&caps->firmwareinfo, buffer); + hardwareinfo = mbim_get_string(&caps->hardwareinfo, buffer); + + printf(" devicetype: %04X - %s\n", le32toh(caps->devicetype), + mbim_enum_string(mbim_device_type_values, le32toh(caps->devicetype))); + printf(" cellularclass: %04X\n", le32toh(caps->cellularclass)); + printf(" voiceclass: %04X - %s\n", le32toh(caps->voiceclass), + mbim_enum_string(mbim_voice_class_values, le32toh(caps->voiceclass))); + printf(" simclass: %04X\n", le32toh(caps->simclass)); + printf(" dataclass: %04X\n", le32toh(caps->dataclass)); + printf(" smscaps: %04X\n", le32toh(caps->smscaps)); + printf(" controlcaps: %04X\n", le32toh(caps->controlcaps)); + printf(" maxsessions: %04X\n", le32toh(caps->maxsessions)); + printf(" deviceid: %s\n", deviceid); + printf(" firmwareinfo: %s\n", firmwareinfo); + printf(" hardwareinfo: %s\n", hardwareinfo); + + return 0; +} + +static int +mbim_pin_state_response(void *buffer, int len) +{ + struct mbim_basic_connect_pin_r *pin = (struct mbim_basic_connect_pin_r *) buffer; + + if (len < sizeof(struct mbim_basic_connect_pin_r)) { + fprintf(stderr, "message not long enough\n"); + return -1; + } + + if (le32toh(pin->pinstate) != MBIM_PIN_STATE_UNLOCKED) { + fprintf(stderr, "required pin: %d - %s\n", + le32toh(pin->pintype), mbim_enum_string(mbim_pin_type_values, le32toh(pin->pintype))); + fprintf(stderr, "remaining attempts: %d\n", le32toh(pin->remainingattempts)); + return le32toh(pin->pintype); + } + + fprintf(stderr, "Pin Unlocked\n"); + + return 0; +} + +static int +mbim_registration_response(void *buffer, int len) +{ + struct mbim_basic_connect_register_state_r *state = (struct mbim_basic_connect_register_state_r *) buffer; + char *provider_id, *provider_name, *roamingtext; + + if (len < sizeof(struct mbim_basic_connect_register_state_r)) { + fprintf(stderr, "message not long enough\n"); + return -1; + } + + provider_id = mbim_get_string(&state->providerid, buffer); + provider_name = mbim_get_string(&state->providername, buffer); + roamingtext = mbim_get_string(&state->roamingtext, buffer); + + printf(" nwerror: %04X - %s\n", le32toh(state->nwerror), + mbim_enum_string(mbim_nw_error_values, le32toh(state->nwerror))); + printf(" registerstate: %04X - %s\n", le32toh(state->registerstate), + mbim_enum_string(mbim_register_state_values, le32toh(state->registerstate))); + printf(" registermode: %04X - %s\n", le32toh(state->registermode), + mbim_enum_string(mbim_register_mode_values, le32toh(state->registermode))); + printf(" availabledataclasses: %04X - %s\n", le32toh(state->availabledataclasses), + mbim_enum_string(mbim_data_class_values, le32toh(state->availabledataclasses))); + printf(" currentcellularclass: %04X - %s\n", le32toh(state->currentcellularclass), + mbim_enum_string(mbim_cellular_class_values, le32toh(state->currentcellularclass))); + printf(" provider_id: %s\n", provider_id); + printf(" provider_name: %s\n", provider_name); + printf(" roamingtext: %s\n", roamingtext); + + if (le32toh(state->registerstate) == MBIM_REGISTER_STATE_HOME) + return 0; + + return le32toh(state->registerstate); +} + +static int +mbim_subscriber_response(void *buffer, int len) +{ + struct mbim_basic_connect_subscriber_ready_status_r *state = (struct mbim_basic_connect_subscriber_ready_status_r *) buffer; + char *subscriberid, *simiccid; + int nr; + + if (len < sizeof(struct mbim_basic_connect_subscriber_ready_status_r)) { + fprintf(stderr, "message not long enough\n"); + return -1; + } + + subscriberid = mbim_get_string(&state->subscriberid, buffer); + simiccid = mbim_get_string(&state->simiccid, buffer); + + printf(" readystate: %04X - %s\n", le32toh(state->readystate), + mbim_enum_string(mbim_subscriber_ready_state_values, le32toh(state->readystate))); + printf(" simiccid: %s\n", simiccid); + printf(" subscriberid: %s\n", subscriberid); + if (le32toh(state->readyinfo) & MBIM_READY_INFO_FLAG_PROTECT_UNIQUE_ID) + printf(" dont display subscriberID: 1\n"); + for (nr = 0; nr < le32toh(state->telephonenumberscount); nr++) { + struct mbim_string *str = buffer + le32toh(state->telephonenumbers) + (nr * sizeof(struct mbim_string)); + char *number = mbim_get_string(str, buffer); + printf(" number: %s\n", number); + } + + if (MBIM_SUBSCRIBER_READY_STATE_INITIALIZED == le32toh(state->readystate)) + return 0; + + return le32toh(state->readystate); +} + +static int +mbim_attach_response(void *buffer, int len) +{ + struct mbim_basic_connect_packet_service_r *ps = (struct mbim_basic_connect_packet_service_r *) buffer; + + if (len < sizeof(struct mbim_basic_connect_packet_service_r)) { + fprintf(stderr, "message not long enough\n"); + return -1; + } + + printf(" nwerror: %04X - %s\n", le32toh(ps->nwerror), + mbim_enum_string(mbim_nw_error_values, le32toh(ps->nwerror))); + printf(" packetservicestate: %04X - %s\n", le32toh(ps->packetservicestate), + mbim_enum_string(mbim_packet_service_state_values, le32toh(ps->packetservicestate))); + printf(" uplinkspeed: %"PRIu64"\n", le64toh(ps->uplinkspeed)); + printf(" downlinkspeed: %"PRIu64"\n", le64toh(ps->downlinkspeed)); + + if (MBIM_PACKET_SERVICE_STATE_ATTACHED == le32toh(ps->packetservicestate)) + return 0; + + return le32toh(ps->packetservicestate); +} + +static int +mbim_connect_response(void *buffer, int len) +{ + struct mbim_basic_connect_connect_r *c = (struct mbim_basic_connect_connect_r *) buffer; + + if (len < sizeof(struct mbim_basic_connect_connect_r)) { + fprintf(stderr, "message not long enough\n"); + return -1; + } + + printf(" sessionid: %d\n", le32toh(c->sessionid)); + printf(" activationstate: %04X - %s\n", le32toh(c->activationstate), + mbim_enum_string(mbim_activation_state_values, le32toh(c->activationstate))); + printf(" voicecallstate: %04X - %s\n", le32toh(c->voicecallstate), + mbim_enum_string(mbim_voice_call_state_values, le32toh(c->voicecallstate))); + printf(" nwerror: %04X - %s\n", le32toh(c->nwerror), + mbim_enum_string(mbim_nw_error_values, le32toh(c->nwerror))); + printf(" iptype: %04X - %s\n", le32toh(c->iptype), + mbim_enum_string(mbim_context_ip_type_values, le32toh(c->iptype))); + + if (MBIM_ACTIVATION_STATE_ACTIVATED == le32toh(c->activationstate)) + return 0; + + return le32toh(c->activationstate); +} + +static int +mbim_config_response(void *buffer, int len) +{ + struct mbim_basic_connect_ip_configuration_r *ip = (struct mbim_basic_connect_ip_configuration_r *) buffer; + char ipv4[16]; + int i; + + if (len < sizeof(struct mbim_basic_connect_ip_configuration_r)) { + fprintf(stderr, "message not long enough\n"); + return -1; + } + + if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS) + for (i = 0; i < le32toh(ip->ipv4addresscount); i++) { + mbim_get_ipv4(buffer, ipv4, ip->ipv4address + (i * 4)); + printf(" ipv4address: %s\n", ipv4); + } + if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) { + mbim_get_ipv4(buffer, ipv4, ip->ipv4gateway); + printf(" ipv4gateway: %s\n", ipv4); + } + if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU) + printf(" ipv4mtu: %d\n", le32toh(ip->ipv4mtu)); + if (le32toh(ip->ipv4configurationavailable) & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) + for (i = 0; i < le32toh(ip->ipv4dnsservercount); i++) { + mbim_get_ipv4(buffer, ipv4, ip->ipv4dnsserver + (i * 4)); + printf(" ipv4dnsserver: %s\n", ipv4); + } + + printf(" ipv6configurationavailable: %04X\n", le32toh(ip->ipv6configurationavailable)); + + return 0; +} + +static int +mbim_device_caps_request(void) +{ + mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_DEVICE_CAPS, 0); + + return mbim_send_command_msg(); +} + +static int +mbim_pin_state_request(void) +{ + mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_PIN, 0); + + return mbim_send_command_msg(); +} + +static int +mbim_registration_request(void) +{ + mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_REGISTER_STATE, 0); + + return mbim_send_command_msg(); +} + +static int +mbim_subscriber_request(void) +{ + mbim_setup_command_msg(basic_connect, MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_SUBSCRIBER_READY_STATUS, 0); + + return mbim_send_command_msg(); +} + +static int +_mbim_attach_request(int action) +{ + struct mbim_basic_connect_packet_service_s *ps = + (struct mbim_basic_connect_packet_service_s *) mbim_setup_command_msg(basic_connect, + MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_PACKET_SERVICE, + sizeof(struct mbim_basic_connect_packet_service_s)); + + ps->packetserviceaction = htole32(action); + + return mbim_send_command_msg(); +} + +static int +mbim_attach_request(void) +{ + return _mbim_attach_request(MBIM_PACKET_SERVICE_ACTION_ATTACH); +} + +static int +mbim_detach_request(void) +{ + return _mbim_attach_request(MBIM_PACKET_SERVICE_ACTION_DETACH); +} + +static int +mbim_connect_request(void) +{ + struct mbim_basic_connect_connect_s *c = + (struct mbim_basic_connect_connect_s *) mbim_setup_command_msg(basic_connect, + MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_CONNECT, + sizeof(struct mbim_basic_connect_connect_s)); + + c->activationcommand = htole32(MBIM_ACTIVATION_COMMAND_ACTIVATE); + c->iptype = htole32(MBIM_CONTEXT_IP_TYPE_DEFAULT); + memcpy(c->contexttype, uuid_context_type_internet, 16); + if (_argc > 0) + mbim_encode_string(&c->accessstring, *_argv); + + return mbim_send_command_msg(); +} + +static int +mbim_disconnect_request(void) +{ + struct mbim_basic_connect_connect_s *c = + (struct mbim_basic_connect_connect_s *) mbim_setup_command_msg(basic_connect, + MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_CONNECT, + sizeof(struct mbim_basic_connect_connect_s)); + + c->activationcommand = htole32(MBIM_ACTIVATION_COMMAND_DEACTIVATE); + memcpy(c->contexttype, uuid_context_type_internet, 16); + + no_close = 0; + + return mbim_send_command_msg(); +} + +static int +mbim_pin_unlock_request(void) +{ + struct mbim_basic_connect_pin_s *p = + (struct mbim_basic_connect_pin_s *) mbim_setup_command_msg(basic_connect, + MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_BASIC_CONNECT_PIN, + sizeof(struct mbim_basic_connect_pin_s)); + + p->pintype = htole32(MBIM_PIN_TYPE_PIN1); + p->pinoperation = htole32(MBIM_PIN_OPERATION_ENTER); + mbim_encode_string(&p->pin, _argv[0]); + + return mbim_send_command_msg(); +} + +static int +mbim_config_request(void) +{ + mbim_setup_command_msg(basic_connect, + MBIM_MESSAGE_COMMAND_TYPE_QUERY, MBIM_CMD_BASIC_CONNECT_IP_CONFIGURATION, + sizeof(struct mbim_basic_connect_ip_configuration_q)); + + return mbim_send_command_msg(); +} + +static struct mbim_handler handlers[] = { + { "caps", 0, mbim_device_caps_request, mbim_device_caps_response }, + { "pinstate", 0, mbim_pin_state_request, mbim_pin_state_response }, + { "unlock", 1, mbim_pin_unlock_request, mbim_pin_state_response }, + { "registration", 0, mbim_registration_request, mbim_registration_response }, + { "subscriber", 0, mbim_subscriber_request, mbim_subscriber_response }, + { "attach", 0, mbim_attach_request, mbim_attach_response }, + { "detach", 0, mbim_detach_request, mbim_attach_response }, + { "connect", 0, mbim_connect_request, mbim_connect_response }, + { "disconnect", 0, mbim_disconnect_request, mbim_connect_response }, + { "config", 0, mbim_config_request, mbim_config_response }, +}; + +static int +usage(void) +{ + fprintf(stderr, "Usage: mbim [options]\n" + "Options:\n" + " -d the device (/dev/cdc-wdmX)\n" + " -t the transaction id\n" + " -n no close\n\n" + " -v verbose\n\n"); + return 1; +} + +int +main(int argc, char **argv) +{ + char *cmd, *device = NULL; + int no_open = 0, ch, i; + + while ((ch = getopt(argc, argv, "nvd:t:")) != -1) { + switch (ch) { + case 'v': + verbose = 1; + break; + case 'n': + no_close = 1; + break; + case 'd': + device = optarg; + break; + case 't': + no_open = 1; + transaction_id = atoi(optarg); + break; + default: + return usage(); + } + } + + if (!device || optind == argc) + return usage(); + + cmd = argv[optind]; + optind++; + + _argc = argc - optind; + _argv = &argv[optind]; + + for (i = 0; i < ARRAY_SIZE(handlers); i++) + if (!strcmp(cmd, handlers[i].name)) + current_handler = &handlers[i]; + + if (!current_handler || (optind + current_handler->argc > argc)) + return usage(); + + uloop_init(); + + mbim_open(device); + if (!no_open) + mbim_send_open_msg(); + else if (current_handler->request() < 0) + return -1; + + uloop_run(); + uloop_done(); + + return return_code; +} diff --git a/data/gen-header.pl b/data/gen-header.pl new file mode 100755 index 0000000..f1d1128 --- /dev/null +++ b/data/gen-header.pl @@ -0,0 +1,137 @@ +#!/usr/bin/perl + +use lib "./lib"; +use JSON; + +use strict; +use warnings; + +binmode STDOUT, ":utf8"; +use utf8; + +if (!@ARGV) { + die("gen-headers.pl \n"); +} + +my $json; +{ + local $/; #Enable 'slurp' mode + open my $fh, "<", $ARGV[0]; + $json = <$fh>; + close $fh; + $json =~ s/^\s*\/\/.*$//mg; +} + +my $data = decode_json($json); + + +my $id = 1; + +sub gen_foreach_field($) +{ + my $field = shift; + my $format; + + if ($field->{format} eq "guint32") { + $format = "uint32_t"; + } elsif ($field->{format} eq "guint64") { + $format = "uint64_t"; + } elsif ($field->{format} eq "struct") { + $format = "struct ". lc $field->{"struct-type"}; + } elsif ($field->{format} eq "uuid") { + print "\tuint8_t " . lc $field->{name} . "[16];\n"; + return; + } elsif ($field->{format} eq "ipv4") { + print "\tuint8_t " . lc $field->{name} . "[4];\n"; + return; + } elsif ($field->{format} eq "ipv6") { + print "\tuint8_t " . lc $field->{name} . "[16];\n"; + return; + } elsif ($field->{format} eq "struct-array") { + print "\t/* struct " . lc $field->{"struct-type"} . " */\n"; + $format = "uint32_t"; + } elsif ($field->{format} eq "string") { + $format = "struct mbim_string"; + } else { + print "\t/* array type: " . $field->{format} . " */\n"; + $format = "uint32_t"; + } + if ($field->{"public-format"}) { + print "\t/* enum " . $field->{"public-format"} . " */\n"; + } + print "\t" . $format . " " . lc $field->{name} . ";\n"; +} + +sub gen_struct($$) +{ + my $struct = shift; + my $entry = shift; + + $struct =~ s/ /_/g; + print "struct " . lc $struct . " {\n"; + foreach my $field (@{$entry}) { + gen_foreach_field($field); + } + print "} __attribute__((packed));\n\n"; +} + +sub gen_foreach_struct($) +{ + my $entry = shift; + + if ($entry->{contents} && @{$entry->{contents}} > 0) { + my $struct = $entry->{name}; + gen_struct($struct, $entry->{contents}); + return; + } + + print "/*\n * ID: " . $id . "\n * Command: " . $entry->{name} . "\n */\n\n"; + my $define = "mbim_cmd_" . $entry->{service} . "_" . $entry->{name}; + $define =~ s/ /_/g; + print "#define " . uc $define . "\t" . $id . "\n\n"; + + $id = $id + 1; + # basic connect has no sequential numbering. ugly hack alert + if ($id == 17) { + $id = 19; + } + + if ($entry->{query} && @{$entry->{query}} > 0) { + my $struct = "mbim_" . $entry->{service} . "_" . $entry->{name} . "_q"; + gen_struct($struct, $entry->{query}); + } + + if ($entry->{response} && @{$entry->{response}} > 0) { + my $struct = "mbim_" . $entry->{service} . "_" . $entry->{name} . "_r"; + gen_struct($struct, $entry->{response}); + } + + if ($entry->{set} && @{$entry->{set}} > 0) { + my $struct = "mbim_" . $entry->{service} . "_" . $entry->{name} . "_s"; + gen_struct($struct, $entry->{set}); + } + + if ($entry->{notification} && @{$entry->{notification}} > 0) { + my $struct = "mbim_" . $entry->{service} . "_" . $entry->{name} . "_n"; + gen_struct($struct, $entry->{notification}); + } +} + +sub gen_foreach_command($) +{ + my $data = shift; + + foreach my $entry (@$data) { + my $args = []; + my $fields = []; + + if ($entry->{type} eq 'Command') { + gen_foreach_struct($entry); + } + if ($entry->{type} eq 'Struct') { + gen_foreach_struct($entry); + } + } +} + +gen_foreach_command($data); diff --git a/data/lib/JSON.pm b/data/lib/JSON.pm new file mode 100644 index 0000000..f57c555 --- /dev/null +++ b/data/lib/JSON.pm @@ -0,0 +1,2267 @@ +package JSON; + + +use strict; +use Carp (); +use base qw(Exporter); +@JSON::EXPORT = qw(from_json to_json jsonToObj objToJson encode_json decode_json); + +BEGIN { + $JSON::VERSION = '2.53'; + $JSON::DEBUG = 0 unless (defined $JSON::DEBUG); + $JSON::DEBUG = $ENV{ PERL_JSON_DEBUG } if exists $ENV{ PERL_JSON_DEBUG }; +} + +my $Module_XS = 'JSON::XS'; +my $Module_PP = 'JSON::PP'; +my $Module_bp = 'JSON::backportPP'; # included in JSON distribution +my $PP_Version = '2.27200'; +my $XS_Version = '2.27'; + + +# XS and PP common methods + +my @PublicMethods = qw/ + ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref + allow_blessed convert_blessed filter_json_object filter_json_single_key_object + shrink max_depth max_size encode decode decode_prefix allow_unknown +/; + +my @Properties = qw/ + ascii latin1 utf8 indent space_before space_after relaxed canonical allow_nonref + allow_blessed convert_blessed shrink max_depth max_size allow_unknown +/; + +my @XSOnlyMethods = qw//; # Currently nothing + +my @PPOnlyMethods = qw/ + indent_length sort_by + allow_singlequote allow_bignum loose allow_barekey escape_slash as_nonblessed +/; # JSON::PP specific + + +# used in _load_xs and _load_pp ($INSTALL_ONLY is not used currently) +my $_INSTALL_DONT_DIE = 1; # When _load_xs fails to load XS, don't die. +my $_INSTALL_ONLY = 2; # Don't call _set_methods() +my $_ALLOW_UNSUPPORTED = 0; +my $_UNIV_CONV_BLESSED = 0; +my $_USSING_bpPP = 0; + + +# Check the environment variable to decide worker module. + +unless ($JSON::Backend) { + $JSON::DEBUG and Carp::carp("Check used worker module..."); + + my $backend = exists $ENV{PERL_JSON_BACKEND} ? $ENV{PERL_JSON_BACKEND} : 1; + + if ($backend eq '1' or $backend =~ /JSON::XS\s*,\s*JSON::PP/) { + _load_xs($_INSTALL_DONT_DIE) or _load_pp(); + } + elsif ($backend eq '0' or $backend eq 'JSON::PP') { + _load_pp(); + } + elsif ($backend eq '2' or $backend eq 'JSON::XS') { + _load_xs(); + } + elsif ($backend eq 'JSON::backportPP') { + $_USSING_bpPP = 1; + _load_pp(); + } + else { + Carp::croak "The value of environmental variable 'PERL_JSON_BACKEND' is invalid."; + } +} + + +sub import { + my $pkg = shift; + my @what_to_export; + my $no_export; + + for my $tag (@_) { + if ($tag eq '-support_by_pp') { + if (!$_ALLOW_UNSUPPORTED++) { + JSON::Backend::XS + ->support_by_pp(@PPOnlyMethods) if ($JSON::Backend eq $Module_XS); + } + next; + } + elsif ($tag eq '-no_export') { + $no_export++, next; + } + elsif ( $tag eq '-convert_blessed_universally' ) { + eval q| + require B; + *UNIVERSAL::TO_JSON = sub { + my $b_obj = B::svref_2object( $_[0] ); + return $b_obj->isa('B::HV') ? { %{ $_[0] } } + : $b_obj->isa('B::AV') ? [ @{ $_[0] } ] + : undef + ; + } + | if ( !$_UNIV_CONV_BLESSED++ ); + next; + } + push @what_to_export, $tag; + } + + return if ($no_export); + + __PACKAGE__->export_to_level(1, $pkg, @what_to_export); +} + + +# OBSOLETED + +sub jsonToObj { + my $alternative = 'from_json'; + if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) { + shift @_; $alternative = 'decode'; + } + Carp::carp "'jsonToObj' will be obsoleted. Please use '$alternative' instead."; + return JSON::from_json(@_); +}; + +sub objToJson { + my $alternative = 'to_json'; + if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) { + shift @_; $alternative = 'encode'; + } + Carp::carp "'objToJson' will be obsoleted. Please use '$alternative' instead."; + JSON::to_json(@_); +}; + + +# INTERFACES + +sub to_json ($@) { + if ( + ref($_[0]) eq 'JSON' + or (@_ > 2 and $_[0] eq 'JSON') + ) { + Carp::croak "to_json should not be called as a method."; + } + my $json = new JSON; + + if (@_ == 2 and ref $_[1] eq 'HASH') { + my $opt = $_[1]; + for my $method (keys %$opt) { + $json->$method( $opt->{$method} ); + } + } + + $json->encode($_[0]); +} + + +sub from_json ($@) { + if ( ref($_[0]) eq 'JSON' or $_[0] eq 'JSON' ) { + Carp::croak "from_json should not be called as a method."; + } + my $json = new JSON; + + if (@_ == 2 and ref $_[1] eq 'HASH') { + my $opt = $_[1]; + for my $method (keys %$opt) { + $json->$method( $opt->{$method} ); + } + } + + return $json->decode( $_[0] ); +} + + +sub true { $JSON::true } + +sub false { $JSON::false } + +sub null { undef; } + + +sub require_xs_version { $XS_Version; } + +sub backend { + my $proto = shift; + $JSON::Backend; +} + +#*module = *backend; + + +sub is_xs { + return $_[0]->module eq $Module_XS; +} + + +sub is_pp { + return not $_[0]->xs; +} + + +sub pureperl_only_methods { @PPOnlyMethods; } + + +sub property { + my ($self, $name, $value) = @_; + + if (@_ == 1) { + my %props; + for $name (@Properties) { + my $method = 'get_' . $name; + if ($name eq 'max_size') { + my $value = $self->$method(); + $props{$name} = $value == 1 ? 0 : $value; + next; + } + $props{$name} = $self->$method(); + } + return \%props; + } + elsif (@_ > 3) { + Carp::croak('property() can take only the option within 2 arguments.'); + } + elsif (@_ == 2) { + if ( my $method = $self->can('get_' . $name) ) { + if ($name eq 'max_size') { + my $value = $self->$method(); + return $value == 1 ? 0 : $value; + } + $self->$method(); + } + } + else { + $self->$name($value); + } + +} + + + +# INTERNAL + +sub _load_xs { + my $opt = shift; + + $JSON::DEBUG and Carp::carp "Load $Module_XS."; + + # if called after install module, overload is disable.... why? + JSON::Boolean::_overrride_overload($Module_XS); + JSON::Boolean::_overrride_overload($Module_PP); + + eval qq| + use $Module_XS $XS_Version (); + |; + + if ($@) { + if (defined $opt and $opt & $_INSTALL_DONT_DIE) { + $JSON::DEBUG and Carp::carp "Can't load $Module_XS...($@)"; + return 0; + } + Carp::croak $@; + } + + unless (defined $opt and $opt & $_INSTALL_ONLY) { + _set_module( $JSON::Backend = $Module_XS ); + my $data = join("", ); # this code is from Jcode 2.xx. + close(DATA); + eval $data; + JSON::Backend::XS->init; + } + + return 1; +}; + + +sub _load_pp { + my $opt = shift; + my $backend = $_USSING_bpPP ? $Module_bp : $Module_PP; + + $JSON::DEBUG and Carp::carp "Load $backend."; + + # if called after install module, overload is disable.... why? + JSON::Boolean::_overrride_overload($Module_XS); + JSON::Boolean::_overrride_overload($backend); + + if ( $_USSING_bpPP ) { + eval qq| require $backend |; + } + else { + eval qq| use $backend $PP_Version () |; + } + + if ($@) { + if ( $backend eq $Module_PP ) { + $JSON::DEBUG and Carp::carp "Can't load $Module_PP ($@), so try to load $Module_bp"; + $_USSING_bpPP++; + $backend = $Module_bp; + JSON::Boolean::_overrride_overload($backend); + local $^W; # if PP installed but invalid version, backportPP redifines methods. + eval qq| require $Module_bp |; + } + Carp::croak $@ if $@; + } + + unless (defined $opt and $opt & $_INSTALL_ONLY) { + _set_module( $JSON::Backend = $Module_PP ); # even if backportPP, set $Backend with 'JSON::PP' + JSON::Backend::PP->init; + } +}; + + +sub _set_module { + return if defined $JSON::true; + + my $module = shift; + + local $^W; + no strict qw(refs); + + $JSON::true = ${"$module\::true"}; + $JSON::false = ${"$module\::false"}; + + push @JSON::ISA, $module; + push @{"$module\::Boolean::ISA"}, qw(JSON::Boolean); + + *{"JSON::is_bool"} = \&{"$module\::is_bool"}; + + for my $method ($module eq $Module_XS ? @PPOnlyMethods : @XSOnlyMethods) { + *{"JSON::$method"} = sub { + Carp::carp("$method is not supported in $module."); + $_[0]; + }; + } + + return 1; +} + + + +# +# JSON Boolean +# + +package JSON::Boolean; + +my %Installed; + +sub _overrride_overload { + return if ($Installed{ $_[0] }++); + + my $boolean = $_[0] . '::Boolean'; + + eval sprintf(q| + package %s; + use overload ( + '""' => sub { ${$_[0]} == 1 ? 'true' : 'false' }, + 'eq' => sub { + my ($obj, $op) = ref ($_[0]) ? ($_[0], $_[1]) : ($_[1], $_[0]); + if ($op eq 'true' or $op eq 'false') { + return "$obj" eq 'true' ? 'true' eq $op : 'false' eq $op; + } + else { + return $obj ? 1 == $op : 0 == $op; + } + }, + ); + |, $boolean); + + if ($@) { Carp::croak $@; } + + return 1; +} + + +# +# Helper classes for Backend Module (PP) +# + +package JSON::Backend::PP; + +sub init { + local $^W; + no strict qw(refs); # this routine may be called after JSON::Backend::XS init was called. + *{"JSON::decode_json"} = \&{"JSON::PP::decode_json"}; + *{"JSON::encode_json"} = \&{"JSON::PP::encode_json"}; + *{"JSON::PP::is_xs"} = sub { 0 }; + *{"JSON::PP::is_pp"} = sub { 1 }; + return 1; +} + +# +# To save memory, the below lines are read only when XS backend is used. +# + +package JSON; + +1; +__DATA__ + + +# +# Helper classes for Backend Module (XS) +# + +package JSON::Backend::XS; + +use constant INDENT_LENGTH_FLAG => 15 << 12; + +use constant UNSUPPORTED_ENCODE_FLAG => { + ESCAPE_SLASH => 0x00000010, + ALLOW_BIGNUM => 0x00000020, + AS_NONBLESSED => 0x00000040, + EXPANDED => 0x10000000, # for developer's +}; + +use constant UNSUPPORTED_DECODE_FLAG => { + LOOSE => 0x00000001, + ALLOW_BIGNUM => 0x00000002, + ALLOW_BAREKEY => 0x00000004, + ALLOW_SINGLEQUOTE => 0x00000008, + EXPANDED => 0x20000000, # for developer's +}; + + +sub init { + local $^W; + no strict qw(refs); + *{"JSON::decode_json"} = \&{"JSON::XS::decode_json"}; + *{"JSON::encode_json"} = \&{"JSON::XS::encode_json"}; + *{"JSON::XS::is_xs"} = sub { 1 }; + *{"JSON::XS::is_pp"} = sub { 0 }; + return 1; +} + + +sub support_by_pp { + my ($class, @methods) = @_; + + local $^W; + no strict qw(refs); + + my $JSON_XS_encode_orignal = \&JSON::XS::encode; + my $JSON_XS_decode_orignal = \&JSON::XS::decode; + my $JSON_XS_incr_parse_orignal = \&JSON::XS::incr_parse; + + *JSON::XS::decode = \&JSON::Backend::XS::Supportable::_decode; + *JSON::XS::encode = \&JSON::Backend::XS::Supportable::_encode; + *JSON::XS::incr_parse = \&JSON::Backend::XS::Supportable::_incr_parse; + + *{JSON::XS::_original_decode} = $JSON_XS_decode_orignal; + *{JSON::XS::_original_encode} = $JSON_XS_encode_orignal; + *{JSON::XS::_original_incr_parse} = $JSON_XS_incr_parse_orignal; + + push @JSON::Backend::XS::Supportable::ISA, 'JSON'; + + my $pkg = 'JSON::Backend::XS::Supportable'; + + *{JSON::new} = sub { + my $proto = new JSON::XS; $$proto = 0; + bless $proto, $pkg; + }; + + + for my $method (@methods) { + my $flag = uc($method); + my $type |= (UNSUPPORTED_ENCODE_FLAG->{$flag} || 0); + $type |= (UNSUPPORTED_DECODE_FLAG->{$flag} || 0); + + next unless($type); + + $pkg->_make_unsupported_method($method => $type); + } + + push @{"JSON::XS::Boolean::ISA"}, qw(JSON::PP::Boolean); + push @{"JSON::PP::Boolean::ISA"}, qw(JSON::Boolean); + + $JSON::DEBUG and Carp::carp("set -support_by_pp mode."); + + return 1; +} + + + + +# +# Helper classes for XS +# + +package JSON::Backend::XS::Supportable; + +$Carp::Internal{'JSON::Backend::XS::Supportable'} = 1; + +sub _make_unsupported_method { + my ($pkg, $method, $type) = @_; + + local $^W; + no strict qw(refs); + + *{"$pkg\::$method"} = sub { + local $^W; + if (defined $_[1] ? $_[1] : 1) { + ${$_[0]} |= $type; + } + else { + ${$_[0]} &= ~$type; + } + $_[0]; + }; + + *{"$pkg\::get_$method"} = sub { + ${$_[0]} & $type ? 1 : ''; + }; + +} + + +sub _set_for_pp { + JSON::_load_pp( $_INSTALL_ONLY ); + + my $type = shift; + my $pp = new JSON::PP; + my $prop = $_[0]->property; + + for my $name (keys %$prop) { + $pp->$name( $prop->{$name} ? $prop->{$name} : 0 ); + } + + my $unsupported = $type eq 'encode' ? JSON::Backend::XS::UNSUPPORTED_ENCODE_FLAG + : JSON::Backend::XS::UNSUPPORTED_DECODE_FLAG; + my $flags = ${$_[0]} || 0; + + for my $name (keys %$unsupported) { + next if ($name eq 'EXPANDED'); # for developer's + my $enable = ($flags & $unsupported->{$name}) ? 1 : 0; + my $method = lc $name; + $pp->$method($enable); + } + + $pp->indent_length( $_[0]->get_indent_length ); + + return $pp; +} + +sub _encode { # using with PP encod + if (${$_[0]}) { + _set_for_pp('encode' => @_)->encode($_[1]); + } + else { + $_[0]->_original_encode( $_[1] ); + } +} + + +sub _decode { # if unsupported-flag is set, use PP + if (${$_[0]}) { + _set_for_pp('decode' => @_)->decode($_[1]); + } + else { + $_[0]->_original_decode( $_[1] ); + } +} + + +sub decode_prefix { # if unsupported-flag is set, use PP + _set_for_pp('decode' => @_)->decode_prefix($_[1]); +} + + +sub _incr_parse { + if (${$_[0]}) { + _set_for_pp('decode' => @_)->incr_parse($_[1]); + } + else { + $_[0]->_original_incr_parse( $_[1] ); + } +} + + +sub get_indent_length { + ${$_[0]} << 4 >> 16; +} + + +sub indent_length { + my $length = $_[1]; + + if (!defined $length or $length > 15 or $length < 0) { + Carp::carp "The acceptable range of indent_length() is 0 to 15."; + } + else { + local $^W; + $length <<= 12; + ${$_[0]} &= ~ JSON::Backend::XS::INDENT_LENGTH_FLAG; + ${$_[0]} |= $length; + *JSON::XS::encode = \&JSON::Backend::XS::Supportable::_encode; + } + + $_[0]; +} + + +1; +__END__ + +=head1 NAME + +JSON - JSON (JavaScript Object Notation) encoder/decoder + +=head1 SYNOPSIS + + use JSON; # imports encode_json, decode_json, to_json and from_json. + + # simple and fast interfaces (expect/generate UTF-8) + + $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref; + $perl_hash_or_arrayref = decode_json $utf8_encoded_json_text; + + # OO-interface + + $json = JSON->new->allow_nonref; + + $json_text = $json->encode( $perl_scalar ); + $perl_scalar = $json->decode( $json_text ); + + $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing + + # If you want to use PP only support features, call with '-support_by_pp' + # When XS unsupported feature is enable, using PP (de|en)code instead of XS ones. + + use JSON -support_by_pp; + + # option-acceptable interfaces (expect/generate UNICODE by default) + + $json_text = to_json( $perl_scalar, { ascii => 1, pretty => 1 } ); + $perl_scalar = from_json( $json_text, { utf8 => 1 } ); + + # Between (en|de)code_json and (to|from)_json, if you want to write + # a code which communicates to an outer world (encoded in UTF-8), + # recommend to use (en|de)code_json. + +=head1 VERSION + + 2.53 + +This version is compatible with JSON::XS B<2.27> and later. + + +=head1 NOTE + +JSON::PP was inculded in C distribution. +It comes to be a perl core module in Perl 5.14. +And L will be split away it. + +C distribution will inculde yet another JSON::PP modules. +They are JSNO::backportPP and so on. JSON.pm should work as it did at all. + +=head1 DESCRIPTION + + ************************** CAUTION ******************************** + * This is 'JSON module version 2' and there are many differences * + * to version 1.xx * + * Please check your applications useing old version. * + * See to 'INCOMPATIBLE CHANGES TO OLD VERSION' * + ******************************************************************* + +JSON (JavaScript Object Notation) is a simple data format. +See to L and C(L). + +This module converts Perl data structures to JSON and vice versa using either +L or L. + +JSON::XS is the fastest and most proper JSON module on CPAN which must be +compiled and installed in your environment. +JSON::PP is a pure-Perl module which is bundled in this distribution and +has a strong compatibility to JSON::XS. + +This module try to use JSON::XS by default and fail to it, use JSON::PP instead. +So its features completely depend on JSON::XS or JSON::PP. + +See to L. + +To distinguish the module name 'JSON' and the format type JSON, +the former is quoted by CEE (its results vary with your using media), +and the latter is left just as it is. + +Module name : C + +Format type : JSON + +=head2 FEATURES + +=over + +=item * correct unicode handling + +This module (i.e. backend modules) knows how to handle Unicode, documents +how and when it does so, and even documents what "correct" means. + +Even though there are limitations, this feature is available since Perl version 5.6. + +JSON::XS requires Perl 5.8.2 (but works correctly in 5.8.8 or later), so in older versions +C sholud call JSON::PP as the backend which can be used since Perl 5.005. + +With Perl 5.8.x JSON::PP works, but from 5.8.0 to 5.8.2, because of a Perl side problem, +JSON::PP works slower in the versions. And in 5.005, the Unicode handling is not available. +See to L for more information. + +See also to L +and L. + + +=item * round-trip integrity + +When you serialise a perl data structure using only data types supported +by JSON and Perl, the deserialised data structure is identical on the Perl +level. (e.g. the string "2.0" doesn't suddenly become "2" just because +it looks like a number). There I minor exceptions to this, read the +L section below to learn about those. + + +=item * strict checking of JSON correctness + +There is no guessing, no generating of illegal JSON texts by default, +and only JSON is accepted as input by default (the latter is a security +feature). + +See to L and L. + +=item * fast + +This module returns a JSON::XS object itself if available. +Compared to other JSON modules and other serialisers such as Storable, +JSON::XS usually compares favourably in terms of speed, too. + +If not available, C returns a JSON::PP object instead of JSON::XS and +it is very slow as pure-Perl. + +=item * simple to use + +This module has both a simple functional interface as well as an +object oriented interface interface. + +=item * reasonably versatile output formats + +You can choose between the most compact guaranteed-single-line format possible +(nice for simple line-based protocols), a pure-ASCII format (for when your transport +is not 8-bit clean, still supports the whole Unicode range), or a pretty-printed +format (for when you want to read that stuff). Or you can combine those features +in whatever way you like. + +=back + +=head1 FUNCTIONAL INTERFACE + +Some documents are copied and modified from L. +C and C are additional functions. + +=head2 encode_json + + $json_text = encode_json $perl_scalar + +Converts the given Perl data structure to a UTF-8 encoded, binary string. + +This function call is functionally identical to: + + $json_text = JSON->new->utf8->encode($perl_scalar) + +=head2 decode_json + + $perl_scalar = decode_json $json_text + +The opposite of C: expects an UTF-8 (binary) string and tries +to parse that as an UTF-8 encoded JSON text, returning the resulting +reference. + +This function call is functionally identical to: + + $perl_scalar = JSON->new->utf8->decode($json_text) + + +=head2 to_json + + $json_text = to_json($perl_scalar) + +Converts the given Perl data structure to a json string. + +This function call is functionally identical to: + + $json_text = JSON->new->encode($perl_scalar) + +Takes a hash reference as the second. + + $json_text = to_json($perl_scalar, $flag_hashref) + +So, + + $json_text = to_json($perl_scalar, {utf8 => 1, pretty => 1}) + +equivalent to: + + $json_text = JSON->new->utf8(1)->pretty(1)->encode($perl_scalar) + +If you want to write a modern perl code which communicates to outer world, +you should use C (supposed that JSON data are encoded in UTF-8). + +=head2 from_json + + $perl_scalar = from_json($json_text) + +The opposite of C: expects a json string and tries +to parse it, returning the resulting reference. + +This function call is functionally identical to: + + $perl_scalar = JSON->decode($json_text) + +Takes a hash reference as the second. + + $perl_scalar = from_json($json_text, $flag_hashref) + +So, + + $perl_scalar = from_json($json_text, {utf8 => 1}) + +equivalent to: + + $perl_scalar = JSON->new->utf8(1)->decode($json_text) + +If you want to write a modern perl code which communicates to outer world, +you should use C (supposed that JSON data are encoded in UTF-8). + +=head2 JSON::is_bool + + $is_boolean = JSON::is_bool($scalar) + +Returns true if the passed scalar represents either JSON::true or +JSON::false, two constants that act like C<1> and C<0> respectively +and are also used to represent JSON C and C in Perl strings. + +=head2 JSON::true + +Returns JSON true value which is blessed object. +It C JSON::Boolean object. + +=head2 JSON::false + +Returns JSON false value which is blessed object. +It C JSON::Boolean object. + +=head2 JSON::null + +Returns C. + +See L, below, for more information on how JSON values are mapped to +Perl. + +=head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER + +This section supposes that your perl vresion is 5.8 or later. + +If you know a JSON text from an outer world - a network, a file content, and so on, +is encoded in UTF-8, you should use C or C module object +with C enable. And the decoded result will contain UNICODE characters. + + # from network + my $json = JSON->new->utf8; + my $json_text = CGI->new->param( 'json_data' ); + my $perl_scalar = $json->decode( $json_text ); + + # from file content + local $/; + open( my $fh, '<', 'json.data' ); + $json_text = <$fh>; + $perl_scalar = decode_json( $json_text ); + +If an outer data is not encoded in UTF-8, firstly you should C it. + + use Encode; + local $/; + open( my $fh, '<', 'json.data' ); + my $encoding = 'cp932'; + my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE + + # or you can write the below code. + # + # open( my $fh, "<:encoding($encoding)", 'json.data' ); + # $unicode_json_text = <$fh>; + +In this case, C<$unicode_json_text> is of course UNICODE string. +So you B use C nor C module object with C enable. +Instead of them, you use C module object with C disable or C. + + $perl_scalar = $json->utf8(0)->decode( $unicode_json_text ); + # or + $perl_scalar = from_json( $unicode_json_text ); + +Or C and C: + + $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) ); + # this way is not efficient. + +And now, you want to convert your C<$perl_scalar> into JSON data and +send it to an outer world - a network or a file content, and so on. + +Your data usually contains UNICODE strings and you want the converted data to be encoded +in UTF-8, you should use C or C module object with C enable. + + print encode_json( $perl_scalar ); # to a network? file? or display? + # or + print $json->utf8->encode( $perl_scalar ); + +If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings +for some reason, then its characters are regarded as B for perl +(because it does not concern with your $encoding). +You B use C nor C module object with C enable. +Instead of them, you use C module object with C disable or C. +Note that the resulted text is a UNICODE string but no problem to print it. + + # $perl_scalar contains $encoding encoded string values + $unicode_json_text = $json->utf8(0)->encode( $perl_scalar ); + # or + $unicode_json_text = to_json( $perl_scalar ); + # $unicode_json_text consists of characters less than 0x100 + print $unicode_json_text; + +Or C all string values and C: + + $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } ); + # ... do it to each string values, then encode_json + $json_text = encode_json( $perl_scalar ); + +This method is a proper way but probably not efficient. + +See to L, L. + + +=head1 COMMON OBJECT-ORIENTED INTERFACE + +=head2 new + + $json = new JSON + +Returns a new C object inherited from either JSON::XS or JSON::PP +that can be used to de/encode JSON strings. + +All boolean flags described below are by default I. + +The mutators for flags all return the JSON object again and thus calls can +be chained: + + my $json = JSON->new->utf8->space_after->encode({a => [1,2]}) + => {"a": [1, 2]} + +=head2 ascii + + $json = $json->ascii([$enable]) + + $enabled = $json->get_ascii + +If $enable is true (or missing), then the encode method will not generate characters outside +the code range 0..127. Any Unicode characters outside that range will be escaped using either +a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627. + +If $enable is false, then the encode method will not escape Unicode characters unless +required by the JSON syntax or other flags. This results in a faster and more compact format. + +This feature depends on the used Perl version and environment. + +See to L if the backend is PP. + + JSON->new->ascii(1)->encode([chr 0x10401]) + => ["\ud801\udc01"] + +=head2 latin1 + + $json = $json->latin1([$enable]) + + $enabled = $json->get_latin1 + +If $enable is true (or missing), then the encode method will encode the resulting JSON +text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255. + +If $enable is false, then the encode method will not escape Unicode characters +unless required by the JSON syntax or other flags. + + JSON->new->latin1->encode (["\x{89}\x{abc}"] + => ["\x{89}\\u0abc"] # (perl syntax, U+abc escaped, U+89 not) + +=head2 utf8 + + $json = $json->utf8([$enable]) + + $enabled = $json->get_utf8 + +If $enable is true (or missing), then the encode method will encode the JSON result +into UTF-8, as required by many protocols, while the decode method expects to be handled +an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any +characters outside the range 0..255, they are thus useful for bytewise/binary I/O. + +In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32 +encoding families, as described in RFC4627. + +If $enable is false, then the encode method will return the JSON string as a (non-encoded) +Unicode string, while decode expects thus a Unicode string. Any decoding or encoding +(e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module. + + +Example, output UTF-16BE-encoded JSON: + + use Encode; + $jsontext = encode "UTF-16BE", JSON::XS->new->encode ($object); + +Example, decode UTF-32LE-encoded JSON: + + use Encode; + $object = JSON::XS->new->decode (decode "UTF-32LE", $jsontext); + +See to L if the backend is PP. + + +=head2 pretty + + $json = $json->pretty([$enable]) + +This enables (or disables) all of the C, C and +C (and in the future possibly more) flags in one call to +generate the most readable (or most compact) form possible. + +Equivalent to: + + $json->indent->space_before->space_after + +The indent space length is three and JSON::XS cannot change the indent +space length. + +=head2 indent + + $json = $json->indent([$enable]) + + $enabled = $json->get_indent + +If C<$enable> is true (or missing), then the C method will use a multiline +format as output, putting every array member or object/hash key-value pair +into its own line, identing them properly. + +If C<$enable> is false, no newlines or indenting will be produced, and the +resulting JSON text is guarenteed not to contain any C. + +This setting has no effect when decoding JSON texts. + +The indent space length is three. +With JSON::PP, you can also access C to change indent space length. + + +=head2 space_before + + $json = $json->space_before([$enable]) + + $enabled = $json->get_space_before + +If C<$enable> is true (or missing), then the C method will add an extra +optional space before the C<:> separating keys from values in JSON objects. + +If C<$enable> is false, then the C method will not add any extra +space at those places. + +This setting has no effect when decoding JSON texts. + +Example, space_before enabled, space_after and indent disabled: + + {"key" :"value"} + + +=head2 space_after + + $json = $json->space_after([$enable]) + + $enabled = $json->get_space_after + +If C<$enable> is true (or missing), then the C method will add an extra +optional space after the C<:> separating keys from values in JSON objects +and extra whitespace after the C<,> separating key-value pairs and array +members. + +If C<$enable> is false, then the C method will not add any extra +space at those places. + +This setting has no effect when decoding JSON texts. + +Example, space_before and indent disabled, space_after enabled: + + {"key": "value"} + + +=head2 relaxed + + $json = $json->relaxed([$enable]) + + $enabled = $json->get_relaxed + +If C<$enable> is true (or missing), then C will accept some +extensions to normal JSON syntax (see below). C will not be +affected in anyway. I. I suggest only to use this option to +parse application-specific files written by humans (configuration files, +resource files etc.) + +If C<$enable> is false (the default), then C will only accept +valid JSON texts. + +Currently accepted extensions are: + +=over 4 + +=item * list items can have an end-comma + +JSON I array elements and key-value pairs with commas. This +can be annoying if you write JSON texts manually and want to be able to +quickly append elements, so this extension accepts comma at the end of +such items not just between them: + + [ + 1, + 2, <- this comma not normally allowed + ] + { + "k1": "v1", + "k2": "v2", <- this comma not normally allowed + } + +=item * shell-style '#'-comments + +Whenever JSON allows whitespace, shell-style comments are additionally +allowed. They are terminated by the first carriage-return or line-feed +character, after which more white-space and comments are allowed. + + [ + 1, # this comment not allowed in JSON + # neither this one... + ] + +=back + + +=head2 canonical + + $json = $json->canonical([$enable]) + + $enabled = $json->get_canonical + +If C<$enable> is true (or missing), then the C method will output JSON objects +by sorting their keys. This is adding a comparatively high overhead. + +If C<$enable> is false, then the C method will output key-value +pairs in the order Perl stores them (which will likely change between runs +of the same script). + +This option is useful if you want the same data structure to be encoded as +the same JSON text (given the same overall settings). If it is disabled, +the same hash might be encoded differently even if contains the same data, +as key-value pairs have no inherent ordering in Perl. + +This setting has no effect when decoding JSON texts. + +=head2 allow_nonref + + $json = $json->allow_nonref([$enable]) + + $enabled = $json->get_allow_nonref + +If C<$enable> is true (or missing), then the C method can convert a +non-reference into its corresponding string, number or null JSON value, +which is an extension to RFC4627. Likewise, C will accept those JSON +values instead of croaking. + +If C<$enable> is false, then the C method will croak if it isn't +passed an arrayref or hashref, as JSON texts must either be an object +or array. Likewise, C will croak if given something that is not a +JSON object or array. + + JSON->new->allow_nonref->encode ("Hello, World!") + => "Hello, World!" + +=head2 allow_unknown + + $json = $json->allow_unknown ([$enable]) + + $enabled = $json->get_allow_unknown + +If $enable is true (or missing), then "encode" will *not* throw an +exception when it encounters values it cannot represent in JSON (for +example, filehandles) but instead will encode a JSON "null" value. +Note that blessed objects are not included here and are handled +separately by c. + +If $enable is false (the default), then "encode" will throw an +exception when it encounters anything it cannot encode as JSON. + +This option does not affect "decode" in any way, and it is +recommended to leave it off unless you know your communications +partner. + +=head2 allow_blessed + + $json = $json->allow_blessed([$enable]) + + $enabled = $json->get_allow_blessed + +If C<$enable> is true (or missing), then the C method will not +barf when it encounters a blessed reference. Instead, the value of the +B option will decide whether C (C +disabled or no C method found) or a representation of the +object (C enabled and C method found) is being +encoded. Has no effect on C. + +If C<$enable> is false (the default), then C will throw an +exception when it encounters a blessed object. + + +=head2 convert_blessed + + $json = $json->convert_blessed([$enable]) + + $enabled = $json->get_convert_blessed + +If C<$enable> is true (or missing), then C, upon encountering a +blessed object, will check for the availability of the C method +on the object's class. If found, it will be called in scalar context +and the resulting scalar will be encoded instead of the object. If no +C method is found, the value of C will decide what +to do. + +The C method may safely call die if it wants. If C +returns other blessed objects, those will be handled in the same +way. C must take care of not causing an endless recursion cycle +(== crash) in this case. The name of C was chosen because other +methods called by the Perl core (== not by the user of the object) are +usually in upper case letters and to avoid collisions with the C +function or method. + +This setting does not yet influence C in any way. + +If C<$enable> is false, then the C setting will decide what +to do when a blessed object is found. + +=over + +=item convert_blessed_universally mode + +If use C with C<-convert_blessed_universally>, the C +subroutine is defined as the below code: + + *UNIVERSAL::TO_JSON = sub { + my $b_obj = B::svref_2object( $_[0] ); + return $b_obj->isa('B::HV') ? { %{ $_[0] } } + : $b_obj->isa('B::AV') ? [ @{ $_[0] } ] + : undef + ; + } + +This will cause that C method converts simple blessed objects into +JSON objects as non-blessed object. + + JSON -convert_blessed_universally; + $json->allow_blessed->convert_blessed->encode( $blessed_object ) + +This feature is experimental and may be removed in the future. + +=back + +=head2 filter_json_object + + $json = $json->filter_json_object([$coderef]) + +When C<$coderef> is specified, it will be called from C each +time it decodes a JSON object. The only argument passed to the coderef +is a reference to the newly-created hash. If the code references returns +a single scalar (which need not be a reference), this value +(i.e. a copy of that scalar to avoid aliasing) is inserted into the +deserialised data structure. If it returns an empty list +(NOTE: I C, which is a valid scalar), the original deserialised +hash will be inserted. This setting can slow down decoding considerably. + +When C<$coderef> is omitted or undefined, any existing callback will +be removed and C will not change the deserialised hash in any +way. + +Example, convert all JSON objects into the integer 5: + + my $js = JSON->new->filter_json_object (sub { 5 }); + # returns [5] + $js->decode ('[{}]'); # the given subroutine takes a hash reference. + # throw an exception because allow_nonref is not enabled + # so a lone 5 is not allowed. + $js->decode ('{"a":1, "b":2}'); + + +=head2 filter_json_single_key_object + + $json = $json->filter_json_single_key_object($key [=> $coderef]) + +Works remotely similar to C, but is only called for +JSON objects having a single key named C<$key>. + +This C<$coderef> is called before the one specified via +C, if any. It gets passed the single value in the JSON +object. If it returns a single value, it will be inserted into the data +structure. If it returns nothing (not even C but the empty list), +the callback from C will be called next, as if no +single-key callback were specified. + +If C<$coderef> is omitted or undefined, the corresponding callback will be +disabled. There can only ever be one callback for a given key. + +As this callback gets called less often then the C +one, decoding speed will not usually suffer as much. Therefore, single-key +objects make excellent targets to serialise Perl objects into, especially +as single-key JSON objects are as close to the type-tagged value concept +as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not +support this in any way, so you need to make sure your data never looks +like a serialised Perl hash. + +Typical names for the single object key are C<__class_whatever__>, or +C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even +things like C<__class_md5sum(classname)__>, to reduce the risk of clashing +with real hashes. + +Example, decode JSON objects of the form C<< { "__widget__" => } >> +into the corresponding C<< $WIDGET{} >> object: + + # return whatever is in $WIDGET{5}: + JSON + ->new + ->filter_json_single_key_object (__widget__ => sub { + $WIDGET{ $_[0] } + }) + ->decode ('{"__widget__": 5') + + # this can be used with a TO_JSON method in some "widget" class + # for serialisation to json: + sub WidgetBase::TO_JSON { + my ($self) = @_; + + unless ($self->{id}) { + $self->{id} = ..get..some..id..; + $WIDGET{$self->{id}} = $self; + } + + { __widget__ => $self->{id} } + } + + +=head2 shrink + + $json = $json->shrink([$enable]) + + $enabled = $json->get_shrink + +With JSON::XS, this flag resizes strings generated by either +C or C to their minimum size possible. This can save +memory when your JSON texts are either very very long or you have many +short strings. It will also try to downgrade any strings to octet-form +if possible: perl stores strings internally either in an encoding called +UTF-X or in octet-form. The latter cannot store everything but uses less +space in general (and some buggy Perl or C code might even rely on that +internal representation being used). + +With JSON::PP, it is noop about resizing strings but tries +C to the returned string by C. See to L. + +See to L and L. + +=head2 max_depth + + $json = $json->max_depth([$maximum_nesting_depth]) + + $max_depth = $json->get_max_depth + +Sets the maximum nesting level (default C<512>) accepted while encoding +or decoding. If a higher nesting level is detected in JSON text or a Perl +data structure, then the encoder and decoder will stop and croak at that +point. + +Nesting level is defined by number of hash- or arrayrefs that the encoder +needs to traverse to reach a given point or the number of C<{> or C<[> +characters without their matching closing parenthesis crossed to reach a +given character in a string. + +If no argument is given, the highest possible setting will be used, which +is rarely useful. + +Note that nesting is implemented by recursion in C. The default value has +been chosen to be as large as typical operating systems allow without +crashing. (JSON::XS) + +With JSON::PP as the backend, when a large value (100 or more) was set and +it de/encodes a deep nested object/text, it may raise a warning +'Deep recursion on subroutin' at the perl runtime phase. + +See L for more info on why this is useful. + +=head2 max_size + + $json = $json->max_size([$maximum_string_size]) + + $max_size = $json->get_max_size + +Set the maximum length a JSON text may have (in bytes) where decoding is +being attempted. The default is C<0>, meaning no limit. When C +is called on a string that is longer then this many bytes, it will not +attempt to decode the string but throw an exception. This setting has no +effect on C (yet). + +If no argument is given, the limit check will be deactivated (same as when +C<0> is specified). + +See L, below, for more info on why this is useful. + +=head2 encode + + $json_text = $json->encode($perl_scalar) + +Converts the given Perl data structure (a simple scalar or a reference +to a hash or array) to its JSON representation. Simple scalars will be +converted into JSON string or number sequences, while references to arrays +become JSON arrays and references to hashes become JSON objects. Undefined +Perl values (e.g. C) become JSON C values. +References to the integers C<0> and C<1> are converted into C and C. + +=head2 decode + + $perl_scalar = $json->decode($json_text) + +The opposite of C: expects a JSON text and tries to parse it, +returning the resulting simple scalar or reference. Croaks on error. + +JSON numbers and strings become simple Perl scalars. JSON arrays become +Perl arrayrefs and JSON objects become Perl hashrefs. C becomes +C<1> (C), C becomes C<0> (C) and +C becomes C. + +=head2 decode_prefix + + ($perl_scalar, $characters) = $json->decode_prefix($json_text) + +This works like the C method, but instead of raising an exception +when there is trailing garbage after the first JSON object, it will +silently stop parsing there and return the number of characters consumed +so far. + + JSON->new->decode_prefix ("[1] the tail") + => ([], 3) + +See to L + +=head2 property + + $boolean = $json->property($property_name) + +Returns a boolean value about above some properties. + +The available properties are C, C, C, +C,C, C, C, C, +C, C, C, C, +C, C and C. + + $boolean = $json->property('utf8'); + => 0 + $json->utf8; + $boolean = $json->property('utf8'); + => 1 + +Sets the property with a given boolean value. + + $json = $json->property($property_name => $boolean); + +With no argumnt, it returns all the above properties as a hash reference. + + $flag_hashref = $json->property(); + +=head1 INCREMENTAL PARSING + +Most of this section are copied and modified from L. + +In some cases, there is the need for incremental parsing of JSON texts. +This module does allow you to parse a JSON stream incrementally. +It does so by accumulating text until it has a full JSON object, which +it then can decode. This process is similar to using C +to see if a full JSON object is available, but is much more efficient +(and can be implemented with a minimum of method calls). + +The backend module will only attempt to parse the JSON text once it is sure it +has enough text to get a decisive result, using a very simple but +truly incremental parser. This means that it sometimes won't stop as +early as the full parser, for example, it doesn't detect parenthese +mismatches. The only thing it guarantees is that it starts decoding as +soon as a syntactically valid JSON text has been seen. This means you need +to set resource limits (e.g. C) to ensure the parser will stop +parsing in the presence if syntax errors. + +The following methods implement this incremental parser. + +=head2 incr_parse + + $json->incr_parse( [$string] ) # void context + + $obj_or_undef = $json->incr_parse( [$string] ) # scalar context + + @obj_or_empty = $json->incr_parse( [$string] ) # list context + +This is the central parsing function. It can both append new text and +extract objects from the stream accumulated so far (both of these +functions are optional). + +If C<$string> is given, then this string is appended to the already +existing JSON fragment stored in the C<$json> object. + +After that, if the function is called in void context, it will simply +return without doing anything further. This can be used to add more text +in as many chunks as you want. + +If the method is called in scalar context, then it will try to extract +exactly I JSON object. If that is successful, it will return this +object, otherwise it will return C. If there is a parse error, +this method will croak just as C would do (one can then use +C to skip the errornous part). This is the most common way of +using the method. + +And finally, in list context, it will try to extract as many objects +from the stream as it can find and return them, or the empty list +otherwise. For this to work, there must be no separators between the JSON +objects or arrays, instead they must be concatenated back-to-back. If +an error occurs, an exception will be raised as in the scalar context +case. Note that in this case, any previously-parsed JSON texts will be +lost. + +Example: Parse some JSON arrays/objects in a given string and return them. + + my @objs = JSON->new->incr_parse ("[5][7][1,2]"); + +=head2 incr_text + + $lvalue_string = $json->incr_text + +This method returns the currently stored JSON fragment as an lvalue, that +is, you can manipulate it. This I works when a preceding call to +C in I successfully returned an object. Under +all other circumstances you must not call this function (I mean it. +although in simple tests it might actually work, it I fail under +real world conditions). As a special exception, you can also call this +method before having parsed anything. + +This function is useful in two cases: a) finding the trailing text after a +JSON object or b) parsing multiple JSON objects separated by non-JSON text +(such as commas). + + $json->incr_text =~ s/\s*,\s*//; + +In Perl 5.005, C attribute is not available. +You must write codes like the below: + + $string = $json->incr_text; + $string =~ s/\s*,\s*//; + $json->incr_text( $string ); + +=head2 incr_skip + + $json->incr_skip + +This will reset the state of the incremental parser and will remove the +parsed text from the input buffer. This is useful after C +died, in which case the input buffer and incremental parser state is left +unchanged, to skip the text parsed so far and to reset the parse state. + +=head2 incr_reset + + $json->incr_reset + +This completely resets the incremental parser, that is, after this call, +it will be as if the parser had never parsed anything. + +This is useful if you want ot repeatedly parse JSON objects and want to +ignore any trailing data, which means you have to reset the parser after +each successful decode. + +See to L for examples. + + +=head1 JSON::PP SUPPORT METHODS + +The below methods are JSON::PP own methods, so when C works +with JSON::PP (i.e. the created object is a JSON::PP object), available. +See to L in detail. + +If you use C with additonal C<-support_by_pp>, some methods +are available even with JSON::XS. See to L. + + BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' } + + use JSON -support_by_pp; + + my $json = new JSON; + $json->allow_nonref->escape_slash->encode("/"); + + # functional interfaces too. + print to_json(["/"], {escape_slash => 1}); + print from_json('["foo"]', {utf8 => 1}); + +If you do not want to all functions but C<-support_by_pp>, +use C<-no_export>. + + use JSON -support_by_pp, -no_export; + # functional interfaces are not exported. + +=head2 allow_singlequote + + $json = $json->allow_singlequote([$enable]) + +If C<$enable> is true (or missing), then C will accept +any JSON strings quoted by single quotations that are invalid JSON +format. + + $json->allow_singlequote->decode({"foo":'bar'}); + $json->allow_singlequote->decode({'foo':"bar"}); + $json->allow_singlequote->decode({'foo':'bar'}); + +As same as the C option, this option may be used to parse +application-specific files written by humans. + +=head2 allow_barekey + + $json = $json->allow_barekey([$enable]) + +If C<$enable> is true (or missing), then C will accept +bare keys of JSON object that are invalid JSON format. + +As same as the C option, this option may be used to parse +application-specific files written by humans. + + $json->allow_barekey->decode('{foo:"bar"}'); + +=head2 allow_bignum + + $json = $json->allow_bignum([$enable]) + +If C<$enable> is true (or missing), then C will convert +the big integer Perl cannot handle as integer into a L +object and convert a floating number (any) into a L. + +On the contary, C converts C objects and C +objects into JSON numbers with C enable. + + $json->allow_nonref->allow_blessed->allow_bignum; + $bigfloat = $json->decode('2.000000000000000000000000001'); + print $json->encode($bigfloat); + # => 2.000000000000000000000000001 + +See to L aboout the conversion of JSON number. + +=head2 loose + + $json = $json->loose([$enable]) + +The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings +and the module doesn't allow to C to these (except for \x2f). +If C<$enable> is true (or missing), then C will accept these +unescaped strings. + + $json->loose->decode(qq|["abc + def"]|); + +See to L. + +=head2 escape_slash + + $json = $json->escape_slash([$enable]) + +According to JSON Grammar, I (U+002F) is escaped. But by default +JSON backend modules encode strings without escaping slash. + +If C<$enable> is true (or missing), then C will escape slashes. + +=head2 indent_length + + $json = $json->indent_length($length) + +With JSON::XS, The indent space length is 3 and cannot be changed. +With JSON::PP, it sets the indent space length with the given $length. +The default is 3. The acceptable range is 0 to 15. + +=head2 sort_by + + $json = $json->sort_by($function_name) + $json = $json->sort_by($subroutine_ref) + +If $function_name or $subroutine_ref are set, its sort routine are used. + + $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj); + # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); + + $js = $pc->sort_by('own_sort')->encode($obj); + # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); + + sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b } + +As the sorting routine runs in the JSON::PP scope, the given +subroutine name and the special variables C<$a>, C<$b> will begin +with 'JSON::PP::'. + +If $integer is set, then the effect is same as C on. + +See to L. + +=head1 MAPPING + +This section is copied from JSON::XS and modified to C. +JSON::XS and JSON::PP mapping mechanisms are almost equivalent. + +See to L. + +=head2 JSON -> PERL + +=over 4 + +=item object + +A JSON object becomes a reference to a hash in Perl. No ordering of object +keys is preserved (JSON does not preserver object key ordering itself). + +=item array + +A JSON array becomes a reference to an array in Perl. + +=item string + +A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON +are represented by the same codepoints in the Perl string, so no manual +decoding is necessary. + +=item number + +A JSON number becomes either an integer, numeric (floating point) or +string scalar in perl, depending on its range and any fractional parts. On +the Perl level, there is no difference between those as Perl handles all +the conversion details, but an integer may take slightly less memory and +might represent more values exactly than floating point numbers. + +If the number consists of digits only, C will try to represent +it as an integer value. If that fails, it will try to represent it as +a numeric (floating point) value if that is possible without loss of +precision. Otherwise it will preserve the number as a string value (in +which case you lose roundtripping ability, as the JSON number will be +re-encoded toa JSON string). + +Numbers containing a fractional or exponential part will always be +represented as numeric (floating point) values, possibly at a loss of +precision (in which case you might lose perfect roundtripping ability, but +the JSON number will still be re-encoded as a JSON number). + +Note that precision is not accuracy - binary floating point values cannot +represent most decimal fractions exactly, and when converting from and to +floating point, C only guarantees precision up to but not including +the leats significant bit. + +If the backend is JSON::PP and C is enable, the big integers +and the numeric can be optionally converted into L and +L objects. + +=item true, false + +These JSON atoms become C and C, +respectively. They are overloaded to act almost exactly like the numbers +C<1> and C<0>. You can check wether a scalar is a JSON boolean by using +the C function. + +If C and C are used as strings or compared as strings, +they represent as C and C respectively. + + print JSON::true . "\n"; + => true + print JSON::true + 1; + => 1 + + ok(JSON::true eq 'true'); + ok(JSON::true eq '1'); + ok(JSON::true == 1); + +C will install these missing overloading features to the backend modules. + + +=item null + +A JSON null atom becomes C in Perl. + +C returns C. + +=back + + +=head2 PERL -> JSON + +The mapping from Perl to JSON is slightly more difficult, as Perl is a +truly typeless language, so we can only guess which JSON type is meant by +a Perl value. + +=over 4 + +=item hash references + +Perl hash references become JSON objects. As there is no inherent ordering +in hash keys (or JSON objects), they will usually be encoded in a +pseudo-random order that can change between runs of the same program but +stays generally the same within a single run of a program. C +optionally sort the hash keys (determined by the I flag), so +the same datastructure will serialise to the same JSON text (given same +settings and version of JSON::XS), but this incurs a runtime overhead +and is only rarely useful, e.g. when you want to compare some JSON text +against another for equality. + +In future, the ordered object feature will be added to JSON::PP using C mechanism. + + +=item array references + +Perl array references become JSON arrays. + +=item other references + +Other unblessed references are generally not allowed and will cause an +exception to be thrown, except for references to the integers C<0> and +C<1>, which get turned into C and C atoms in JSON. You can +also use C and C to improve readability. + + to_json [\0,JSON::true] # yields [false,true] + +=item JSON::true, JSON::false, JSON::null + +These special values become JSON true and JSON false values, +respectively. You can also use C<\1> and C<\0> directly if you want. + +JSON::null returns C. + +=item blessed objects + +Blessed objects are not directly representable in JSON. See the +C and C methods on various options on +how to deal with this: basically, you can choose between throwing an +exception, encoding the reference as if it weren't blessed, or provide +your own serialiser method. + +With C mode, C converts blessed +hash references or blessed array references (contains other blessed references) +into JSON members and arrays. + + use JSON -convert_blessed_universally; + JSON->new->allow_blessed->convert_blessed->encode( $blessed_object ); + +See to L. + +=item simple scalars + +Simple Perl scalars (any scalar that is not a reference) are the most +difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as +JSON C values, scalars that have last been used in a string context +before encoding as JSON strings, and anything else as number value: + + # dump as number + encode_json [2] # yields [2] + encode_json [-3.0e17] # yields [-3e+17] + my $value = 5; encode_json [$value] # yields [5] + + # used as string, so dump as string + print $value; + encode_json [$value] # yields ["5"] + + # undef becomes null + encode_json [undef] # yields [null] + +You can force the type to be a string by stringifying it: + + my $x = 3.1; # some variable containing a number + "$x"; # stringified + $x .= ""; # another, more awkward way to stringify + print $x; # perl does it for you, too, quite often + +You can force the type to be a number by numifying it: + + my $x = "3"; # some variable containing a string + $x += 0; # numify it, ensuring it will be dumped as a number + $x *= 1; # same thing, the choise is yours. + +You can not currently force the type in other, less obscure, ways. + +Note that numerical precision has the same meaning as under Perl (so +binary to decimal conversion follows the same rules as in Perl, which +can differ to other languages). Also, your perl interpreter might expose +extensions to the floating point numbers of your platform, such as +infinities or NaN's - these cannot be represented in JSON, and it is an +error to pass those in. + +=item Big Number + +If the backend is JSON::PP and C is enable, +C converts C objects and C +objects into JSON numbers. + + +=back + +=head1 JSON and ECMAscript + +See to L. + +=head1 JSON and YAML + +JSON is not a subset of YAML. +See to L. + + +=head1 BACKEND MODULE DECISION + +When you use C, C tries to C JSON::XS. If this call failed, it will +C JSON::PP. The required JSON::XS version is I<2.2> or later. + +The C constructor method returns an object inherited from the backend module, +and JSON::XS object is a blessed scaler reference while JSON::PP is a blessed hash +reference. + +So, your program should not depend on the backend module, especially +returned objects should not be modified. + + my $json = JSON->new; # XS or PP? + $json->{stash} = 'this is xs object'; # this code may raise an error! + +To check the backend module, there are some methods - C, C and C. + + JSON->backend; # 'JSON::XS' or 'JSON::PP' + + JSON->backend->is_pp: # 0 or 1 + + JSON->backend->is_xs: # 1 or 0 + + $json->is_xs; # 1 or 0 + + $json->is_pp; # 0 or 1 + + +If you set an enviornment variable C, The calling action will be changed. + +=over + +=item PERL_JSON_BACKEND = 0 or PERL_JSON_BACKEND = 'JSON::PP' + +Always use JSON::PP + +=item PERL_JSON_BACKEND == 1 or PERL_JSON_BACKEND = 'JSON::XS,JSON::PP' + +(The default) Use compiled JSON::XS if it is properly compiled & installed, +otherwise use JSON::PP. + +=item PERL_JSON_BACKEND == 2 or PERL_JSON_BACKEND = 'JSON::XS' + +Always use compiled JSON::XS, die if it isn't properly compiled & installed. + +=item PERL_JSON_BACKEND = 'JSON::backportPP' + +Always use JSON::backportPP. +JSON::backportPP is JSON::PP back port module. +C includs JSON::backportPP instead of JSON::PP. + +=back + +These ideas come from L mechanism. + +example: + + BEGIN { $ENV{PERL_JSON_BACKEND} = 'JSON::PP' } + use JSON; # always uses JSON::PP + +In future, it may be able to specify another module. + +=head1 USE PP FEATURES EVEN THOUGH XS BACKEND + +Many methods are available with either JSON::XS or JSON::PP and +when the backend module is JSON::XS, if any JSON::PP specific (i.e. JSON::XS unspported) +method is called, it will C and be noop. + +But If you C C passing the optional string C<-support_by_pp>, +it makes a part of those unupported methods available. +This feature is achieved by using JSON::PP in C. + + BEGIN { $ENV{PERL_JSON_BACKEND} = 2 } # with JSON::XS + use JSON -support_by_pp; + my $json = new JSON; + $json->allow_nonref->escape_slash->encode("/"); + +At this time, the returned object is a C +object (re-blessed XS object), and by checking JSON::XS unsupported flags +in de/encoding, can support some unsupported methods - C, C, +C, C, C and C. + +When any unsupported methods are not enable, C will be +used as is. The switch is achieved by changing the symbolic tables. + +C<-support_by_pp> is effective only when the backend module is JSON::XS +and it makes the de/encoding speed down a bit. + +See to L. + +=head1 INCOMPATIBLE CHANGES TO OLD VERSION + +There are big incompatibility between new version (2.00) and old (1.xx). +If you use old C 1.xx in your code, please check it. + +See to L + +=over + +=item jsonToObj and objToJson are obsoleted. + +Non Perl-style name C and C are obsoleted +(but not yet deleted from the source). +If you use these functions in your code, please replace them +with C and C. + + +=item Global variables are no longer available. + +C class variables - C<$JSON::AUTOCONVERT>, C<$JSON::BareKey>, etc... +- are not available any longer. +Instead, various features can be used through object methods. + + +=item Package JSON::Converter and JSON::Parser are deleted. + +Now C bundles with JSON::PP which can handle JSON more properly than them. + +=item Package JSON::NotString is deleted. + +There was C class which represents JSON value C, C, C +and numbers. It was deleted and replaced by C. + +C represents C and C. + +C does not represent C. + +C returns C. + +C makes L and L is-a relation +to L. + +=item function JSON::Number is obsoleted. + +C is now needless because JSON::XS and JSON::PP have +round-trip integrity. + +=item JSONRPC modules are deleted. + +Perl implementation of JSON-RPC protocol - C, C +and C are deleted in this distribution. +Instead of them, there is L which supports JSON-RPC protocol version 1.1. + +=back + +=head2 Transition ways from 1.xx to 2.xx. + +You should set C mode firstly, because +it is always successful for the below codes even with JSON::XS. + + use JSON -support_by_pp; + +=over + +=item Exported jsonToObj (simple) + + from_json($json_text); + +=item Exported objToJson (simple) + + to_json($perl_scalar); + +=item Exported jsonToObj (advanced) + + $flags = {allow_barekey => 1, allow_singlequote => 1}; + from_json($json_text, $flags); + +equivalent to: + + $JSON::BareKey = 1; + $JSON::QuotApos = 1; + jsonToObj($json_text); + +=item Exported objToJson (advanced) + + $flags = {allow_blessed => 1, allow_barekey => 1}; + to_json($perl_scalar, $flags); + +equivalent to: + + $JSON::BareKey = 1; + objToJson($perl_scalar); + +=item jsonToObj as object method + + $json->decode($json_text); + +=item objToJson as object method + + $json->encode($perl_scalar); + +=item new method with parameters + +The C method in 2.x takes any parameters no longer. +You can set parameters instead; + + $json = JSON->new->pretty; + +=item $JSON::Pretty, $JSON::Indent, $JSON::Delimiter + +If C is enable, that means C<$JSON::Pretty> flag set. And +C<$JSON::Delimiter> was substituted by C and C. +In conclusion: + + $json->indent->space_before->space_after; + +Equivalent to: + + $json->pretty; + +To change indent length, use C. + +(Only with JSON::PP, if C<-support_by_pp> is not used.) + + $json->pretty->indent_length(2)->encode($perl_scalar); + +=item $JSON::BareKey + +(Only with JSON::PP, if C<-support_by_pp> is not used.) + + $json->allow_barekey->decode($json_text) + +=item $JSON::ConvBlessed + +use C<-convert_blessed_universally>. See to L. + +=item $JSON::QuotApos + +(Only with JSON::PP, if C<-support_by_pp> is not used.) + + $json->allow_singlequote->decode($json_text) + +=item $JSON::SingleQuote + +Disable. C does not make such a invalid JSON string any longer. + +=item $JSON::KeySort + + $json->canonical->encode($perl_scalar) + +This is the ascii sort. + +If you want to use with your own sort routine, check the C method. + +(Only with JSON::PP, even if C<-support_by_pp> is used currently.) + + $json->sort_by($sort_routine_ref)->encode($perl_scalar) + + $json->sort_by(sub { $JSON::PP::a <=> $JSON::PP::b })->encode($perl_scalar) + +Can't access C<$a> and C<$b> but C<$JSON::PP::a> and C<$JSON::PP::b>. + +=item $JSON::SkipInvalid + + $json->allow_unknown + +=item $JSON::AUTOCONVERT + +Needless. C backend modules have the round-trip integrity. + +=item $JSON::UTF8 + +Needless because C (JSON::XS/JSON::PP) sets +the UTF8 flag on properly. + + # With UTF8-flagged strings + + $json->allow_nonref; + $str = chr(1000); # UTF8-flagged + + $json_text = $json->utf8(0)->encode($str); + utf8::is_utf8($json_text); + # true + $json_text = $json->utf8(1)->encode($str); + utf8::is_utf8($json_text); + # false + + $str = '"' . chr(1000) . '"'; # UTF8-flagged + + $perl_scalar = $json->utf8(0)->decode($str); + utf8::is_utf8($perl_scalar); + # true + $perl_scalar = $json->utf8(1)->decode($str); + # died because of 'Wide character in subroutine' + +See to L. + +=item $JSON::UnMapping + +Disable. See to L. + +=item $JSON::SelfConvert + +This option was deleted. +Instead of it, if a givien blessed object has the C method, +C will be executed with C. + + $json->convert_blessed->encode($bleesed_hashref_or_arrayref) + # if need, call allow_blessed + +Note that it was C in old version, but now not C but C. + +=back + +=head1 TODO + +=over + +=item example programs + +=back + +=head1 THREADS + +No test with JSON::PP. If with JSON::XS, See to L. + + +=head1 BUGS + +Please report bugs relevant to C to Emakamaka[at]cpan.orgE. + + +=head1 SEE ALSO + +Most of the document is copied and modified from JSON::XS doc. + +L, L + +C(L) + +=head1 AUTHOR + +Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE + +JSON::XS was written by Marc Lehmann + +The relese of this new version owes to the courtesy of Marc Lehmann. + + +=head1 COPYRIGHT AND LICENSE + +Copyright 2005-2011 by Makamaka Hannyaharamitu + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + diff --git a/data/lib/JSON/backportPP.pm b/data/lib/JSON/backportPP.pm new file mode 100644 index 0000000..ab37416 --- /dev/null +++ b/data/lib/JSON/backportPP.pm @@ -0,0 +1,2797 @@ +package # This is JSON::backportPP + JSON::PP; + +# JSON-2.0 + +use 5.005; +use strict; +use base qw(Exporter); +use overload (); + +use Carp (); +use B (); +#use Devel::Peek; + +$JSON::PP::VERSION = '2.27200'; + +@JSON::PP::EXPORT = qw(encode_json decode_json from_json to_json); + +# instead of hash-access, i tried index-access for speed. +# but this method is not faster than what i expected. so it will be changed. + +use constant P_ASCII => 0; +use constant P_LATIN1 => 1; +use constant P_UTF8 => 2; +use constant P_INDENT => 3; +use constant P_CANONICAL => 4; +use constant P_SPACE_BEFORE => 5; +use constant P_SPACE_AFTER => 6; +use constant P_ALLOW_NONREF => 7; +use constant P_SHRINK => 8; +use constant P_ALLOW_BLESSED => 9; +use constant P_CONVERT_BLESSED => 10; +use constant P_RELAXED => 11; + +use constant P_LOOSE => 12; +use constant P_ALLOW_BIGNUM => 13; +use constant P_ALLOW_BAREKEY => 14; +use constant P_ALLOW_SINGLEQUOTE => 15; +use constant P_ESCAPE_SLASH => 16; +use constant P_AS_NONBLESSED => 17; + +use constant P_ALLOW_UNKNOWN => 18; + +use constant OLD_PERL => $] < 5.008 ? 1 : 0; + +BEGIN { + my @xs_compati_bit_properties = qw( + latin1 ascii utf8 indent canonical space_before space_after allow_nonref shrink + allow_blessed convert_blessed relaxed allow_unknown + ); + my @pp_bit_properties = qw( + allow_singlequote allow_bignum loose + allow_barekey escape_slash as_nonblessed + ); + + # Perl version check, Unicode handling is enable? + # Helper module sets @JSON::PP::_properties. + if ($] < 5.008 ) { + my $helper = $] >= 5.006 ? 'JSON::backportPP::Compat5006' : 'JSON::backportPP::Compat5005'; + eval qq| require $helper |; + if ($@) { Carp::croak $@; } + } + + for my $name (@xs_compati_bit_properties, @pp_bit_properties) { + my $flag_name = 'P_' . uc($name); + + eval qq/ + sub $name { + my \$enable = defined \$_[1] ? \$_[1] : 1; + + if (\$enable) { + \$_[0]->{PROPS}->[$flag_name] = 1; + } + else { + \$_[0]->{PROPS}->[$flag_name] = 0; + } + + \$_[0]; + } + + sub get_$name { + \$_[0]->{PROPS}->[$flag_name] ? 1 : ''; + } + /; + } + +} + + + +# Functions + +my %encode_allow_method + = map {($_ => 1)} qw/utf8 pretty allow_nonref latin1 self_encode escape_slash + allow_blessed convert_blessed indent indent_length allow_bignum + as_nonblessed + /; +my %decode_allow_method + = map {($_ => 1)} qw/utf8 allow_nonref loose allow_singlequote allow_bignum + allow_barekey max_size relaxed/; + + +my $JSON; # cache + +sub encode_json ($) { # encode + ($JSON ||= __PACKAGE__->new->utf8)->encode(@_); +} + + +sub decode_json { # decode + ($JSON ||= __PACKAGE__->new->utf8)->decode(@_); +} + +# Obsoleted + +sub to_json($) { + Carp::croak ("JSON::PP::to_json has been renamed to encode_json."); +} + + +sub from_json($) { + Carp::croak ("JSON::PP::from_json has been renamed to decode_json."); +} + + +# Methods + +sub new { + my $class = shift; + my $self = { + max_depth => 512, + max_size => 0, + indent => 0, + FLAGS => 0, + fallback => sub { encode_error('Invalid value. JSON can only reference.') }, + indent_length => 3, + }; + + bless $self, $class; +} + + +sub encode { + return $_[0]->PP_encode_json($_[1]); +} + + +sub decode { + return $_[0]->PP_decode_json($_[1], 0x00000000); +} + + +sub decode_prefix { + return $_[0]->PP_decode_json($_[1], 0x00000001); +} + + +# accessor + + +# pretty printing + +sub pretty { + my ($self, $v) = @_; + my $enable = defined $v ? $v : 1; + + if ($enable) { # indent_length(3) for JSON::XS compatibility + $self->indent(1)->indent_length(3)->space_before(1)->space_after(1); + } + else { + $self->indent(0)->space_before(0)->space_after(0); + } + + $self; +} + +# etc + +sub max_depth { + my $max = defined $_[1] ? $_[1] : 0x80000000; + $_[0]->{max_depth} = $max; + $_[0]; +} + + +sub get_max_depth { $_[0]->{max_depth}; } + + +sub max_size { + my $max = defined $_[1] ? $_[1] : 0; + $_[0]->{max_size} = $max; + $_[0]; +} + + +sub get_max_size { $_[0]->{max_size}; } + + +sub filter_json_object { + $_[0]->{cb_object} = defined $_[1] ? $_[1] : 0; + $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0; + $_[0]; +} + +sub filter_json_single_key_object { + if (@_ > 1) { + $_[0]->{cb_sk_object}->{$_[1]} = $_[2]; + } + $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0; + $_[0]; +} + +sub indent_length { + if (!defined $_[1] or $_[1] > 15 or $_[1] < 0) { + Carp::carp "The acceptable range of indent_length() is 0 to 15."; + } + else { + $_[0]->{indent_length} = $_[1]; + } + $_[0]; +} + +sub get_indent_length { + $_[0]->{indent_length}; +} + +sub sort_by { + $_[0]->{sort_by} = defined $_[1] ? $_[1] : 1; + $_[0]; +} + +sub allow_bigint { + Carp::carp("allow_bigint() is obsoleted. use allow_bignum() insted."); +} + +############################### + +### +### Perl => JSON +### + + +{ # Convert + + my $max_depth; + my $indent; + my $ascii; + my $latin1; + my $utf8; + my $space_before; + my $space_after; + my $canonical; + my $allow_blessed; + my $convert_blessed; + + my $indent_length; + my $escape_slash; + my $bignum; + my $as_nonblessed; + + my $depth; + my $indent_count; + my $keysort; + + + sub PP_encode_json { + my $self = shift; + my $obj = shift; + + $indent_count = 0; + $depth = 0; + + my $idx = $self->{PROPS}; + + ($ascii, $latin1, $utf8, $indent, $canonical, $space_before, $space_after, $allow_blessed, + $convert_blessed, $escape_slash, $bignum, $as_nonblessed) + = @{$idx}[P_ASCII .. P_SPACE_AFTER, P_ALLOW_BLESSED, P_CONVERT_BLESSED, + P_ESCAPE_SLASH, P_ALLOW_BIGNUM, P_AS_NONBLESSED]; + + ($max_depth, $indent_length) = @{$self}{qw/max_depth indent_length/}; + + $keysort = $canonical ? sub { $a cmp $b } : undef; + + if ($self->{sort_by}) { + $keysort = ref($self->{sort_by}) eq 'CODE' ? $self->{sort_by} + : $self->{sort_by} =~ /\D+/ ? $self->{sort_by} + : sub { $a cmp $b }; + } + + encode_error("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)") + if(!ref $obj and !$idx->[ P_ALLOW_NONREF ]); + + my $str = $self->object_to_json($obj); + + $str .= "\n" if ( $indent ); # JSON::XS 2.26 compatible + + unless ($ascii or $latin1 or $utf8) { + utf8::upgrade($str); + } + + if ($idx->[ P_SHRINK ]) { + utf8::downgrade($str, 1); + } + + return $str; + } + + + sub object_to_json { + my ($self, $obj) = @_; + my $type = ref($obj); + + if($type eq 'HASH'){ + return $self->hash_to_json($obj); + } + elsif($type eq 'ARRAY'){ + return $self->array_to_json($obj); + } + elsif ($type) { # blessed object? + if (blessed($obj)) { + + return $self->value_to_json($obj) if ( $obj->isa('JSON::PP::Boolean') ); + + if ( $convert_blessed and $obj->can('TO_JSON') ) { + my $result = $obj->TO_JSON(); + if ( defined $result and ref( $result ) ) { + if ( refaddr( $obj ) eq refaddr( $result ) ) { + encode_error( sprintf( + "%s::TO_JSON method returned same object as was passed instead of a new one", + ref $obj + ) ); + } + } + + return $self->object_to_json( $result ); + } + + return "$obj" if ( $bignum and _is_bignum($obj) ); + return $self->blessed_to_json($obj) if ($allow_blessed and $as_nonblessed); # will be removed. + + encode_error( sprintf("encountered object '%s', but neither allow_blessed " + . "nor convert_blessed settings are enabled", $obj) + ) unless ($allow_blessed); + + return 'null'; + } + else { + return $self->value_to_json($obj); + } + } + else{ + return $self->value_to_json($obj); + } + } + + + sub hash_to_json { + my ($self, $obj) = @_; + my @res; + + encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)") + if (++$depth > $max_depth); + + my ($pre, $post) = $indent ? $self->_up_indent() : ('', ''); + my $del = ($space_before ? ' ' : '') . ':' . ($space_after ? ' ' : ''); + + for my $k ( _sort( $obj ) ) { + if ( OLD_PERL ) { utf8::decode($k) } # key for Perl 5.6 / be optimized + push @res, string_to_json( $self, $k ) + . $del + . ( $self->object_to_json( $obj->{$k} ) || $self->value_to_json( $obj->{$k} ) ); + } + + --$depth; + $self->_down_indent() if ($indent); + + return '{' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' ) . '}'; + } + + + sub array_to_json { + my ($self, $obj) = @_; + my @res; + + encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)") + if (++$depth > $max_depth); + + my ($pre, $post) = $indent ? $self->_up_indent() : ('', ''); + + for my $v (@$obj){ + push @res, $self->object_to_json($v) || $self->value_to_json($v); + } + + --$depth; + $self->_down_indent() if ($indent); + + return '[' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' ) . ']'; + } + + + sub value_to_json { + my ($self, $value) = @_; + + return 'null' if(!defined $value); + + my $b_obj = B::svref_2object(\$value); # for round trip problem + my $flags = $b_obj->FLAGS; + + return $value # as is + if $flags & ( B::SVp_IOK | B::SVp_NOK ) and !( $flags & B::SVp_POK ); # SvTYPE is IV or NV? + + my $type = ref($value); + + if(!$type){ + return string_to_json($self, $value); + } + elsif( blessed($value) and $value->isa('JSON::PP::Boolean') ){ + return $$value == 1 ? 'true' : 'false'; + } + elsif ($type) { + if ((overload::StrVal($value) =~ /=(\w+)/)[0]) { + return $self->value_to_json("$value"); + } + + if ($type eq 'SCALAR' and defined $$value) { + return $$value eq '1' ? 'true' + : $$value eq '0' ? 'false' + : $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ? 'null' + : encode_error("cannot encode reference to scalar"); + } + + if ( $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ) { + return 'null'; + } + else { + if ( $type eq 'SCALAR' or $type eq 'REF' ) { + encode_error("cannot encode reference to scalar"); + } + else { + encode_error("encountered $value, but JSON can only represent references to arrays or hashes"); + } + } + + } + else { + return $self->{fallback}->($value) + if ($self->{fallback} and ref($self->{fallback}) eq 'CODE'); + return 'null'; + } + + } + + + my %esc = ( + "\n" => '\n', + "\r" => '\r', + "\t" => '\t', + "\f" => '\f', + "\b" => '\b', + "\"" => '\"', + "\\" => '\\\\', + "\'" => '\\\'', + ); + + + sub string_to_json { + my ($self, $arg) = @_; + + $arg =~ s/([\x22\x5c\n\r\t\f\b])/$esc{$1}/g; + $arg =~ s/\//\\\//g if ($escape_slash); + $arg =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg; + + if ($ascii) { + $arg = JSON_PP_encode_ascii($arg); + } + + if ($latin1) { + $arg = JSON_PP_encode_latin1($arg); + } + + if ($utf8) { + utf8::encode($arg); + } + + return '"' . $arg . '"'; + } + + + sub blessed_to_json { + my $reftype = reftype($_[1]) || ''; + if ($reftype eq 'HASH') { + return $_[0]->hash_to_json($_[1]); + } + elsif ($reftype eq 'ARRAY') { + return $_[0]->array_to_json($_[1]); + } + else { + return 'null'; + } + } + + + sub encode_error { + my $error = shift; + Carp::croak "$error"; + } + + + sub _sort { + defined $keysort ? (sort $keysort (keys %{$_[0]})) : keys %{$_[0]}; + } + + + sub _up_indent { + my $self = shift; + my $space = ' ' x $indent_length; + + my ($pre,$post) = ('',''); + + $post = "\n" . $space x $indent_count; + + $indent_count++; + + $pre = "\n" . $space x $indent_count; + + return ($pre,$post); + } + + + sub _down_indent { $indent_count--; } + + + sub PP_encode_box { + { + depth => $depth, + indent_count => $indent_count, + }; + } + +} # Convert + + +sub _encode_ascii { + join('', + map { + $_ <= 127 ? + chr($_) : + $_ <= 65535 ? + sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_)); + } unpack('U*', $_[0]) + ); +} + + +sub _encode_latin1 { + join('', + map { + $_ <= 255 ? + chr($_) : + $_ <= 65535 ? + sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_)); + } unpack('U*', $_[0]) + ); +} + + +sub _encode_surrogates { # from perlunicode + my $uni = $_[0] - 0x10000; + return ($uni / 0x400 + 0xD800, $uni % 0x400 + 0xDC00); +} + + +sub _is_bignum { + $_[0]->isa('Math::BigInt') or $_[0]->isa('Math::BigFloat'); +} + + + +# +# JSON => Perl +# + +my $max_intsize; + +BEGIN { + my $checkint = 1111; + for my $d (5..64) { + $checkint .= 1; + my $int = eval qq| $checkint |; + if ($int =~ /[eE]/) { + $max_intsize = $d - 1; + last; + } + } +} + +{ # PARSE + + my %escapes = ( # by Jeremy Muhlich + b => "\x8", + t => "\x9", + n => "\xA", + f => "\xC", + r => "\xD", + '\\' => '\\', + '"' => '"', + '/' => '/', + ); + + my $text; # json data + my $at; # offset + my $ch; # 1chracter + my $len; # text length (changed according to UTF8 or NON UTF8) + # INTERNAL + my $depth; # nest counter + my $encoding; # json text encoding + my $is_valid_utf8; # temp variable + my $utf8_len; # utf8 byte length + # FLAGS + my $utf8; # must be utf8 + my $max_depth; # max nest nubmer of objects and arrays + my $max_size; + my $relaxed; + my $cb_object; + my $cb_sk_object; + + my $F_HOOK; + + my $allow_bigint; # using Math::BigInt + my $singlequote; # loosely quoting + my $loose; # + my $allow_barekey; # bareKey + + # $opt flag + # 0x00000001 .... decode_prefix + # 0x10000000 .... incr_parse + + sub PP_decode_json { + my ($self, $opt); # $opt is an effective flag during this decode_json. + + ($self, $text, $opt) = @_; + + ($at, $ch, $depth) = (0, '', 0); + + if ( !defined $text or ref $text ) { + decode_error("malformed JSON string, neither array, object, number, string or atom"); + } + + my $idx = $self->{PROPS}; + + ($utf8, $relaxed, $loose, $allow_bigint, $allow_barekey, $singlequote) + = @{$idx}[P_UTF8, P_RELAXED, P_LOOSE .. P_ALLOW_SINGLEQUOTE]; + + if ( $utf8 ) { + utf8::downgrade( $text, 1 ) or Carp::croak("Wide character in subroutine entry"); + } + else { + utf8::upgrade( $text ); + } + + $len = length $text; + + ($max_depth, $max_size, $cb_object, $cb_sk_object, $F_HOOK) + = @{$self}{qw/max_depth max_size cb_object cb_sk_object F_HOOK/}; + + if ($max_size > 1) { + use bytes; + my $bytes = length $text; + decode_error( + sprintf("attempted decode of JSON text of %s bytes size, but max_size is set to %s" + , $bytes, $max_size), 1 + ) if ($bytes > $max_size); + } + + # Currently no effect + # should use regexp + my @octets = unpack('C4', $text); + $encoding = ( $octets[0] and $octets[1]) ? 'UTF-8' + : (!$octets[0] and $octets[1]) ? 'UTF-16BE' + : (!$octets[0] and !$octets[1]) ? 'UTF-32BE' + : ( $octets[2] ) ? 'UTF-16LE' + : (!$octets[2] ) ? 'UTF-32LE' + : 'unknown'; + + white(); # remove head white space + + my $valid_start = defined $ch; # Is there a first character for JSON structure? + + my $result = value(); + + return undef if ( !$result && ( $opt & 0x10000000 ) ); # for incr_parse + + decode_error("malformed JSON string, neither array, object, number, string or atom") unless $valid_start; + + if ( !$idx->[ P_ALLOW_NONREF ] and !ref $result ) { + decode_error( + 'JSON text must be an object or array (but found number, string, true, false or null,' + . ' use allow_nonref to allow this)', 1); + } + + Carp::croak('something wrong.') if $len < $at; # we won't arrive here. + + my $consumed = defined $ch ? $at - 1 : $at; # consumed JSON text length + + white(); # remove tail white space + + if ( $ch ) { + return ( $result, $consumed ) if ($opt & 0x00000001); # all right if decode_prefix + decode_error("garbage after JSON object"); + } + + ( $opt & 0x00000001 ) ? ( $result, $consumed ) : $result; + } + + + sub next_chr { + return $ch = undef if($at >= $len); + $ch = substr($text, $at++, 1); + } + + + sub value { + white(); + return if(!defined $ch); + return object() if($ch eq '{'); + return array() if($ch eq '['); + return string() if($ch eq '"' or ($singlequote and $ch eq "'")); + return number() if($ch =~ /[0-9]/ or $ch eq '-'); + return word(); + } + + sub string { + my ($i, $s, $t, $u); + my $utf16; + my $is_utf8; + + ($is_valid_utf8, $utf8_len) = ('', 0); + + $s = ''; # basically UTF8 flag on + + if($ch eq '"' or ($singlequote and $ch eq "'")){ + my $boundChar = $ch; + + OUTER: while( defined(next_chr()) ){ + + if($ch eq $boundChar){ + next_chr(); + + if ($utf16) { + decode_error("missing low surrogate character in surrogate pair"); + } + + utf8::decode($s) if($is_utf8); + + return $s; + } + elsif($ch eq '\\'){ + next_chr(); + if(exists $escapes{$ch}){ + $s .= $escapes{$ch}; + } + elsif($ch eq 'u'){ # UNICODE handling + my $u = ''; + + for(1..4){ + $ch = next_chr(); + last OUTER if($ch !~ /[0-9a-fA-F]/); + $u .= $ch; + } + + # U+D800 - U+DBFF + if ($u =~ /^[dD][89abAB][0-9a-fA-F]{2}/) { # UTF-16 high surrogate? + $utf16 = $u; + } + # U+DC00 - U+DFFF + elsif ($u =~ /^[dD][c-fC-F][0-9a-fA-F]{2}/) { # UTF-16 low surrogate? + unless (defined $utf16) { + decode_error("missing high surrogate character in surrogate pair"); + } + $is_utf8 = 1; + $s .= JSON_PP_decode_surrogates($utf16, $u) || next; + $utf16 = undef; + } + else { + if (defined $utf16) { + decode_error("surrogate pair expected"); + } + + if ( ( my $hex = hex( $u ) ) > 127 ) { + $is_utf8 = 1; + $s .= JSON_PP_decode_unicode($u) || next; + } + else { + $s .= chr $hex; + } + } + + } + else{ + unless ($loose) { + $at -= 2; + decode_error('illegal backslash escape sequence in string'); + } + $s .= $ch; + } + } + else{ + + if ( ord $ch > 127 ) { + if ( $utf8 ) { + unless( $ch = is_valid_utf8($ch) ) { + $at -= 1; + decode_error("malformed UTF-8 character in JSON string"); + } + else { + $at += $utf8_len - 1; + } + } + else { + utf8::encode( $ch ); + } + + $is_utf8 = 1; + } + + if (!$loose) { + if ($ch =~ /[\x00-\x1f\x22\x5c]/) { # '/' ok + $at--; + decode_error('invalid character encountered while parsing JSON string'); + } + } + + $s .= $ch; + } + } + } + + decode_error("unexpected end of string while parsing JSON string"); + } + + + sub white { + while( defined $ch ){ + if($ch le ' '){ + next_chr(); + } + elsif($ch eq '/'){ + next_chr(); + if(defined $ch and $ch eq '/'){ + 1 while(defined(next_chr()) and $ch ne "\n" and $ch ne "\r"); + } + elsif(defined $ch and $ch eq '*'){ + next_chr(); + while(1){ + if(defined $ch){ + if($ch eq '*'){ + if(defined(next_chr()) and $ch eq '/'){ + next_chr(); + last; + } + } + else{ + next_chr(); + } + } + else{ + decode_error("Unterminated comment"); + } + } + next; + } + else{ + $at--; + decode_error("malformed JSON string, neither array, object, number, string or atom"); + } + } + else{ + if ($relaxed and $ch eq '#') { # correctly? + pos($text) = $at; + $text =~ /\G([^\n]*(?:\r\n|\r|\n|$))/g; + $at = pos($text); + next_chr; + next; + } + + last; + } + } + } + + + sub array { + my $a = $_[0] || []; # you can use this code to use another array ref object. + + decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)') + if (++$depth > $max_depth); + + next_chr(); + white(); + + if(defined $ch and $ch eq ']'){ + --$depth; + next_chr(); + return $a; + } + else { + while(defined($ch)){ + push @$a, value(); + + white(); + + if (!defined $ch) { + last; + } + + if($ch eq ']'){ + --$depth; + next_chr(); + return $a; + } + + if($ch ne ','){ + last; + } + + next_chr(); + white(); + + if ($relaxed and $ch eq ']') { + --$depth; + next_chr(); + return $a; + } + + } + } + + decode_error(", or ] expected while parsing array"); + } + + + sub object { + my $o = $_[0] || {}; # you can use this code to use another hash ref object. + my $k; + + decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)') + if (++$depth > $max_depth); + next_chr(); + white(); + + if(defined $ch and $ch eq '}'){ + --$depth; + next_chr(); + if ($F_HOOK) { + return _json_object_hook($o); + } + return $o; + } + else { + while (defined $ch) { + $k = ($allow_barekey and $ch ne '"' and $ch ne "'") ? bareKey() : string(); + white(); + + if(!defined $ch or $ch ne ':'){ + $at--; + decode_error("':' expected"); + } + + next_chr(); + $o->{$k} = value(); + white(); + + last if (!defined $ch); + + if($ch eq '}'){ + --$depth; + next_chr(); + if ($F_HOOK) { + return _json_object_hook($o); + } + return $o; + } + + if($ch ne ','){ + last; + } + + next_chr(); + white(); + + if ($relaxed and $ch eq '}') { + --$depth; + next_chr(); + if ($F_HOOK) { + return _json_object_hook($o); + } + return $o; + } + + } + + } + + $at--; + decode_error(", or } expected while parsing object/hash"); + } + + + sub bareKey { # doesn't strictly follow Standard ECMA-262 3rd Edition + my $key; + while($ch =~ /[^\x00-\x23\x25-\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]/){ + $key .= $ch; + next_chr(); + } + return $key; + } + + + sub word { + my $word = substr($text,$at-1,4); + + if($word eq 'true'){ + $at += 3; + next_chr; + return $JSON::PP::true; + } + elsif($word eq 'null'){ + $at += 3; + next_chr; + return undef; + } + elsif($word eq 'fals'){ + $at += 3; + if(substr($text,$at,1) eq 'e'){ + $at++; + next_chr; + return $JSON::PP::false; + } + } + + $at--; # for decode_error report + + decode_error("'null' expected") if ($word =~ /^n/); + decode_error("'true' expected") if ($word =~ /^t/); + decode_error("'false' expected") if ($word =~ /^f/); + decode_error("malformed JSON string, neither array, object, number, string or atom"); + } + + + sub number { + my $n = ''; + my $v; + + # According to RFC4627, hex or oct digts are invalid. + if($ch eq '0'){ + my $peek = substr($text,$at,1); + my $hex = $peek =~ /[xX]/; # 0 or 1 + + if($hex){ + decode_error("malformed number (leading zero must not be followed by another digit)"); + ($n) = ( substr($text, $at+1) =~ /^([0-9a-fA-F]+)/); + } + else{ # oct + ($n) = ( substr($text, $at) =~ /^([0-7]+)/); + if (defined $n and length $n > 1) { + decode_error("malformed number (leading zero must not be followed by another digit)"); + } + } + + if(defined $n and length($n)){ + if (!$hex and length($n) == 1) { + decode_error("malformed number (leading zero must not be followed by another digit)"); + } + $at += length($n) + $hex; + next_chr; + return $hex ? hex($n) : oct($n); + } + } + + if($ch eq '-'){ + $n = '-'; + next_chr; + if (!defined $ch or $ch !~ /\d/) { + decode_error("malformed number (no digits after initial minus)"); + } + } + + while(defined $ch and $ch =~ /\d/){ + $n .= $ch; + next_chr; + } + + if(defined $ch and $ch eq '.'){ + $n .= '.'; + + next_chr; + if (!defined $ch or $ch !~ /\d/) { + decode_error("malformed number (no digits after decimal point)"); + } + else { + $n .= $ch; + } + + while(defined(next_chr) and $ch =~ /\d/){ + $n .= $ch; + } + } + + if(defined $ch and ($ch eq 'e' or $ch eq 'E')){ + $n .= $ch; + next_chr; + + if(defined($ch) and ($ch eq '+' or $ch eq '-')){ + $n .= $ch; + next_chr; + if (!defined $ch or $ch =~ /\D/) { + decode_error("malformed number (no digits after exp sign)"); + } + $n .= $ch; + } + elsif(defined($ch) and $ch =~ /\d/){ + $n .= $ch; + } + else { + decode_error("malformed number (no digits after exp sign)"); + } + + while(defined(next_chr) and $ch =~ /\d/){ + $n .= $ch; + } + + } + + $v .= $n; + + if ($v !~ /[.eE]/ and length $v > $max_intsize) { + if ($allow_bigint) { # from Adam Sussman + require Math::BigInt; + return Math::BigInt->new($v); + } + else { + return "$v"; + } + } + elsif ($allow_bigint) { + require Math::BigFloat; + return Math::BigFloat->new($v); + } + + return 0+$v; + } + + + sub is_valid_utf8 { + + $utf8_len = $_[0] =~ /[\x00-\x7F]/ ? 1 + : $_[0] =~ /[\xC2-\xDF]/ ? 2 + : $_[0] =~ /[\xE0-\xEF]/ ? 3 + : $_[0] =~ /[\xF0-\xF4]/ ? 4 + : 0 + ; + + return unless $utf8_len; + + my $is_valid_utf8 = substr($text, $at - 1, $utf8_len); + + return ( $is_valid_utf8 =~ /^(?: + [\x00-\x7F] + |[\xC2-\xDF][\x80-\xBF] + |[\xE0][\xA0-\xBF][\x80-\xBF] + |[\xE1-\xEC][\x80-\xBF][\x80-\xBF] + |[\xED][\x80-\x9F][\x80-\xBF] + |[\xEE-\xEF][\x80-\xBF][\x80-\xBF] + |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF] + |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF] + |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF] + )$/x ) ? $is_valid_utf8 : ''; + } + + + sub decode_error { + my $error = shift; + my $no_rep = shift; + my $str = defined $text ? substr($text, $at) : ''; + my $mess = ''; + my $type = $] >= 5.008 ? 'U*' + : $] < 5.006 ? 'C*' + : utf8::is_utf8( $str ) ? 'U*' # 5.6 + : 'C*' + ; + + for my $c ( unpack( $type, $str ) ) { # emulate pv_uni_display() ? + $mess .= $c == 0x07 ? '\a' + : $c == 0x09 ? '\t' + : $c == 0x0a ? '\n' + : $c == 0x0d ? '\r' + : $c == 0x0c ? '\f' + : $c < 0x20 ? sprintf('\x{%x}', $c) + : $c == 0x5c ? '\\\\' + : $c < 0x80 ? chr($c) + : sprintf('\x{%x}', $c) + ; + if ( length $mess >= 20 ) { + $mess .= '...'; + last; + } + } + + unless ( length $mess ) { + $mess = '(end of string)'; + } + + Carp::croak ( + $no_rep ? "$error" : "$error, at character offset $at (before \"$mess\")" + ); + + } + + + sub _json_object_hook { + my $o = $_[0]; + my @ks = keys %{$o}; + + if ( $cb_sk_object and @ks == 1 and exists $cb_sk_object->{ $ks[0] } and ref $cb_sk_object->{ $ks[0] } ) { + my @val = $cb_sk_object->{ $ks[0] }->( $o->{$ks[0]} ); + if (@val == 1) { + return $val[0]; + } + } + + my @val = $cb_object->($o) if ($cb_object); + if (@val == 0 or @val > 1) { + return $o; + } + else { + return $val[0]; + } + } + + + sub PP_decode_box { + { + text => $text, + at => $at, + ch => $ch, + len => $len, + depth => $depth, + encoding => $encoding, + is_valid_utf8 => $is_valid_utf8, + }; + } + +} # PARSE + + +sub _decode_surrogates { # from perlunicode + my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00); + my $un = pack('U*', $uni); + utf8::encode( $un ); + return $un; +} + + +sub _decode_unicode { + my $un = pack('U', hex shift); + utf8::encode( $un ); + return $un; +} + +# +# Setup for various Perl versions (the code from JSON::PP58) +# + +BEGIN { + + unless ( defined &utf8::is_utf8 ) { + require Encode; + *utf8::is_utf8 = *Encode::is_utf8; + } + + if ( $] >= 5.008 ) { + *JSON::PP::JSON_PP_encode_ascii = \&_encode_ascii; + *JSON::PP::JSON_PP_encode_latin1 = \&_encode_latin1; + *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates; + *JSON::PP::JSON_PP_decode_unicode = \&_decode_unicode; + } + + if ($] >= 5.008 and $] < 5.008003) { # join() in 5.8.0 - 5.8.2 is broken. + package JSON::PP; + require subs; + subs->import('join'); + eval q| + sub join { + return '' if (@_ < 2); + my $j = shift; + my $str = shift; + for (@_) { $str .= $j . $_; } + return $str; + } + |; + } + + + sub JSON::PP::incr_parse { + local $Carp::CarpLevel = 1; + ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_parse( @_ ); + } + + + sub JSON::PP::incr_skip { + ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_skip; + } + + + sub JSON::PP::incr_reset { + ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_reset; + } + + eval q{ + sub JSON::PP::incr_text : lvalue { + $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new; + + if ( $_[0]->{_incr_parser}->{incr_parsing} ) { + Carp::croak("incr_text can not be called when the incremental parser already started parsing"); + } + $_[0]->{_incr_parser}->{incr_text}; + } + } if ( $] >= 5.006 ); + +} # Setup for various Perl versions (the code from JSON::PP58) + + +############################### +# Utilities +# + +BEGIN { + eval 'require Scalar::Util'; + unless($@){ + *JSON::PP::blessed = \&Scalar::Util::blessed; + *JSON::PP::reftype = \&Scalar::Util::reftype; + *JSON::PP::refaddr = \&Scalar::Util::refaddr; + } + else{ # This code is from Sclar::Util. + # warn $@; + eval 'sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) }'; + *JSON::PP::blessed = sub { + local($@, $SIG{__DIE__}, $SIG{__WARN__}); + ref($_[0]) ? eval { $_[0]->a_sub_not_likely_to_be_here } : undef; + }; + my %tmap = qw( + B::NULL SCALAR + B::HV HASH + B::AV ARRAY + B::CV CODE + B::IO IO + B::GV GLOB + B::REGEXP REGEXP + ); + *JSON::PP::reftype = sub { + my $r = shift; + + return undef unless length(ref($r)); + + my $t = ref(B::svref_2object($r)); + + return + exists $tmap{$t} ? $tmap{$t} + : length(ref($$r)) ? 'REF' + : 'SCALAR'; + }; + *JSON::PP::refaddr = sub { + return undef unless length(ref($_[0])); + + my $addr; + if(defined(my $pkg = blessed($_[0]))) { + $addr .= bless $_[0], 'Scalar::Util::Fake'; + bless $_[0], $pkg; + } + else { + $addr .= $_[0] + } + + $addr =~ /0x(\w+)/; + local $^W; + #no warnings 'portable'; + hex($1); + } + } +} + + +# shamely copied and modified from JSON::XS code. + +$JSON::PP::true = do { bless \(my $dummy = 1), "JSON::backportPP::Boolean" }; +$JSON::PP::false = do { bless \(my $dummy = 0), "JSON::backportPP::Boolean" }; + +sub is_bool { defined $_[0] and UNIVERSAL::isa($_[0], "JSON::PP::Boolean"); } + +sub true { $JSON::PP::true } +sub false { $JSON::PP::false } +sub null { undef; } + +############################### + +package JSON::backportPP::Boolean; + +@JSON::backportPP::Boolean::ISA = ('JSON::PP::Boolean'); +use overload ( + "0+" => sub { ${$_[0]} }, + "++" => sub { $_[0] = ${$_[0]} + 1 }, + "--" => sub { $_[0] = ${$_[0]} - 1 }, + fallback => 1, +); + + +############################### + +package + JSON::PP::IncrParser; + +use strict; + +use constant INCR_M_WS => 0; # initial whitespace skipping +use constant INCR_M_STR => 1; # inside string +use constant INCR_M_BS => 2; # inside backslash +use constant INCR_M_JSON => 3; # outside anything, count nesting +use constant INCR_M_C0 => 4; +use constant INCR_M_C1 => 5; + +$JSON::PP::IncrParser::VERSION = '1.01'; + +my $unpack_format = $] < 5.006 ? 'C*' : 'U*'; + +sub new { + my ( $class ) = @_; + + bless { + incr_nest => 0, + incr_text => undef, + incr_parsing => 0, + incr_p => 0, + }, $class; +} + + +sub incr_parse { + my ( $self, $coder, $text ) = @_; + + $self->{incr_text} = '' unless ( defined $self->{incr_text} ); + + if ( defined $text ) { + if ( utf8::is_utf8( $text ) and !utf8::is_utf8( $self->{incr_text} ) ) { + utf8::upgrade( $self->{incr_text} ) ; + utf8::decode( $self->{incr_text} ) ; + } + $self->{incr_text} .= $text; + } + + + my $max_size = $coder->get_max_size; + + if ( defined wantarray ) { + + $self->{incr_mode} = INCR_M_WS unless defined $self->{incr_mode}; + + if ( wantarray ) { + my @ret; + + $self->{incr_parsing} = 1; + + do { + push @ret, $self->_incr_parse( $coder, $self->{incr_text} ); + + unless ( !$self->{incr_nest} and $self->{incr_mode} == INCR_M_JSON ) { + $self->{incr_mode} = INCR_M_WS if $self->{incr_mode} != INCR_M_STR; + } + + } until ( length $self->{incr_text} >= $self->{incr_p} ); + + $self->{incr_parsing} = 0; + + return @ret; + } + else { # in scalar context + $self->{incr_parsing} = 1; + my $obj = $self->_incr_parse( $coder, $self->{incr_text} ); + $self->{incr_parsing} = 0 if defined $obj; # pointed by Martin J. Evans + return $obj ? $obj : undef; # $obj is an empty string, parsing was completed. + } + + } + +} + + +sub _incr_parse { + my ( $self, $coder, $text, $skip ) = @_; + my $p = $self->{incr_p}; + my $restore = $p; + + my @obj; + my $len = length $text; + + if ( $self->{incr_mode} == INCR_M_WS ) { + while ( $len > $p ) { + my $s = substr( $text, $p, 1 ); + $p++ and next if ( 0x20 >= unpack($unpack_format, $s) ); + $self->{incr_mode} = INCR_M_JSON; + last; + } + } + + while ( $len > $p ) { + my $s = substr( $text, $p++, 1 ); + + if ( $s eq '"' ) { + if (substr( $text, $p - 2, 1 ) eq '\\' ) { + next; + } + + if ( $self->{incr_mode} != INCR_M_STR ) { + $self->{incr_mode} = INCR_M_STR; + } + else { + $self->{incr_mode} = INCR_M_JSON; + unless ( $self->{incr_nest} ) { + last; + } + } + } + + if ( $self->{incr_mode} == INCR_M_JSON ) { + + if ( $s eq '[' or $s eq '{' ) { + if ( ++$self->{incr_nest} > $coder->get_max_depth ) { + Carp::croak('json text or perl structure exceeds maximum nesting level (max_depth set too low?)'); + } + } + elsif ( $s eq ']' or $s eq '}' ) { + last if ( --$self->{incr_nest} <= 0 ); + } + elsif ( $s eq '#' ) { + while ( $len > $p ) { + last if substr( $text, $p++, 1 ) eq "\n"; + } + } + + } + + } + + $self->{incr_p} = $p; + + return if ( $self->{incr_mode} == INCR_M_STR and not $self->{incr_nest} ); + return if ( $self->{incr_mode} == INCR_M_JSON and $self->{incr_nest} > 0 ); + + return '' unless ( length substr( $self->{incr_text}, 0, $p ) ); + + local $Carp::CarpLevel = 2; + + $self->{incr_p} = $restore; + $self->{incr_c} = $p; + + my ( $obj, $tail ) = $coder->PP_decode_json( substr( $self->{incr_text}, 0, $p ), 0x10000001 ); + + $self->{incr_text} = substr( $self->{incr_text}, $p ); + $self->{incr_p} = 0; + + return $obj or ''; +} + + +sub incr_text { + if ( $_[0]->{incr_parsing} ) { + Carp::croak("incr_text can not be called when the incremental parser already started parsing"); + } + $_[0]->{incr_text}; +} + + +sub incr_skip { + my $self = shift; + $self->{incr_text} = substr( $self->{incr_text}, $self->{incr_c} ); + $self->{incr_p} = 0; +} + + +sub incr_reset { + my $self = shift; + $self->{incr_text} = undef; + $self->{incr_p} = 0; + $self->{incr_mode} = 0; + $self->{incr_nest} = 0; + $self->{incr_parsing} = 0; +} + +############################### + + +1; +__END__ +=pod + +=head1 NAME + +JSON::PP - JSON::XS compatible pure-Perl module. + +=head1 SYNOPSIS + + use JSON::PP; + + # exported functions, they croak on error + # and expect/generate UTF-8 + + $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref; + $perl_hash_or_arrayref = decode_json $utf8_encoded_json_text; + + # OO-interface + + $coder = JSON::PP->new->ascii->pretty->allow_nonref; + + $json_text = $json->encode( $perl_scalar ); + $perl_scalar = $json->decode( $json_text ); + + $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing + + # Note that JSON version 2.0 and above will automatically use + # JSON::XS or JSON::PP, so you should be able to just: + + use JSON; + + +=head1 VERSION + + 2.27200 + +L 2.27 (~2.30) compatible. + +=head1 DESCRIPTION + +This module is L compatible pure Perl module. +(Perl 5.8 or later is recommended) + +JSON::XS is the fastest and most proper JSON module on CPAN. +It is written by Marc Lehmann in C, so must be compiled and +installed in the used environment. + +JSON::PP is a pure-Perl module and has compatibility to JSON::XS. + + +=head2 FEATURES + +=over + +=item * correct unicode handling + +This module knows how to handle Unicode (depending on Perl version). + +See to L and L. + + +=item * round-trip integrity + +When you serialise a perl data structure using only data types supported +by JSON and Perl, the deserialised data structure is identical on the Perl +level. (e.g. the string "2.0" doesn't suddenly become "2" just because +it looks like a number). There I minor exceptions to this, read the +MAPPING section below to learn about those. + + +=item * strict checking of JSON correctness + +There is no guessing, no generating of illegal JSON texts by default, +and only JSON is accepted as input by default (the latter is a security feature). +But when some options are set, loose chcking features are available. + +=back + +=head1 FUNCTIONAL INTERFACE + +Some documents are copied and modified from L. + +=head2 encode_json + + $json_text = encode_json $perl_scalar + +Converts the given Perl data structure to a UTF-8 encoded, binary string. + +This function call is functionally identical to: + + $json_text = JSON::PP->new->utf8->encode($perl_scalar) + +=head2 decode_json + + $perl_scalar = decode_json $json_text + +The opposite of C: expects an UTF-8 (binary) string and tries +to parse that as an UTF-8 encoded JSON text, returning the resulting +reference. + +This function call is functionally identical to: + + $perl_scalar = JSON::PP->new->utf8->decode($json_text) + +=head2 JSON::PP::is_bool + + $is_boolean = JSON::PP::is_bool($scalar) + +Returns true if the passed scalar represents either JSON::PP::true or +JSON::PP::false, two constants that act like C<1> and C<0> respectively +and are also used to represent JSON C and C in Perl strings. + +=head2 JSON::PP::true + +Returns JSON true value which is blessed object. +It C JSON::PP::Boolean object. + +=head2 JSON::PP::false + +Returns JSON false value which is blessed object. +It C JSON::PP::Boolean object. + +=head2 JSON::PP::null + +Returns C. + +See L, below, for more information on how JSON values are mapped to +Perl. + + +=head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER + +This section supposes that your perl vresion is 5.8 or later. + +If you know a JSON text from an outer world - a network, a file content, and so on, +is encoded in UTF-8, you should use C or C module object +with C enable. And the decoded result will contain UNICODE characters. + + # from network + my $json = JSON::PP->new->utf8; + my $json_text = CGI->new->param( 'json_data' ); + my $perl_scalar = $json->decode( $json_text ); + + # from file content + local $/; + open( my $fh, '<', 'json.data' ); + $json_text = <$fh>; + $perl_scalar = decode_json( $json_text ); + +If an outer data is not encoded in UTF-8, firstly you should C it. + + use Encode; + local $/; + open( my $fh, '<', 'json.data' ); + my $encoding = 'cp932'; + my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE + + # or you can write the below code. + # + # open( my $fh, "<:encoding($encoding)", 'json.data' ); + # $unicode_json_text = <$fh>; + +In this case, C<$unicode_json_text> is of course UNICODE string. +So you B use C nor C module object with C enable. +Instead of them, you use C module object with C disable. + + $perl_scalar = $json->utf8(0)->decode( $unicode_json_text ); + +Or C and C: + + $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) ); + # this way is not efficient. + +And now, you want to convert your C<$perl_scalar> into JSON data and +send it to an outer world - a network or a file content, and so on. + +Your data usually contains UNICODE strings and you want the converted data to be encoded +in UTF-8, you should use C or C module object with C enable. + + print encode_json( $perl_scalar ); # to a network? file? or display? + # or + print $json->utf8->encode( $perl_scalar ); + +If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings +for some reason, then its characters are regarded as B for perl +(because it does not concern with your $encoding). +You B use C nor C module object with C enable. +Instead of them, you use C module object with C disable. +Note that the resulted text is a UNICODE string but no problem to print it. + + # $perl_scalar contains $encoding encoded string values + $unicode_json_text = $json->utf8(0)->encode( $perl_scalar ); + # $unicode_json_text consists of characters less than 0x100 + print $unicode_json_text; + +Or C all string values and C: + + $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } ); + # ... do it to each string values, then encode_json + $json_text = encode_json( $perl_scalar ); + +This method is a proper way but probably not efficient. + +See to L, L. + + +=head1 METHODS + +Basically, check to L or L. + +=head2 new + + $json = JSON::PP->new + +Rturns a new JSON::PP object that can be used to de/encode JSON +strings. + +All boolean flags described below are by default I. + +The mutators for flags all return the JSON object again and thus calls can +be chained: + + my $json = JSON::PP->new->utf8->space_after->encode({a => [1,2]}) + => {"a": [1, 2]} + +=head2 ascii + + $json = $json->ascii([$enable]) + + $enabled = $json->get_ascii + +If $enable is true (or missing), then the encode method will not generate characters outside +the code range 0..127. Any Unicode characters outside that range will be escaped using either +a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627. +(See to L). + +In Perl 5.005, there is no character having high value (more than 255). +See to L. + +If $enable is false, then the encode method will not escape Unicode characters unless +required by the JSON syntax or other flags. This results in a faster and more compact format. + + JSON::PP->new->ascii(1)->encode([chr 0x10401]) + => ["\ud801\udc01"] + +=head2 latin1 + + $json = $json->latin1([$enable]) + + $enabled = $json->get_latin1 + +If $enable is true (or missing), then the encode method will encode the resulting JSON +text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255. + +If $enable is false, then the encode method will not escape Unicode characters +unless required by the JSON syntax or other flags. + + JSON::XS->new->latin1->encode (["\x{89}\x{abc}"] + => ["\x{89}\\u0abc"] # (perl syntax, U+abc escaped, U+89 not) + +See to L. + +=head2 utf8 + + $json = $json->utf8([$enable]) + + $enabled = $json->get_utf8 + +If $enable is true (or missing), then the encode method will encode the JSON result +into UTF-8, as required by many protocols, while the decode method expects to be handled +an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any +characters outside the range 0..255, they are thus useful for bytewise/binary I/O. + +(In Perl 5.005, any character outside the range 0..255 does not exist. +See to L.) + +In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32 +encoding families, as described in RFC4627. + +If $enable is false, then the encode method will return the JSON string as a (non-encoded) +Unicode string, while decode expects thus a Unicode string. Any decoding or encoding +(e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module. + +Example, output UTF-16BE-encoded JSON: + + use Encode; + $jsontext = encode "UTF-16BE", JSON::PP->new->encode ($object); + +Example, decode UTF-32LE-encoded JSON: + + use Encode; + $object = JSON::PP->new->decode (decode "UTF-32LE", $jsontext); + + +=head2 pretty + + $json = $json->pretty([$enable]) + +This enables (or disables) all of the C, C and +C flags in one call to generate the most readable +(or most compact) form possible. + +Equivalent to: + + $json->indent->space_before->space_after + +=head2 indent + + $json = $json->indent([$enable]) + + $enabled = $json->get_indent + +The default indent space length is three. +You can use C to change the length. + +=head2 space_before + + $json = $json->space_before([$enable]) + + $enabled = $json->get_space_before + +If C<$enable> is true (or missing), then the C method will add an extra +optional space before the C<:> separating keys from values in JSON objects. + +If C<$enable> is false, then the C method will not add any extra +space at those places. + +This setting has no effect when decoding JSON texts. + +Example, space_before enabled, space_after and indent disabled: + + {"key" :"value"} + +=head2 space_after + + $json = $json->space_after([$enable]) + + $enabled = $json->get_space_after + +If C<$enable> is true (or missing), then the C method will add an extra +optional space after the C<:> separating keys from values in JSON objects +and extra whitespace after the C<,> separating key-value pairs and array +members. + +If C<$enable> is false, then the C method will not add any extra +space at those places. + +This setting has no effect when decoding JSON texts. + +Example, space_before and indent disabled, space_after enabled: + + {"key": "value"} + +=head2 relaxed + + $json = $json->relaxed([$enable]) + + $enabled = $json->get_relaxed + +If C<$enable> is true (or missing), then C will accept some +extensions to normal JSON syntax (see below). C will not be +affected in anyway. I. I suggest only to use this option to +parse application-specific files written by humans (configuration files, +resource files etc.) + +If C<$enable> is false (the default), then C will only accept +valid JSON texts. + +Currently accepted extensions are: + +=over 4 + +=item * list items can have an end-comma + +JSON I array elements and key-value pairs with commas. This +can be annoying if you write JSON texts manually and want to be able to +quickly append elements, so this extension accepts comma at the end of +such items not just between them: + + [ + 1, + 2, <- this comma not normally allowed + ] + { + "k1": "v1", + "k2": "v2", <- this comma not normally allowed + } + +=item * shell-style '#'-comments + +Whenever JSON allows whitespace, shell-style comments are additionally +allowed. They are terminated by the first carriage-return or line-feed +character, after which more white-space and comments are allowed. + + [ + 1, # this comment not allowed in JSON + # neither this one... + ] + +=back + +=head2 canonical + + $json = $json->canonical([$enable]) + + $enabled = $json->get_canonical + +If C<$enable> is true (or missing), then the C method will output JSON objects +by sorting their keys. This is adding a comparatively high overhead. + +If C<$enable> is false, then the C method will output key-value +pairs in the order Perl stores them (which will likely change between runs +of the same script). + +This option is useful if you want the same data structure to be encoded as +the same JSON text (given the same overall settings). If it is disabled, +the same hash might be encoded differently even if contains the same data, +as key-value pairs have no inherent ordering in Perl. + +This setting has no effect when decoding JSON texts. + +If you want your own sorting routine, you can give a code referece +or a subroutine name to C. See to C. + +=head2 allow_nonref + + $json = $json->allow_nonref([$enable]) + + $enabled = $json->get_allow_nonref + +If C<$enable> is true (or missing), then the C method can convert a +non-reference into its corresponding string, number or null JSON value, +which is an extension to RFC4627. Likewise, C will accept those JSON +values instead of croaking. + +If C<$enable> is false, then the C method will croak if it isn't +passed an arrayref or hashref, as JSON texts must either be an object +or array. Likewise, C will croak if given something that is not a +JSON object or array. + + JSON::PP->new->allow_nonref->encode ("Hello, World!") + => "Hello, World!" + +=head2 allow_unknown + + $json = $json->allow_unknown ([$enable]) + + $enabled = $json->get_allow_unknown + +If $enable is true (or missing), then "encode" will *not* throw an +exception when it encounters values it cannot represent in JSON (for +example, filehandles) but instead will encode a JSON "null" value. +Note that blessed objects are not included here and are handled +separately by c. + +If $enable is false (the default), then "encode" will throw an +exception when it encounters anything it cannot encode as JSON. + +This option does not affect "decode" in any way, and it is +recommended to leave it off unless you know your communications +partner. + +=head2 allow_blessed + + $json = $json->allow_blessed([$enable]) + + $enabled = $json->get_allow_blessed + +If C<$enable> is true (or missing), then the C method will not +barf when it encounters a blessed reference. Instead, the value of the +B option will decide whether C (C +disabled or no C method found) or a representation of the +object (C enabled and C method found) is being +encoded. Has no effect on C. + +If C<$enable> is false (the default), then C will throw an +exception when it encounters a blessed object. + +=head2 convert_blessed + + $json = $json->convert_blessed([$enable]) + + $enabled = $json->get_convert_blessed + +If C<$enable> is true (or missing), then C, upon encountering a +blessed object, will check for the availability of the C method +on the object's class. If found, it will be called in scalar context +and the resulting scalar will be encoded instead of the object. If no +C method is found, the value of C will decide what +to do. + +The C method may safely call die if it wants. If C +returns other blessed objects, those will be handled in the same +way. C must take care of not causing an endless recursion cycle +(== crash) in this case. The name of C was chosen because other +methods called by the Perl core (== not by the user of the object) are +usually in upper case letters and to avoid collisions with the C +function or method. + +This setting does not yet influence C in any way. + +If C<$enable> is false, then the C setting will decide what +to do when a blessed object is found. + +=head2 filter_json_object + + $json = $json->filter_json_object([$coderef]) + +When C<$coderef> is specified, it will be called from C each +time it decodes a JSON object. The only argument passed to the coderef +is a reference to the newly-created hash. If the code references returns +a single scalar (which need not be a reference), this value +(i.e. a copy of that scalar to avoid aliasing) is inserted into the +deserialised data structure. If it returns an empty list +(NOTE: I C, which is a valid scalar), the original deserialised +hash will be inserted. This setting can slow down decoding considerably. + +When C<$coderef> is omitted or undefined, any existing callback will +be removed and C will not change the deserialised hash in any +way. + +Example, convert all JSON objects into the integer 5: + + my $js = JSON::PP->new->filter_json_object (sub { 5 }); + # returns [5] + $js->decode ('[{}]'); # the given subroutine takes a hash reference. + # throw an exception because allow_nonref is not enabled + # so a lone 5 is not allowed. + $js->decode ('{"a":1, "b":2}'); + +=head2 filter_json_single_key_object + + $json = $json->filter_json_single_key_object($key [=> $coderef]) + +Works remotely similar to C, but is only called for +JSON objects having a single key named C<$key>. + +This C<$coderef> is called before the one specified via +C, if any. It gets passed the single value in the JSON +object. If it returns a single value, it will be inserted into the data +structure. If it returns nothing (not even C but the empty list), +the callback from C will be called next, as if no +single-key callback were specified. + +If C<$coderef> is omitted or undefined, the corresponding callback will be +disabled. There can only ever be one callback for a given key. + +As this callback gets called less often then the C +one, decoding speed will not usually suffer as much. Therefore, single-key +objects make excellent targets to serialise Perl objects into, especially +as single-key JSON objects are as close to the type-tagged value concept +as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not +support this in any way, so you need to make sure your data never looks +like a serialised Perl hash. + +Typical names for the single object key are C<__class_whatever__>, or +C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even +things like C<__class_md5sum(classname)__>, to reduce the risk of clashing +with real hashes. + +Example, decode JSON objects of the form C<< { "__widget__" => } >> +into the corresponding C<< $WIDGET{} >> object: + + # return whatever is in $WIDGET{5}: + JSON::PP + ->new + ->filter_json_single_key_object (__widget__ => sub { + $WIDGET{ $_[0] } + }) + ->decode ('{"__widget__": 5') + + # this can be used with a TO_JSON method in some "widget" class + # for serialisation to json: + sub WidgetBase::TO_JSON { + my ($self) = @_; + + unless ($self->{id}) { + $self->{id} = ..get..some..id..; + $WIDGET{$self->{id}} = $self; + } + + { __widget__ => $self->{id} } + } + +=head2 shrink + + $json = $json->shrink([$enable]) + + $enabled = $json->get_shrink + +In JSON::XS, this flag resizes strings generated by either +C or C to their minimum size possible. +It will also try to downgrade any strings to octet-form if possible. + +In JSON::PP, it is noop about resizing strings but tries +C to the returned string by C. +See to L. + +See to L + +=head2 max_depth + + $json = $json->max_depth([$maximum_nesting_depth]) + + $max_depth = $json->get_max_depth + +Sets the maximum nesting level (default C<512>) accepted while encoding +or decoding. If a higher nesting level is detected in JSON text or a Perl +data structure, then the encoder and decoder will stop and croak at that +point. + +Nesting level is defined by number of hash- or arrayrefs that the encoder +needs to traverse to reach a given point or the number of C<{> or C<[> +characters without their matching closing parenthesis crossed to reach a +given character in a string. + +If no argument is given, the highest possible setting will be used, which +is rarely useful. + +See L for more info on why this is useful. + +When a large value (100 or more) was set and it de/encodes a deep nested object/text, +it may raise a warning 'Deep recursion on subroutin' at the perl runtime phase. + +=head2 max_size + + $json = $json->max_size([$maximum_string_size]) + + $max_size = $json->get_max_size + +Set the maximum length a JSON text may have (in bytes) where decoding is +being attempted. The default is C<0>, meaning no limit. When C +is called on a string that is longer then this many bytes, it will not +attempt to decode the string but throw an exception. This setting has no +effect on C (yet). + +If no argument is given, the limit check will be deactivated (same as when +C<0> is specified). + +See L for more info on why this is useful. + +=head2 encode + + $json_text = $json->encode($perl_scalar) + +Converts the given Perl data structure (a simple scalar or a reference +to a hash or array) to its JSON representation. Simple scalars will be +converted into JSON string or number sequences, while references to arrays +become JSON arrays and references to hashes become JSON objects. Undefined +Perl values (e.g. C) become JSON C values. +References to the integers C<0> and C<1> are converted into C and C. + +=head2 decode + + $perl_scalar = $json->decode($json_text) + +The opposite of C: expects a JSON text and tries to parse it, +returning the resulting simple scalar or reference. Croaks on error. + +JSON numbers and strings become simple Perl scalars. JSON arrays become +Perl arrayrefs and JSON objects become Perl hashrefs. C becomes +C<1> (C), C becomes C<0> (C) and +C becomes C. + +=head2 decode_prefix + + ($perl_scalar, $characters) = $json->decode_prefix($json_text) + +This works like the C method, but instead of raising an exception +when there is trailing garbage after the first JSON object, it will +silently stop parsing there and return the number of characters consumed +so far. + + JSON->new->decode_prefix ("[1] the tail") + => ([], 3) + +=head1 INCREMENTAL PARSING + +Most of this section are copied and modified from L. + +In some cases, there is the need for incremental parsing of JSON texts. +This module does allow you to parse a JSON stream incrementally. +It does so by accumulating text until it has a full JSON object, which +it then can decode. This process is similar to using C +to see if a full JSON object is available, but is much more efficient +(and can be implemented with a minimum of method calls). + +This module will only attempt to parse the JSON text once it is sure it +has enough text to get a decisive result, using a very simple but +truly incremental parser. This means that it sometimes won't stop as +early as the full parser, for example, it doesn't detect parenthese +mismatches. The only thing it guarantees is that it starts decoding as +soon as a syntactically valid JSON text has been seen. This means you need +to set resource limits (e.g. C) to ensure the parser will stop +parsing in the presence if syntax errors. + +The following methods implement this incremental parser. + +=head2 incr_parse + + $json->incr_parse( [$string] ) # void context + + $obj_or_undef = $json->incr_parse( [$string] ) # scalar context + + @obj_or_empty = $json->incr_parse( [$string] ) # list context + +This is the central parsing function. It can both append new text and +extract objects from the stream accumulated so far (both of these +functions are optional). + +If C<$string> is given, then this string is appended to the already +existing JSON fragment stored in the C<$json> object. + +After that, if the function is called in void context, it will simply +return without doing anything further. This can be used to add more text +in as many chunks as you want. + +If the method is called in scalar context, then it will try to extract +exactly I JSON object. If that is successful, it will return this +object, otherwise it will return C. If there is a parse error, +this method will croak just as C would do (one can then use +C to skip the errornous part). This is the most common way of +using the method. + +And finally, in list context, it will try to extract as many objects +from the stream as it can find and return them, or the empty list +otherwise. For this to work, there must be no separators between the JSON +objects or arrays, instead they must be concatenated back-to-back. If +an error occurs, an exception will be raised as in the scalar context +case. Note that in this case, any previously-parsed JSON texts will be +lost. + +Example: Parse some JSON arrays/objects in a given string and return them. + + my @objs = JSON->new->incr_parse ("[5][7][1,2]"); + +=head2 incr_text + + $lvalue_string = $json->incr_text + +This method returns the currently stored JSON fragment as an lvalue, that +is, you can manipulate it. This I works when a preceding call to +C in I successfully returned an object. Under +all other circumstances you must not call this function (I mean it. +although in simple tests it might actually work, it I fail under +real world conditions). As a special exception, you can also call this +method before having parsed anything. + +This function is useful in two cases: a) finding the trailing text after a +JSON object or b) parsing multiple JSON objects separated by non-JSON text +(such as commas). + + $json->incr_text =~ s/\s*,\s*//; + +In Perl 5.005, C attribute is not available. +You must write codes like the below: + + $string = $json->incr_text; + $string =~ s/\s*,\s*//; + $json->incr_text( $string ); + +=head2 incr_skip + + $json->incr_skip + +This will reset the state of the incremental parser and will remove the +parsed text from the input buffer. This is useful after C +died, in which case the input buffer and incremental parser state is left +unchanged, to skip the text parsed so far and to reset the parse state. + +=head2 incr_reset + + $json->incr_reset + +This completely resets the incremental parser, that is, after this call, +it will be as if the parser had never parsed anything. + +This is useful if you want ot repeatedly parse JSON objects and want to +ignore any trailing data, which means you have to reset the parser after +each successful decode. + +See to L for examples. + + +=head1 JSON::PP OWN METHODS + +=head2 allow_singlequote + + $json = $json->allow_singlequote([$enable]) + +If C<$enable> is true (or missing), then C will accept +JSON strings quoted by single quotations that are invalid JSON +format. + + $json->allow_singlequote->decode({"foo":'bar'}); + $json->allow_singlequote->decode({'foo':"bar"}); + $json->allow_singlequote->decode({'foo':'bar'}); + +As same as the C option, this option may be used to parse +application-specific files written by humans. + + +=head2 allow_barekey + + $json = $json->allow_barekey([$enable]) + +If C<$enable> is true (or missing), then C will accept +bare keys of JSON object that are invalid JSON format. + +As same as the C option, this option may be used to parse +application-specific files written by humans. + + $json->allow_barekey->decode('{foo:"bar"}'); + +=head2 allow_bignum + + $json = $json->allow_bignum([$enable]) + +If C<$enable> is true (or missing), then C will convert +the big integer Perl cannot handle as integer into a L +object and convert a floating number (any) into a L. + +On the contary, C converts C objects and C +objects into JSON numbers with C enable. + + $json->allow_nonref->allow_blessed->allow_bignum; + $bigfloat = $json->decode('2.000000000000000000000000001'); + print $json->encode($bigfloat); + # => 2.000000000000000000000000001 + +See to L aboout the normal conversion of JSON number. + +=head2 loose + + $json = $json->loose([$enable]) + +The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings +and the module doesn't allow to C to these (except for \x2f). +If C<$enable> is true (or missing), then C will accept these +unescaped strings. + + $json->loose->decode(qq|["abc + def"]|); + +See L. + +=head2 escape_slash + + $json = $json->escape_slash([$enable]) + +According to JSON Grammar, I (U+002F) is escaped. But default +JSON::PP (as same as JSON::XS) encodes strings without escaping slash. + +If C<$enable> is true (or missing), then C will escape slashes. + +=head2 indent_length + + $json = $json->indent_length($length) + +JSON::XS indent space length is 3 and cannot be changed. +JSON::PP set the indent space length with the given $length. +The default is 3. The acceptable range is 0 to 15. + +=head2 sort_by + + $json = $json->sort_by($function_name) + $json = $json->sort_by($subroutine_ref) + +If $function_name or $subroutine_ref are set, its sort routine are used +in encoding JSON objects. + + $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj); + # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); + + $js = $pc->sort_by('own_sort')->encode($obj); + # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); + + sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b } + +As the sorting routine runs in the JSON::PP scope, the given +subroutine name and the special variables C<$a>, C<$b> will begin +'JSON::PP::'. + +If $integer is set, then the effect is same as C on. + +=head1 INTERNAL + +For developers. + +=over + +=item PP_encode_box + +Returns + + { + depth => $depth, + indent_count => $indent_count, + } + + +=item PP_decode_box + +Returns + + { + text => $text, + at => $at, + ch => $ch, + len => $len, + depth => $depth, + encoding => $encoding, + is_valid_utf8 => $is_valid_utf8, + }; + +=back + +=head1 MAPPING + +This section is copied from JSON::XS and modified to C. +JSON::XS and JSON::PP mapping mechanisms are almost equivalent. + +See to L. + +=head2 JSON -> PERL + +=over 4 + +=item object + +A JSON object becomes a reference to a hash in Perl. No ordering of object +keys is preserved (JSON does not preserver object key ordering itself). + +=item array + +A JSON array becomes a reference to an array in Perl. + +=item string + +A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON +are represented by the same codepoints in the Perl string, so no manual +decoding is necessary. + +=item number + +A JSON number becomes either an integer, numeric (floating point) or +string scalar in perl, depending on its range and any fractional parts. On +the Perl level, there is no difference between those as Perl handles all +the conversion details, but an integer may take slightly less memory and +might represent more values exactly than floating point numbers. + +If the number consists of digits only, C will try to represent +it as an integer value. If that fails, it will try to represent it as +a numeric (floating point) value if that is possible without loss of +precision. Otherwise it will preserve the number as a string value (in +which case you lose roundtripping ability, as the JSON number will be +re-encoded toa JSON string). + +Numbers containing a fractional or exponential part will always be +represented as numeric (floating point) values, possibly at a loss of +precision (in which case you might lose perfect roundtripping ability, but +the JSON number will still be re-encoded as a JSON number). + +Note that precision is not accuracy - binary floating point values cannot +represent most decimal fractions exactly, and when converting from and to +floating point, C only guarantees precision up to but not including +the leats significant bit. + +When C is enable, the big integers +and the numeric can be optionally converted into L and +L objects. + +=item true, false + +These JSON atoms become C and C, +respectively. They are overloaded to act almost exactly like the numbers +C<1> and C<0>. You can check wether a scalar is a JSON boolean by using +the C function. + + print JSON::PP::true . "\n"; + => true + print JSON::PP::true + 1; + => 1 + + ok(JSON::true eq '1'); + ok(JSON::true == 1); + +C will install these missing overloading features to the backend modules. + + +=item null + +A JSON null atom becomes C in Perl. + +C returns C. + +=back + + +=head2 PERL -> JSON + +The mapping from Perl to JSON is slightly more difficult, as Perl is a +truly typeless language, so we can only guess which JSON type is meant by +a Perl value. + +=over 4 + +=item hash references + +Perl hash references become JSON objects. As there is no inherent ordering +in hash keys (or JSON objects), they will usually be encoded in a +pseudo-random order that can change between runs of the same program but +stays generally the same within a single run of a program. C +optionally sort the hash keys (determined by the I flag), so +the same datastructure will serialise to the same JSON text (given same +settings and version of JSON::XS), but this incurs a runtime overhead +and is only rarely useful, e.g. when you want to compare some JSON text +against another for equality. + + +=item array references + +Perl array references become JSON arrays. + +=item other references + +Other unblessed references are generally not allowed and will cause an +exception to be thrown, except for references to the integers C<0> and +C<1>, which get turned into C and C atoms in JSON. You can +also use C and C to improve readability. + + to_json [\0,JSON::PP::true] # yields [false,true] + +=item JSON::PP::true, JSON::PP::false, JSON::PP::null + +These special values become JSON true and JSON false values, +respectively. You can also use C<\1> and C<\0> directly if you want. + +JSON::PP::null returns C. + +=item blessed objects + +Blessed objects are not directly representable in JSON. See the +C and C methods on various options on +how to deal with this: basically, you can choose between throwing an +exception, encoding the reference as if it weren't blessed, or provide +your own serialiser method. + +See to L. + +=item simple scalars + +Simple Perl scalars (any scalar that is not a reference) are the most +difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as +JSON C values, scalars that have last been used in a string context +before encoding as JSON strings, and anything else as number value: + + # dump as number + encode_json [2] # yields [2] + encode_json [-3.0e17] # yields [-3e+17] + my $value = 5; encode_json [$value] # yields [5] + + # used as string, so dump as string + print $value; + encode_json [$value] # yields ["5"] + + # undef becomes null + encode_json [undef] # yields [null] + +You can force the type to be a string by stringifying it: + + my $x = 3.1; # some variable containing a number + "$x"; # stringified + $x .= ""; # another, more awkward way to stringify + print $x; # perl does it for you, too, quite often + +You can force the type to be a number by numifying it: + + my $x = "3"; # some variable containing a string + $x += 0; # numify it, ensuring it will be dumped as a number + $x *= 1; # same thing, the choise is yours. + +You can not currently force the type in other, less obscure, ways. + +Note that numerical precision has the same meaning as under Perl (so +binary to decimal conversion follows the same rules as in Perl, which +can differ to other languages). Also, your perl interpreter might expose +extensions to the floating point numbers of your platform, such as +infinities or NaN's - these cannot be represented in JSON, and it is an +error to pass those in. + +=item Big Number + +When C is enable, +C converts C objects and C +objects into JSON numbers. + + +=back + +=head1 UNICODE HANDLING ON PERLS + +If you do not know about Unicode on Perl well, +please check L. + +=head2 Perl 5.8 and later + +Perl can handle Unicode and the JSON::PP de/encode methods also work properly. + + $json->allow_nonref->encode(chr hex 3042); + $json->allow_nonref->encode(chr hex 12345); + +Reuturns C<"\u3042"> and C<"\ud808\udf45"> respectively. + + $json->allow_nonref->decode('"\u3042"'); + $json->allow_nonref->decode('"\ud808\udf45"'); + +Returns UTF-8 encoded strings with UTF8 flag, regarded as C and C. + +Note that the versions from Perl 5.8.0 to 5.8.2, Perl built-in C was broken, +so JSON::PP wraps the C with a subroutine. Thus JSON::PP works slow in the versions. + + +=head2 Perl 5.6 + +Perl can handle Unicode and the JSON::PP de/encode methods also work. + +=head2 Perl 5.005 + +Perl 5.005 is a byte sementics world -- all strings are sequences of bytes. +That means the unicode handling is not available. + +In encoding, + + $json->allow_nonref->encode(chr hex 3042); # hex 3042 is 12354. + $json->allow_nonref->encode(chr hex 12345); # hex 12345 is 74565. + +Returns C and C, as C takes a value more than 255, it treats +as C<$value % 256>, so the above codes are equivalent to : + + $json->allow_nonref->encode(chr 66); + $json->allow_nonref->encode(chr 69); + +In decoding, + + $json->decode('"\u00e3\u0081\u0082"'); + +The returned is a byte sequence C<0xE3 0x81 0x82> for UTF-8 encoded +japanese character (C). +And if it is represented in Unicode code point, C. + +Next, + + $json->decode('"\u3042"'); + +We ordinary expect the returned value is a Unicode character C. +But here is 5.005 world. This is C<0xE3 0x81 0x82>. + + $json->decode('"\ud808\udf45"'); + +This is not a character C but bytes - C<0xf0 0x92 0x8d 0x85>. + + +=head1 TODO + +=over + +=item speed + +=item memory saving + +=back + + +=head1 SEE ALSO + +Most of the document are copied and modified from JSON::XS doc. + +L + +RFC4627 (L) + +=head1 AUTHOR + +Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE + + +=head1 COPYRIGHT AND LICENSE + +Copyright 2007-2011 by Makamaka Hannyaharamitu + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/data/lib/JSON/backportPP/Boolean.pm b/data/lib/JSON/backportPP/Boolean.pm new file mode 100644 index 0000000..2646b8e --- /dev/null +++ b/data/lib/JSON/backportPP/Boolean.pm @@ -0,0 +1,26 @@ +=head1 NAME + +JSON::PP::Boolean - dummy module providing JSON::PP::Boolean + +=head1 SYNOPSIS + + # do not "use" yourself + +=head1 DESCRIPTION + +This module exists only to provide overload resolution for Storable and similar modules. See +L for more info about this class. + +=cut + +use JSON::backportPP (); +use strict; + +1; + +=head1 AUTHOR + +This idea is from L written by Marc Lehmann + +=cut + diff --git a/data/lib/JSON/backportPP/Compat5005.pm b/data/lib/JSON/backportPP/Compat5005.pm new file mode 100644 index 0000000..f51741c --- /dev/null +++ b/data/lib/JSON/backportPP/Compat5005.pm @@ -0,0 +1,131 @@ +package # This is JSON::backportPP + JSON::backportPP5005; + +use 5.005; +use strict; + +my @properties; + +$JSON::PP5005::VERSION = '1.10'; + +BEGIN { + + sub utf8::is_utf8 { + 0; # It is considered that UTF8 flag off for Perl 5.005. + } + + sub utf8::upgrade { + } + + sub utf8::downgrade { + 1; # must always return true. + } + + sub utf8::encode { + } + + sub utf8::decode { + } + + *JSON::PP::JSON_PP_encode_ascii = \&_encode_ascii; + *JSON::PP::JSON_PP_encode_latin1 = \&_encode_latin1; + *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates; + *JSON::PP::JSON_PP_decode_unicode = \&_decode_unicode; + + # missing in B module. + sub B::SVp_IOK () { 0x01000000; } + sub B::SVp_NOK () { 0x02000000; } + sub B::SVp_POK () { 0x04000000; } + + $INC{'bytes.pm'} = 1; # dummy +} + + + +sub _encode_ascii { + join('', map { $_ <= 127 ? chr($_) : sprintf('\u%04x', $_) } unpack('C*', $_[0]) ); +} + + +sub _encode_latin1 { + join('', map { chr($_) } unpack('C*', $_[0]) ); +} + + +sub _decode_surrogates { # from http://homepage1.nifty.com/nomenclator/unicode/ucs_utf.htm + my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00); # from perlunicode + my $bit = unpack('B32', pack('N', $uni)); + + if ( $bit =~ /^00000000000(...)(......)(......)(......)$/ ) { + my ($w, $x, $y, $z) = ($1, $2, $3, $4); + return pack('B*', sprintf('11110%s10%s10%s10%s', $w, $x, $y, $z)); + } + else { + Carp::croak("Invalid surrogate pair"); + } +} + + +sub _decode_unicode { + my ($u) = @_; + my ($utf8bit); + + if ( $u =~ /^00([89a-f][0-9a-f])$/i ) { # 0x80-0xff + return pack( 'H2', $1 ); + } + + my $bit = unpack("B*", pack("H*", $u)); + + if ( $bit =~ /^00000(.....)(......)$/ ) { + $utf8bit = sprintf('110%s10%s', $1, $2); + } + elsif ( $bit =~ /^(....)(......)(......)$/ ) { + $utf8bit = sprintf('1110%s10%s10%s', $1, $2, $3); + } + else { + Carp::croak("Invalid escaped unicode"); + } + + return pack('B*', $utf8bit); +} + + +sub JSON::PP::incr_text { + $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new; + + if ( $_[0]->{_incr_parser}->{incr_parsing} ) { + Carp::croak("incr_text can not be called when the incremental parser already started parsing"); + } + + $_[0]->{_incr_parser}->{incr_text} = $_[1] if ( @_ > 1 ); + $_[0]->{_incr_parser}->{incr_text}; +} + + +1; +__END__ + +=pod + +=head1 NAME + +JSON::PP5005 - Helper module in using JSON::PP in Perl 5.005 + +=head1 DESCRIPTION + +JSON::PP calls internally. + +=head1 AUTHOR + +Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE + + +=head1 COPYRIGHT AND LICENSE + +Copyright 2007-2010 by Makamaka Hannyaharamitu + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + diff --git a/data/lib/JSON/backportPP/Compat5006.pm b/data/lib/JSON/backportPP/Compat5006.pm new file mode 100644 index 0000000..820dc93 --- /dev/null +++ b/data/lib/JSON/backportPP/Compat5006.pm @@ -0,0 +1,173 @@ +package # This is JSON::backportPP + JSON::backportPP56; + +use 5.006; +use strict; + +my @properties; + +$JSON::PP56::VERSION = '1.08'; + +BEGIN { + + sub utf8::is_utf8 { + my $len = length $_[0]; # char length + { + use bytes; # byte length; + return $len != length $_[0]; # if !=, UTF8-flagged on. + } + } + + + sub utf8::upgrade { + ; # noop; + } + + + sub utf8::downgrade ($;$) { + return 1 unless ( utf8::is_utf8( $_[0] ) ); + + if ( _is_valid_utf8( $_[0] ) ) { + my $downgrade; + for my $c ( unpack( "U*", $_[0] ) ) { + if ( $c < 256 ) { + $downgrade .= pack("C", $c); + } + else { + $downgrade .= pack("U", $c); + } + } + $_[0] = $downgrade; + return 1; + } + else { + Carp::croak("Wide character in subroutine entry") unless ( $_[1] ); + 0; + } + } + + + sub utf8::encode ($) { # UTF8 flag off + if ( utf8::is_utf8( $_[0] ) ) { + $_[0] = pack( "C*", unpack( "C*", $_[0] ) ); + } + else { + $_[0] = pack( "U*", unpack( "C*", $_[0] ) ); + $_[0] = pack( "C*", unpack( "C*", $_[0] ) ); + } + } + + + sub utf8::decode ($) { # UTF8 flag on + if ( _is_valid_utf8( $_[0] ) ) { + utf8::downgrade( $_[0] ); + $_[0] = pack( "U*", unpack( "U*", $_[0] ) ); + } + } + + + *JSON::PP::JSON_PP_encode_ascii = \&_encode_ascii; + *JSON::PP::JSON_PP_encode_latin1 = \&_encode_latin1; + *JSON::PP::JSON_PP_decode_surrogates = \&JSON::PP::_decode_surrogates; + *JSON::PP::JSON_PP_decode_unicode = \&JSON::PP::_decode_unicode; + + unless ( defined &B::SVp_NOK ) { # missing in B module. + eval q{ sub B::SVp_NOK () { 0x02000000; } }; + } + +} + + + +sub _encode_ascii { + join('', + map { + $_ <= 127 ? + chr($_) : + $_ <= 65535 ? + sprintf('\u%04x', $_) : sprintf('\u%x\u%x', JSON::PP::_encode_surrogates($_)); + } _unpack_emu($_[0]) + ); +} + + +sub _encode_latin1 { + join('', + map { + $_ <= 255 ? + chr($_) : + $_ <= 65535 ? + sprintf('\u%04x', $_) : sprintf('\u%x\u%x', JSON::PP::_encode_surrogates($_)); + } _unpack_emu($_[0]) + ); +} + + +sub _unpack_emu { # for Perl 5.6 unpack warnings + return !utf8::is_utf8($_[0]) ? unpack('C*', $_[0]) + : _is_valid_utf8($_[0]) ? unpack('U*', $_[0]) + : unpack('C*', $_[0]); +} + + +sub _is_valid_utf8 { + my $str = $_[0]; + my $is_utf8; + + while ($str =~ /(?: + ( + [\x00-\x7F] + |[\xC2-\xDF][\x80-\xBF] + |[\xE0][\xA0-\xBF][\x80-\xBF] + |[\xE1-\xEC][\x80-\xBF][\x80-\xBF] + |[\xED][\x80-\x9F][\x80-\xBF] + |[\xEE-\xEF][\x80-\xBF][\x80-\xBF] + |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF] + |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF] + |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF] + ) + | (.) + )/xg) + { + if (defined $1) { + $is_utf8 = 1 if (!defined $is_utf8); + } + else { + $is_utf8 = 0 if (!defined $is_utf8); + if ($is_utf8) { # eventually, not utf8 + return; + } + } + } + + return $is_utf8; +} + + +1; +__END__ + +=pod + +=head1 NAME + +JSON::PP56 - Helper module in using JSON::PP in Perl 5.6 + +=head1 DESCRIPTION + +JSON::PP calls internally. + +=head1 AUTHOR + +Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE + + +=head1 COPYRIGHT AND LICENSE + +Copyright 2007-2009 by Makamaka Hannyaharamitu + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + diff --git a/data/mbim-service-auth.h b/data/mbim-service-auth.h new file mode 100644 index 0000000..7e1b47f --- /dev/null +++ b/data/mbim-service-auth.h @@ -0,0 +1,65 @@ +/* + * ID: 1 + * Command: Aka + */ + +#define MBIM_CMD_AUTH_AKA 1 + +struct mbim_auth_aka_q = { + struct mbim_byte_array rand; + struct mbim_byte_array autn; +} + +struct mbim_auth_aka_r = + struct mbim_byte_array res; + u32 reslen; + struct mbim_byte_array integratingkey; + struct mbim_byte_array cipheringkey; + struct mbim_byte_array auts; +} + +/* + * ID: 2 + * Command: Akap + */ + +#define MBIM_CMD_AUTH_AKAP 2 + +struct mbim_auth_akap_q = { + struct mbim_byte_array rand; + struct mbim_byte_array autn; + struct mbim_string networkname; +} + +struct mbim_auth_akap_r = + struct mbim_byte_array res; + u32 reslen; + struct mbim_byte_array integratingkey; + struct mbim_byte_array cipheringkey; + struct mbim_byte_array auts; +} + +/* + * ID: 3 + * Command: Sim + */ + +#define MBIM_CMD_AUTH_SIM 3 + +struct mbim_auth_sim_q = { + struct mbim_byte_array rand1; + struct mbim_byte_array rand2; + struct mbim_byte_array rand3; + u32 n; +} + +struct mbim_auth_sim_r = + u32 sres1; + u64 kc1; + u32 sres2; + u64 kc2; + u32 sres3; + u64 kc3; + u32 n; +} + diff --git a/data/mbim-service-auth.json b/data/mbim-service-auth.json new file mode 100644 index 0000000..b518e38 --- /dev/null +++ b/data/mbim-service-auth.json @@ -0,0 +1,89 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "Auth" }, + + // ********************************************************************************* + { "name" : "Aka", + "service" : "Auth", + "type" : "Command", + "query" : [ { "name" : "Rand", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "Autn", + "format" : "byte-array", + "array-size" : "16" } ], + "response" : [ { "name" : "Res", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "ResLen", + "format" : "guint32" }, + { "name" : "IntegratingKey", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "CipheringKey", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "Auts", + "format" : "byte-array", + "array-size" : "14" } ] }, + + // ********************************************************************************* + { "name" : "Akap", + "service" : "Auth", + "type" : "Command", + "query" : [ { "name" : "Rand", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "Autn", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "NetworkName", + "format" : "string" } ], + "response" : [ { "name" : "Res", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "ResLen", + "format" : "guint32" }, + { "name" : "IntegratingKey", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "CipheringKey", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "Auts", + "format" : "byte-array", + "array-size" : "14" } ] }, + + // ********************************************************************************* + { "name" : "Sim", + "service" : "Auth", + "type" : "Command", + "query" : [ { "name" : "Rand1", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "Rand2", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "Rand3", + "format" : "byte-array", + "array-size" : "16" }, + { "name" : "N", + "format" : "guint32" } ], + "response" : [ { "name" : "Sres1", + "format" : "guint32" }, + { "name" : "Kc1", + "format" : "guint64" }, + { "name" : "Sres2", + "format" : "guint32" }, + { "name" : "Kc2", + "format" : "guint64" }, + { "name" : "Sres3", + "format" : "guint32" }, + { "name" : "Kc3", + "format" : "guint64" }, + { "name" : "N", + "format" : "guint32" } ] } + +] diff --git a/data/mbim-service-basic-connect.h b/data/mbim-service-basic-connect.h new file mode 100644 index 0000000..7d6e542 --- /dev/null +++ b/data/mbim-service-basic-connect.h @@ -0,0 +1,704 @@ +/* + * ID: 1 + * Command: Device Caps + */ + +#define MBIM_CMD_BASIC_CONNECT_DEVICE_CAPS 1 + +struct mbim_basic_connect_device_caps_r { + /* enum MbimDeviceType */ + uint32_t devicetype; + /* enum MbimCellularClass */ + uint32_t cellularclass; + /* enum MbimVoiceClass */ + uint32_t voiceclass; + /* enum MbimSimClass */ + uint32_t simclass; + /* enum MbimDataClass */ + uint32_t dataclass; + /* enum MbimSmsCaps */ + uint32_t smscaps; + /* enum MbimCtrlCaps */ + uint32_t controlcaps; + uint32_t maxsessions; + struct mbim_string customdataclass; + struct mbim_string deviceid; + struct mbim_string firmwareinfo; + struct mbim_string hardwareinfo; +} __attribute__((packed)); + +/* + * ID: 2 + * Command: Subscriber Ready Status + */ + +#define MBIM_CMD_BASIC_CONNECT_SUBSCRIBER_READY_STATUS 2 + +struct mbim_basic_connect_subscriber_ready_status_r { + /* enum MbimSubscriberReadyState */ + uint32_t readystate; + struct mbim_string subscriberid; + struct mbim_string simiccid; + /* enum MbimReadyInfoFlag */ + uint32_t readyinfo; + uint32_t telephonenumberscount; + /* array type: string-array */ + uint32_t telephonenumbers; +} __attribute__((packed)); + +struct mbim_basic_connect_subscriber_ready_status_n { + /* enum MbimSubscriberReadyState */ + uint32_t readystate; + struct mbim_string subscriberid; + struct mbim_string simiccid; + /* enum MbimReadyInfoFlag */ + uint32_t readyinfo; + uint32_t telephonenumberscount; + /* array type: string-array */ + uint32_t telephonenumbers; +} __attribute__((packed)); + +/* + * ID: 3 + * Command: Radio State + */ + +#define MBIM_CMD_BASIC_CONNECT_RADIO_STATE 3 + +struct mbim_basic_connect_radio_state_r { + /* enum MbimRadioSwitchState */ + uint32_t hwradiostate; + /* enum MbimRadioSwitchState */ + uint32_t swradiostate; +} __attribute__((packed)); + +struct mbim_basic_connect_radio_state_s { + /* enum MbimRadioSwitchState */ + uint32_t radiostate; +} __attribute__((packed)); + +struct mbim_basic_connect_radio_state_n { + /* enum MbimRadioSwitchState */ + uint32_t hwradiostate; + /* enum MbimRadioSwitchState */ + uint32_t swradiostate; +} __attribute__((packed)); + +/* + * ID: 4 + * Command: Pin + */ + +#define MBIM_CMD_BASIC_CONNECT_PIN 4 + +struct mbim_basic_connect_pin_r { + /* enum MbimPinType */ + uint32_t pintype; + /* enum MbimPinState */ + uint32_t pinstate; + uint32_t remainingattempts; +} __attribute__((packed)); + +struct mbim_basic_connect_pin_s { + /* enum MbimPinType */ + uint32_t pintype; + /* enum MbimPinOperation */ + uint32_t pinoperation; + struct mbim_string pin; + struct mbim_string newpin; +} __attribute__((packed)); + +struct mbimpindesc { + /* enum MbimPinMode */ + uint32_t pinmode; + /* enum MbimPinFormat */ + uint32_t pinformat; + uint32_t pinlengthmin; + uint32_t pinlengthmax; +} __attribute__((packed)); + +/* + * ID: 5 + * Command: Pin List + */ + +#define MBIM_CMD_BASIC_CONNECT_PIN_LIST 5 + +struct mbim_basic_connect_pin_list_r { + struct mbimpindesc pindescpin1; + struct mbimpindesc pindescpin2; + struct mbimpindesc pindescdevicesimpin; + struct mbimpindesc pindescdevicefirstsimpin; + struct mbimpindesc pindescnetworkpin; + struct mbimpindesc pindescnetworksubsetpin; + struct mbimpindesc pindescserviceproviderpin; + struct mbimpindesc pindesccorporatepin; + struct mbimpindesc pindescsubsidylock; + struct mbimpindesc pindesccustom; +} __attribute__((packed)); + +struct mbimprovider { + struct mbim_string providerid; + /* enum MbimProviderState */ + uint32_t providerstate; + struct mbim_string providername; + /* enum MbimCellularClass */ + uint32_t cellularclass; + uint32_t rssi; + uint32_t errorrate; +} __attribute__((packed)); + +/* + * ID: 6 + * Command: Home Provider + */ + +#define MBIM_CMD_BASIC_CONNECT_HOME_PROVIDER 6 + +struct mbim_basic_connect_home_provider_r { + struct mbimprovider provider; +} __attribute__((packed)); + +struct mbim_basic_connect_home_provider_s { + struct mbimprovider provider; +} __attribute__((packed)); + +/* + * ID: 7 + * Command: Preferred Providers + */ + +#define MBIM_CMD_BASIC_CONNECT_PREFERRED_PROVIDERS 7 + +struct mbim_basic_connect_preferred_providers_r { + uint32_t providerscount; + /* array type: ref-struct-array */ + uint32_t providers; +} __attribute__((packed)); + +struct mbim_basic_connect_preferred_providers_s { + uint32_t providerscount; + /* array type: ref-struct-array */ + uint32_t providers; +} __attribute__((packed)); + +struct mbim_basic_connect_preferred_providers_n { + uint32_t providerscount; + /* array type: ref-struct-array */ + uint32_t providers; +} __attribute__((packed)); + +/* + * ID: 8 + * Command: Visible Providers + */ + +#define MBIM_CMD_BASIC_CONNECT_VISIBLE_PROVIDERS 8 + +struct mbim_basic_connect_visible_providers_q { + /* enum MbimVisibleProvidersAction */ + uint32_t action; +} __attribute__((packed)); + +struct mbim_basic_connect_visible_providers_r { + uint32_t providerscount; + /* array type: ref-struct-array */ + uint32_t providers; +} __attribute__((packed)); + +/* + * ID: 9 + * Command: Register State + */ + +#define MBIM_CMD_BASIC_CONNECT_REGISTER_STATE 9 + +struct mbim_basic_connect_register_state_r { + /* enum MbimNwError */ + uint32_t nwerror; + /* enum MbimRegisterState */ + uint32_t registerstate; + /* enum MbimRegisterMode */ + uint32_t registermode; + /* enum MbimDataClass */ + uint32_t availabledataclasses; + /* enum MbimCellularClass */ + uint32_t currentcellularclass; + struct mbim_string providerid; + struct mbim_string providername; + struct mbim_string roamingtext; + /* enum MbimRegistrationFlag */ + uint32_t registrationflag; +} __attribute__((packed)); + +struct mbim_basic_connect_register_state_s { + struct mbim_string providerid; + /* enum MbimRegisterAction */ + uint32_t registeraction; + /* enum MbimDataClass */ + uint32_t dataclass; +} __attribute__((packed)); + +struct mbim_basic_connect_register_state_n { + /* enum MbimNwError */ + uint32_t nwerror; + /* enum MbimRegisterState */ + uint32_t registerstate; + /* enum MbimRegisterMode */ + uint32_t registermode; + /* enum MbimDataClass */ + uint32_t availabledataclasses; + /* enum MbimCellularClass */ + uint32_t currentcellularclass; + struct mbim_string providerid; + struct mbim_string providername; + struct mbim_string roamingtext; + /* enum MbimRegistrationFlag */ + uint32_t registrationflag; +} __attribute__((packed)); + +/* + * ID: 10 + * Command: Packet Service + */ + +#define MBIM_CMD_BASIC_CONNECT_PACKET_SERVICE 10 + +struct mbim_basic_connect_packet_service_r { + uint32_t nwerror; + /* enum MbimPacketServiceState */ + uint32_t packetservicestate; + /* enum MbimDataClass */ + uint32_t highestavailabledataclass; + uint64_t uplinkspeed; + uint64_t downlinkspeed; +} __attribute__((packed)); + +struct mbim_basic_connect_packet_service_s { + /* enum MbimPacketServiceAction */ + uint32_t packetserviceaction; +} __attribute__((packed)); + +struct mbim_basic_connect_packet_service_n { + uint32_t nwerror; + /* enum MbimPacketServiceState */ + uint32_t packetservicestate; + /* enum MbimDataClass */ + uint32_t highestavailabledataclass; + uint64_t uplinkspeed; + uint64_t downlinkspeed; +} __attribute__((packed)); + +/* + * ID: 11 + * Command: Signal State + */ + +#define MBIM_CMD_BASIC_CONNECT_SIGNAL_STATE 11 + +struct mbim_basic_connect_signal_state_r { + uint32_t rssi; + uint32_t errorrate; + uint32_t signalstrengthinterval; + uint32_t rssithreshold; + uint32_t errorratethreshold; +} __attribute__((packed)); + +struct mbim_basic_connect_signal_state_s { + uint32_t signalstrengthinterval; + uint32_t rssithreshold; + uint32_t errorratethreshold; +} __attribute__((packed)); + +struct mbim_basic_connect_signal_state_n { + uint32_t rssi; + uint32_t errorrate; + uint32_t signalstrengthinterval; + uint32_t rssithreshold; + uint32_t errorratethreshold; +} __attribute__((packed)); + +/* + * ID: 12 + * Command: Connect + */ + +#define MBIM_CMD_BASIC_CONNECT_CONNECT 12 + +struct mbim_basic_connect_connect_q { + uint32_t sessionid; + /* enum MbimActivationState */ + uint32_t activationstate; + /* enum MbimVoiceCallState */ + uint32_t voicecallstate; + /* enum MbimContextIpType */ + uint32_t iptype; + uint8_t contexttype[16]; + uint32_t nwerror; +} __attribute__((packed)); + +struct mbim_basic_connect_connect_r { + uint32_t sessionid; + /* enum MbimActivationState */ + uint32_t activationstate; + /* enum MbimVoiceCallState */ + uint32_t voicecallstate; + /* enum MbimContextIpType */ + uint32_t iptype; + uint8_t contexttype[16]; + uint32_t nwerror; +} __attribute__((packed)); + +struct mbim_basic_connect_connect_s { + uint32_t sessionid; + /* enum MbimActivationCommand */ + uint32_t activationcommand; + struct mbim_string accessstring; + struct mbim_string username; + struct mbim_string password; + /* enum MbimCompression */ + uint32_t compression; + /* enum MbimAuthProtocol */ + uint32_t authprotocol; + /* enum MbimContextIpType */ + uint32_t iptype; + uint8_t contexttype[16]; +} __attribute__((packed)); + +struct mbim_basic_connect_connect_n { + uint32_t sessionid; + /* enum MbimActivationState */ + uint32_t activationstate; + /* enum MbimVoiceCallState */ + uint32_t voicecallstate; + /* enum MbimContextIpType */ + uint32_t iptype; + uint8_t contexttype[16]; + uint32_t nwerror; +} __attribute__((packed)); + +struct mbimprovisionedcontextelement { + uint32_t contextid; + uint8_t contexttype[16]; + struct mbim_string accessstring; + struct mbim_string username; + struct mbim_string password; + /* enum MbimCompression */ + uint32_t compression; + /* enum MbimAuthProtocol */ + uint32_t authprotocol; +} __attribute__((packed)); + +/* + * ID: 13 + * Command: Provisioned Contexts + */ + +#define MBIM_CMD_BASIC_CONNECT_PROVISIONED_CONTEXTS 13 + +struct mbim_basic_connect_provisioned_contexts_r { + uint32_t provisionedcontextscount; + /* array type: ref-struct-array */ + uint32_t provisionedcontexts; +} __attribute__((packed)); + +struct mbim_basic_connect_provisioned_contexts_s { + uint32_t contextid; + uint8_t contexttype[16]; + struct mbim_string accessstring; + struct mbim_string username; + struct mbim_string password; + /* enum MbimCompression */ + uint32_t compression; + /* enum MbimAuthProtocol */ + uint32_t authprotocol; + struct mbim_string providerid; +} __attribute__((packed)); + +struct mbim_basic_connect_provisioned_contexts_n { + uint32_t provisionedcontextscount; + /* array type: ref-struct-array */ + uint32_t provisionedcontexts; +} __attribute__((packed)); + +/* + * ID: 14 + * Command: Service Activation + */ + +#define MBIM_CMD_BASIC_CONNECT_SERVICE_ACTIVATION 14 + +struct mbim_basic_connect_service_activation_r { + /* enum MbimNwError */ + uint32_t nwerror; + /* array type: unsized-byte-array */ + uint32_t buffer; +} __attribute__((packed)); + +struct mbim_basic_connect_service_activation_s { + /* array type: unsized-byte-array */ + uint32_t buffer; +} __attribute__((packed)); + +struct mbimipv4element { + uint32_t onlinkprefixlength; + uint8_t ipv4address[4]; +} __attribute__((packed)); + +struct mbimipv6element { + uint32_t onlinkprefixlength; + uint8_t ipv6address[16]; +} __attribute__((packed)); + +/* + * ID: 15 + * Command: IP Configuration + */ + +#define MBIM_CMD_BASIC_CONNECT_IP_CONFIGURATION 15 + +struct mbim_basic_connect_ip_configuration_q { + uint32_t sessionid; + /* enum MbimIPConfigurationAvailableFlag */ + uint32_t ipv4configurationavailable; + /* enum MbimIPConfigurationAvailableFlag */ + uint32_t ipv6configurationavailable; + uint32_t ipv4addresscount; + /* struct mbimipv4element */ + uint32_t ipv4address; + uint32_t ipv6addresscount; + /* struct mbimipv6element */ + uint32_t ipv6address; + /* array type: ref-ipv4 */ + uint32_t ipv4gateway; + /* array type: ref-ipv6 */ + uint32_t ipv6gateway; + uint32_t ipv4dnsservercount; + /* array type: ipv4-array */ + uint32_t ipv4dnsserver; + uint32_t ipv6dnsservercount; + /* array type: ipv6-array */ + uint32_t ipv6dnsserver; + uint32_t ipv4mtu; + uint32_t ipv6mtu; +} __attribute__((packed)); + +struct mbim_basic_connect_ip_configuration_r { + uint32_t sessionid; + /* enum MbimIPConfigurationAvailableFlag */ + uint32_t ipv4configurationavailable; + /* enum MbimIPConfigurationAvailableFlag */ + uint32_t ipv6configurationavailable; + uint32_t ipv4addresscount; + /* struct mbimipv4element */ + uint32_t ipv4address; + uint32_t ipv6addresscount; + /* struct mbimipv6element */ + uint32_t ipv6address; + /* array type: ref-ipv4 */ + uint32_t ipv4gateway; + /* array type: ref-ipv6 */ + uint32_t ipv6gateway; + uint32_t ipv4dnsservercount; + /* array type: ipv4-array */ + uint32_t ipv4dnsserver; + uint32_t ipv6dnsservercount; + /* array type: ipv6-array */ + uint32_t ipv6dnsserver; + uint32_t ipv4mtu; + uint32_t ipv6mtu; +} __attribute__((packed)); + +struct mbim_basic_connect_ip_configuration_n { + uint32_t sessionid; + /* enum MbimIPConfigurationAvailableFlag */ + uint32_t ipv4configurationavailable; + /* enum MbimIPConfigurationAvailableFlag */ + uint32_t ipv6configurationavailable; + uint32_t ipv4addresscount; + /* struct mbimipv4element */ + uint32_t ipv4address; + uint32_t ipv6addresscount; + /* struct mbimipv6element */ + uint32_t ipv6address; + /* array type: ref-ipv4 */ + uint32_t ipv4gateway; + /* array type: ref-ipv6 */ + uint32_t ipv6gateway; + uint32_t ipv4dnsservercount; + /* array type: ipv4-array */ + uint32_t ipv4dnsserver; + uint32_t ipv6dnsservercount; + /* array type: ipv6-array */ + uint32_t ipv6dnsserver; + uint32_t ipv4mtu; + uint32_t ipv6mtu; +} __attribute__((packed)); + +struct mbimdeviceserviceelement { + uint8_t deviceserviceid[16]; + uint32_t dsspayload; + uint32_t maxdssinstances; + uint32_t cidscount; + /* array type: guint32-array */ + uint32_t cids; +} __attribute__((packed)); + +/* + * ID: 16 + * Command: Device Services + */ + +#define MBIM_CMD_BASIC_CONNECT_DEVICE_SERVICES 16 + +struct mbim_basic_connect_device_services_r { + uint32_t deviceservicescount; + uint32_t maxdsssessions; + /* array type: ref-struct-array */ + uint32_t deviceservices; +} __attribute__((packed)); + +struct mbimevententry { + uint8_t deviceserviceid[16]; + uint32_t cidscount; + /* array type: guint32-array */ + uint32_t cids; +} __attribute__((packed)); + +/* + * ID: 19 + * Command: Device Service Subscribe List + */ + +#define MBIM_CMD_BASIC_CONNECT_DEVICE_SERVICE_SUBSCRIBE_LIST 19 + +struct mbim_basic_connect_device_service_subscribe_list_r { + uint32_t eventscount; + /* array type: ref-struct-array */ + uint32_t events; +} __attribute__((packed)); + +struct mbim_basic_connect_device_service_subscribe_list_s { + uint32_t eventscount; + /* array type: ref-struct-array */ + uint32_t events; +} __attribute__((packed)); + +/* + * ID: 20 + * Command: Packet Statistics + */ + +#define MBIM_CMD_BASIC_CONNECT_PACKET_STATISTICS 20 + +struct mbim_basic_connect_packet_statistics_r { + uint32_t indiscards; + uint32_t inerrors; + uint64_t inoctets; + uint64_t inpackets; + uint64_t outoctets; + uint64_t outpackets; + uint32_t outerrors; + uint32_t outdiscards; +} __attribute__((packed)); + +/* + * ID: 21 + * Command: Network Idle Hint + */ + +#define MBIM_CMD_BASIC_CONNECT_NETWORK_IDLE_HINT 21 + +struct mbim_basic_connect_network_idle_hint_r { + /* enum MbimNetworkIdleHintState */ + uint32_t state; +} __attribute__((packed)); + +struct mbim_basic_connect_network_idle_hint_s { + /* enum MbimNetworkIdleHintState */ + uint32_t state; +} __attribute__((packed)); + +/* + * ID: 22 + * Command: Emergency Mode + */ + +#define MBIM_CMD_BASIC_CONNECT_EMERGENCY_MODE 22 + +struct mbim_basic_connect_emergency_mode_r { + /* enum MbimEmergencyModeState */ + uint32_t state; +} __attribute__((packed)); + +struct mbim_basic_connect_emergency_mode_s { + /* enum MbimEmergencyModeState */ + uint32_t state; +} __attribute__((packed)); + +struct mbim_basic_connect_emergency_mode_n { + /* enum MbimEmergencyModeState */ + uint32_t state; +} __attribute__((packed)); + +struct mbimpacketfilter { + uint32_t filtersize; + /* array type: ref-byte-array */ + uint32_t packetfilter; + /* array type: ref-byte-array */ + uint32_t packetmask; +} __attribute__((packed)); + +/* + * ID: 23 + * Command: IP Packet Filters + */ + +#define MBIM_CMD_BASIC_CONNECT_IP_PACKET_FILTERS 23 + +struct mbim_basic_connect_ip_packet_filters_q { + uint32_t sessionid; + uint32_t packetfilterscount; + /* array type: ref-struct-array */ + uint32_t packetfilters; +} __attribute__((packed)); + +struct mbim_basic_connect_ip_packet_filters_r { + uint32_t sessionid; + uint32_t packetfilterscount; + /* array type: ref-struct-array */ + uint32_t packetfilters; +} __attribute__((packed)); + +struct mbim_basic_connect_ip_packet_filters_s { + uint32_t sessionid; + uint32_t packetfilterscount; + /* array type: ref-struct-array */ + uint32_t packetfilters; +} __attribute__((packed)); + +/* + * ID: 24 + * Command: Multicarrier Providers + */ + +#define MBIM_CMD_BASIC_CONNECT_MULTICARRIER_PROVIDERS 24 + +struct mbim_basic_connect_multicarrier_providers_r { + uint32_t providerscount; + /* array type: ref-struct-array */ + uint32_t providers; +} __attribute__((packed)); + +struct mbim_basic_connect_multicarrier_providers_s { + uint32_t providerscount; + /* array type: ref-struct-array */ + uint32_t providers; +} __attribute__((packed)); + +struct mbim_basic_connect_multicarrier_providers_n { + uint32_t providerscount; + /* array type: ref-struct-array */ + uint32_t providers; +} __attribute__((packed)); + diff --git a/data/mbim-service-basic-connect.json b/data/mbim-service-basic-connect.json new file mode 100644 index 0000000..88d878c --- /dev/null +++ b/data/mbim-service-basic-connect.json @@ -0,0 +1,814 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "Basic Connect" }, + + // ********************************************************************************* + { "name" : "Device Caps", + "service" : "Basic Connect", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "DeviceType", + "format" : "guint32", + "public-format" : "MbimDeviceType" }, + { "name" : "CellularClass", + "format" : "guint32", + "public-format" : "MbimCellularClass" }, + { "name" : "VoiceClass", + "format" : "guint32", + "public-format" : "MbimVoiceClass" }, + { "name" : "SimClass", + "format" : "guint32", + "public-format" : "MbimSimClass" }, + { "name" : "DataClass", + "format" : "guint32", + "public-format" : "MbimDataClass" }, + { "name" : "SmsCaps", + "format" : "guint32", + "public-format" : "MbimSmsCaps" }, + { "name" : "ControlCaps", + "format" : "guint32", + "public-format" : "MbimCtrlCaps" }, + { "name" : "MaxSessions", + "format" : "guint32" }, + { "name" : "CustomDataClass", + "format" : "string", + "max-size" : "22" }, + { "name" : "DeviceId", + "format" : "string", + "max-size" : "36" }, + { "name" : "FirmwareInfo", + "format" : "string", + "max-size" : "60" }, + { "name" : "HardwareInfo", + "format" : "string", + "max-size" : "60" } ] }, + + // ********************************************************************************* + { "name" : "Subscriber Ready Status", + "service" : "Basic Connect", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "ReadyState", + "format" : "guint32", + "public-format" : "MbimSubscriberReadyState" }, + { "name" : "SubscriberId", + "format" : "string" }, + { "name" : "SimIccId", + "format" : "string" }, + { "name" : "ReadyInfo", + "format" : "guint32", + "public-format" : "MbimReadyInfoFlag" }, + { "name" : "TelephoneNumbersCount", + "format" : "guint32" }, + { "name" : "TelephoneNumbers", + "format" : "string-array", + "array-size-field" : "TelephoneNumbersCount" } ], + "notification" : [ { "name" : "ReadyState", + "format" : "guint32", + "public-format" : "MbimSubscriberReadyState" }, + { "name" : "SubscriberId", + "format" : "string" }, + { "name" : "SimIccId", + "format" : "string" }, + { "name" : "ReadyInfo", + "format" : "guint32", + "public-format" : "MbimReadyInfoFlag" }, + { "name" : "TelephoneNumbersCount", + "format" : "guint32" }, + { "name" : "TelephoneNumbers", + "format" : "string-array", + "array-size-field" : "TelephoneNumbersCount" } ] }, + + // ********************************************************************************* + { "name" : "Radio State", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "RadioState", + "format" : "guint32", + "public-format" : "MbimRadioSwitchState" } ], + "query" : [], + "response" : [ { "name" : "HwRadioState", + "format" : "guint32", + "public-format" : "MbimRadioSwitchState" }, + { "name" : "SwRadioState", + "format" : "guint32", + "public-format" : "MbimRadioSwitchState" } ], + "notification" : [ { "name" : "HwRadioState", + "format" : "guint32", + "public-format" : "MbimRadioSwitchState" }, + { "name" : "SwRadioState", + "format" : "guint32", + "public-format" : "MbimRadioSwitchState" } ] }, + + // ********************************************************************************* + { "name" : "Pin", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "PinType", + "format" : "guint32", + "public-format" : "MbimPinType" }, + { "name" : "PinOperation", + "format" : "guint32", + "public-format" : "MbimPinOperation" }, + { "name" : "Pin", + "format" : "string" }, + { "name" : "NewPin", + "format" : "string" } ], + "query" : [], + "response" : [ { "name" : "PinType", + "format" : "guint32", + "public-format" : "MbimPinType" }, + { "name" : "PinState", + "format" : "guint32", + "public-format" : "MbimPinState" }, + { "name" : "RemainingAttempts", + "format" : "guint32" } ] }, + + // ********************************************************************************* + { "name" : "MbimPinDesc", + "type" : "Struct", + "contents" : [ { "name" : "PinMode", + "format" : "guint32", + "public-format" : "MbimPinMode" }, + { "name" : "PinFormat", + "format" : "guint32", + "public-format" : "MbimPinFormat" }, + { "name" : "PinLengthMin", + "format" : "guint32" }, + { "name" : "PinLengthMax", + "format" : "guint32" } ] }, + + { "name" : "Pin List", + "service" : "Basic Connect", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "PinDescPin1", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescPin2", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescDeviceSimPin", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescDeviceFirstSimPin", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescNetworkPin", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescNetworkSubsetPin", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescServiceProviderPin", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescCorporatePin", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescSubsidyLock", + "format" : "struct", + "struct-type" : "MbimPinDesc" }, + { "name" : "PinDescCustom", + "format" : "struct", + "struct-type" : "MbimPinDesc" } ] }, + + // ********************************************************************************* + { "name" : "MbimProvider", + "type" : "Struct", + "contents" : [ { "name" : "ProviderId", + "format" : "string" }, + { "name" : "ProviderState", + "format" : "guint32", + "public-format" : "MbimProviderState" }, + { "name" : "ProviderName", + "format" : "string" }, + { "name" : "CellularClass", + "format" : "guint32", + "public-format" : "MbimCellularClass" }, + { "name" : "Rssi", + "format" : "guint32" }, + { "name" : "ErrorRate", + "format" : "guint32" } ] }, + + { "name" : "Home Provider", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "Provider", + "format" : "struct" , + "struct-type" : "MbimProvider" } ], + "query" : [], + "response" : [ { "name" : "Provider", + "format" : "struct", + "struct-type" : "MbimProvider" } ] }, + + // ********************************************************************************* + { "name" : "Preferred Providers", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "ProvidersCount", + "format" : "guint32" }, + { "name" : "Providers", + "format" : "ref-struct-array" , + "struct-type" : "MbimProvider", + "array-size-field" : "ProvidersCount" } ], + "query" : [], + "response" : [ { "name" : "ProvidersCount", + "format" : "guint32" }, + { "name" : "Providers", + "format" : "ref-struct-array" , + "struct-type" : "MbimProvider", + "array-size-field" : "ProvidersCount" } ], + "notification" : [ { "name" : "ProvidersCount", + "format" : "guint32" }, + { "name" : "Providers", + "format" : "ref-struct-array" , + "struct-type" : "MbimProvider", + "array-size-field" : "ProvidersCount" } ] }, + + // ********************************************************************************* + { "name" : "Visible Providers", + "service" : "Basic Connect", + "type" : "Command", + "query" : [ { "name" : "Action", + "format": "guint32", + "public-format" : "MbimVisibleProvidersAction" } ], + "response" : [ { "name" : "ProvidersCount", + "format" : "guint32" }, + { "name" : "Providers", + "format" : "ref-struct-array" , + "struct-type" : "MbimProvider", + "array-size-field" : "ProvidersCount" } ] }, + + // ********************************************************************************* + { "name" : "Register State", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "ProviderId", + "format" : "string" }, + { "name" : "RegisterAction", + "format" : "guint32", + "public-format" : "MbimRegisterAction" }, + { "name" : "DataClass", + "format" : "guint32", + "public-format" : "MbimDataClass" } ], + "query" : [], + "response" : [ { "name" : "NwError", + "format" : "guint32", + "public-format" : "MbimNwError" }, + { "name" : "RegisterState", + "format" : "guint32", + "public-format" : "MbimRegisterState" }, + { "name" : "RegisterMode", + "format" : "guint32", + "public-format" : "MbimRegisterMode" }, + { "name" : "AvailableDataClasses", + "format" : "guint32", + "public-format" : "MbimDataClass" }, + { "name" : "CurrentCellularClass", + "format" : "guint32", + "public-format" : "MbimCellularClass" }, + { "name" : "ProviderId", + "format" : "string" }, + { "name" : "ProviderName", + "format" : "string" }, + { "name" : "RoamingText", + "format" : "string" }, + { "name" : "RegistrationFlag", + "format" : "guint32", + "public-format" : "MbimRegistrationFlag" } ], + "notification" : [ { "name" : "NwError", + "format" : "guint32", + "public-format" : "MbimNwError" }, + { "name" : "RegisterState", + "format" : "guint32", + "public-format" : "MbimRegisterState" }, + { "name" : "RegisterMode", + "format" : "guint32", + "public-format" : "MbimRegisterMode" }, + { "name" : "AvailableDataClasses", + "format" : "guint32", + "public-format" : "MbimDataClass" }, + { "name" : "CurrentCellularClass", + "format" : "guint32", + "public-format" : "MbimCellularClass" }, + { "name" : "ProviderId", + "format" : "string" }, + { "name" : "ProviderName", + "format" : "string" }, + { "name" : "RoamingText", + "format" : "string" }, + { "name" : "RegistrationFlag", + "format" : "guint32", + "public-format" : "MbimRegistrationFlag" } ] }, + + // ********************************************************************************* + { "name" : "Signal State", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "SignalStrengthInterval", + "format" : "guint32" }, + { "name" : "RssiThreshold", + "format" : "guint32" }, + { "name" : "ErrorRateThreshold", + "format" : "guint32" } ], + "query" : [], + "response" : [ { "name" : "Rssi", + "format" : "guint32" }, + { "name" : "ErrorRate", + "format" : "guint32" }, + { "name" : "SignalStrengthInterval", + "format" : "guint32" }, + { "name" : "RssiThreshold", + "format" : "guint32" }, + { "name" : "ErrorRateThreshold", + "format" : "guint32" } ], + "notification" : [ { "name" : "Rssi", + "format" : "guint32" }, + { "name" : "ErrorRate", + "format" : "guint32" }, + { "name" : "SignalStrengthInterval", + "format" : "guint32" }, + { "name" : "RssiThreshold", + "format" : "guint32" }, + { "name" : "ErrorRateThreshold", + "format" : "guint32" } ] }, + + + // ********************************************************************************* + { "name" : "Packet Service", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "PacketServiceAction", + "format" : "guint32", + "public-format" : "MbimPacketServiceAction" } ], + "query" : [], + "response" : [ { "name" : "NwError", + "format" : "guint32" }, + { "name" : "PacketServiceState", + "format" : "guint32", + "public-format" : "MbimPacketServiceState" }, + { "name" : "HighestAvailableDataClass", + "format" : "guint32", + "public-format" : "MbimDataClass" }, + { "name" : "UplinkSpeed", + "format" : "guint64" }, + { "name" : "DownlinkSpeed", + "format" : "guint64" } ], + "notification" : [ { "name" : "NwError", + "format" : "guint32" }, + { "name" : "PacketServiceState", + "format" : "guint32", + "public-format" : "MbimPacketServiceState" }, + { "name" : "HighestAvailableDataClass", + "format" : "guint32", + "public-format" : "MbimDataClass" }, + { "name" : "UplinkSpeed", + "format" : "guint64" }, + { "name" : "DownlinkSpeed", + "format" : "guint64" } ] }, + + // ********************************************************************************* + { "name" : "Connect", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "ActivationCommand", + "format" : "guint32", + "public-format" : "MbimActivationCommand" }, + { "name" : "AccessString", + "format" : "string" }, + { "name" : "UserName", + "format" : "string" }, + { "name" : "Password", + "format" : "string" }, + { "name" : "Compression", + "format" : "guint32", + "public-format" : "MbimCompression" }, + { "name" : "AuthProtocol", + "format" : "guint32", + "public-format" : "MbimAuthProtocol" }, + { "name" : "IpType", + "format" : "guint32", + "public-format" : "MbimContextIpType" }, + { "name" : "ContextType", + "format" : "uuid" } ], + "query" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "ActivationState", + "format" : "guint32", + "public-format" : "MbimActivationState" }, + { "name" : "VoiceCallState", + "format" : "guint32", + "public-format" : "MbimVoiceCallState" }, + { "name" : "IpType", + "format" : "guint32", + "public-format" : "MbimContextIpType" }, + { "name" : "ContextType", + "format" : "uuid" }, + { "name" : "NwError", + "format" : "guint32" } ], + "response" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "ActivationState", + "format" : "guint32", + "public-format" : "MbimActivationState" }, + { "name" : "VoiceCallState", + "format" : "guint32", + "public-format" : "MbimVoiceCallState" }, + { "name" : "IpType", + "format" : "guint32", + "public-format" : "MbimContextIpType" }, + { "name" : "ContextType", + "format" : "uuid" }, + { "name" : "NwError", + "format" : "guint32" } ], + "notification" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "ActivationState", + "format" : "guint32", + "public-format" : "MbimActivationState" }, + { "name" : "VoiceCallState", + "format" : "guint32", + "public-format" : "MbimVoiceCallState" }, + { "name" : "IpType", + "format" : "guint32", + "public-format" : "MbimContextIpType" }, + { "name" : "ContextType", + "format" : "uuid" }, + { "name" : "NwError", + "format" : "guint32" } ] }, + + // ********************************************************************************* + { "name" : "MbimProvisionedContextElement", + "type" : "Struct", + "contents" : [ { "name" : "ContextId", + "format" : "guint32" }, + { "name" : "ContextType", + "format" : "uuid" }, + { "name" : "AccessString", + "format" : "string" }, + { "name" : "UserName", + "format" : "string" }, + { "name" : "Password", + "format" : "string" }, + { "name" : "Compression", + "format" : "guint32", + "public-format" : "MbimCompression" }, + { "name" : "AuthProtocol", + "format" : "guint32", + "public-format" : "MbimAuthProtocol" } ] }, + + { "name" : "Provisioned Contexts", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "ContextId", + "format" : "guint32" }, + { "name" : "ContextType", + "format" : "uuid" }, + { "name" : "AccessString", + "format" : "string" }, + { "name" : "UserName", + "format" : "string" }, + { "name" : "Password", + "format" : "string" }, + { "name" : "Compression", + "format" : "guint32", + "public-format" : "MbimCompression" }, + { "name" : "AuthProtocol", + "format" : "guint32", + "public-format" : "MbimAuthProtocol" }, + { "name" : "ProviderId", + "format" : "string" } ], + "query" : [], + "response" : [ { "name" : "ProvisionedContextsCount", + "format" : "guint32" }, + { "name" : "ProvisionedContexts", + "format" : "ref-struct-array", + "struct-type" : "MbimProvisionedContextElement", + "array-size-field" : "ProvisionedContextsCount" } ], + "notification" : [ { "name" : "ProvisionedContextsCount", + "format" : "guint32" }, + { "name" : "ProvisionedContexts", + "format" : "ref-struct-array", + "struct-type" : "MbimProvisionedContextElement", + "array-size-field" : "ProvisionedContextsCount" } ] }, + + // ********************************************************************************* + + { "name" : "Service Activation", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "Buffer", + "format" : "unsized-byte-array" } ], + "response" : [ { "name" : "NwError", + "format" : "guint32", + "public-format" : "MbimNwError" }, + { "name" : "Buffer", + "format" : "unsized-byte-array" } ] }, + + // ********************************************************************************* + { "name" : "MbimIPv4Element", + "type" : "Struct", + "contents" : [ { "name" : "OnLinkPrefixLength", + "format" : "guint32" }, + { "name" : "IPv4Address", + "format" : "ipv4" } ] }, + + { "name" : "MbimIPv6Element", + "type" : "Struct", + "contents" : [ { "name" : "OnLinkPrefixLength", + "format" : "guint32" }, + { "name" : "IPv6Address", + "format" : "ipv6" } ] }, + + { "name" : "IP Configuration", + "service" : "Basic Connect", + "type" : "Command", + "query" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "IPv4ConfigurationAvailable", + "format" : "guint32", + "public-format" : "MbimIPConfigurationAvailableFlag" }, + { "name" : "IPv6ConfigurationAvailable", + "format" : "guint32", + "public-format" : "MbimIPConfigurationAvailableFlag" }, + { "name" : "IPv4AddressCount", + "format" : "guint32" }, + { "name" : "IPv4Address", + "format" : "struct-array", + "struct-type" : "MbimIPv4Element", + "array-size-field" : "IPv4AddressCount" }, + { "name" : "IPv6AddressCount", + "format" : "guint32" }, + { "name" : "IPv6Address", + "format" : "struct-array", + "struct-type" : "MbimIPv6Element", + "array-size-field" : "IPv6AddressCount" }, + { "name" : "IPv4Gateway", + "format" : "ref-ipv4" }, + { "name" : "IPv6Gateway", + "format" : "ref-ipv6" }, + { "name" : "IPv4DnsServerCount", + "format" : "guint32" }, + { "name" : "IPv4DnsServer", + "format" : "ipv4-array", + "array-size-field" : "IPv4DnsServerCount" }, + { "name" : "IPv6DnsServerCount", + "format" : "guint32" }, + { "name" : "IPv6DnsServer", + "format" : "ipv6-array", + "array-size-field" : "IPv6DnsServerCount" }, + { "name" : "IPv4Mtu", + "format" : "guint32" }, + { "name" : "IPv6Mtu", + "format" : "guint32" } ], + "response" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "IPv4ConfigurationAvailable", + "format" : "guint32", + "public-format" : "MbimIPConfigurationAvailableFlag" }, + { "name" : "IPv6ConfigurationAvailable", + "format" : "guint32", + "public-format" : "MbimIPConfigurationAvailableFlag" }, + { "name" : "IPv4AddressCount", + "format" : "guint32" }, + { "name" : "IPv4Address", + "format" : "struct-array", + "struct-type" : "MbimIPv4Element", + "array-size-field" : "IPv4AddressCount" }, + { "name" : "IPv6AddressCount", + "format" : "guint32" }, + { "name" : "IPv6Address", + "format" : "struct-array", + "struct-type" : "MbimIPv6Element", + "array-size-field" : "IPv6AddressCount" }, + { "name" : "IPv4Gateway", + "format" : "ref-ipv4" }, + { "name" : "IPv6Gateway", + "format" : "ref-ipv6" }, + { "name" : "IPv4DnsServerCount", + "format" : "guint32" }, + { "name" : "IPv4DnsServer", + "format" : "ipv4-array", + "array-size-field" : "IPv4DnsServerCount" }, + { "name" : "IPv6DnsServerCount", + "format" : "guint32" }, + { "name" : "IPv6DnsServer", + "format" : "ipv6-array", + "array-size-field" : "IPv6DnsServerCount" }, + { "name" : "IPv4Mtu", + "format" : "guint32" }, + { "name" : "IPv6Mtu", + "format" : "guint32" } ], + "notification" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "IPv4ConfigurationAvailable", + "format" : "guint32", + "public-format" : "MbimIPConfigurationAvailableFlag" }, + { "name" : "IPv6ConfigurationAvailable", + "format" : "guint32", + "public-format" : "MbimIPConfigurationAvailableFlag" }, + { "name" : "IPv4AddressCount", + "format" : "guint32" }, + { "name" : "IPv4Address", + "format" : "struct-array", + "struct-type" : "MbimIPv4Element", + "array-size-field" : "IPv4AddressCount" }, + { "name" : "IPv6AddressCount", + "format" : "guint32" }, + { "name" : "IPv6Address", + "format" : "struct-array", + "struct-type" : "MbimIPv6Element", + "array-size-field" : "IPv6AddressCount" }, + { "name" : "IPv4Gateway", + "format" : "ref-ipv4" }, + { "name" : "IPv6Gateway", + "format" : "ref-ipv6" }, + { "name" : "IPv4DnsServerCount", + "format" : "guint32" }, + { "name" : "IPv4DnsServer", + "format" : "ipv4-array", + "array-size-field" : "IPv4DnsServerCount" }, + { "name" : "IPv6DnsServerCount", + "format" : "guint32" }, + { "name" : "IPv6DnsServer", + "format" : "ipv6-array", + "array-size-field" : "IPv6DnsServerCount" }, + { "name" : "IPv4Mtu", + "format" : "guint32" }, + { "name" : "IPv6Mtu", + "format" : "guint32" } ] }, + + // ********************************************************************************* + { "name" : "MbimDeviceServiceElement", + "type" : "Struct", + "contents" : [ { "name" : "DeviceServiceId", + "format" : "uuid" }, + { "name" : "DssPayload", + "format" : "guint32" }, + { "name" : "MaxDssInstances", + "format" : "guint32" }, + { "name" : "CidsCount", + "format" : "guint32" }, + { "name" : "Cids", + "format" : "guint32-array", + "array-size-field" : "CidsCount" } ] }, + + { "name" : "Device Services", + "service" : "Basic Connect", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "DeviceServicesCount", + "format" : "guint32" }, + { "name" : "MaxDssSessions", + "format" : "guint32" }, + { "name" : "DeviceServices", + "format" : "ref-struct-array", + "struct-type" : "MbimDeviceServiceElement", + "array-size-field" : "DeviceServicesCount" } ] }, + + // ********************************************************************************* + { "name" : "MbimEventEntry", + "type" : "Struct", + "contents" : [ { "name" : "DeviceServiceId", + "format" : "uuid" }, + { "name" : "CidsCount", + "format" : "guint32" }, + { "name" : "Cids", + "format" : "guint32-array", + "array-size-field" : "CidsCount" } ] }, + + { "name" : "Device Service Subscribe List", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "EventsCount", + "format" : "guint32" }, + { "name" : "Events", + "format" : "ref-struct-array", + "struct-type" : "MbimEventEntry", + "array-size-field" : "EventsCount" } ], + "response" : [ { "name" : "EventsCount", + "format" : "guint32" }, + { "name" : "Events", + "format" : "ref-struct-array", + "struct-type" : "MbimEventEntry", + "array-size-field" : "EventsCount" } ] }, + + // ********************************************************************************* + { "name" : "Packet Statistics", + "service" : "Basic Connect", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "InDiscards", + "format" : "guint32" }, + { "name" : "InErrors", + "format" : "guint32" }, + { "name" : "InOctets", + "format" : "guint64" }, + { "name" : "InPackets", + "format" : "guint64" }, + { "name" : "OutOctets", + "format" : "guint64" }, + { "name" : "OutPackets", + "format" : "guint64" }, + { "name" : "OutErrors", + "format" : "guint32" }, + { "name" : "OutDiscards", + "format" : "guint32" } ] }, + + // ********************************************************************************* + { "name" : "Network Idle Hint", + "service" : "Basic Connect", + "type" : "Command", + "query" : [], + "set" : [ { "name" : "State", + "format" : "guint32", + "public-format" : "MbimNetworkIdleHintState" } ], + "response" : [ { "name" : "State", + "format" : "guint32", + "public-format" : "MbimNetworkIdleHintState" } ] }, + + // ********************************************************************************* + { "name" : "Emergency Mode", + "service" : "Basic Connect", + "type" : "Command", + "query" : [], + "set" : [ { "name" : "State", + "format" : "guint32", + "public-format" : "MbimEmergencyModeState" } ], + "response" : [ { "name" : "State", + "format" : "guint32", + "public-format" : "MbimEmergencyModeState" } ], + "notification" : [ { "name" : "State", + "format" : "guint32", + "public-format" : "MbimEmergencyModeState" } ] }, + + // ********************************************************************************* + { "name" : "MbimPacketFilter", + "type" : "Struct", + "contents" : [ { "name" : "FilterSize", + "format" : "guint32" }, + { "name" : "PacketFilter", + "format" : "ref-byte-array", + "array-size-field" : "FilterSize" }, + { "name" : "PacketMask", + "format" : "ref-byte-array", + "array-size-field" : "FilterSize" } ] }, + + { "name" : "IP Packet Filters", + "service" : "Basic Connect", + "type" : "Command", + "query" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "PacketFiltersCount", + "format" : "guint32" }, + { "name" : "PacketFilters", + "format" : "ref-struct-array", + "struct-type" : "MbimPacketFilter", + "array-size-field" : "PacketFiltersCount" } ], + "set" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "PacketFiltersCount", + "format" : "guint32" }, + { "name" : "PacketFilters", + "format" : "ref-struct-array", + "struct-type" : "MbimPacketFilter", + "array-size-field" : "PacketFiltersCount" } ], + "response" : [ { "name" : "SessionId", + "format" : "guint32" }, + { "name" : "PacketFiltersCount", + "format" : "guint32" }, + { "name" : "PacketFilters", + "format" : "ref-struct-array", + "struct-type" : "MbimPacketFilter", + "array-size-field" : "PacketFiltersCount" } ] }, + + // ********************************************************************************* + { "name" : "Multicarrier Providers", + "service" : "Basic Connect", + "type" : "Command", + "set" : [ { "name" : "ProvidersCount", + "format" : "guint32" }, + { "name" : "Providers", + "format" : "ref-struct-array" , + "struct-type" : "MbimProvider", + "array-size-field" : "ProvidersCount" } ], + "query" : [], + "response" : [ { "name" : "ProvidersCount", + "format" : "guint32" }, + { "name" : "Providers", + "format" : "ref-struct-array" , + "struct-type" : "MbimProvider", + "array-size-field" : "ProvidersCount" } ], + "notification" : [ { "name" : "ProvidersCount", + "format" : "guint32" }, + { "name" : "Providers", + "format" : "ref-struct-array" , + "struct-type" : "MbimProvider", + "array-size-field" : "ProvidersCount" } ] } + +] diff --git a/data/mbim-service-dss.h b/data/mbim-service-dss.h new file mode 100644 index 0000000..975b9c0 --- /dev/null +++ b/data/mbim-service-dss.h @@ -0,0 +1,7 @@ +/* + * ID: 1 + * Command: Connect + */ + +#define MBIM_CMD_DSS_CONNECT 1 + diff --git a/data/mbim-service-dss.json b/data/mbim-service-dss.json new file mode 100644 index 0000000..6beb300 --- /dev/null +++ b/data/mbim-service-dss.json @@ -0,0 +1,20 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "DSS" }, + + // ********************************************************************************* + { "name" : "Connect", + "service" : "DSS", + "type" : "Command", + "set" : [ { "name" : "DeviceServiceId", + "format" : "uuid" }, + { "name" : "DssSessionId", + "format" : "guint32" }, + { "name" : "DssLinkState", + "format" : "guint32", + "public-format" : "MbimDssLinkState" } ], + "response" : [] } + +] diff --git a/data/mbim-service-ms-firmware-id.h b/data/mbim-service-ms-firmware-id.h new file mode 100644 index 0000000..546c995 --- /dev/null +++ b/data/mbim-service-ms-firmware-id.h @@ -0,0 +1,11 @@ +/* + * ID: 1 + * Command: Get + */ + +#define MBIM_CMD_MS_FIRMWARE_ID_GET 1 + +struct mbim_ms_firmware_id_get_r = + struct mbim_uuid firmwareid; +} + diff --git a/data/mbim-service-ms-firmware-id.json b/data/mbim-service-ms-firmware-id.json new file mode 100644 index 0000000..aae7475 --- /dev/null +++ b/data/mbim-service-ms-firmware-id.json @@ -0,0 +1,13 @@ +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "MS Firmware ID" }, + + // ********************************************************************************* + { "name" : "Get", + "service" : "MS Firmware ID", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "FirmwareId", + "format" : "uuid" } ] } +] diff --git a/data/mbim-service-ms-host-shutdown.h b/data/mbim-service-ms-host-shutdown.h new file mode 100644 index 0000000..0048470 --- /dev/null +++ b/data/mbim-service-ms-host-shutdown.h @@ -0,0 +1,7 @@ +/* + * ID: 1 + * Command: Notify + */ + +#define MBIM_CMD_MS_HOST_SHUTDOWN_NOTIFY 1 + diff --git a/data/mbim-service-ms-host-shutdown.json b/data/mbim-service-ms-host-shutdown.json new file mode 100644 index 0000000..9240295 --- /dev/null +++ b/data/mbim-service-ms-host-shutdown.json @@ -0,0 +1,11 @@ +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "MS Host Shutdown" }, + + // ********************************************************************************* + { "name" : "Notify", + "service" : "MS Host Shutdown", + "type" : "Command", + "set" : [] } +] diff --git a/data/mbim-service-phonebook.h b/data/mbim-service-phonebook.h new file mode 100644 index 0000000..f984da4 --- /dev/null +++ b/data/mbim-service-phonebook.h @@ -0,0 +1,52 @@ +/* + * ID: 1 + * Command: Configuration + */ + +#define MBIM_CMD_PHONEBOOK_CONFIGURATION 1 + +struct mbim_phonebook_configuration_r = + u32 state; + u32 numberofentries; + u32 usedentries; + u32 maxnumberlength; + u32 maxname; +} + +struct mbimphonebookentry = { + u32 entryindex; + struct mbim_string number; + struct mbim_string name; +} + +/* + * ID: 2 + * Command: Read + */ + +#define MBIM_CMD_PHONEBOOK_READ 2 + +struct mbim_phonebook_read_q = { + u32 filterflag; + u32 filtermessageindex; +} + +struct mbim_phonebook_read_r = + u32 entrycount; + struct mbim_ref_struct_array entries; +} + +/* + * ID: 3 + * Command: Delete + */ + +#define MBIM_CMD_PHONEBOOK_DELETE 3 + +/* + * ID: 4 + * Command: Write + */ + +#define MBIM_CMD_PHONEBOOK_WRITE 4 + diff --git a/data/mbim-service-phonebook.json b/data/mbim-service-phonebook.json new file mode 100644 index 0000000..dffa598 --- /dev/null +++ b/data/mbim-service-phonebook.json @@ -0,0 +1,89 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "Phonebook" }, + + // ********************************************************************************* + { "name" : "Configuration", + "service" : "Phonebook", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "State", + "format" : "guint32", + "public-format" : "MbimPhonebookState" }, + { "name" : "NumberOfEntries", + "format" : "guint32" }, + { "name" : "UsedEntries", + "format" : "guint32" }, + { "name" : "MaxNumberLength", + "format" : "guint32" }, + { "name" : "MaxName", + "format" : "guint32" } ], + "notification" : [ { "name" : "State", + "format" : "guint32", + "public-format" : "MbimPhonebookState" }, + { "name" : "NumberOfEntries", + "format" : "guint32" }, + { "name" : "UsedEntries", + "format" : "guint32" }, + { "name" : "MaxNumberLength", + "format" : "guint32" }, + { "name" : "MaxName", + "format" : "guint32" } ] }, + + // ********************************************************************************* + { "name" : "MbimPhonebookEntry", + "type" : "Struct", + "contents" : [ { "name" : "EntryIndex", + "format" : "guint32" }, + { "name" : "Number", + "format" : "string" }, + { "name" : "Name", + "format" : "string" } ] }, + + { "name" : "Read", + "service" : "Phonebook", + "type" : "Command", + "query" : [ { "name" : "FilterFlag", + "format" : "guint32", + "public-format" : "MbimPhonebookFlag" }, + { "name" : "FilterMessageIndex", + "format" : "guint32" } ], + "response" : [ { "name" : "EntryCount", + "format" : "guint32" }, + { "name" : "Entries", + "format" : "ref-struct-array", + "struct-type" : "MbimPhonebookEntry", + "array-size-field" : "EntryCount" } ] }, + + // ********************************************************************************* + + { "name" : "Delete", + "service" : "Phonebook", + "type" : "Command", + "set" : [ { "name" : "FilterFlag", + "format" : "guint32", + "public-format" : "MbimPhonebookFlag" }, + { "name" : "FilterMessageIndex", + "format" : "guint32" } ], + "response" : [] }, + + + // ********************************************************************************* + + { "name" : "Write", + "service" : "Phonebook", + "type" : "Command", + "set" : [ { "name" : "SaveFlag", + "format" : "guint32", + "public-format" : "MbimPhonebookWriteFlag" }, + { "name" : "SaveIndex", + "format" : "guint32" }, + { "name" : "Number", + "format" : "string" }, + { "name" : "Name", + "format" : "string" } ], + "response" : [] } + +] diff --git a/data/mbim-service-proxy-control.h b/data/mbim-service-proxy-control.h new file mode 100644 index 0000000..7d81e7d --- /dev/null +++ b/data/mbim-service-proxy-control.h @@ -0,0 +1,7 @@ +/* + * ID: 1 + * Command: Configuration + */ + +#define MBIM_CMD_PROXY_CONTROL_CONFIGURATION 1 + diff --git a/data/mbim-service-proxy-control.json b/data/mbim-service-proxy-control.json new file mode 100644 index 0000000..2379e79 --- /dev/null +++ b/data/mbim-service-proxy-control.json @@ -0,0 +1,17 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "Proxy Control" }, + + // ********************************************************************************* + { "name" : "Configuration", + "service" : "Proxy Control", + "type" : "Command", + "set" : [ { "name" : "DevicePath", + "format" : "string" }, + { "name" : "Timeout", + "format" : "guint32" } ], + "response" : [] } + +] diff --git a/data/mbim-service-sms.h b/data/mbim-service-sms.h new file mode 100644 index 0000000..f6ca81b --- /dev/null +++ b/data/mbim-service-sms.h @@ -0,0 +1,94 @@ +/* + * ID: 1 + * Command: Configuration + */ + +#define MBIM_CMD_SMS_CONFIGURATION 1 + +struct mbim_sms_configuration_r = + u32 smsstoragestate; + u32 format; + u32 maxmessages; + u32 cdmashortmessagesize; + struct mbim_string scaddress; +} + +struct mbimsmspdureadrecord = { + u32 messageindex; + u32 messagestatus; + struct mbim_ref_byte_array pdudata; +} + +struct mbimsmscdmareadrecord = { + u32 messageindex; + u32 messagestatus; + struct mbim_string address; + struct mbim_string timestamp; + u32 encoding; + u32 language; + struct mbim_ref_byte_array encodedmessage; + u32 encodedmessagesizeincharacters; +} + +/* + * ID: 2 + * Command: Read + */ + +#define MBIM_CMD_SMS_READ 2 + +struct mbim_sms_read_q = { + u32 format; + u32 flag; + u32 messageindex; +} + +struct mbim_sms_read_r = + u32 format; + u32 messagescount; + struct mbim_ref_struct_array pdumessages; + struct mbim_ref_struct_array cdmamessages; +} + +struct mbimsmspdusendrecord = { + struct mbim_ref_byte_array pdudata; +} + +struct mbimsmscdmasendrecord = { + u32 encoding; + u32 language; + struct mbim_string address; + struct mbim_ref_byte_array encodedmessage; + u32 encodedmessagesizeincharacters; +} + +/* + * ID: 3 + * Command: Send + */ + +#define MBIM_CMD_SMS_SEND 3 + +struct mbim_sms_send_r = + u32 messagereference; +} + +/* + * ID: 4 + * Command: Delete + */ + +#define MBIM_CMD_SMS_DELETE 4 + +/* + * ID: 5 + * Command: Message Store Status + */ + +#define MBIM_CMD_SMS_MESSAGE_STORE_STATUS 5 + +struct mbim_sms_message_store_status_r = + u32 flag; + u32 messageindex; +} + diff --git a/data/mbim-service-sms.json b/data/mbim-service-sms.json new file mode 100644 index 0000000..57e63c1 --- /dev/null +++ b/data/mbim-service-sms.json @@ -0,0 +1,181 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "SMS" }, + + // ********************************************************************************* + { "name" : "Configuration", + "service" : "SMS", + "type" : "Command", + "set" : [ { "name" : "Format", + "format" : "guint32", + "public-format" : "MbimSmsFormat" }, + { "name" : "ScAddress", + "format" : "string" } ], + "query" : [], + "response" : [ { "name" : "SmsStorageState", + "format" : "guint32", + "public-format" : "MbimSmsStorageState" }, + { "name" : "Format", + "format" : "guint32", + "public-format" : "MbimSmsFormat" }, + { "name" : "MaxMessages", + "format" : "guint32" }, + { "name" : "CdmaShortMessageSize", + "format" : "guint32" }, + { "name" : "ScAddress", + "format" : "string" } ] }, + + // ********************************************************************************* + { "name" : "MbimSmsPduReadRecord", + "type" : "Struct", + "contents" : [ { "name" : "MessageIndex", + "format" : "guint32" }, + { "name" : "MessageStatus", + "format" : "guint32", + "public-format" : "MbimSmsStatus" }, + { "name" : "PduData", + "format" : "ref-byte-array" } ] }, + + { "name" : "MbimSmsCdmaReadRecord", + "type" : "Struct", + "contents" : [ { "name" : "MessageIndex", + "format" : "guint32" }, + { "name" : "MessageStatus", + "format" : "guint32", + "public-format" : "MbimSmsStatus" }, + { "name" : "Address", + "format" : "string" }, + { "name" : "Timestamp", + "format" : "string" }, + { "name" : "Encoding", + "format" : "guint32", + "public-format" : "MbimSmsCdmaEncoding" }, + { "name" : "Language", + "format" : "guint32", + "public-format" : "MbimSmsCdmaLanguage" }, + { "name" : "EncodedMessage", + "format" : "ref-byte-array" }, + { "name" : "EncodedMessageSizeInCharacters", + "format" : "guint32" } ] }, + + { "name" : "Read", + "service" : "SMS", + "type" : "Command", + "query" : [ { "name" : "Format", + "format" : "guint32", + "public-format" : "MbimSmsFormat" }, + { "name" : "Flag", + "format" : "guint32", + "public-format" : "MbimSmsFlag" }, + { "name" : "MessageIndex", + "format" : "guint32" } ], + "response" : [ { "name" : "Format", + "format" : "guint32", + "public-format" : "MbimSmsFormat" }, + { "name" : "MessagesCount", + "format" : "guint32" }, + { "name" : "PduMessages", + "format" : "ref-struct-array" , + "struct-type" : "MbimSmsPduReadRecord", + "array-size-field" : "MessagesCount", + "available-if" : { "field" : "Format", + "operation" : "==", + "value" : "MBIM_SMS_FORMAT_PDU" } }, + { "name" : "CdmaMessages", + "format" : "ref-struct-array" , + "struct-type" : "MbimSmsCdmaReadRecord", + "array-size-field" : "MessagesCount", + "available-if" : { "field" : "Format", + "operation" : "==", + "value" : "MBIM_SMS_FORMAT_CDMA" } } ], + "notification" : [ { "name" : "Format", + "format" : "guint32", + "public-format" : "MbimSmsFormat" }, + { "name" : "MessagesCount", + "format" : "guint32" }, + { "name" : "PduMessages", + "format" : "ref-struct-array" , + "struct-type" : "MbimSmsPduReadRecord", + "array-size-field" : "MessagesCount", + "available-if" : { "field" : "Format", + "operation" : "==", + "value" : "MBIM_SMS_FORMAT_PDU" } }, + { "name" : "CdmaMessages", + "format" : "ref-struct-array" , + "struct-type" : "MbimSmsCdmaReadRecord", + "array-size-field" : "MessagesCount", + "available-if" : { "field" : "Format", + "operation" : "==", + "value" : "MBIM_SMS_FORMAT_CDMA" } } ] }, + + // ********************************************************************************* + { "name" : "MbimSmsPduSendRecord", + "type" : "Struct", + "contents" : [ { "name" : "PduData", + "format" : "ref-byte-array" } ] }, + + { "name" : "MbimSmsCdmaSendRecord", + "type" : "Struct", + "contents" : [ { "name" : "Encoding", + "format" : "guint32", + "public-format" : "MbimSmsCdmaEncoding" }, + { "name" : "Language", + "format" : "guint32", + "public-format" : "MbimSmsCdmaLanguage" }, + { "name" : "Address", + "format" : "string" }, + { "name" : "EncodedMessage", + "format" : "ref-byte-array" }, + { "name" : "EncodedMessageSizeInCharacters", + "format" : "guint32" } ] }, + + { "name" : "Send", + "service" : "SMS", + "type" : "Command", + "set" : [ { "name" : "Format", + "format" : "guint32", + "public-format" : "MbimSmsFormat" }, + { "name" : "PduMessage", + "format" : "struct", + "struct-type" : "MbimSmsPduSendRecord", + "available-if" : { "field" : "Format", + "operation" : "==", + "value" : "MBIM_SMS_FORMAT_PDU" } }, + { "name" : "CdmaMessage", + "format" : "struct", + "struct-type" : "MbimSmsCdmaSendRecord", + "available-if" : { "field" : "Format", + "operation" : "==", + "value" : "MBIM_SMS_FORMAT_CDMA" } } ], + "response" : [ { "name" : "MessageReference", + "format" : "guint32" } ] }, + + // ********************************************************************************* + { "name" : "Delete", + "service" : "SMS", + "type" : "Command", + "set" : [ { "name" : "Flag", + "format" : "guint32", + "public-format" : "MbimSmsFlag" }, + { "name" : "MessageIndex", + "format" : "guint32" } ], + "response" : [] }, + + // ********************************************************************************* + { "name" : "Message Store Status", + "service" : "SMS", + "type" : "Command", + "query" : [], + "response" : [ { "name" : "Flag", + "format" : "guint32", + "public-format" : "MbimSmsStatusFlag" }, + { "name" : "MessageIndex", + "format" : "guint32" } ], + "notification" : [ { "name" : "Flag", + "format" : "guint32", + "public-format" : "MbimSmsStatusFlag" }, + { "name" : "MessageIndex", + "format" : "guint32" } ] } +] diff --git a/data/mbim-service-stk.h b/data/mbim-service-stk.h new file mode 100644 index 0000000..6d3d9db --- /dev/null +++ b/data/mbim-service-stk.h @@ -0,0 +1,34 @@ +/* + * ID: 1 + * Command: Pac + */ + +#define MBIM_CMD_STK_PAC 1 + +struct mbim_stk_pac_r = + struct mbim_byte_array pacsupport; +} + +/* + * ID: 2 + * Command: Terminal Response + */ + +#define MBIM_CMD_STK_TERMINAL_RESPONSE 2 + +struct mbim_stk_terminal_response_r = + struct mbim_ref_byte_array resultdata; + u32 statuswords; +} + +/* + * ID: 3 + * Command: Envelope + */ + +#define MBIM_CMD_STK_ENVELOPE 3 + +struct mbim_stk_envelope_r = + struct mbim_byte_array envelopesupport; +} + diff --git a/data/mbim-service-stk.json b/data/mbim-service-stk.json new file mode 100644 index 0000000..d470542 --- /dev/null +++ b/data/mbim-service-stk.json @@ -0,0 +1,47 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "STK" }, + + // ********************************************************************************* + { "name" : "Pac", + "service" : "STK", + "type" : "Command", + "query" : [], + "set" : [ { "name" : "PacHostControl", + "format" : "byte-array", + "array-size" : "32" } ], + + "response" : [ { "name" : "PacSupport", + "format" : "byte-array", + "array-size" : "256" } ], + "notification" : [ { "name" : "PacType", + "format" : "guint32", + "public-format" : "MbimStkPacType" }, + { "name" : "DataBuffer", + "format" : "unsized-byte-array" } ] }, + + // ********************************************************************************* + { "name" : "Terminal Response", + "service" : "STK", + "type" : "Command", + "set" : [ { "name" : "Response", + "format" : "ref-byte-array-no-offset" } ], + "response" : [ { "name" : "ResultData", + "format" : "ref-byte-array" }, + { "name" : "StatusWords", + "format" : "guint32" } ] }, + + // ********************************************************************************* + { "name" : "Envelope", + "service" : "STK", + "type" : "Command", + "query" : [], + "set" : [ { "name" : "Data", + "format" : "unsized-byte-array" } ], + // This response is only for the 'query', the 'set' one is empty... + "response" : [ { "name" : "EnvelopeSupport", + "format" : "byte-array", + "array-size" : "32" } ] } +] diff --git a/data/mbim-service-ussd.h b/data/mbim-service-ussd.h new file mode 100644 index 0000000..c510670 --- /dev/null +++ b/data/mbim-service-ussd.h @@ -0,0 +1,14 @@ +/* + * ID: 1 + * Command: + */ + +#define MBIM_CMD_USSD_ 1 + +struct mbim_ussd__r = + u32 response; + u32 sessionstate; + u32 datacodingscheme; + struct mbim_ref_byte_array payload; +} + diff --git a/data/mbim-service-ussd.json b/data/mbim-service-ussd.json new file mode 100644 index 0000000..10471e1 --- /dev/null +++ b/data/mbim-service-ussd.json @@ -0,0 +1,38 @@ + +[ + // ********************************************************************************* + { "type" : "Service", + "name" : "USSD" }, + + // ********************************************************************************* + { "name" : "", + "service" : "USSD", + "type" : "Command", + "set" : [ { "name" : "Action", + "format" : "guint32", + "public-format" : "MbimUssdAction" }, + { "name" : "DataCodingScheme", + "format" : "guint32" }, + { "name" : "Payload", + "format" : "ref-byte-array" } ], + "response" : [ { "name" : "Response", + "format" : "guint32", + "public-format" : "MbimUssdResponse" }, + { "name" : "SessionState", + "format" : "guint32", + "public-format" : "MbimUssdSessionState" }, + { "name" : "DataCodingScheme", + "format" : "guint32" }, + { "name" : "Payload", + "format" : "ref-byte-array" } ], + "notification" : [ { "name" : "Response", + "format" : "guint32", + "public-format" : "MbimUssdResponse" }, + { "name" : "SessionState", + "format" : "guint32", + "public-format" : "MbimUssdSessionState" }, + { "name" : "DataCodingScheme", + "format" : "guint32" }, + { "name" : "Payload", + "format" : "ref-byte-array" } ] } +] diff --git a/mbim-cid.h b/mbim-cid.h new file mode 100644 index 0000000..c7d5a18 --- /dev/null +++ b/mbim-cid.h @@ -0,0 +1,213 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + * libmbim-glib -- GLib/GIO based library to control MBIM devices + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2013 - 2014 Aleksander Morgado + */ + +#ifndef _LIBMBIM_GLIB_MBIM_CID_H_ +#define _LIBMBIM_GLIB_MBIM_CID_H_ + +/** + * MbimCidBasicConnect: + * @MBIM_CID_BASIC_CONNECT_UNKNOWN: Unknown command. + * @MBIM_CID_BASIC_CONNECT_DEVICE_CAPS: Device capabilities. + * @MBIM_CID_BASIC_CONNECT_SUBSCRIBER_READY_STATUS: Subscriber ready status. + * @MBIM_CID_BASIC_CONNECT_RADIO_STATE: Radio state. + * @MBIM_CID_BASIC_CONNECT_PIN: PIN. + * @MBIM_CID_BASIC_CONNECT_PIN_LIST: PIN list. + * @MBIM_CID_BASIC_CONNECT_HOME_PROVIDER: Home provider. + * @MBIM_CID_BASIC_CONNECT_PREFERRED_PROVIDERS: Preferred providers. + * @MBIM_CID_BASIC_CONNECT_VISIBLE_PROVIDERS: Visible providers. + * @MBIM_CID_BASIC_CONNECT_REGISTER_STATE: Register state. + * @MBIM_CID_BASIC_CONNECT_PACKET_SERVICE: Packet service. + * @MBIM_CID_BASIC_CONNECT_SIGNAL_STATE: Signal state. + * @MBIM_CID_BASIC_CONNECT_CONNECT: Connect. + * @MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS: Provisioned contexts. + * @MBIM_CID_BASIC_CONNECT_SERVICE_ACTIVATION: Service activation. + * @MBIM_CID_BASIC_CONNECT_IP_CONFIGURATION: IP configuration. + * @MBIM_CID_BASIC_CONNECT_DEVICE_SERVICES: Device services. + * @MBIM_CID_BASIC_CONNECT_DEVICE_SERVICE_SUBSCRIBE_LIST: Device service subscribe list. + * @MBIM_CID_BASIC_CONNECT_PACKET_STATISTICS: Packet statistics. + * @MBIM_CID_BASIC_CONNECT_NETWORK_IDLE_HINT: Network idle hint. + * @MBIM_CID_BASIC_CONNECT_EMERGENCY_MODE: Emergency mode. + * @MBIM_CID_BASIC_CONNECT_IP_PACKET_FILTERS: IP packet filters. + * @MBIM_CID_BASIC_CONNECT_MULTICARRIER_PROVIDERS: Multicarrier providers. + * + * MBIM commands in the %MBIM_SERVICE_BASIC_CONNECT service. + */ +typedef enum { + MBIM_CID_BASIC_CONNECT_UNKNOWN = 0, + MBIM_CID_BASIC_CONNECT_DEVICE_CAPS = 1, + MBIM_CID_BASIC_CONNECT_SUBSCRIBER_READY_STATUS = 2, + MBIM_CID_BASIC_CONNECT_RADIO_STATE = 3, + MBIM_CID_BASIC_CONNECT_PIN = 4, + MBIM_CID_BASIC_CONNECT_PIN_LIST = 5, + MBIM_CID_BASIC_CONNECT_HOME_PROVIDER = 6, + MBIM_CID_BASIC_CONNECT_PREFERRED_PROVIDERS = 7, + MBIM_CID_BASIC_CONNECT_VISIBLE_PROVIDERS = 8, + MBIM_CID_BASIC_CONNECT_REGISTER_STATE = 9, + MBIM_CID_BASIC_CONNECT_PACKET_SERVICE = 10, + MBIM_CID_BASIC_CONNECT_SIGNAL_STATE = 11, + MBIM_CID_BASIC_CONNECT_CONNECT = 12, + MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS = 13, + MBIM_CID_BASIC_CONNECT_SERVICE_ACTIVATION = 14, + MBIM_CID_BASIC_CONNECT_IP_CONFIGURATION = 15, + MBIM_CID_BASIC_CONNECT_DEVICE_SERVICES = 16, + /* 17, 18 reserved */ + MBIM_CID_BASIC_CONNECT_DEVICE_SERVICE_SUBSCRIBE_LIST = 19, + MBIM_CID_BASIC_CONNECT_PACKET_STATISTICS = 20, + MBIM_CID_BASIC_CONNECT_NETWORK_IDLE_HINT = 21, + MBIM_CID_BASIC_CONNECT_EMERGENCY_MODE = 22, + MBIM_CID_BASIC_CONNECT_IP_PACKET_FILTERS = 23, + MBIM_CID_BASIC_CONNECT_MULTICARRIER_PROVIDERS = 24, +} MbimCidBasicConnect; + +/** + * MbimCidSms: + * @MBIM_CID_SMS_UNKNOWN: Unknown command. + * @MBIM_CID_SMS_CONFIGURATION: SMS configuration. + * @MBIM_CID_SMS_READ: Read. + * @MBIM_CID_SMS_SEND: Send. + * @MBIM_CID_SMS_DELETE: Delete. + * @MBIM_CID_SMS_MESSAGE_STORE_STATUS: Store message status. + * + * MBIM commands in the %MBIM_SERVICE_SMS service. + */ +typedef enum { + MBIM_CID_SMS_UNKNOWN = 0, + MBIM_CID_SMS_CONFIGURATION = 1, + MBIM_CID_SMS_READ = 2, + MBIM_CID_SMS_SEND = 3, + MBIM_CID_SMS_DELETE = 4, + MBIM_CID_SMS_MESSAGE_STORE_STATUS = 5, +} MbimCidSms; + +/** + * MbimCidUssd: + * @MBIM_CID_USSD_UNKNOWN: Unknown command. + * @MBIM_CID_USSD: USSD operation. + * + * MBIM commands in the %MBIM_SERVICE_USSD service. + */ +typedef enum { + MBIM_CID_USSD_UNKNOWN = 0, + MBIM_CID_USSD = 1, +} MbimCidUssd; + +/** + * MbimCidPhonebook: + * @MBIM_CID_PHONEBOOK_UNKNOWN: Unknown command. + * @MBIM_CID_PHONEBOOK_CONFIGURATION: Configuration. + * @MBIM_CID_PHONEBOOK_READ: Read. + * @MBIM_CID_PHONEBOOK_DELETE: Delete. + * @MBIM_CID_PHONEBOOK_WRITE: Write. + * + * MBIM commands in the %MBIM_SERVICE_PHONEBOOK service. + */ +typedef enum { + MBIM_CID_PHONEBOOK_UNKNOWN = 0, + MBIM_CID_PHONEBOOK_CONFIGURATION = 1, + MBIM_CID_PHONEBOOK_READ = 2, + MBIM_CID_PHONEBOOK_DELETE = 3, + MBIM_CID_PHONEBOOK_WRITE = 4, +} MbimCidPhonebook; + +/** + * MbimCidStk: + * @MBIM_CID_STK_UNKNOWN: Unknown command. + * @MBIM_CID_STK_PAC: PAC. + * @MBIM_CID_STK_TERMINAL_RESPONSE: Terminal response. + * @MBIM_CID_STK_ENVELOPE: Envelope. + * + * MBIM commands in the %MBIM_SERVICE_STK service. + */ +typedef enum { + MBIM_CID_STK_UNKNOWN = 0, + MBIM_CID_STK_PAC = 1, + MBIM_CID_STK_TERMINAL_RESPONSE = 2, + MBIM_CID_STK_ENVELOPE = 3, +} MbimCidStk; + +/** + * MbimCidAuth: + * @MBIM_CID_AUTH_UNKNOWN: Unknow command + * @MBIM_CID_AUTH_AKA: AKA. + * @MBIM_CID_AUTH_AKAP: AKAP. + * @MBIM_CID_AUTH_SIM: SIM. + * + * MBIM commands in the %MBIM_SERVICE_AUTH service. + */ +typedef enum { + MBIM_CID_AUTH_UNKNOWN = 0, + MBIM_CID_AUTH_AKA = 1, + MBIM_CID_AUTH_AKAP = 2, + MBIM_CID_AUTH_SIM = 3, +} MbimCidAuth; + +/** + * MbimCidDss: + * @MBIM_CID_DSS_UNKNOWN: Unknown command. + * @MBIM_CID_DSS_CONNECT: Connect. + * + * MBIM commands in the %MBIM_SERVICE_DSS service. + */ +typedef enum { + MBIM_CID_DSS_UNKNOWN = 0, + MBIM_CID_DSS_CONNECT = 1 +} MbimCidDss; + +/** + * MbimCidMsFirmwareId: + * @MBIM_CID_MS_FIRMWARE_ID_UNKNOWN: Unknown command. + * @MBIM_CID_MS_FIRMWARE_ID_GET: Get Firmware ID. + * + * MBIM commands in the %MBIM_SERVICE_MS_FIRMWARE_ID service. + */ +typedef enum { + MBIM_CID_MS_FIRMWARE_ID_UNKNOWN = 0, + MBIM_CID_MS_FIRMWARE_ID_GET = 1 +} MbimCidMsFirmwareId; + +/** + * MbimCidMsHostShutdown: + * @MBIM_CID_MS_HOST_SHUTDOWN_UNKNOWN: Unknown command. + * @MBIM_CID_MS_HOST_SHUTDOWN_NOTIFY: Notify that the host is shutting down. + * + * MBIM commands in the %MBIM_SERVICE_MS_HOST_SHUTDOWN service. + */ +typedef enum { + MBIM_CID_MS_HOST_SHUTDOWN_UNKNOWN = 0, + MBIM_CID_MS_HOST_SHUTDOWN_NOTIFY = 1 +} MbimCidMsHostShutdown; + +/** + * MbimCidProxyControl: + * @MBIM_CID_PROXY_CONTROL_UNKNOWN: Unknown command. + * @MBIM_CID_PROXY_CONTROL_CONFIGURATION: Configuration. + * + * MBIM commands in the %MBIM_SERVICE_PROXY_CONTROL service. + */ +typedef enum { + MBIM_CID_PROXY_CONTROL_UNKNOWN = 0, + MBIM_CID_PROXY_CONTROL_CONFIGURATION = 1 +} MbimCidProxyControl; + + +#endif /* _LIBMBIM_GLIB_MBIM_CID_H_ */ diff --git a/mbim-dev.c b/mbim-dev.c new file mode 100644 index 0000000..e5d90f9 --- /dev/null +++ b/mbim-dev.c @@ -0,0 +1,120 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "mbim.h" + +uint8_t mbim_buffer[MBIM_BUFFER_SIZE]; +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(); +} + +static struct uloop_timeout tout = { + .cb = mbim_msg_tout_cb, +}; + +int +mbim_send(void) +{ + struct mbim_message_header *hdr = (struct mbim_message_header *) mbim_buffer; + int ret = 0; + + if (le32toh(hdr->length) > MBIM_BUFFER_SIZE) { + fprintf(stderr, "message too big %d\n", le32toh(hdr->length)); + return -1; + } + + if (verbose) { + fprintf(stderr, "sending (%d): ", le32toh(hdr->length)); + for (ret = 0; ret < le32toh(hdr->length); ret++) + printf("%02x ", ((uint8_t *) mbim_buffer)[ret]); + printf("\n"); + printf(" header_type: %04X\n", le32toh(hdr->type)); + printf(" header_length: %04X\n", le32toh(hdr->length)); + printf(" header_transaction: %04X\n", le32toh(hdr->transaction_id)); + } + + ret = write(mbim_fd.fd, mbim_buffer, le32toh(hdr->length)); + if (!ret) { + perror("writing data failed: "); + } else { + expected = le32toh(hdr->type) | 0x80000000; + uloop_timeout_set(&tout, 15000); + } + return ret; +} + +static void +mbim_recv(struct uloop_fd *u, unsigned int events) +{ + ssize_t cnt = read(u->fd, mbim_buffer, MBIM_BUFFER_SIZE); + struct mbim_message_header *hdr = (struct mbim_message_header *) mbim_buffer; + struct command_message *msg = (struct command_message *) mbim_buffer; + int i; + + if (cnt < 0) + return; + + if (cnt < sizeof(struct mbim_message_header)) { + perror("failed to read() data: "); + return; + } + if (verbose) { + printf("reading (%zu): ", cnt); + for (i = 0; i < cnt; i++) + printf("%02x ", mbim_buffer[i]); + printf("\n"); + printf(" header_type: %04X\n", le32toh(hdr->type)); + printf(" header_length: %04X\n", le32toh(hdr->length)); + printf(" header_transaction: %04X\n", le32toh(hdr->transaction_id)); + } + + if (le32toh(hdr->type) == expected) + uloop_timeout_cancel(&tout); + + switch(le32toh(hdr->type)) { + case MBIM_MESSAGE_TYPE_OPEN_DONE: + if (current_handler->request() < 0) + mbim_send_close_msg(); + break; + case MBIM_MESSAGE_TYPE_COMMAND_DONE: + 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(); + break; + case MBIM_MESSAGE_TYPE_FUNCTION_ERROR: + no_close = 0; + mbim_send_close_msg(); + return_code = -1; + break; + } +} + +void +mbim_open(const char *path) +{ + mbim_fd.cb = mbim_recv; + mbim_fd.fd = open(path, O_RDWR); + if (mbim_fd.fd < 1) { + perror("open failed: "); + exit(-1); + } + uloop_fd_add(&mbim_fd, ULOOP_READ); +} diff --git a/mbim-dev.h b/mbim-dev.h new file mode 100644 index 0000000..3f345ce --- /dev/null +++ b/mbim-dev.h @@ -0,0 +1,10 @@ +#ifndef _MBIM_DEV_H__ +#define _MBIM_DEV_H__ + +extern uint8_t mbim_buffer[MBIM_BUFFER_SIZE]; +extern int no_close; + +int mbim_send(void); +void mbim_open(const char *path); + +#endif diff --git a/mbim-enum.c b/mbim-enum.c new file mode 100644 index 0000000..473e68f --- /dev/null +++ b/mbim-enum.c @@ -0,0 +1,576 @@ +#include + +#include "mbim.h" + +struct mbim_enum mbim_service_values[] = { + { MBIM_SERVICE_INVALID, "MBIM_SERVICE_INVALID", "invalid" }, + { MBIM_SERVICE_BASIC_CONNECT, "MBIM_SERVICE_BASIC_CONNECT", "basic-connect" }, + { MBIM_SERVICE_SMS, "MBIM_SERVICE_SMS", "sms" }, + { MBIM_SERVICE_USSD, "MBIM_SERVICE_USSD", "ussd" }, + { MBIM_SERVICE_PHONEBOOK, "MBIM_SERVICE_PHONEBOOK", "phonebook" }, + { MBIM_SERVICE_STK, "MBIM_SERVICE_STK", "stk" }, + { MBIM_SERVICE_AUTH, "MBIM_SERVICE_AUTH", "auth" }, + { MBIM_SERVICE_DSS, "MBIM_SERVICE_DSS", "dss" }, + { MBIM_SERVICE_MS_FIRMWARE_ID, "MBIM_SERVICE_MS_FIRMWARE_ID", "ms-firmware-id" }, + { MBIM_SERVICE_MS_HOST_SHUTDOWN, "MBIM_SERVICE_MS_HOST_SHUTDOWN", "ms-host-shutdown" }, + { MBIM_SERVICE_PROXY_CONTROL, "MBIM_SERVICE_PROXY_CONTROL", "proxy-control" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_context_type_values[] = { + { MBIM_CONTEXT_TYPE_INVALID, "MBIM_CONTEXT_TYPE_INVALID", "invalid" }, + { MBIM_CONTEXT_TYPE_NONE, "MBIM_CONTEXT_TYPE_NONE", "none" }, + { MBIM_CONTEXT_TYPE_INTERNET, "MBIM_CONTEXT_TYPE_INTERNET", "internet" }, + { MBIM_CONTEXT_TYPE_VPN, "MBIM_CONTEXT_TYPE_VPN", "vpn" }, + { MBIM_CONTEXT_TYPE_VOICE, "MBIM_CONTEXT_TYPE_VOICE", "voice" }, + { MBIM_CONTEXT_TYPE_VIDEO_SHARE, "MBIM_CONTEXT_TYPE_VIDEO_SHARE", "video-share" }, + { MBIM_CONTEXT_TYPE_PURCHASE, "MBIM_CONTEXT_TYPE_PURCHASE", "purchase" }, + { MBIM_CONTEXT_TYPE_IMS, "MBIM_CONTEXT_TYPE_IMS", "ims" }, + { MBIM_CONTEXT_TYPE_MMS, "MBIM_CONTEXT_TYPE_MMS", "mms" }, + { MBIM_CONTEXT_TYPE_LOCAL, "MBIM_CONTEXT_TYPE_LOCAL", "local" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_basic_connect_values[] = { + { MBIM_CID_BASIC_CONNECT_UNKNOWN, "MBIM_CID_BASIC_CONNECT_UNKNOWN", "unknown" }, + { MBIM_CID_BASIC_CONNECT_DEVICE_CAPS, "MBIM_CID_BASIC_CONNECT_DEVICE_CAPS", "device-caps" }, + { MBIM_CID_BASIC_CONNECT_SUBSCRIBER_READY_STATUS, "MBIM_CID_BASIC_CONNECT_SUBSCRIBER_READY_STATUS", "subscriber-ready-status" }, + { MBIM_CID_BASIC_CONNECT_RADIO_STATE, "MBIM_CID_BASIC_CONNECT_RADIO_STATE", "radio-state" }, + { MBIM_CID_BASIC_CONNECT_PIN, "MBIM_CID_BASIC_CONNECT_PIN", "pin" }, + { MBIM_CID_BASIC_CONNECT_PIN_LIST, "MBIM_CID_BASIC_CONNECT_PIN_LIST", "pin-list" }, + { MBIM_CID_BASIC_CONNECT_HOME_PROVIDER, "MBIM_CID_BASIC_CONNECT_HOME_PROVIDER", "home-provider" }, + { MBIM_CID_BASIC_CONNECT_PREFERRED_PROVIDERS, "MBIM_CID_BASIC_CONNECT_PREFERRED_PROVIDERS", "preferred-providers" }, + { MBIM_CID_BASIC_CONNECT_VISIBLE_PROVIDERS, "MBIM_CID_BASIC_CONNECT_VISIBLE_PROVIDERS", "visible-providers" }, + { MBIM_CID_BASIC_CONNECT_REGISTER_STATE, "MBIM_CID_BASIC_CONNECT_REGISTER_STATE", "register-state" }, + { MBIM_CID_BASIC_CONNECT_PACKET_SERVICE, "MBIM_CID_BASIC_CONNECT_PACKET_SERVICE", "packet-service" }, + { MBIM_CID_BASIC_CONNECT_SIGNAL_STATE, "MBIM_CID_BASIC_CONNECT_SIGNAL_STATE", "signal-state" }, + { MBIM_CID_BASIC_CONNECT_CONNECT, "MBIM_CID_BASIC_CONNECT_CONNECT", "connect" }, + { MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS, "MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS", "provisioned-contexts" }, + { MBIM_CID_BASIC_CONNECT_SERVICE_ACTIVATION, "MBIM_CID_BASIC_CONNECT_SERVICE_ACTIVATION", "service-activation" }, + { MBIM_CID_BASIC_CONNECT_IP_CONFIGURATION, "MBIM_CID_BASIC_CONNECT_IP_CONFIGURATION", "ip-configuration" }, + { MBIM_CID_BASIC_CONNECT_DEVICE_SERVICES, "MBIM_CID_BASIC_CONNECT_DEVICE_SERVICES", "device-services" }, + { MBIM_CID_BASIC_CONNECT_DEVICE_SERVICE_SUBSCRIBE_LIST, "MBIM_CID_BASIC_CONNECT_DEVICE_SERVICE_SUBSCRIBE_LIST", "device-service-subscribe-list" }, + { MBIM_CID_BASIC_CONNECT_PACKET_STATISTICS, "MBIM_CID_BASIC_CONNECT_PACKET_STATISTICS", "packet-statistics" }, + { MBIM_CID_BASIC_CONNECT_NETWORK_IDLE_HINT, "MBIM_CID_BASIC_CONNECT_NETWORK_IDLE_HINT", "network-idle-hint" }, + { MBIM_CID_BASIC_CONNECT_EMERGENCY_MODE, "MBIM_CID_BASIC_CONNECT_EMERGENCY_MODE", "emergency-mode" }, + { MBIM_CID_BASIC_CONNECT_IP_PACKET_FILTERS, "MBIM_CID_BASIC_CONNECT_IP_PACKET_FILTERS", "ip-packet-filters" }, + { MBIM_CID_BASIC_CONNECT_MULTICARRIER_PROVIDERS, "MBIM_CID_BASIC_CONNECT_MULTICARRIER_PROVIDERS", "multicarrier-providers" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_sms_values[] = { + { MBIM_CID_SMS_UNKNOWN, "MBIM_CID_SMS_UNKNOWN", "unknown" }, + { MBIM_CID_SMS_CONFIGURATION, "MBIM_CID_SMS_CONFIGURATION", "configuration" }, + { MBIM_CID_SMS_READ, "MBIM_CID_SMS_READ", "read" }, + { MBIM_CID_SMS_SEND, "MBIM_CID_SMS_SEND", "send" }, + { MBIM_CID_SMS_DELETE, "MBIM_CID_SMS_DELETE", "delete" }, + { MBIM_CID_SMS_MESSAGE_STORE_STATUS, "MBIM_CID_SMS_MESSAGE_STORE_STATUS", "message-store-status" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_ussd_values[] = { + { MBIM_CID_USSD_UNKNOWN, "MBIM_CID_USSD_UNKNOWN", "ussd-unknown" }, + { MBIM_CID_USSD, "MBIM_CID_USSD", "ussd" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_phonebook_values[] = { + { MBIM_CID_PHONEBOOK_UNKNOWN, "MBIM_CID_PHONEBOOK_UNKNOWN", "unknown" }, + { MBIM_CID_PHONEBOOK_CONFIGURATION, "MBIM_CID_PHONEBOOK_CONFIGURATION", "configuration" }, + { MBIM_CID_PHONEBOOK_READ, "MBIM_CID_PHONEBOOK_READ", "read" }, + { MBIM_CID_PHONEBOOK_DELETE, "MBIM_CID_PHONEBOOK_DELETE", "delete" }, + { MBIM_CID_PHONEBOOK_WRITE, "MBIM_CID_PHONEBOOK_WRITE", "write" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_stk_values[] = { + { MBIM_CID_STK_UNKNOWN, "MBIM_CID_STK_UNKNOWN", "unknown" }, + { MBIM_CID_STK_PAC, "MBIM_CID_STK_PAC", "pac" }, + { MBIM_CID_STK_TERMINAL_RESPONSE, "MBIM_CID_STK_TERMINAL_RESPONSE", "terminal-response" }, + { MBIM_CID_STK_ENVELOPE, "MBIM_CID_STK_ENVELOPE", "envelope" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_auth_values[] = { + { MBIM_CID_AUTH_UNKNOWN, "MBIM_CID_AUTH_UNKNOWN", "unknown" }, + { MBIM_CID_AUTH_AKA, "MBIM_CID_AUTH_AKA", "aka" }, + { MBIM_CID_AUTH_AKAP, "MBIM_CID_AUTH_AKAP", "akap" }, + { MBIM_CID_AUTH_SIM, "MBIM_CID_AUTH_SIM", "sim" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_dss_values[] = { + { MBIM_CID_DSS_UNKNOWN, "MBIM_CID_DSS_UNKNOWN", "unknown" }, + { MBIM_CID_DSS_CONNECT, "MBIM_CID_DSS_CONNECT", "connect" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_ms_firmware_id_values[] = { + { MBIM_CID_MS_FIRMWARE_ID_UNKNOWN, "MBIM_CID_MS_FIRMWARE_ID_UNKNOWN", "unknown" }, + { MBIM_CID_MS_FIRMWARE_ID_GET, "MBIM_CID_MS_FIRMWARE_ID_GET", "get" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_ms_host_shutdown_values[] = { + { MBIM_CID_MS_HOST_SHUTDOWN_UNKNOWN, "MBIM_CID_MS_HOST_SHUTDOWN_UNKNOWN", "unknown" }, + { MBIM_CID_MS_HOST_SHUTDOWN_NOTIFY, "MBIM_CID_MS_HOST_SHUTDOWN_NOTIFY", "notify" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cid_proxy_control_values[] = { + { MBIM_CID_PROXY_CONTROL_UNKNOWN, "MBIM_CID_PROXY_CONTROL_UNKNOWN", "unknown" }, + { MBIM_CID_PROXY_CONTROL_CONFIGURATION, "MBIM_CID_PROXY_CONTROL_CONFIGURATION", "configuration" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_message_type_values[] = { + { MBIM_MESSAGE_TYPE_INVALID, "MBIM_MESSAGE_TYPE_INVALID", "invalid" }, + { MBIM_MESSAGE_TYPE_OPEN, "MBIM_MESSAGE_TYPE_OPEN", "open" }, + { MBIM_MESSAGE_TYPE_CLOSE, "MBIM_MESSAGE_TYPE_CLOSE", "close" }, + { MBIM_MESSAGE_TYPE_COMMAND, "MBIM_MESSAGE_TYPE_COMMAND", "command" }, + { MBIM_MESSAGE_TYPE_HOST_ERROR, "MBIM_MESSAGE_TYPE_HOST_ERROR", "host-error" }, + { MBIM_MESSAGE_TYPE_OPEN_DONE, "MBIM_MESSAGE_TYPE_OPEN_DONE", "open-done" }, + { MBIM_MESSAGE_TYPE_CLOSE_DONE, "MBIM_MESSAGE_TYPE_CLOSE_DONE", "close-done" }, + { MBIM_MESSAGE_TYPE_COMMAND_DONE, "MBIM_MESSAGE_TYPE_COMMAND_DONE", "command-done" }, + { MBIM_MESSAGE_TYPE_FUNCTION_ERROR, "MBIM_MESSAGE_TYPE_FUNCTION_ERROR", "function-error" }, + { MBIM_MESSAGE_TYPE_INDICATE_STATUS, "MBIM_MESSAGE_TYPE_INDICATE_STATUS", "indicate-status" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_message_command_type_values[] = { + { MBIM_MESSAGE_COMMAND_TYPE_UNKNOWN, "MBIM_MESSAGE_COMMAND_TYPE_UNKNOWN", "unknown" }, + { MBIM_MESSAGE_COMMAND_TYPE_QUERY, "MBIM_MESSAGE_COMMAND_TYPE_QUERY", "query" }, + { MBIM_MESSAGE_COMMAND_TYPE_SET, "MBIM_MESSAGE_COMMAND_TYPE_SET", "set" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_device_type_values[] = { + { MBIM_DEVICE_TYPE_UNKNOWN, "MBIM_DEVICE_TYPE_UNKNOWN", "unknown" }, + { MBIM_DEVICE_TYPE_EMBEDDED, "MBIM_DEVICE_TYPE_EMBEDDED", "embedded" }, + { MBIM_DEVICE_TYPE_REMOVABLE, "MBIM_DEVICE_TYPE_REMOVABLE", "removable" }, + { MBIM_DEVICE_TYPE_REMOTE, "MBIM_DEVICE_TYPE_REMOTE", "remote" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_cellular_class_values[] = { + { MBIM_CELLULAR_CLASS_GSM, "MBIM_CELLULAR_CLASS_GSM", "gsm" }, + { MBIM_CELLULAR_CLASS_CDMA, "MBIM_CELLULAR_CLASS_CDMA", "cdma" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_voice_class_values[] = { + { MBIM_VOICE_CLASS_UNKNOWN, "MBIM_VOICE_CLASS_UNKNOWN", "unknown" }, + { MBIM_VOICE_CLASS_NO_VOICE, "MBIM_VOICE_CLASS_NO_VOICE", "no-voice" }, + { MBIM_VOICE_CLASS_SEPARATED_VOICE_DATA, "MBIM_VOICE_CLASS_SEPARATED_VOICE_DATA", "separated-voice-data" }, + { MBIM_VOICE_CLASS_SIMULTANEOUS_VOICE_DATA, "MBIM_VOICE_CLASS_SIMULTANEOUS_VOICE_DATA", "simultaneous-voice-data" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sim_class_values[] = { + { MBIM_SIM_CLASS_LOGICAL, "MBIM_SIM_CLASS_LOGICAL", "logical" }, + { MBIM_SIM_CLASS_REMOVABLE, "MBIM_SIM_CLASS_REMOVABLE", "removable" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_data_class_values[] = { + { MBIM_DATA_CLASS_GPRS, "MBIM_DATA_CLASS_GPRS", "gprs" }, + { MBIM_DATA_CLASS_EDGE, "MBIM_DATA_CLASS_EDGE", "edge" }, + { MBIM_DATA_CLASS_UMTS, "MBIM_DATA_CLASS_UMTS", "umts" }, + { MBIM_DATA_CLASS_HSDPA, "MBIM_DATA_CLASS_HSDPA", "hsdpa" }, + { MBIM_DATA_CLASS_HSUPA, "MBIM_DATA_CLASS_HSUPA", "hsupa" }, + { MBIM_DATA_CLASS_LTE, "MBIM_DATA_CLASS_LTE", "lte" }, + { MBIM_DATA_CLASS_1XRTT, "MBIM_DATA_CLASS_1XRTT", "1xrtt" }, + { MBIM_DATA_CLASS_1XEVDO, "MBIM_DATA_CLASS_1XEVDO", "1xevdo" }, + { MBIM_DATA_CLASS_1XEVDO_REVA, "MBIM_DATA_CLASS_1XEVDO_REVA", "1xevdo-reva" }, + { MBIM_DATA_CLASS_1XEVDV, "MBIM_DATA_CLASS_1XEVDV", "1xevdv" }, + { MBIM_DATA_CLASS_3XRTT, "MBIM_DATA_CLASS_3XRTT", "3xrtt" }, + { MBIM_DATA_CLASS_1XEVDO_REVB, "MBIM_DATA_CLASS_1XEVDO_REVB", "1xevdo-revb" }, + { MBIM_DATA_CLASS_UMB, "MBIM_DATA_CLASS_UMB", "umb" }, + { MBIM_DATA_CLASS_CUSTOM, "MBIM_DATA_CLASS_CUSTOM", "custom" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_caps_values[] = { + { MBIM_SMS_CAPS_PDU_RECEIVE, "MBIM_SMS_CAPS_PDU_RECEIVE", "pdu-receive" }, + { MBIM_SMS_CAPS_PDU_SEND, "MBIM_SMS_CAPS_PDU_SEND", "pdu-send" }, + { MBIM_SMS_CAPS_TEXT_RECEIVE, "MBIM_SMS_CAPS_TEXT_RECEIVE", "text-receive" }, + { MBIM_SMS_CAPS_TEXT_SEND, "MBIM_SMS_CAPS_TEXT_SEND", "text-send" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_ctrl_caps_values[] = { + { MBIM_CTRL_CAPS_REG_MANUAL, "MBIM_CTRL_CAPS_REG_MANUAL", "reg-manual" }, + { MBIM_CTRL_CAPS_HW_RADIO_SWITCH, "MBIM_CTRL_CAPS_HW_RADIO_SWITCH", "hw-radio-switch" }, + { MBIM_CTRL_CAPS_CDMA_MOBILE_IP, "MBIM_CTRL_CAPS_CDMA_MOBILE_IP", "cdma-mobile-ip" }, + { MBIM_CTRL_CAPS_CDMA_SIMPLE_IP, "MBIM_CTRL_CAPS_CDMA_SIMPLE_IP", "cdma-simple-ip" }, + { MBIM_CTRL_CAPS_MULTI_CARRIER, "MBIM_CTRL_CAPS_MULTI_CARRIER", "multi-carrier" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_subscriber_ready_state_values[] = { + { MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED, "MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED", "not-initialized" }, + { MBIM_SUBSCRIBER_READY_STATE_INITIALIZED, "MBIM_SUBSCRIBER_READY_STATE_INITIALIZED", "initialized" }, + { MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED, "MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED", "sim-not-inserted" }, + { MBIM_SUBSCRIBER_READY_STATE_BAD_SIM, "MBIM_SUBSCRIBER_READY_STATE_BAD_SIM", "bad-sim" }, + { MBIM_SUBSCRIBER_READY_STATE_FAILURE, "MBIM_SUBSCRIBER_READY_STATE_FAILURE", "failure" }, + { MBIM_SUBSCRIBER_READY_STATE_NOT_ACTIVATED, "MBIM_SUBSCRIBER_READY_STATE_NOT_ACTIVATED", "not-activated" }, + { MBIM_SUBSCRIBER_READY_STATE_DEVICE_LOCKED, "MBIM_SUBSCRIBER_READY_STATE_DEVICE_LOCKED", "device-locked" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_ready_info_flag_values[] = { + { MBIM_READY_INFO_FLAG_PROTECT_UNIQUE_ID, "MBIM_READY_INFO_FLAG_PROTECT_UNIQUE_ID", "id" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_radio_switch_state_values[] = { + { MBIM_RADIO_SWITCH_STATE_OFF, "MBIM_RADIO_SWITCH_STATE_OFF", "off" }, + { MBIM_RADIO_SWITCH_STATE_ON, "MBIM_RADIO_SWITCH_STATE_ON", "on" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_pin_type_values[] = { + { MBIM_PIN_TYPE_UNKNOWN, "MBIM_PIN_TYPE_UNKNOWN", "unknown" }, + { MBIM_PIN_TYPE_CUSTOM, "MBIM_PIN_TYPE_CUSTOM", "custom" }, + { MBIM_PIN_TYPE_PIN1, "MBIM_PIN_TYPE_PIN1", "pin1" }, + { MBIM_PIN_TYPE_PIN2, "MBIM_PIN_TYPE_PIN2", "pin2" }, + { MBIM_PIN_TYPE_DEVICE_SIM_PIN, "MBIM_PIN_TYPE_DEVICE_SIM_PIN", "device-sim-pin" }, + { MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PIN, "MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PIN", "device-first-sim-pin" }, + { MBIM_PIN_TYPE_NETWORK_PIN, "MBIM_PIN_TYPE_NETWORK_PIN", "network-pin" }, + { MBIM_PIN_TYPE_NETWORK_SUBSET_PIN, "MBIM_PIN_TYPE_NETWORK_SUBSET_PIN", "network-subset-pin" }, + { MBIM_PIN_TYPE_SERVICE_PROVIDER_PIN, "MBIM_PIN_TYPE_SERVICE_PROVIDER_PIN", "service-provider-pin" }, + { MBIM_PIN_TYPE_CORPORATE_PIN, "MBIM_PIN_TYPE_CORPORATE_PIN", "corporate-pin" }, + { MBIM_PIN_TYPE_SUBSIDY_PIN, "MBIM_PIN_TYPE_SUBSIDY_PIN", "subsidy-pin" }, + { MBIM_PIN_TYPE_PUK1, "MBIM_PIN_TYPE_PUK1", "puk1" }, + { MBIM_PIN_TYPE_PUK2, "MBIM_PIN_TYPE_PUK2", "puk2" }, + { MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PUK, "MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PUK", "device-first-sim-puk" }, + { MBIM_PIN_TYPE_NETWORK_PUK, "MBIM_PIN_TYPE_NETWORK_PUK", "network-puk" }, + { MBIM_PIN_TYPE_NETWORK_SUBSET_PUK, "MBIM_PIN_TYPE_NETWORK_SUBSET_PUK", "network-subset-puk" }, + { MBIM_PIN_TYPE_SERVICE_PROVIDER_PUK, "MBIM_PIN_TYPE_SERVICE_PROVIDER_PUK", "service-provider-puk" }, + { MBIM_PIN_TYPE_CORPORATE_PUK, "MBIM_PIN_TYPE_CORPORATE_PUK", "corporate-puk" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_pin_state_values[] = { + { MBIM_PIN_STATE_UNLOCKED, "MBIM_PIN_STATE_UNLOCKED", "unlocked" }, + { MBIM_PIN_STATE_LOCKED, "MBIM_PIN_STATE_LOCKED", "locked" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_pin_operation_values[] = { + { MBIM_PIN_OPERATION_ENTER, "MBIM_PIN_OPERATION_ENTER", "enter" }, + { MBIM_PIN_OPERATION_ENABLE, "MBIM_PIN_OPERATION_ENABLE", "enable" }, + { MBIM_PIN_OPERATION_DISABLE, "MBIM_PIN_OPERATION_DISABLE", "disable" }, + { MBIM_PIN_OPERATION_CHANGE, "MBIM_PIN_OPERATION_CHANGE", "change" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_pin_mode_values[] = { + { MBIM_PIN_MODE_NOT_SUPPORTED, "MBIM_PIN_MODE_NOT_SUPPORTED", "not-supported" }, + { MBIM_PIN_MODE_ENABLED, "MBIM_PIN_MODE_ENABLED", "enabled" }, + { MBIM_PIN_MODE_DISABLED, "MBIM_PIN_MODE_DISABLED", "disabled" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_pin_format_values[] = { + { MBIM_PIN_FORMAT_UNKNOWN, "MBIM_PIN_FORMAT_UNKNOWN", "unknown" }, + { MBIM_PIN_FORMAT_NUMERIC, "MBIM_PIN_FORMAT_NUMERIC", "numeric" }, + { MBIM_PIN_FORMAT_ALPHANUMERIC, "MBIM_PIN_FORMAT_ALPHANUMERIC", "alphanumeric" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_provider_state_values[] = { + { MBIM_PROVIDER_STATE_UNKNOWN, "MBIM_PROVIDER_STATE_UNKNOWN", "unknown" }, + { MBIM_PROVIDER_STATE_HOME, "MBIM_PROVIDER_STATE_HOME", "home" }, + { MBIM_PROVIDER_STATE_FORBIDDEN, "MBIM_PROVIDER_STATE_FORBIDDEN", "forbidden" }, + { MBIM_PROVIDER_STATE_PREFERRED, "MBIM_PROVIDER_STATE_PREFERRED", "preferred" }, + { MBIM_PROVIDER_STATE_VISIBLE, "MBIM_PROVIDER_STATE_VISIBLE", "visible" }, + { MBIM_PROVIDER_STATE_REGISTERED, "MBIM_PROVIDER_STATE_REGISTERED", "registered" }, + { MBIM_PROVIDER_STATE_PREFERRED_MULTICARRIER, "MBIM_PROVIDER_STATE_PREFERRED_MULTICARRIER", "preferred-multicarrier" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_visible_providers_action_values[] = { + { MBIM_VISIBLE_PROVIDERS_ACTION_FULL_SCAN, "MBIM_VISIBLE_PROVIDERS_ACTION_FULL_SCAN", "full-scan" }, + { MBIM_VISIBLE_PROVIDERS_ACTION_RESTRICTED_SCAN, "MBIM_VISIBLE_PROVIDERS_ACTION_RESTRICTED_SCAN", "restricted-scan" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_nw_error_values[] = { + { MBIM_NW_ERROR_UNKNOWN, "MBIM_NW_ERROR_UNKNOWN", "unknown" }, + { MBIM_NW_ERROR_IMSI_UNKNOWN_IN_HLR, "MBIM_NW_ERROR_IMSI_UNKNOWN_IN_HLR", "imsi-unknown-in-hlr" }, + { MBIM_NW_ERROR_ILLEGAL_MS, "MBIM_NW_ERROR_ILLEGAL_MS", "illegal-ms" }, + { MBIM_NW_ERROR_IMSI_UNKNOWN_IN_VLR, "MBIM_NW_ERROR_IMSI_UNKNOWN_IN_VLR", "imsi-unknown-in-vlr" }, + { MBIM_NW_ERROR_IMEI_NOT_ACCEPTED, "MBIM_NW_ERROR_IMEI_NOT_ACCEPTED", "imei-not-accepted" }, + { MBIM_NW_ERROR_ILLEGAL_ME, "MBIM_NW_ERROR_ILLEGAL_ME", "illegal-me" }, + { MBIM_NW_ERROR_GPRS_NOT_ALLOWED, "MBIM_NW_ERROR_GPRS_NOT_ALLOWED", "gprs-not-allowed" }, + { MBIM_NW_ERROR_GPRS_AND_NON_GPRS_NOT_ALLOWED, "MBIM_NW_ERROR_GPRS_AND_NON_GPRS_NOT_ALLOWED", "gprs-and-non-gprs-not-allowed" }, + { MBIM_NW_ERROR_MS_IDENTITY_NOT_DERIVED_BY_NETWORK, "MBIM_NW_ERROR_MS_IDENTITY_NOT_DERIVED_BY_NETWORK", "ms-identity-not-derived-by-network" }, + { MBIM_NW_ERROR_IMPLICITLY_DETACHED, "MBIM_NW_ERROR_IMPLICITLY_DETACHED", "implicitly-detached" }, + { MBIM_NW_ERROR_PLMN_NOT_ALLOWED, "MBIM_NW_ERROR_PLMN_NOT_ALLOWED", "plmn-not-allowed" }, + { MBIM_NW_ERROR_LOCATION_AREA_NOT_ALLOWED, "MBIM_NW_ERROR_LOCATION_AREA_NOT_ALLOWED", "location-area-not-allowed" }, + { MBIM_NW_ERROR_ROAMING_NOT_ALLOWED_IN_LOCATION_AREA, "MBIM_NW_ERROR_ROAMING_NOT_ALLOWED_IN_LOCATION_AREA", "roaming-not-allowed-in-location-area" }, + { MBIM_NW_ERROR_GPRS_NOT_ALLOWED_IN_PLMN, "MBIM_NW_ERROR_GPRS_NOT_ALLOWED_IN_PLMN", "gprs-not-allowed-in-plmn" }, + { MBIM_NW_ERROR_NO_CELLS_IN_LOCATION_AREA, "MBIM_NW_ERROR_NO_CELLS_IN_LOCATION_AREA", "no-cells-in-location-area" }, + { MBIM_NW_ERROR_MSC_TEMPORARILY_NOT_REACHABLE, "MBIM_NW_ERROR_MSC_TEMPORARILY_NOT_REACHABLE", "msc-temporarily-not-reachable" }, + { MBIM_NW_ERROR_NETWORK_FAILURE, "MBIM_NW_ERROR_NETWORK_FAILURE", "network-failure" }, + { MBIM_NW_ERROR_MAC_FAILURE, "MBIM_NW_ERROR_MAC_FAILURE", "mac-failure" }, + { MBIM_NW_ERROR_SYNCH_FAILURE, "MBIM_NW_ERROR_SYNCH_FAILURE", "synch-failure" }, + { MBIM_NW_ERROR_CONGESTION, "MBIM_NW_ERROR_CONGESTION", "congestion" }, + { MBIM_NW_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE, "MBIM_NW_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE", "gsm-authentication-unacceptable" }, + { MBIM_NW_ERROR_NOT_AUTHORIZED_FOR_CSG, "MBIM_NW_ERROR_NOT_AUTHORIZED_FOR_CSG", "not-authorized-for-csg" }, + { MBIM_NW_ERROR_MISSING_OR_UNKNOWN_APN, "MBIM_NW_ERROR_MISSING_OR_UNKNOWN_APN", "missing-or-unknown-apn" }, + { MBIM_NW_ERROR_SERVICE_OPTION_NOT_SUPPORTED, "MBIM_NW_ERROR_SERVICE_OPTION_NOT_SUPPORTED", "service-option-not-supported" }, + { MBIM_NW_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED, "MBIM_NW_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED", "requested-service-option-not-subscribed" }, + { MBIM_NW_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER, "MBIM_NW_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER", "service-option-temporarily-out-of-order" }, + { MBIM_NW_ERROR_NO_PDP_CONTEXT_ACTIVATED, "MBIM_NW_ERROR_NO_PDP_CONTEXT_ACTIVATED", "no-pdp-context-activated" }, + { MBIM_NW_ERROR_SEMANTICALLY_INCORRECT_MESSAGE, "MBIM_NW_ERROR_SEMANTICALLY_INCORRECT_MESSAGE", "semantically-incorrect-message" }, + { MBIM_NW_ERROR_INVALID_MANDATORY_INFORMATION, "MBIM_NW_ERROR_INVALID_MANDATORY_INFORMATION", "invalid-mandatory-information" }, + { MBIM_NW_ERROR_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED, "MBIM_NW_ERROR_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED", "message-type-non-existent-or-not-implemented" }, + { MBIM_NW_ERROR_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, "MBIM_NW_ERROR_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE", "message-type-not-compatible-with-protocol-state" }, + { MBIM_NW_ERROR_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED, "MBIM_NW_ERROR_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED", "information-element-non-existent-or-not-implemented" }, + { MBIM_NW_ERROR_CONDITIONAL_IE_ERROR, "MBIM_NW_ERROR_CONDITIONAL_IE_ERROR", "conditional-ie-error" }, + { MBIM_NW_ERROR_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, "MBIM_NW_ERROR_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE", "message-not-compatible-with-protocol-state" }, + { MBIM_NW_ERROR_PROTOCOL_ERROR_UNSPECIFIED, "MBIM_NW_ERROR_PROTOCOL_ERROR_UNSPECIFIED", "protocol-error-unspecified" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_register_action_values[] = { + { MBIM_REGISTER_ACTION_AUTOMATIC, "MBIM_REGISTER_ACTION_AUTOMATIC", "automatic" }, + { MBIM_REGISTER_ACTION_MANUAL, "MBIM_REGISTER_ACTION_MANUAL", "manual" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_register_state_values[] = { + { MBIM_REGISTER_STATE_UNKNOWN, "MBIM_REGISTER_STATE_UNKNOWN", "unknown" }, + { MBIM_REGISTER_STATE_DEREGISTERED, "MBIM_REGISTER_STATE_DEREGISTERED", "deregistered" }, + { MBIM_REGISTER_STATE_SEARCHING, "MBIM_REGISTER_STATE_SEARCHING", "searching" }, + { MBIM_REGISTER_STATE_HOME, "MBIM_REGISTER_STATE_HOME", "home" }, + { MBIM_REGISTER_STATE_ROAMING, "MBIM_REGISTER_STATE_ROAMING", "roaming" }, + { MBIM_REGISTER_STATE_PARTNER, "MBIM_REGISTER_STATE_PARTNER", "partner" }, + { MBIM_REGISTER_STATE_DENIED, "MBIM_REGISTER_STATE_DENIED", "denied" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_register_mode_values[] = { + { MBIM_REGISTER_MODE_UNKNOWN, "MBIM_REGISTER_MODE_UNKNOWN", "unknown" }, + { MBIM_REGISTER_MODE_AUTOMATIC, "MBIM_REGISTER_MODE_AUTOMATIC", "automatic" }, + { MBIM_REGISTER_MODE_MANUAL, "MBIM_REGISTER_MODE_MANUAL", "manual" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_registration_flag_values[] = { + { MBIM_REGISTRATION_FLAG_NONE, "MBIM_REGISTRATION_FLAG_NONE", "none" }, + { MBIM_REGISTRATION_FLAG_MANUAL_SELECTION_NOT_AVAILABLE, "MBIM_REGISTRATION_FLAG_MANUAL_SELECTION_NOT_AVAILABLE", "manual-selection-not-available" }, + { MBIM_REGISTRATION_FLAG_PACKET_SERVICE_AUTOMATIC_ATTACH, "MBIM_REGISTRATION_FLAG_PACKET_SERVICE_AUTOMATIC_ATTACH", "packet-service-automatic-attach" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_packet_service_action_values[] = { + { MBIM_PACKET_SERVICE_ACTION_ATTACH, "MBIM_PACKET_SERVICE_ACTION_ATTACH", "attach" }, + { MBIM_PACKET_SERVICE_ACTION_DETACH, "MBIM_PACKET_SERVICE_ACTION_DETACH", "detach" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_packet_service_state_values[] = { + { MBIM_PACKET_SERVICE_STATE_UNKNOWN, "MBIM_PACKET_SERVICE_STATE_UNKNOWN", "unknown" }, + { MBIM_PACKET_SERVICE_STATE_ATTACHING, "MBIM_PACKET_SERVICE_STATE_ATTACHING", "attaching" }, + { MBIM_PACKET_SERVICE_STATE_ATTACHED, "MBIM_PACKET_SERVICE_STATE_ATTACHED", "attached" }, + { MBIM_PACKET_SERVICE_STATE_DETACHING, "MBIM_PACKET_SERVICE_STATE_DETACHING", "detaching" }, + { MBIM_PACKET_SERVICE_STATE_DETACHED, "MBIM_PACKET_SERVICE_STATE_DETACHED", "detached" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_activation_command_values[] = { + { MBIM_ACTIVATION_COMMAND_DEACTIVATE, "MBIM_ACTIVATION_COMMAND_DEACTIVATE", "deactivate" }, + { MBIM_ACTIVATION_COMMAND_ACTIVATE, "MBIM_ACTIVATION_COMMAND_ACTIVATE", "activate" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_compression_values[] = { + { MBIM_COMPRESSION_NONE, "MBIM_COMPRESSION_NONE", "none" }, + { MBIM_COMPRESSION_ENABLE, "MBIM_COMPRESSION_ENABLE", "enable" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_auth_protocol_values[] = { + { MBIM_AUTH_PROTOCOL_NONE, "MBIM_AUTH_PROTOCOL_NONE", "none" }, + { MBIM_AUTH_PROTOCOL_PAP, "MBIM_AUTH_PROTOCOL_PAP", "pap" }, + { MBIM_AUTH_PROTOCOL_CHAP, "MBIM_AUTH_PROTOCOL_CHAP", "chap" }, + { MBIM_AUTH_PROTOCOL_MSCHAPV2, "MBIM_AUTH_PROTOCOL_MSCHAPV2", "mschapv2" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_context_ip_type_values[] = { + { MBIM_CONTEXT_IP_TYPE_DEFAULT, "MBIM_CONTEXT_IP_TYPE_DEFAULT", "default" }, + { MBIM_CONTEXT_IP_TYPE_IPV4, "MBIM_CONTEXT_IP_TYPE_IPV4", "ipv4" }, + { MBIM_CONTEXT_IP_TYPE_IPV6, "MBIM_CONTEXT_IP_TYPE_IPV6", "ipv6" }, + { MBIM_CONTEXT_IP_TYPE_IPV4V6, "MBIM_CONTEXT_IP_TYPE_IPV4V6", "ipv4v6" }, + { MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6, "MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6", "ipv4-and-ipv6" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_activation_state_values[] = { + { MBIM_ACTIVATION_STATE_UNKNOWN, "MBIM_ACTIVATION_STATE_UNKNOWN", "unknown" }, + { MBIM_ACTIVATION_STATE_ACTIVATED, "MBIM_ACTIVATION_STATE_ACTIVATED", "activated" }, + { MBIM_ACTIVATION_STATE_ACTIVATING, "MBIM_ACTIVATION_STATE_ACTIVATING", "activating" }, + { MBIM_ACTIVATION_STATE_DEACTIVATED, "MBIM_ACTIVATION_STATE_DEACTIVATED", "deactivated" }, + { MBIM_ACTIVATION_STATE_DEACTIVATING, "MBIM_ACTIVATION_STATE_DEACTIVATING", "deactivating" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_voice_call_state_values[] = { + { MBIM_VOICE_CALL_STATE_NONE, "MBIM_VOICE_CALL_STATE_NONE", "none" }, + { MBIM_VOICE_CALL_STATE_IN_PROGRESS, "MBIM_VOICE_CALL_STATE_IN_PROGRESS", "in-progress" }, + { MBIM_VOICE_CALL_STATE_HANG_UP, "MBIM_VOICE_CALL_STATE_HANG_UP", "hang-up" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_ip_configuration_available_flag_values[] = { + { MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE, "MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE", "none" }, + { MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS, "MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS", "address" }, + { MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY, "MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY", "gateway" }, + { MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS, "MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS", "dns" }, + { MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU, "MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU", "mtu" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_storage_state_values[] = { + { MBIM_SMS_STORAGE_STATE_NOT_INITIALIZED, "MBIM_SMS_STORAGE_STATE_NOT_INITIALIZED", "not-initialized" }, + { MBIM_SMS_STORAGE_STATE_INITIALIZED, "MBIM_SMS_STORAGE_STATE_INITIALIZED", "initialized" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_format_values[] = { + { MBIM_SMS_FORMAT_PDU, "MBIM_SMS_FORMAT_PDU", "pdu" }, + { MBIM_SMS_FORMAT_CDMA, "MBIM_SMS_FORMAT_CDMA", "cdma" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_flag_values[] = { + { MBIM_SMS_FLAG_ALL, "MBIM_SMS_FLAG_ALL", "all" }, + { MBIM_SMS_FLAG_INDEX, "MBIM_SMS_FLAG_INDEX", "index" }, + { MBIM_SMS_FLAG_NEW, "MBIM_SMS_FLAG_NEW", "new" }, + { MBIM_SMS_FLAG_OLD, "MBIM_SMS_FLAG_OLD", "old" }, + { MBIM_SMS_FLAG_SENT, "MBIM_SMS_FLAG_SENT", "sent" }, + { MBIM_SMS_FLAG_DRAFT, "MBIM_SMS_FLAG_DRAFT", "draft" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_cdma_lang_values[] = { + { MBIM_SMS_CDMA_LANG_UNKNOWN, "MBIM_SMS_CDMA_LANG_UNKNOWN", "unknown" }, + { MBIM_SMS_CDMA_LANG_ENGLISH, "MBIM_SMS_CDMA_LANG_ENGLISH", "english" }, + { MBIM_SMS_CDMA_LANG_FRENCH, "MBIM_SMS_CDMA_LANG_FRENCH", "french" }, + { MBIM_SMS_CDMA_LANG_SPANISH, "MBIM_SMS_CDMA_LANG_SPANISH", "spanish" }, + { MBIM_SMS_CDMA_LANG_JAPANESE, "MBIM_SMS_CDMA_LANG_JAPANESE", "japanese" }, + { MBIM_SMS_CDMA_LANG_KOREAN, "MBIM_SMS_CDMA_LANG_KOREAN", "korean" }, + { MBIM_SMS_CDMA_LANG_CHINESE, "MBIM_SMS_CDMA_LANG_CHINESE", "chinese" }, + { MBIM_SMS_CDMA_LANG_HEBREW, "MBIM_SMS_CDMA_LANG_HEBREW", "hebrew" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_cdma_encoding_values[] = { + { MBIM_SMS_CDMA_ENCODING_OCTET, "MBIM_SMS_CDMA_ENCODING_OCTET", "octet" }, + { MBIM_SMS_CDMA_ENCODING_EPM, "MBIM_SMS_CDMA_ENCODING_EPM", "epm" }, + { MBIM_SMS_CDMA_ENCODING_7BIT_ASCII, "MBIM_SMS_CDMA_ENCODING_7BIT_ASCII", "7bit-ascii" }, + { MBIM_SMS_CDMA_ENCODING_LA5, "MBIM_SMS_CDMA_ENCODING_LA5", "la5" }, + { MBIM_SMS_CDMA_ENCODING_UNICODE, "MBIM_SMS_CDMA_ENCODING_UNICODE", "unicode" }, + { MBIM_SMS_CDMA_ENCODING_SHIFT_JIS, "MBIM_SMS_CDMA_ENCODING_SHIFT_JIS", "shift-jis" }, + { MBIM_SMS_CDMA_ENCODING_KOREAN, "MBIM_SMS_CDMA_ENCODING_KOREAN", "korean" }, + { MBIM_SMS_CDMA_ENCODING_LATIN_HEBREW, "MBIM_SMS_CDMA_ENCODING_LATIN_HEBREW", "latin-hebrew" }, + { MBIM_SMS_CDMA_ENCODING_LATIN, "MBIM_SMS_CDMA_ENCODING_LATIN", "latin" }, + { MBIM_SMS_CDMA_ENCODING_GSM_7BIT, "MBIM_SMS_CDMA_ENCODING_GSM_7BIT", "gsm-7bit" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_status_values[] = { + { MBIM_SMS_STATUS_NEW, "MBIM_SMS_STATUS_NEW", "new" }, + { MBIM_SMS_STATUS_OLD, "MBIM_SMS_STATUS_OLD", "old" }, + { MBIM_SMS_STATUS_DRAFT, "MBIM_SMS_STATUS_DRAFT", "draft" }, + { MBIM_SMS_STATUS_SENT, "MBIM_SMS_STATUS_SENT", "sent" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_sms_status_flag_values[] = { + { MBIM_SMS_STATUS_FLAG_NONE, "MBIM_SMS_STATUS_FLAG_NONE", "none" }, + { MBIM_SMS_STATUS_FLAG_MESSAGE_STORE_FULL, "MBIM_SMS_STATUS_FLAG_MESSAGE_STORE_FULL", "message-store-full" }, + { MBIM_SMS_STATUS_FLAG_NEW_MESSAGE, "MBIM_SMS_STATUS_FLAG_NEW_MESSAGE", "new-message" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_ussd_action_values[] = { + { MBIM_USSD_ACTION_INITIATE, "MBIM_USSD_ACTION_INITIATE", "initiate" }, + { MBIM_USSD_ACTION_CONTINUE, "MBIM_USSD_ACTION_CONTINUE", "continue" }, + { MBIM_USSD_ACTION_CANCEL, "MBIM_USSD_ACTION_CANCEL", "cancel" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_ussd_response_values[] = { + { MBIM_USSD_RESPONSE_NO_ACTION_REQUIRED, "MBIM_USSD_RESPONSE_NO_ACTION_REQUIRED", "no-action-required" }, + { MBIM_USSD_RESPONSE_ACTION_REQUIRED, "MBIM_USSD_RESPONSE_ACTION_REQUIRED", "action-required" }, + { MBIM_USSD_RESPONSE_TERMINATED_BY_NETWORK, "MBIM_USSD_RESPONSE_TERMINATED_BY_NETWORK", "terminated-by-network" }, + { MBIM_USSD_RESPONSE_OTHER_LOCAL_CLIENT, "MBIM_USSD_RESPONSE_OTHER_LOCAL_CLIENT", "other-local-client" }, + { MBIM_USSD_RESPONSE_OPERATION_NOT_SUPPORTED, "MBIM_USSD_RESPONSE_OPERATION_NOT_SUPPORTED", "operation-not-supported" }, + { MBIM_USSD_RESPONSE_NETWORK_TIMEOUT, "MBIM_USSD_RESPONSE_NETWORK_TIMEOUT", "network-timeout" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_ussd_session_state_values[] = { + { MBIM_USSD_SESSION_STATE_NEW_SESSION, "MBIM_USSD_SESSION_STATE_NEW_SESSION", "new-session" }, + { MBIM_USSD_SESSION_STATE_EXISTING_SESSION, "MBIM_USSD_SESSION_STATE_EXISTING_SESSION", "existing-session" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_phonebook_state_values[] = { + { MBIM_PHONEBOOK_STATE_NOT_INITIALIZED, "MBIM_PHONEBOOK_STATE_NOT_INITIALIZED", "not-initialized" }, + { MBIM_PHONEBOOK_STATE_INITIALIZED, "MBIM_PHONEBOOK_STATE_INITIALIZED", "initialized" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_phonebook_flag_values[] = { + { MBIM_PHONEBOOK_FLAG_ALL, "MBIM_PHONEBOOK_FLAG_ALL", "all" }, + { MBIM_PHONEBOOK_FLAG_INDEX, "MBIM_PHONEBOOK_FLAG_INDEX", "index" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_phonebook_write_flag_values[] = { + { MBIM_PHONEBOOK_WRITE_FLAG_SAVE_UNUSED, "MBIM_PHONEBOOK_WRITE_FLAG_SAVE_UNUSED", "unused" }, + { MBIM_PHONEBOOK_WRITE_FLAG_SAVE_INDEX, "MBIM_PHONEBOOK_WRITE_FLAG_SAVE_INDEX", "index" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_stk_pac_profile_values[] = { + { MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_HANDLED_BY_HOST, "MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_HANDLED_BY_HOST", "not-handled-by-function-handled-by-host" }, + { MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_MAY_BE_HANDLED_BY_HOST, "MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_MAY_BE_HANDLED_BY_HOST", "not-handled-by-function-may-be-handled-by-host" }, + { MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_ONLY_TRANSPARENT_TO_HOST, "MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_ONLY_TRANSPARENT_TO_HOST", "handled-by-function-only-transparent-to-host" }, + { MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATION_TO_HOST_POSSIBLE, "MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATION_TO_HOST_POSSIBLE", "handled-by-function-notification-to-host-possible" }, + { MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATIONS_TO_HOST_ENABLED, "MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATIONS_TO_HOST_ENABLED", "handled-by-function-notifications-to-host-enabled" }, + { MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_CAN_BE_OVERRIDEN_BY_HOST, "MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_CAN_BE_OVERRIDEN_BY_HOST", "handled-by-function-can-be-overriden-by-host" }, + { MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_NOT_ABLE_TO_HANDLE, "MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_NOT_ABLE_TO_HANDLE", "handled-by-host-function-not-able-to-handle" }, + { MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_ABLE_TO_HANDLE, "MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_ABLE_TO_HANDLE", "handled-by-host-function-able-to-handle" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_stk_pac_type_values[] = { + { MBIM_STK_PAC_TYPE_PROACTIVE_COMMAND, "MBIM_STK_PAC_TYPE_PROACTIVE_COMMAND", "proactive-command" }, + { MBIM_STK_PAC_TYPE_NOTIFICATION, "MBIM_STK_PAC_TYPE_NOTIFICATION", "notification" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_network_idle_hint_state_values[] = { + { MBIM_NETWORK_IDLE_HINT_STATE_DISABLED, "MBIM_NETWORK_IDLE_HINT_STATE_DISABLED", "disabled" }, + { MBIM_NETWORK_IDLE_HINT_STATE_ENABLED, "MBIM_NETWORK_IDLE_HINT_STATE_ENABLED", "enabled" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_emergency_mode_state_values[] = { + { MBIM_EMERGENCY_MODE_STATE_OFF, "MBIM_EMERGENCY_MODE_STATE_OFF", "off" }, + { MBIM_EMERGENCY_MODE_STATE_ON, "MBIM_EMERGENCY_MODE_STATE_ON", "on" }, + { 0, NULL, NULL }, +}; + +struct mbim_enum mbim_dss_link_state_values[] = { + { MBIM_DSS_LINK_STATE_DEACTIVATE, "MBIM_DSS_LINK_STATE_DEACTIVATE", "deactivate" }, + { MBIM_DSS_LINK_STATE_ACTIVATE, "MBIM_DSS_LINK_STATE_ACTIVATE", "activate" }, + { 0, NULL, NULL }, +}; diff --git a/mbim-enum.h b/mbim-enum.h new file mode 100644 index 0000000..3f6f414 --- /dev/null +++ b/mbim-enum.h @@ -0,0 +1,1062 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* + * libmbim-glib -- GLib/GIO based library to control MBIM devices + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2013 - 2014 Aleksander Morgado + */ + +#ifndef _LIBMBIM_GLIB_MBIM_ENUMS_H_ +#define _LIBMBIM_GLIB_MBIM_ENUMS_H_ + +/** + * MbimMessageType: + * @MBIM_MESSAGE_TYPE_INVALID: Invalid MBIM message. + * @MBIM_MESSAGE_TYPE_OPEN: Initialization request. + * @MBIM_MESSAGE_TYPE_CLOSE: Close request. + * @MBIM_MESSAGE_TYPE_COMMAND: Command request. + * @MBIM_MESSAGE_TYPE_HOST_ERROR: Host-reported error in the communication. + * @MBIM_MESSAGE_TYPE_OPEN_DONE: Response to initialization request. + * @MBIM_MESSAGE_TYPE_CLOSE_DONE: Response to close request. + * @MBIM_MESSAGE_TYPE_COMMAND_DONE: Response to command request. + * @MBIM_MESSAGE_TYPE_FUNCTION_ERROR: Function-reported error in the communication. + * @MBIM_MESSAGE_TYPE_INDICATE_STATUS: Unsolicited message from the function. + * + * Type of MBIM messages. + */ +typedef enum { + MBIM_MESSAGE_TYPE_INVALID = 0x00000000, + /* From Host to Function */ + MBIM_MESSAGE_TYPE_OPEN = 0x00000001, + MBIM_MESSAGE_TYPE_CLOSE = 0x00000002, + MBIM_MESSAGE_TYPE_COMMAND = 0x00000003, + MBIM_MESSAGE_TYPE_HOST_ERROR = 0x00000004, + /* From Function to Host */ + MBIM_MESSAGE_TYPE_OPEN_DONE = 0x80000001, + MBIM_MESSAGE_TYPE_CLOSE_DONE = 0x80000002, + MBIM_MESSAGE_TYPE_COMMAND_DONE = 0x80000003, + MBIM_MESSAGE_TYPE_FUNCTION_ERROR = 0x80000004, + MBIM_MESSAGE_TYPE_INDICATE_STATUS = 0x80000007 +} MbimMessageType; + +/** + * MbimMessageCommandType: + * @MBIM_MESSAGE_COMMAND_TYPE_UNKNOWN: Unknown type. + * @MBIM_MESSAGE_COMMAND_TYPE_QUERY: Query command. + * @MBIM_MESSAGE_COMMAND_TYPE_SET: Set command. + * + * Type of command message. + */ +typedef enum { + MBIM_MESSAGE_COMMAND_TYPE_UNKNOWN = -1, + MBIM_MESSAGE_COMMAND_TYPE_QUERY = 0, + MBIM_MESSAGE_COMMAND_TYPE_SET = 1 +} MbimMessageCommandType; + +/** + * SECTION: mbim-enums + * @title: Enumerations and Flags + * @short_description: Common enumeration and flag types. + * + * This section defines common enum and flag types used in the interface. + */ + +/*****************************************************************************/ +/* 'Device Caps' enums */ + +/** + * MbimDeviceType: + * @MBIM_DEVICE_TYPE_UNKNOWN: Unknown type. + * @MBIM_DEVICE_TYPE_EMBEDDED: Device is embedded in the system. + * @MBIM_DEVICE_TYPE_REMOVABLE: Device is removable. + * @MBIM_DEVICE_TYPE_REMOTE: Device is remote. + * + * Type of device. + */ +typedef enum { + MBIM_DEVICE_TYPE_UNKNOWN = 0, + MBIM_DEVICE_TYPE_EMBEDDED = 1, + MBIM_DEVICE_TYPE_REMOVABLE = 2, + MBIM_DEVICE_TYPE_REMOTE = 3 +} MbimDeviceType; + +/** + * MbimCellularClass: + * @MBIM_CELLULAR_CLASS_GSM: Device is 3GPP. + * @MBIM_CELLULAR_CLASS_CDMA: Device is 3GPP2. + * + * Cellular class. + */ +typedef enum { + MBIM_CELLULAR_CLASS_GSM = 1 << 0, + MBIM_CELLULAR_CLASS_CDMA = 1 << 1 +} MbimCellularClass; + +/** + * MbimVoiceClass: + * @MBIM_VOICE_CLASS_UNKNOWN: Unknown voice class. + * @MBIM_VOICE_CLASS_NO_VOICE: Device doesn't support voice. + * @MBIM_VOICE_CLASS_SEPARATED_VOICE_DATA: Device supports separate voice and data connections. + * @MBIM_VOICE_CLASS_SIMULTANEOUS_VOICE_DATA: Device supports simultaneous voice and data connections. + * + * Voice class. + */ +typedef enum { + MBIM_VOICE_CLASS_UNKNOWN = 0, + MBIM_VOICE_CLASS_NO_VOICE = 1, + MBIM_VOICE_CLASS_SEPARATED_VOICE_DATA = 2, + MBIM_VOICE_CLASS_SIMULTANEOUS_VOICE_DATA = 3 +} MbimVoiceClass; + +/** + * MbimSimClass: + * @MBIM_SIM_CLASS_LOGICAL: No physical SIM. + * @MBIM_SIM_CLASS_REMOVABLE: Physical removable SIM. + * + * SIM class. + */ +typedef enum { + MBIM_SIM_CLASS_LOGICAL = 1 << 0, + MBIM_SIM_CLASS_REMOVABLE = 1 << 1 +} MbimSimClass; + +/** + * MbimDataClass: + * @MBIM_DATA_CLASS_GPRS: GPRS. + * @MBIM_DATA_CLASS_EDGE: EDGE. + * @MBIM_DATA_CLASS_UMTS: UMTS. + * @MBIM_DATA_CLASS_HSDPA: HSDPA. + * @MBIM_DATA_CLASS_HSUPA: HSUPA. + * @MBIM_DATA_CLASS_LTE: LTE. + * @MBIM_DATA_CLASS_1XRTT: 1xRTT. + * @MBIM_DATA_CLASS_1XEVDO: 1xEV-DO. + * @MBIM_DATA_CLASS_1XEVDO_REVA: 1xEV-DO RevA + * @MBIM_DATA_CLASS_1XEVDV: 1xEV-DV. + * @MBIM_DATA_CLASS_3XRTT: 3xRTT. + * @MBIM_DATA_CLASS_1XEVDO_REVB: 1xEV-DO RevB. + * @MBIM_DATA_CLASS_UMB: UMB. + * @MBIM_DATA_CLASS_CUSTOM: Custom. + * + * Data class. + */ +typedef enum { + MBIM_DATA_CLASS_GPRS = 1 << 0, + MBIM_DATA_CLASS_EDGE = 1 << 1, + MBIM_DATA_CLASS_UMTS = 1 << 2, + MBIM_DATA_CLASS_HSDPA = 1 << 3, + MBIM_DATA_CLASS_HSUPA = 1 << 4, + MBIM_DATA_CLASS_LTE = 1 << 5, + /* Bits 6 to 15 reserved for future 3GPP classes */ + MBIM_DATA_CLASS_1XRTT = 1 << 16, + MBIM_DATA_CLASS_1XEVDO = 1 << 17, + MBIM_DATA_CLASS_1XEVDO_REVA = 1 << 18, + MBIM_DATA_CLASS_1XEVDV = 1 << 19, + MBIM_DATA_CLASS_3XRTT = 1 << 20, + MBIM_DATA_CLASS_1XEVDO_REVB = 1 << 21, + MBIM_DATA_CLASS_UMB = 1 << 22, + /* Bits 23 to 30 reserved for future 3GPP2 classes */ + MBIM_DATA_CLASS_CUSTOM = 1 << 31 +} MbimDataClass; + +/** + * MbimSmsCaps: + * @MBIM_SMS_CAPS_PDU_RECEIVE: Can receive in PDU mode. + * @MBIM_SMS_CAPS_PDU_SEND: Can send in PDU mode. + * @MBIM_SMS_CAPS_TEXT_RECEIVE: Can receive in text mode. + * @MBIM_SMS_CAPS_TEXT_SEND: Can send in text mode. + * + * SMS capabilities. + */ +typedef enum { + MBIM_SMS_CAPS_PDU_RECEIVE = 1 << 0, + MBIM_SMS_CAPS_PDU_SEND = 1 << 1, + MBIM_SMS_CAPS_TEXT_RECEIVE = 1 << 2, + MBIM_SMS_CAPS_TEXT_SEND = 1 << 3 +} MbimSmsCaps; + +/** + * MbimCtrlCaps: + * @MBIM_CTRL_CAPS_REG_MANUAL: Device allows manual network selection. + * @MBIM_CTRL_CAPS_HW_RADIO_SWITCH: Device has a hardware radio power switch. + * @MBIM_CTRL_CAPS_CDMA_MOBILE_IP: The CDMA function supports Mobile IP. + * @MBIM_CTRL_CAPS_CDMA_SIMPLE_IP: The CDMA function supports Simple IP. + * @MBIM_CTRL_CAPS_MULTI_CARRIER: Device can work with multiple providers. + * + * Control capabilities. + */ +typedef enum { + MBIM_CTRL_CAPS_REG_MANUAL = 1 << 0, + MBIM_CTRL_CAPS_HW_RADIO_SWITCH = 1 << 1, + MBIM_CTRL_CAPS_CDMA_MOBILE_IP = 1 << 2, + MBIM_CTRL_CAPS_CDMA_SIMPLE_IP = 1 << 3, + MBIM_CTRL_CAPS_MULTI_CARRIER = 1 << 4 +} MbimCtrlCaps; + +/*****************************************************************************/ +/* 'Subscriber Ready Status' enums */ + +/** + * MbimSubscriberReadyState: + * @MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED: Not initialized. + * @MBIM_SUBSCRIBER_READY_STATE_INITIALIZED: Initialized. + * @MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED: SIM not inserted. + * @MBIM_SUBSCRIBER_READY_STATE_BAD_SIM: Bad SIM. + * @MBIM_SUBSCRIBER_READY_STATE_FAILURE: Failure. + * @MBIM_SUBSCRIBER_READY_STATE_NOT_ACTIVATED: Not activated. + * @MBIM_SUBSCRIBER_READY_STATE_DEVICE_LOCKED: Device locked. + * + * Ready state of the subscriber. + */ +typedef enum { + MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED = 0, + MBIM_SUBSCRIBER_READY_STATE_INITIALIZED = 1, + MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED = 2, + MBIM_SUBSCRIBER_READY_STATE_BAD_SIM = 3, + MBIM_SUBSCRIBER_READY_STATE_FAILURE = 4, + MBIM_SUBSCRIBER_READY_STATE_NOT_ACTIVATED = 5, + MBIM_SUBSCRIBER_READY_STATE_DEVICE_LOCKED = 6, +} MbimSubscriberReadyState; + +/** + * MbimReadyInfoFlag: + * @MBIM_READY_INFO_FLAG_PROTECT_UNIQUE_ID: Request to avoid displaying subscriber ID. + */ +typedef enum { + MBIM_READY_INFO_FLAG_PROTECT_UNIQUE_ID = 1 << 0 +} MbimReadyInfoFlag; + +/*****************************************************************************/ +/* 'Radio State' enums */ + +/** + * MbimRadioSwitchState: + * @MBIM_RADIO_SWITCH_STATE_OFF: Radio is off. + * @MBIM_RADIO_SWITCH_STATE_ON: Radio is on. + * + * Radio switch state. + */ +typedef enum { + MBIM_RADIO_SWITCH_STATE_OFF = 0, + MBIM_RADIO_SWITCH_STATE_ON = 1 +} MbimRadioSwitchState; + +/*****************************************************************************/ +/* 'Pin' enums */ + +/** + * MbimPinType: + * @MBIM_PIN_TYPE_UNKNOWN: Unknown or unset. + * @MBIM_PIN_TYPE_CUSTOM: The PIN type is a custom type and is none of the other PIN types listed in this enumeration. + * @MBIM_PIN_TYPE_PIN1: The PIN1 key. + * @MBIM_PIN_TYPE_PIN2: The PIN2 key. + * @MBIM_PIN_TYPE_DEVICE_SIM_PIN: The device to SIM key. + * @MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PIN: The device to very first SIM key. + * @MBIM_PIN_TYPE_NETWORK_PIN: The network personalization key. + * @MBIM_PIN_TYPE_NETWORK_SUBSET_PIN: The network subset personalization key. + * @MBIM_PIN_TYPE_SERVICE_PROVIDER_PIN: The service provider (SP) personalization key. + * @MBIM_PIN_TYPE_CORPORATE_PIN: The corporate personalization key. + * @MBIM_PIN_TYPE_SUBSIDY_PIN: The subsidy unlock key. + * @MBIM_PIN_TYPE_PUK1: The Personal Identification Number1 Unlock Key (PUK1). + * @MBIM_PIN_TYPE_PUK2: The Personal Identification Number2 Unlock Key (PUK2). + * @MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PUK: The device to very first SIM PIN unlock key. + * @MBIM_PIN_TYPE_NETWORK_PUK: The network personalization unlock key. + * @MBIM_PIN_TYPE_NETWORK_SUBSET_PUK: The network subset personalization unlock key. + * @MBIM_PIN_TYPE_SERVICE_PROVIDER_PUK: The service provider (SP) personalization unlock key. + * @MBIM_PIN_TYPE_CORPORATE_PUK: The corporate personalization unlock key. + * + * PIN Types. + */ +typedef enum { + MBIM_PIN_TYPE_UNKNOWN = 0, + MBIM_PIN_TYPE_CUSTOM = 1, + MBIM_PIN_TYPE_PIN1 = 2, + MBIM_PIN_TYPE_PIN2 = 3, + MBIM_PIN_TYPE_DEVICE_SIM_PIN = 4, + MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PIN = 5, + MBIM_PIN_TYPE_NETWORK_PIN = 6, + MBIM_PIN_TYPE_NETWORK_SUBSET_PIN = 7, + MBIM_PIN_TYPE_SERVICE_PROVIDER_PIN = 8, + MBIM_PIN_TYPE_CORPORATE_PIN = 9, + MBIM_PIN_TYPE_SUBSIDY_PIN = 10, + MBIM_PIN_TYPE_PUK1 = 11, + MBIM_PIN_TYPE_PUK2 = 12, + MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PUK = 13, + MBIM_PIN_TYPE_NETWORK_PUK = 14, + MBIM_PIN_TYPE_NETWORK_SUBSET_PUK = 15, + MBIM_PIN_TYPE_SERVICE_PROVIDER_PUK = 16, + MBIM_PIN_TYPE_CORPORATE_PUK = 17 +} MbimPinType; + +/** + * MbimPinState: + * @MBIM_PIN_STATE_UNLOCKED: The device does not require a PIN. + * @MBIM_PIN_STATE_LOCKED: The device requires the user to enter a PIN. + * + * PIN States. + */ +typedef enum { + MBIM_PIN_STATE_UNLOCKED = 0, + MBIM_PIN_STATE_LOCKED = 1 +} MbimPinState; + +/** + * MbimPinOperation: + * @MBIM_PIN_OPERATION_ENTER: Enter the specified PIN into the device. + * @MBIM_PIN_OPERATION_ENABLE: Enable the specified PIN. + * @MBIM_PIN_OPERATION_DISABLE: Disable the specified PIN. + * @MBIM_PIN_OPERATION_CHANGE: Change the specified PIN. +*/ +typedef enum { + MBIM_PIN_OPERATION_ENTER = 0, + MBIM_PIN_OPERATION_ENABLE = 1, + MBIM_PIN_OPERATION_DISABLE = 2, + MBIM_PIN_OPERATION_CHANGE = 3 +} MbimPinOperation; + +/*****************************************************************************/ +/* 'Pin List' enums */ + +/** + * MbimPinMode: + * @MBIM_PIN_MODE_NOT_SUPPORTED: Not supported. + * @MBIM_PIN_MODE_ENABLED: Enabled. + * @MBIM_PIN_MODE_DISABLED: Disabled. + * + * Whether the lock is enabled or disabled. + */ +typedef enum { + MBIM_PIN_MODE_NOT_SUPPORTED = 0, + MBIM_PIN_MODE_ENABLED = 1, + MBIM_PIN_MODE_DISABLED = 2 +} MbimPinMode; + +/** + * MbimPinFormat: + * @MBIM_PIN_FORMAT_UNKNOWN: Unknown format. + * @MBIM_PIN_FORMAT_NUMERIC: Numeric-only format. + * @MBIM_PIN_FORMAT_ALPHANUMERIC: Alphanumeric format. + * + * Format of the expected PIN code. + */ +typedef enum { + MBIM_PIN_FORMAT_UNKNOWN = 0, + MBIM_PIN_FORMAT_NUMERIC = 1, + MBIM_PIN_FORMAT_ALPHANUMERIC = 2 +} MbimPinFormat; + +/*****************************************************************************/ +/* 'Home Provider' enums */ + +/** + * MbimProviderState: + * @MBIM_PROVIDER_STATE_UNKNOWN: Unknown. + * @MBIM_PROVIDER_STATE_HOME: Home operator. + * @MBIM_PROVIDER_STATE_FORBIDDEN: Provider blocked. + * @MBIM_PROVIDER_STATE_PREFERRED: Provider is in the preferred list. + * @MBIM_PROVIDER_STATE_VISIBLE: Provider is visible. + * @MBIM_PROVIDER_STATE_REGISTERED: Currently registered to the provider. + * @MBIM_PROVIDER_STATE_PREFERRED_MULTICARRIER: Provider is a preferred multicarrier network. + * + * State of the provider. + */ +typedef enum { + MBIM_PROVIDER_STATE_UNKNOWN = 0, + MBIM_PROVIDER_STATE_HOME = 1 << 0, + MBIM_PROVIDER_STATE_FORBIDDEN = 1 << 1, + MBIM_PROVIDER_STATE_PREFERRED = 1 << 2, + MBIM_PROVIDER_STATE_VISIBLE = 1 << 3, + MBIM_PROVIDER_STATE_REGISTERED = 1 << 4, + MBIM_PROVIDER_STATE_PREFERRED_MULTICARRIER = 1 << 5 +} MbimProviderState; + +/*****************************************************************************/ +/* 'Visible Providers' enums */ + +/** + * MbimVisibleProvidersAction: + * @MBIM_VISIBLE_PROVIDERS_ACTION_FULL_SCAN: Full scan. + * @MBIM_VISIBLE_PROVIDERS_ACTION_RESTRICTED_SCAN: Locate preferred multicarrier providers. + * + * Type of action to perform when listing visible providers. + */ +typedef enum { + MBIM_VISIBLE_PROVIDERS_ACTION_FULL_SCAN = 0, + MBIM_VISIBLE_PROVIDERS_ACTION_RESTRICTED_SCAN = 1 +} MbimVisibleProvidersAction; + +/*****************************************************************************/ +/* 'Register State' enums */ + +/** + * MbimNwError: + * @MBIM_NW_ERROR_UNKNOWN: Unknown or unset error. + * @MBIM_NW_ERROR_IMSI_UNKNOWN_IN_HLR: IMSI unknown in the HLR. + * @MBIM_NW_ERROR_ILLEGAL_MS: Illegal MS. + * @MBIM_NW_ERROR_IMSI_UNKNOWN_IN_VLR: IMSI unknown in the VLR. + * @MBIM_NW_ERROR_IMEI_NOT_ACCEPTED: IMEI not accepted. + * @MBIM_NW_ERROR_ILLEGAL_ME: Illegal ME. + * @MBIM_NW_ERROR_GPRS_NOT_ALLOWED: GPRS not allowed. + * @MBIM_NW_ERROR_GPRS_AND_NON_GPRS_NOT_ALLOWED: GPRS and non-GPRS not allowed. + * @MBIM_NW_ERROR_MS_IDENTITY_NOT_DERIVED_BY_NETWORK: MS identity cannot be derived by the network. + * @MBIM_NW_ERROR_IMPLICITLY_DETACHED: Implicitly detached. + * @MBIM_NW_ERROR_PLMN_NOT_ALLOWED: PLMN not allowed. + * @MBIM_NW_ERROR_LOCATION_AREA_NOT_ALLOWED: Location area not allowed. + * @MBIM_NW_ERROR_ROAMING_NOT_ALLOWED_IN_LOCATION_AREA: Roaming not allowed in the location area. + * @MBIM_NW_ERROR_GPRS_NOT_ALLOWED_IN_PLMN: GPRS not allowed in PLMN. + * @MBIM_NW_ERROR_NO_CELLS_IN_LOCATION_AREA: No cells in location area. + * @MBIM_NW_ERROR_MSC_TEMPORARILY_NOT_REACHABLE: MSC temporarily not reachable. + * @MBIM_NW_ERROR_NETWORK_FAILURE: Network failure. + * @MBIM_NW_ERROR_MAC_FAILURE: MAC failure. + * @MBIM_NW_ERROR_SYNCH_FAILURE: Synch failure. + * @MBIM_NW_ERROR_CONGESTION: Congestion. + * @MBIM_NW_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE: GSM authentication unacceptable. + * @MBIM_NW_ERROR_NOT_AUTHORIZED_FOR_CSG: Not authorized for this CSG. + * @MBIM_NW_ERROR_MISSING_OR_UNKNOWN_APN: Missing or unknown access point name. + * @MBIM_NW_ERROR_SERVICE_OPTION_NOT_SUPPORTED: Service option not supported. + * @MBIM_NW_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED: Requested service option not subscribed. + * @MBIM_NW_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER: Service option temporarily out of order. + * @MBIM_NW_ERROR_NO_PDP_CONTEXT_ACTIVATED: No PDP context activated. + * @MBIM_NW_ERROR_SEMANTICALLY_INCORRECT_MESSAGE: Semantically incorrect message. + * @MBIM_NW_ERROR_INVALID_MANDATORY_INFORMATION: Invalid mandatory information. + * @MBIM_NW_ERROR_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED: Message type non-existent or not implemented. + * @MBIM_NW_ERROR_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE: Message type not compatible with protocol state. + * @MBIM_NW_ERROR_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED: Information element non-existent or not implemented. + * @MBIM_NW_ERROR_CONDITIONAL_IE_ERROR: Conditional IE error. + * @MBIM_NW_ERROR_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE: Message not compatible with protocol state. + * @MBIM_NW_ERROR_PROTOCOL_ERROR_UNSPECIFIED: Protocol error, unspecified. + * + * Network errors. + */ +typedef enum { + MBIM_NW_ERROR_UNKNOWN = 0, + MBIM_NW_ERROR_IMSI_UNKNOWN_IN_HLR = 2, + MBIM_NW_ERROR_ILLEGAL_MS = 3, + MBIM_NW_ERROR_IMSI_UNKNOWN_IN_VLR = 4, + MBIM_NW_ERROR_IMEI_NOT_ACCEPTED = 5, + MBIM_NW_ERROR_ILLEGAL_ME = 6, + MBIM_NW_ERROR_GPRS_NOT_ALLOWED = 7, + MBIM_NW_ERROR_GPRS_AND_NON_GPRS_NOT_ALLOWED = 8, + MBIM_NW_ERROR_MS_IDENTITY_NOT_DERIVED_BY_NETWORK = 9, + MBIM_NW_ERROR_IMPLICITLY_DETACHED = 10, + MBIM_NW_ERROR_PLMN_NOT_ALLOWED = 11, + MBIM_NW_ERROR_LOCATION_AREA_NOT_ALLOWED = 12, + MBIM_NW_ERROR_ROAMING_NOT_ALLOWED_IN_LOCATION_AREA = 13, + MBIM_NW_ERROR_GPRS_NOT_ALLOWED_IN_PLMN = 14, + MBIM_NW_ERROR_NO_CELLS_IN_LOCATION_AREA = 15, + MBIM_NW_ERROR_MSC_TEMPORARILY_NOT_REACHABLE = 16, + MBIM_NW_ERROR_NETWORK_FAILURE = 17, + MBIM_NW_ERROR_MAC_FAILURE = 20, + MBIM_NW_ERROR_SYNCH_FAILURE = 21, + MBIM_NW_ERROR_CONGESTION = 22, + MBIM_NW_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE = 23, + MBIM_NW_ERROR_NOT_AUTHORIZED_FOR_CSG = 25, + MBIM_NW_ERROR_MISSING_OR_UNKNOWN_APN = 27, + MBIM_NW_ERROR_SERVICE_OPTION_NOT_SUPPORTED = 32, + MBIM_NW_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED = 33, + MBIM_NW_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER = 34, + MBIM_NW_ERROR_NO_PDP_CONTEXT_ACTIVATED = 40, + MBIM_NW_ERROR_SEMANTICALLY_INCORRECT_MESSAGE = 95, + MBIM_NW_ERROR_INVALID_MANDATORY_INFORMATION = 96, + MBIM_NW_ERROR_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED = 97, + MBIM_NW_ERROR_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, + MBIM_NW_ERROR_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED = 99, + MBIM_NW_ERROR_CONDITIONAL_IE_ERROR = 100, + MBIM_NW_ERROR_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, + MBIM_NW_ERROR_PROTOCOL_ERROR_UNSPECIFIED = 111 +} MbimNwError; + +/** + * MbimRegisterAction: + * @MBIM_REGISTER_ACTION_AUTOMATIC: Automatic registration. + * @MBIM_REGISTER_ACTION_MANUAL: Manual registration. + * + * Type of registration requested. + */ +typedef enum { + MBIM_REGISTER_ACTION_AUTOMATIC = 0, + MBIM_REGISTER_ACTION_MANUAL = 1 +} MbimRegisterAction; + +/** + * MbimRegisterState: + * @MBIM_REGISTER_STATE_UNKNOWN: Unknown registration state. + * @MBIM_REGISTER_STATE_DEREGISTERED: Not registered. + * @MBIM_REGISTER_STATE_SEARCHING: Searching. + * @MBIM_REGISTER_STATE_HOME: Registered in home network. + * @MBIM_REGISTER_STATE_ROAMING: Registered in roaming network. + * @MBIM_REGISTER_STATE_PARTNER: Registered in a preferred roaming network. + * @MBIM_REGISTER_STATE_DENIED: Registration denied. + * + * Registration state. + */ +typedef enum { + MBIM_REGISTER_STATE_UNKNOWN = 0, + MBIM_REGISTER_STATE_DEREGISTERED = 1, + MBIM_REGISTER_STATE_SEARCHING = 2, + MBIM_REGISTER_STATE_HOME = 3, + MBIM_REGISTER_STATE_ROAMING = 4, + MBIM_REGISTER_STATE_PARTNER = 5, + MBIM_REGISTER_STATE_DENIED = 6 +} MbimRegisterState; + +/** + * MbimRegisterMode: + * @MBIM_REGISTER_MODE_UNKNOWN: Unknown. + * @MBIM_REGISTER_MODE_AUTOMATIC: Automatic registration. + * @MBIM_REGISTER_MODE_MANUAL: Manual registration. + * + * Type of registration requested. + */ +typedef enum { + MBIM_REGISTER_MODE_UNKNOWN = 0, + MBIM_REGISTER_MODE_AUTOMATIC = 1, + MBIM_REGISTER_MODE_MANUAL = 2 +} MbimRegisterMode; + +/** + * MbimRegistrationFlag: + * @MBIM_REGISTRATION_FLAG_NONE: None. + * @MBIM_REGISTRATION_FLAG_MANUAL_SELECTION_NOT_AVAILABLE: Network doesn't support manual network selection. + * @MBIM_REGISTRATION_FLAG_PACKET_SERVICE_AUTOMATIC_ATTACH: Modem should auto-attach to the network after registration. + * + * Registration flags. + */ +typedef enum { + MBIM_REGISTRATION_FLAG_NONE = 0, + MBIM_REGISTRATION_FLAG_MANUAL_SELECTION_NOT_AVAILABLE = 1 << 0, + MBIM_REGISTRATION_FLAG_PACKET_SERVICE_AUTOMATIC_ATTACH = 1 << 1, +} MbimRegistrationFlag; + +/*****************************************************************************/ +/* 'Packet Service' enums */ + +/** + * MbimPacketServiceAction: + * @MBIM_PACKET_SERVICE_ACTION_ATTACH: Attach. + * @MBIM_PACKET_SERVICE_ACTION_DETACH: Detach. + * + * Packet Service Action. + */ +typedef enum { + MBIM_PACKET_SERVICE_ACTION_ATTACH = 0, + MBIM_PACKET_SERVICE_ACTION_DETACH = 1 +} MbimPacketServiceAction; + +/** + * MbimPacketServiceState: + * @MBIM_PACKET_SERVICE_STATE_UNKNOWN: Unknown. + * @MBIM_PACKET_SERVICE_STATE_ATTACHING: Attaching. + * @MBIM_PACKET_SERVICE_STATE_ATTACHED: Attached. + * @MBIM_PACKET_SERVICE_STATE_DETACHING: Detaching. + * @MBIM_PACKET_SERVICE_STATE_DETACHED: Detached. + * + * Packet Service State. + */ +typedef enum { + MBIM_PACKET_SERVICE_STATE_UNKNOWN = 0, + MBIM_PACKET_SERVICE_STATE_ATTACHING = 1, + MBIM_PACKET_SERVICE_STATE_ATTACHED = 2, + MBIM_PACKET_SERVICE_STATE_DETACHING = 3, + MBIM_PACKET_SERVICE_STATE_DETACHED = 4 +} MbimPacketServiceState; + +/*****************************************************************************/ +/* 'Connect' enums */ + +/** + * MbimActivationCommand: + * @MBIM_ACTIVATION_COMMAND_DEACTIVATE: Deactivate. + * @MBIM_ACTIVATION_COMMAND_ACTIVATE: Activate. + * + * Activation Command. + */ +typedef enum { + MBIM_ACTIVATION_COMMAND_DEACTIVATE = 0, + MBIM_ACTIVATION_COMMAND_ACTIVATE = 1 +} MbimActivationCommand; + +/** + * MbimCompression: + * @MBIM_COMPRESSION_NONE: None. + * @MBIM_COMPRESSION_ENABLE: Enable. + * + * Compression. + */ +typedef enum { + MBIM_COMPRESSION_NONE = 0, + MBIM_COMPRESSION_ENABLE = 1 +} MbimCompression; + +/** + * MbimAuthProtocol: + * @MBIM_AUTH_PROTOCOL_NONE: None. + * @MBIM_AUTH_PROTOCOL_PAP: Pap. + * @MBIM_AUTH_PROTOCOL_CHAP: Chap. + * @MBIM_AUTH_PROTOCOL_MSCHAPV2: V2. + * + * Auth Protocol. + */ +typedef enum { + MBIM_AUTH_PROTOCOL_NONE = 0, + MBIM_AUTH_PROTOCOL_PAP = 1, + MBIM_AUTH_PROTOCOL_CHAP = 2, + MBIM_AUTH_PROTOCOL_MSCHAPV2 = 3 +} MbimAuthProtocol; + +/** + * MbimContextIpType: + * @MBIM_CONTEXT_IP_TYPE_DEFAULT: It is up to the function to decide, the host does not care. + * @MBIM_CONTEXT_IP_TYPE_IPV4: IPv4 context. + * @MBIM_CONTEXT_IP_TYPE_IPV6: IPv6 context. + * @MBIM_CONTEXT_IP_TYPE_IPV4V6: The context is IPv4, IPv6 or dualstack IPv4v6. + * @MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6: Both an IPv4 and an IPv6 context. + * + * Context IP Type. + */ +typedef enum { + MBIM_CONTEXT_IP_TYPE_DEFAULT = 0, + MBIM_CONTEXT_IP_TYPE_IPV4 = 1, + MBIM_CONTEXT_IP_TYPE_IPV6 = 2, + MBIM_CONTEXT_IP_TYPE_IPV4V6 = 3, + MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6 = 4 +} MbimContextIpType; + +/** + * MbimActivationState: + * @MBIM_ACTIVATION_STATE_UNKNOWN: Unknown. + * @MBIM_ACTIVATION_STATE_ACTIVATED: Activated. + * @MBIM_ACTIVATION_STATE_ACTIVATING: Activating. + * @MBIM_ACTIVATION_STATE_DEACTIVATED: Deactivated. + * @MBIM_ACTIVATION_STATE_DEACTIVATING: Deactivating. + * + * Activation State. + */ +typedef enum { + MBIM_ACTIVATION_STATE_UNKNOWN = 0, + MBIM_ACTIVATION_STATE_ACTIVATED = 1, + MBIM_ACTIVATION_STATE_ACTIVATING = 2, + MBIM_ACTIVATION_STATE_DEACTIVATED = 3, + MBIM_ACTIVATION_STATE_DEACTIVATING = 4 +} MbimActivationState; + +/** + * MbimVoiceCallState: + * @MBIM_VOICE_CALL_STATE_NONE: None. + * @MBIM_VOICE_CALL_STATE_IN_PROGRESS: Progress. + * @MBIM_VOICE_CALL_STATE_HANG_UP: Up. + * + * Voice Call State. + */ +typedef enum { + MBIM_VOICE_CALL_STATE_NONE = 0, + MBIM_VOICE_CALL_STATE_IN_PROGRESS = 1, + MBIM_VOICE_CALL_STATE_HANG_UP = 2 +} MbimVoiceCallState; + +/*****************************************************************************/ +/* 'IP Configuration' enums */ + +/** + * MbimIPConfigurationAvailableFlag: + * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE: No info available. + * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS: Address info available. + * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY: Gateway info available. + * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS: DNS info available. + * @MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU: MTU info available. + * + * Mask of available information about an IP address. + */ +typedef enum { /*< underscore_name=mbim_ip_configuration_available_flag >*/ + MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE = 0, + MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS = 1 << 0, + MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY = 1 << 1, + MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS = 1 << 2, + MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU = 1 << 3, +} MbimIPConfigurationAvailableFlag; + +/*****************************************************************************/ +/* 'SMS Configuration' enums */ + +/** + * MbimSmsStorageState: + * @MBIM_SMS_STORAGE_STATE_NOT_INITIALIZED: Storage not initialized. + * @MBIM_SMS_STORAGE_STATE_INITIALIZED: Storage initialized. + * + * State of the SMS storage. + */ +typedef enum { + MBIM_SMS_STORAGE_STATE_NOT_INITIALIZED = 0, + MBIM_SMS_STORAGE_STATE_INITIALIZED = 1 +} MbimSmsStorageState; + +/** + * MbimSmsFormat: + * @MBIM_SMS_FORMAT_PDU: PDU format. + * @MBIM_SMS_FORMAT_CDMA: CDMA format. + * + * SMS format. + */ +typedef enum { + MBIM_SMS_FORMAT_PDU = 0, + MBIM_SMS_FORMAT_CDMA = 1 +} MbimSmsFormat; + +/*****************************************************************************/ +/* 'SMS Read' enums */ + +/** + * MbimSmsFlag: + * @MBIM_SMS_FLAG_ALL: All. + * @MBIM_SMS_FLAG_INDEX: Index. + * @MBIM_SMS_FLAG_NEW: New. + * @MBIM_SMS_FLAG_OLD: Old. + * @MBIM_SMS_FLAG_SENT: Sent. + * @MBIM_SMS_FLAG_DRAFT: Draft. + * + * Flags to use when requesting to read SMS. @MBIM_SMS_FLAG_ALL and + * @MBIM_SMS_FLAG_NEW are mandatory, all the others are optional. +*/ +typedef enum { + MBIM_SMS_FLAG_ALL = 0, + MBIM_SMS_FLAG_INDEX = 1, + MBIM_SMS_FLAG_NEW = 2, + MBIM_SMS_FLAG_OLD = 3, + MBIM_SMS_FLAG_SENT = 4, + MBIM_SMS_FLAG_DRAFT = 5 +} MbimSmsFlag; + +/** + * MbimSmsCdmaLang: + * @MBIM_SMS_CDMA_LANG_UNKNOWN: Unknown language. + * @MBIM_SMS_CDMA_LANG_ENGLISH: English. + * @MBIM_SMS_CDMA_LANG_FRENCH: French. + * @MBIM_SMS_CDMA_LANG_SPANISH: Spanish. + * @MBIM_SMS_CDMA_LANG_JAPANESE: Japanese. + * @MBIM_SMS_CDMA_LANG_KOREAN: Korean. + * @MBIM_SMS_CDMA_LANG_CHINESE: Chinese. + * @MBIM_SMS_CDMA_LANG_HEBREW: Hebrew. + * + * Language of a CDMA SMS. + */ +typedef enum { + MBIM_SMS_CDMA_LANG_UNKNOWN = 0, + MBIM_SMS_CDMA_LANG_ENGLISH = 1, + MBIM_SMS_CDMA_LANG_FRENCH = 2, + MBIM_SMS_CDMA_LANG_SPANISH = 3, + MBIM_SMS_CDMA_LANG_JAPANESE = 4, + MBIM_SMS_CDMA_LANG_KOREAN = 5, + MBIM_SMS_CDMA_LANG_CHINESE = 6, + MBIM_SMS_CDMA_LANG_HEBREW = 7 +} MbimSmsCdmaLang; + +/** + * MbimSmsCdmaEncoding: + * @MBIM_SMS_CDMA_ENCODING_OCTET: Octet. + * @MBIM_SMS_CDMA_ENCODING_EPM: EPM. + * @MBIM_SMS_CDMA_ENCODING_7BIT_ASCII: 7-bit ASCII. + * @MBIM_SMS_CDMA_ENCODING_LA5: LA5. + * @MBIM_SMS_CDMA_ENCODING_UNICODE: Unicode. + * @MBIM_SMS_CDMA_ENCODING_SHIFT_JIS: Shift JIS. + * @MBIM_SMS_CDMA_ENCODING_KOREAN: Korean. + * @MBIM_SMS_CDMA_ENCODING_LATIN_HEBREW: Latin hebrew. + * @MBIM_SMS_CDMA_ENCODING_LATIN: Latin. + * @MBIM_SMS_CDMA_ENCODING_GSM_7BIT: 7-bit GSM. + * + * Type of encoding of a CDMA SMS. + */ +typedef enum { + MBIM_SMS_CDMA_ENCODING_OCTET = 0, + MBIM_SMS_CDMA_ENCODING_EPM = 1, + MBIM_SMS_CDMA_ENCODING_7BIT_ASCII = 2, + MBIM_SMS_CDMA_ENCODING_LA5 = 3, + MBIM_SMS_CDMA_ENCODING_UNICODE = 4, + MBIM_SMS_CDMA_ENCODING_SHIFT_JIS = 5, + MBIM_SMS_CDMA_ENCODING_KOREAN = 6, + MBIM_SMS_CDMA_ENCODING_LATIN_HEBREW = 7, + MBIM_SMS_CDMA_ENCODING_LATIN = 8, + MBIM_SMS_CDMA_ENCODING_GSM_7BIT = 9 +} MbimSmsCdmaEncoding; + +/** + * MbimSmsStatus: + * @MBIM_SMS_STATUS_NEW: New. + * @MBIM_SMS_STATUS_OLD: Old. + * @MBIM_SMS_STATUS_DRAFT: Draft. + * @MBIM_SMS_STATUS_SENT: Sent. + * + * Status of a SMS message. + */ +typedef enum { + MBIM_SMS_STATUS_NEW = 0, + MBIM_SMS_STATUS_OLD = 1, + MBIM_SMS_STATUS_DRAFT = 2, + MBIM_SMS_STATUS_SENT = 3 +} MbimSmsStatus; + +/*****************************************************************************/ +/* 'SMS Message Store Status' enums */ + +/** + * MbimSmsStatusFlag: + * @MBIM_SMS_STATUS_FLAG_NONE: None. + * @MBIM_SMS_STATUS_FLAG_MESSAGE_STORE_FULL: Message store is full. + * @MBIM_SMS_STATUS_FLAG_NEW_MESSAGE: New non-Class 0 message arrived. + * + * SMS status flags. + */ +typedef enum { + MBIM_SMS_STATUS_FLAG_NONE = 0, + MBIM_SMS_STATUS_FLAG_MESSAGE_STORE_FULL = 1, + MBIM_SMS_STATUS_FLAG_NEW_MESSAGE = 2 +} MbimSmsStatusFlag; + +/*****************************************************************************/ +/* 'USSD' enums */ + +/** + * MbimUssdAction: + * @MBIM_USSD_ACTION_INITIATE: Initiate USSD session. + * @MBIM_USSD_ACTION_CONTINUE: Continue USSD session. + * @MBIM_USSD_ACTION_CANCEL: Cancel USSD session. + * + * USSD action. + */ +typedef enum { + MBIM_USSD_ACTION_INITIATE = 0, + MBIM_USSD_ACTION_CONTINUE = 1, + MBIM_USSD_ACTION_CANCEL = 2 +} MbimUssdAction; + +/** + * MbimUssdResponse: + * @MBIM_USSD_RESPONSE_NO_ACTION_REQUIRED: No action required. + * @MBIM_USSD_RESPONSE_ACTION_REQUIRED: An action is required. + * @MBIM_USSD_RESPONSE_TERMINATED_BY_NETWORK: Terminated by network + * @MBIM_USSD_RESPONSE_OTHER_LOCAL_CLIENT: Other local client. + * @MBIM_USSD_RESPONSE_OPERATION_NOT_SUPPORTED: Operation not supported. + * @MBIM_USSD_RESPONSE_NETWORK_TIMEOUT: Network timeout. + * + * USSD response. + */ +typedef enum { + MBIM_USSD_RESPONSE_NO_ACTION_REQUIRED = 0, + MBIM_USSD_RESPONSE_ACTION_REQUIRED = 1, + MBIM_USSD_RESPONSE_TERMINATED_BY_NETWORK = 2, + MBIM_USSD_RESPONSE_OTHER_LOCAL_CLIENT = 3, + MBIM_USSD_RESPONSE_OPERATION_NOT_SUPPORTED = 4, + MBIM_USSD_RESPONSE_NETWORK_TIMEOUT = 5 +} MbimUssdResponse; + +/** + * MbimUssdSessionState: + * @MBIM_USSD_SESSION_STATE_NEW_SESSION: New session. + * @MBIM_USSD_SESSION_STATE_EXISTING_SESSION: Existing session. + * + * Session state. + */ +typedef enum { + MBIM_USSD_SESSION_STATE_NEW_SESSION = 0, + MBIM_USSD_SESSION_STATE_EXISTING_SESSION = 1 +} MbimUssdSessionState; + +/*****************************************************************************/ +/* 'Phonebook configuration' enums */ + +/** + * MbimPhonebookState: + * @MBIM_PHONEBOOK_STATE_NOT_INITIALIZED: Not initialized. + * @MBIM_PHONEBOOK_STATE_INITIALIZED: Initialized + * + * Phonebook state. + */ +typedef enum { + MBIM_PHONEBOOK_STATE_NOT_INITIALIZED = 0, + MBIM_PHONEBOOK_STATE_INITIALIZED = 1 +} MbimPhonebookState; + +/*****************************************************************************/ +/* 'Phonebook read' enums */ + +/** + * MbimPhonebookFlag: + * @MBIM_PHONEBOOK_FLAG_ALL: Request all. + * @MBIM_PHONEBOOK_FLAG_INDEX: Request single entry by index. + * + * Flags to use when reading the phonebook. + */ +typedef enum { + MBIM_PHONEBOOK_FLAG_ALL = 0, + MBIM_PHONEBOOK_FLAG_INDEX = 1 +} MbimPhonebookFlag; + +/** + * MbimPhonebookWriteFlag: + * @MBIM_PHONEBOOK_WRITE_FLAG_SAVE_UNUSED: Store the record in an unused slot. + * @MBIM_PHONEBOOK_WRITE_FLAG_SAVE_INDEX: Index where to store the record. + * + * Flags to use when writing the phonebook. + */ +typedef enum { + MBIM_PHONEBOOK_WRITE_FLAG_SAVE_UNUSED = 0, + MBIM_PHONEBOOK_WRITE_FLAG_SAVE_INDEX = 1, +} MbimPhonebookWriteFlag; + +/*****************************************************************************/ +/* 'STK PAC' enums */ + +/** + * MbimStkPacProfile: + * @MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_HANDLED_BY_HOST: Command not handled by function but handled by host. + * @MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_MAY_BE_HANDLED_BY_HOST: Command not handled by function but may be handled by host. + * @MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_ONLY_TRANSPARENT_TO_HOST: Command handled by function without informing the host. + * @MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATION_TO_HOST_POSSIBLE: Command handled by function without informing the host, but notifications may be sent to host. + * @MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATIONS_TO_HOST_ENABLED: Command handled by function, and the function wil also send notification to the host. + * @MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_CAN_BE_OVERRIDEN_BY_HOST: Command handled by function, but the host may request full control of the command. + * @MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_NOT_ABLE_TO_HANDLE: Command will be forwarded to the host. If the host decides not to receive the command, the function will not handle it. + * @MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_ABLE_TO_HANDLE: Command will be forwarded to the host. If the host decides not to receive the command, the function will handle it. + * + * Proactive command profile. + */ +typedef enum { + MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_HANDLED_BY_HOST = 0, + MBIM_STK_PAC_PROFILE_NOT_HANDLED_BY_FUNCTION_MAY_BE_HANDLED_BY_HOST = 1, + MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_ONLY_TRANSPARENT_TO_HOST = 2, + MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATION_TO_HOST_POSSIBLE = 3, + MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_NOTIFICATIONS_TO_HOST_ENABLED = 4, + MBIM_STK_PAC_PROFILE_HANDLED_BY_FUNCTION_CAN_BE_OVERRIDEN_BY_HOST = 5, + MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_NOT_ABLE_TO_HANDLE = 6, + MBIM_STK_PAC_PROFILE_HANDLED_BY_HOST_FUNCTION_ABLE_TO_HANDLE = 7 +} MbimStkPacProfile; + +/** + * MbimStkPacType: + * @MBIM_STK_PAC_TYPE_PROACTIVE_COMMAND: Host is requested to handle the Proactive command. + * @MBIM_STK_PAC_TYPE_NOTIFICATION: Proactive command is handled by the function, but the host is notified. + * + * Type of proactive command. + */ +typedef enum { + MBIM_STK_PAC_TYPE_PROACTIVE_COMMAND = 0, + MBIM_STK_PAC_TYPE_NOTIFICATION = 1 +} MbimStkPacType; + +/*****************************************************************************/ +/* 'Network idle hint' enums */ + +/** + * MbimNetworkIdleHintState: + * @MBIM_NETWORK_IDLE_HINT_STATE_DISABLED: Disabled. + * @MBIM_NETWORK_IDLE_HINT_STATE_ENABLED: Enabled. + * + * Enable or disable network idle hint. + */ +typedef enum { + MBIM_NETWORK_IDLE_HINT_STATE_DISABLED = 0, + MBIM_NETWORK_IDLE_HINT_STATE_ENABLED = 1 +} MbimNetworkIdleHintState; + +/*****************************************************************************/ +/* 'Emergency mode' enums */ + +/** + * MbimEmergencyModeState: + * @MBIM_EMERGENCY_MODE_STATE_OFF: Off. + * @MBIM_EMERGENCY_MODE_STATE_ON: On. + * + * Emergency mode state. + */ +typedef enum { + MBIM_EMERGENCY_MODE_STATE_OFF = 0, + MBIM_EMERGENCY_MODE_STATE_ON = 1 +} MbimEmergencyModeState; + +/*****************************************************************************/ +/* 'DSS connect' enums */ + +/** + * MbimDssLinkState: + * @MBIM_DSS_LINK_STATE_DEACTIVATE: Deactivate. + * @MBIM_DSS_LINK_STATE_ACTIVATE: Activate. + * + * Action performed in the link state. + */ +typedef enum { + MBIM_DSS_LINK_STATE_DEACTIVATE = 0, + MBIM_DSS_LINK_STATE_ACTIVATE = 1 +} MbimDssLinkState; + +/** + * MbimService: + * @MBIM_SERVICE_INVALID: Invalid service. + * @MBIM_SERVICE_BASIC_CONNECT: Basic connectivity service. + * @MBIM_SERVICE_SMS: SMS messaging service. + * @MBIM_SERVICE_USSD: USSD service. + * @MBIM_SERVICE_PHONEBOOK: Phonebook service. + * @MBIM_SERVICE_STK: SIM toolkit service. + * @MBIM_SERVICE_AUTH: Authentication service. + * @MBIM_SERVICE_DSS: Device Service Stream service. + * @MBIM_SERVICE_MS_FIRMWARE_ID: Microsoft Firmware ID service. + * @MBIM_SERVICE_MS_HOST_SHUTDOWN: Microsoft Host Shutdown service. + * @MBIM_SERVICE_PROXY_CONTROL: Proxy Control service. + * + * Enumeration of the generic MBIM services. + */ +typedef enum { + MBIM_SERVICE_INVALID = 0, + MBIM_SERVICE_BASIC_CONNECT = 1, + MBIM_SERVICE_SMS = 2, + MBIM_SERVICE_USSD = 3, + MBIM_SERVICE_PHONEBOOK = 4, + MBIM_SERVICE_STK = 5, + MBIM_SERVICE_AUTH = 6, + MBIM_SERVICE_DSS = 7, + MBIM_SERVICE_MS_FIRMWARE_ID = 8, + MBIM_SERVICE_MS_HOST_SHUTDOWN = 9, + MBIM_SERVICE_PROXY_CONTROL = 10, + /* Note: update MBIM_SERVICE_LAST when a new value is added */ +} MbimService; + +/** + * MbimContextType: + * @MBIM_CONTEXT_TYPE_INVALID: Invalid context type. + * @MBIM_CONTEXT_TYPE_NONE: Context not yet provisioned. + * @MBIM_CONTEXT_TYPE_INTERNET: Connection to the Internet. + * @MBIM_CONTEXT_TYPE_VPN: Connection to a VPN. + * @MBIM_CONTEXT_TYPE_VOICE: Connection to a VoIP service. + * @MBIM_CONTEXT_TYPE_VIDEO_SHARE: Connection to a video sharing service. + * @MBIM_CONTEXT_TYPE_PURCHASE: Connection to an over-the-air activation site. + * @MBIM_CONTEXT_TYPE_IMS: Connection to IMS. + * @MBIM_CONTEXT_TYPE_MMS: Connection to MMS. + * @MBIM_CONTEXT_TYPE_LOCAL: A local. + * + * Enumeration of the generic MBIM context types. + */ +typedef enum { + MBIM_CONTEXT_TYPE_INVALID = 0, + MBIM_CONTEXT_TYPE_NONE = 1, + MBIM_CONTEXT_TYPE_INTERNET = 2, + MBIM_CONTEXT_TYPE_VPN = 3, + MBIM_CONTEXT_TYPE_VOICE = 4, + MBIM_CONTEXT_TYPE_VIDEO_SHARE = 5, + MBIM_CONTEXT_TYPE_PURCHASE = 6, + MBIM_CONTEXT_TYPE_IMS = 7, + MBIM_CONTEXT_TYPE_MMS = 8, + MBIM_CONTEXT_TYPE_LOCAL = 9, +} MbimContextType; + +#endif /* _LIBMBIM_GLIB_MBIM_ENUMS_H_ */ diff --git a/mbim-enums.h b/mbim-enums.h new file mode 100644 index 0000000..55f2fcb --- /dev/null +++ b/mbim-enums.h @@ -0,0 +1,68 @@ +#ifndef _MBIM_ENUMS_H__ +#define _MBIM_ENUMS_H__ + +extern struct mbim_enum mbim_service_values[]; +extern struct mbim_enum mbim_context_type_values[]; +extern struct mbim_enum mbim_cid_basic_connect_values[]; +extern struct mbim_enum mbim_cid_sms_values[]; +extern struct mbim_enum mbim_cid_ussd_values[]; +extern struct mbim_enum mbim_cid_phonebook_values[]; +extern struct mbim_enum mbim_cid_stk_values[]; +extern struct mbim_enum mbim_cid_auth_values[]; +extern struct mbim_enum mbim_cid_dss_values[]; +extern struct mbim_enum mbim_cid_ms_firmware_id_values[]; +extern struct mbim_enum mbim_cid_ms_host_shutdown_values[]; +extern struct mbim_enum mbim_cid_proxy_control_values[]; +extern struct mbim_enum mbim_message_type_values[]; +extern struct mbim_enum mbim_message_command_type_values[]; +extern struct mbim_enum mbim_device_type_values[]; +extern struct mbim_enum mbim_cellular_class_values[]; +extern struct mbim_enum mbim_voice_class_values[]; +extern struct mbim_enum mbim_sim_class_values[]; +extern struct mbim_enum mbim_data_class_values[]; +extern struct mbim_enum mbim_sms_caps_values[]; +extern struct mbim_enum mbim_ctrl_caps_values[]; +extern struct mbim_enum mbim_subscriber_ready_state_values[]; +extern struct mbim_enum mbim_ready_info_flag_values[]; +extern struct mbim_enum mbim_radio_switch_state_values[]; +extern struct mbim_enum mbim_pin_type_values[]; +extern struct mbim_enum mbim_pin_state_values[]; +extern struct mbim_enum mbim_pin_operation_values[]; +extern struct mbim_enum mbim_pin_mode_values[]; +extern struct mbim_enum mbim_pin_format_values[]; +extern struct mbim_enum mbim_provider_state_values[]; +extern struct mbim_enum mbim_visible_providers_action_values[]; +extern struct mbim_enum mbim_nw_error_values[]; +extern struct mbim_enum mbim_register_action_values[]; +extern struct mbim_enum mbim_register_state_values[]; +extern struct mbim_enum mbim_register_mode_values[]; +extern struct mbim_enum mbim_registration_flag_values[]; +extern struct mbim_enum mbim_packet_service_action_values[]; +extern struct mbim_enum mbim_packet_service_state_values[]; +extern struct mbim_enum mbim_activation_command_values[]; +extern struct mbim_enum mbim_compression_values[]; +extern struct mbim_enum mbim_auth_protocol_values[]; +extern struct mbim_enum mbim_context_ip_type_values[]; +extern struct mbim_enum mbim_activation_state_values[]; +extern struct mbim_enum mbim_voice_call_state_values[]; +extern struct mbim_enum mbim_ip_configuration_available_flag_values[]; +extern struct mbim_enum mbim_sms_storage_state_values[]; +extern struct mbim_enum mbim_sms_format_values[]; +extern struct mbim_enum mbim_sms_flag_values[]; +extern struct mbim_enum mbim_sms_cdma_lang_values[]; +extern struct mbim_enum mbim_sms_cdma_encoding_values[]; +extern struct mbim_enum mbim_sms_status_values[]; +extern struct mbim_enum mbim_sms_status_flag_values[]; +extern struct mbim_enum mbim_ussd_action_values[]; +extern struct mbim_enum mbim_ussd_response_values[]; +extern struct mbim_enum mbim_ussd_session_state_values[]; +extern struct mbim_enum mbim_phonebook_state_values[]; +extern struct mbim_enum mbim_phonebook_flag_values[]; +extern struct mbim_enum mbim_phonebook_write_flag_values[]; +extern struct mbim_enum mbim_stk_pac_profile_values[]; +extern struct mbim_enum mbim_stk_pac_type_values[]; +extern struct mbim_enum mbim_network_idle_hint_state_values[]; +extern struct mbim_enum mbim_emergency_mode_state_values[]; +extern struct mbim_enum mbim_dss_link_state_values[]; + +#endif diff --git a/mbim-msg.c b/mbim-msg.c new file mode 100644 index 0000000..88df1b6 --- /dev/null +++ b/mbim-msg.c @@ -0,0 +1,169 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mbim.h" + +#include "data/mbim-service-basic-connect.h" + +int transaction_id = 1; +uint8_t basic_connect[16] = { 0xa2, 0x89, 0xcc, 0x33, 0xbc, 0xbb, 0x8b, 0x4f, + 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6,0xdf }; +static int payload_offset, payload_free, payload_len; +static uint8_t *payload_buffer; + +int +mbim_add_payload(uint8_t len) +{ + uint32_t offset = payload_offset; + + if (payload_free < len) + return 0; + + payload_free -= len; + payload_offset += len; + payload_len += len; + + return offset; +} + +int +mbim_encode_string(struct mbim_string *str, char *in) +{ + int l = strlen(in); + int s = mbim_add_payload(l * 2); + uint8_t *p = &payload_buffer[s]; + int i; + + if (!s) + return -1; + + str->offset = htole32(s); + str->length = htole32(l * 2); + for (i = 0; i < l; i++) + p[i * 2] = in[i]; + + return 0; +} + + +char * +mbim_get_string(struct mbim_string *str, char *in) +{ + char *p = &in[le32toh(str->offset)]; + int i; + + if (!le32toh(str->offset)) + return NULL; + + if (le32toh(str->length)) { + for (i = 0; i < le32toh(str->length) / 2; i++) + p[i] = p[i * 2]; + p[i] = '\0'; + str->length = 0; + } + + return p; +} + +void +mbim_get_ipv4(void *buffer, char *out, uint32_t offset) +{ + uint8_t *b = buffer + offset; + + snprintf(out, 16, "%d.%d.%d.%d", b[0], b[1], b[2], b[3]); +} + +const char* +mbim_enum_string(struct mbim_enum *e, uint32_t key) +{ + while (e->skey) { + if (key == e->key) + return e->val; + e++; + } + return NULL; +} + +void +mbim_setup_header(struct mbim_message_header *hdr, MbimMessageType type, int length) +{ + if (length < 16) + length = 16; + + hdr->transaction_id = htole32(transaction_id++); + hdr->type = htole32(type); + hdr->length = htole32(length); +} + +uint8_t* +mbim_setup_command_msg(uint8_t *uuid, uint32_t type, uint32_t command_id, int len) +{ + struct command_message *cmd = (struct command_message *) mbim_buffer; + + memset(mbim_buffer, 0, MBIM_BUFFER_SIZE); + + cmd->fragment_header.total = htole32(1); + cmd->fragment_header.current = htole32(0); + memcpy(cmd->service_id, uuid, 16); + cmd->command_id = htole32(command_id); + cmd->command_type = htole32(type); + cmd->buffer_length = htole32(len); + + payload_offset = len; + payload_free = MBIM_BUFFER_SIZE - (sizeof(*cmd) + len); + payload_len = 0; + payload_buffer = cmd->buffer; + + return cmd->buffer; +} + +int +mbim_send_command_msg(void) +{ + struct command_message *cmd = (struct command_message *) mbim_buffer; + + if (payload_len & 0x3) { + payload_len &= ~0x3; + payload_len += 4; + } + + cmd->buffer_length = htole32(le32toh(cmd->buffer_length) + payload_len); + mbim_setup_header(&cmd->header, MBIM_MESSAGE_TYPE_COMMAND, sizeof(*cmd) + le32toh(cmd->buffer_length)); + + return mbim_send(); +} + +int +mbim_send_open_msg(void) +{ + struct mbim_open_message *msg = (struct mbim_open_message *) mbim_buffer; + + mbim_setup_header(&msg->header, MBIM_MESSAGE_TYPE_OPEN, sizeof(*msg)); + msg->max_control_transfer = htole32(MBIM_BUFFER_SIZE); + + return mbim_send(); +} + +int +mbim_send_close_msg(void) +{ + struct mbim_message_header *hdr = (struct mbim_message_header *) mbim_buffer; + + if (no_close) { + uloop_end(); + return 0; + } + mbim_setup_header(hdr, MBIM_MESSAGE_TYPE_CLOSE, sizeof(*hdr)); + + return mbim_send(); +} diff --git a/mbim-msg.h b/mbim-msg.h new file mode 100644 index 0000000..1f84031 --- /dev/null +++ b/mbim-msg.h @@ -0,0 +1,84 @@ +#ifndef _MBIM_MSG_H__ +#define _MBIM_MSG_H__ + +#include + +struct mbim_message_header { + uint32_t type; + uint32_t length; + uint32_t transaction_id; +} __attribute__((packed)); + +struct mbim_open_message { + struct mbim_message_header header; + uint32_t max_control_transfer; +} __attribute__((packed)); + +struct mbim_open_done_message { + struct mbim_message_header header; + uint32_t status_code; +} __attribute__((packed)); + +struct mbim_close_done_message { + uint32_t status_code; +} __attribute__((packed)); + +struct mbim_error_message { + uint32_t error_status_code; +} __attribute__((packed)); + +struct mbim_fragment_header { + uint32_t total; + uint32_t current; +} __attribute__((packed)); + +struct fragment_message { + struct mbim_fragment_header fragment_header; + uint8_t buffer[]; +} __attribute__((packed)); + +struct command_message { + struct mbim_message_header header; + struct mbim_fragment_header fragment_header; + uint8_t service_id[16]; + uint32_t command_id; + uint32_t command_type; + uint32_t buffer_length; + uint8_t buffer[]; +} __attribute__((packed)); + +struct command_done_message { + struct mbim_fragment_header fragment_header; + uint8_t service_id[16]; + uint32_t command_id; + uint32_t status_code; + uint32_t buffer_length; + uint8_t buffer[]; +} __attribute__((packed)); + +struct indicate_status_message { + struct mbim_fragment_header fragment_header; + uint8_t service_id[16]; + uint32_t command_id; + uint32_t buffer_length; + uint8_t buffer[]; +} __attribute__((packed)); + +typedef int (*_mbim_cmd_request)(void); +typedef int (*_mbim_cmd_response)(void *buffer, int len); + +extern uint8_t basic_connect[16]; +extern int transaction_id; + +const char* mbim_enum_string(struct mbim_enum *e, uint32_t key); +char* mbim_get_string(struct mbim_string *str, char *in); +void mbim_setup_header(struct mbim_message_header *hdr, MbimMessageType type, int length); +uint8_t* mbim_setup_command_msg(uint8_t *uuid, uint32_t type, uint32_t command_id, int len); +int mbim_send_open_msg(void); +int mbim_send_close_msg(void); +int mbim_send_command_msg(void); +int mbim_add_payload(uint8_t len); +int mbim_encode_string(struct mbim_string *str, char *in); +void mbim_get_ipv4(void *buffer, char *out, uint32_t offset); + +#endif diff --git a/mbim-type.h b/mbim-type.h new file mode 100644 index 0000000..d54d8a2 --- /dev/null +++ b/mbim-type.h @@ -0,0 +1,15 @@ +#ifndef _MBIM_TYPE_H__ +#define _MBIM_TYPE_H__ + +struct mbim_string { + uint32_t offset; + uint32_t length; +}; + +struct mbim_enum { + uint32_t key; + char *skey; + char *val; +}; + +#endif diff --git a/mbim.h b/mbim.h new file mode 100644 index 0000000..d76892a --- /dev/null +++ b/mbim.h @@ -0,0 +1,28 @@ +#ifndef _MBIM_H__ +#define _MBIM_H__ + +#include +#include + +#define MBIM_BUFFER_SIZE 1024 + +extern int return_code; +extern int verbose; + +#include "mbim-type.h" +#include "mbim-enum.h" +#include "mbim-enums.h" +#include "mbim-msg.h" +#include "mbim-cid.h" +#include "mbim-dev.h" + +struct mbim_handler { + char *name; + int argc; + + _mbim_cmd_request request; + _mbim_cmd_response response; +}; +extern struct mbim_handler *current_handler; + +#endif -- 2.11.0