guint32 => "le32_to_cpu(*(uint32_t *) get_next(4))",
gint64 => "le64_to_cpu(*(uint64_t *) get_next(8))",
guint64 => "le64_to_cpu(*(uint64_t *) get_next(8))",
+ gfloat => "({ uint32_t data = le32_to_cpu(*(uint32_t *) get_next(4)); float _val; memcpy(&_val, &data, sizeof(_val)); _val; })"
);
my %tlv_get_be = (
$size = $tlv_get{$prefix};
die "Unknown size element type '$prefix'" if not defined $size;
+ my $curvar = "$var\_n";
+ if (rindex($var,"]") == length($var)-1) {
+ $curvar = substr($var, 0, index($var, "["))."\_i";
+ $data .= $indent."$curvar = 0;\n";
+ }
($var_data, $var_iterator) =
- gen_tlv_parse_field($var."[$var\_n]", $elem->{"array-element"}, $n_indent + 1, "i$iterator");
+ gen_tlv_parse_field($var."[$curvar]", $elem->{"array-element"}, $n_indent + 1, "i$iterator");
- $var_data .= $indent."\t$var\_n++;\n";
+ $var_data .= $indent."\t$curvar++;\n";
$data .= $indent."$iterator = $size;\n";
$data .= $indent."$var = __qmi_alloc_static($iterator * sizeof($var\[0]));\n";
$data .= $indent."while($iterator\-- > 0) {\n";
}
- $var_iterator and $data .= $indent."\tint i$iterator;\n";
+ $var_iterator and $data .= $indent."\tunsigned int i$iterator;\n";
$data .= $var_data;
$data .= $indent."}\n";
}
}
-sub gen_tlv_type($$) {
+sub gen_tlv_type($$$) {
my $cname = shift;
my $elem = shift;
+ my $idx = shift;
+ my $idx_word = "found[".int($idx / 32)."]";
+ my $idx_bit = "(1 << ".($idx % 32).")";
my $type = $elem->{"format"};
my $id = $elem->{"id"};
print <<EOF;
case $id:
+ if ($idx_word & $idx_bit)
+ break;
+
+ $idx_word |= $idx_bit;
EOF
my $val = $tlv_get{$type};
print <<EOF;
{
void *tlv_buf = &msg->$type.tlv;
- int tlv_len = le16_to_cpu(msg->$type.tlv_len);
+ unsigned int tlv_len = le16_to_cpu(msg->$type.tlv_len);
EOF
if (gen_has_types($data)) {
+ my $n_bits = scalar @$data;
+ my $n_words = int(($n_bits + 31) / 32);
+ my $i = 0;
+
+ print <<EOF;
+ struct tlv *tlv;
+ int i;
+ uint32_t found[$n_words] = {};
+
+ memset(res, 0, sizeof(*res));
+
+ __qmi_alloc_reset();
+ while ((tlv = tlv_get_next(&tlv_buf, &tlv_len)) != NULL) {
+ unsigned int cur_tlv_len = le16_to_cpu(tlv->len);
+ unsigned int ofs = 0;
+
+ switch(tlv->type) {
+EOF
+ foreach my $field (@$data) {
+ $field = gen_common_ref($field);
+ my $cname = gen_cname($field->{name});
+ gen_tlv_type($cname, $field, $i++);
+ }
+
+ print <<EOF;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+
+error_len:
+ fprintf(stderr, "%s: Invalid TLV length in message, tlv=0x%02x, len=%d\\n",
+ __func__, tlv->type, le16_to_cpu(tlv->len));
+ return QMI_ERROR_INVALID_DATA;
+EOF
+ } else {
+ print <<EOF;
+
+ return qmi_check_message_status(tlv_buf, tlv_len);
+EOF
+ }
+
+ print <<EOF;
+}
+
+EOF
+}
+
+sub gen_parse_ind_func($$)
+{
+ my $name = shift;
+ my $data = shift;
+
+ my $type = "svc";
+ $ctl and $type = "ctl";
+
+ print gen_tlv_parse_func($name, $data)."\n";
+ print <<EOF;
+{
+ void *tlv_buf = &msg->$type.tlv;
+ unsigned int tlv_len = le16_to_cpu(msg->$type.tlv_len);
+EOF
+
+ if (gen_has_types($data)) {
+ my $n_bits = scalar @$data;
+ my $n_words = int(($n_bits + 31) / 32);
+ my $i = 0;
+
print <<EOF;
struct tlv *tlv;
int i;
+ uint32_t found[$n_words] = {};
memset(res, 0, sizeof(*res));
switch(tlv->type) {
EOF
foreach my $field (@$data) {
+ $field = gen_common_ref($field);
my $cname = gen_cname($field->{name});
- gen_tlv_type($cname, $field);
+ gen_tlv_type($cname, $field, $i++);
}
print <<EOF;
my ($var_data, $var_iterator) =
gen_tlv_val_set($cname."[$iterator]", $elem->{"array-element"}, "$indent\t", "i$iterator", undef);
- $var_iterator and $data .= $indent."\tint i$iterator;\n";
+ $var_iterator and $data .= $indent."\tunsigned int i$iterator;\n";
$data .= $var_data;
$data .= $indent."}\n";
my $cond = "req->set.$cname";
my ($var_data, $use_iterator) =
gen_tlv_val_set("req->data.$cname", $elem, "\t\t", "i", \$cond);
- $use_iterator and $iterator = "\t\tint i;\n";
+ $use_iterator and $iterator = "\t\tunsigned int i;\n";
$data = <<EOF;
if ($cond) {
void *buf;
- int ofs;
+ unsigned int ofs;
$iterator$size_var
__qmi_alloc_reset();
$var_data
EOF
foreach my $field (@$fields) {
+ $field = gen_common_ref($field);
my $cname = gen_cname($field->{name});
gen_tlv_attr_set($cname, $field);
}
#define get_next(_size) ({ void *_buf = &tlv->data[ofs]; ofs += _size; if (ofs > cur_tlv_len) goto error_len; _buf; })
#define copy_tlv(_val, _size) \\
do { \\
- int __size = _size; \\
+ unsigned int __size = _size; \\
if (__size > 0) \\
memcpy(__qmi_alloc_static(__size), _val, __size); \\
} while (0);
EOF
-gen_foreach_message_type($data, \&gen_set_func, \&gen_parse_func);
+gen_foreach_message_type($data, \&gen_set_func, \&gen_parse_func, \&gen_parse_ind_func);