mirror of
https://github.com/open5gs/open5gs.git
synced 2025-11-01 12:33:41 +00:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b5cc4a568 | ||
|
|
094d40b073 | ||
|
|
852756f902 | ||
|
|
fea48f5a44 | ||
|
|
b19b3e9dd1 | ||
|
|
7901a1164f | ||
|
|
950c4c0a12 | ||
|
|
5e839e25fe | ||
|
|
d3fa7619bf | ||
|
|
6cd755ac97 | ||
|
|
f597c9e899 | ||
|
|
9e8303762c | ||
|
|
e7c261d0d3 | ||
|
|
e7cb25ac9b | ||
|
|
f47f65a51c | ||
|
|
0311d2255c | ||
|
|
d9417be9a6 | ||
|
|
373ba1452f | ||
|
|
848b7ffc29 | ||
|
|
ff5236f3e0 | ||
|
|
388e64213f | ||
|
|
49a9e58efe | ||
|
|
0fc5190a09 | ||
|
|
19014a3a25 | ||
|
|
ada01fca8f | ||
|
|
61778f9142 | ||
|
|
776d323a16 | ||
|
|
9eac90252e | ||
|
|
708784e222 | ||
|
|
50db1aaeb1 | ||
|
|
8e29eb2417 | ||
|
|
0552bc49c9 | ||
|
|
c9363b1320 | ||
|
|
408c378b94 | ||
|
|
bfa6eae71c | ||
|
|
55e9f08430 | ||
|
|
1c13d7f5ec | ||
|
|
8d0ce5b03c | ||
|
|
5fb0611cb2 |
17
README.md
17
README.md
@@ -3,13 +3,22 @@
|
||||
If you find Open5GS useful for work, please consider supporting this Open Source project by [Becoming a sponsor](https://github.com/sponsors/acetcom). To manage the funding transactions transparently, you can donate through [OpenCollective](https://opencollective.com/open5gs).
|
||||
|
||||
<h3 align="center">Special Sponsor</h3>
|
||||
<!--special start-->
|
||||
|
||||
<p align="center">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://nextepc.com/" target="_blank">
|
||||
<img width="260px" src="https://open5gs.org/assets/img/nextepc_logo.jpg">
|
||||
</a>
|
||||
</p>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://sdr.eee.strath.ac.uk/" target="_blank">
|
||||
<img width="260px" src="https://open5gs.org/assets/img/strath.png">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3 align="center">Sponsors</h3>
|
||||
<table>
|
||||
|
||||
@@ -160,6 +160,10 @@ logger:
|
||||
#
|
||||
# amf_name: amf1.open5gs.amf.5gc.mnc70.mcc901.3gppnetwork.org
|
||||
#
|
||||
# <Relative Capacity> - Default(255)
|
||||
#
|
||||
# relative_capacity: 100
|
||||
#
|
||||
amf:
|
||||
sbi:
|
||||
- addr: 127.0.0.5
|
||||
@@ -264,7 +268,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -272,7 +276,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
@@ -300,4 +304,12 @@ pool:
|
||||
# o Message Wait Duration (3000 ms)
|
||||
# message:
|
||||
# duration: 3000
|
||||
#
|
||||
# o Handover Wait Duration (Default : 300 ms)
|
||||
# Time to wait for AMF to send UEContextReleaseCommand
|
||||
# to the source gNB after receiving HandoverNotify
|
||||
#
|
||||
# o Handover Wait Duration (500ms)
|
||||
# handover:
|
||||
# duration: 500
|
||||
time:
|
||||
|
||||
@@ -140,7 +140,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -148,7 +148,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -66,7 +66,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -74,7 +74,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -201,6 +201,10 @@ logger:
|
||||
#
|
||||
# mme_name: open5gs-mme0
|
||||
#
|
||||
# <Relative Capacity> - Default(255)
|
||||
#
|
||||
# relative_capacity: 100
|
||||
#
|
||||
mme:
|
||||
freeDiameter: @sysconfdir@/freeDiameter/mme.conf
|
||||
s1ap:
|
||||
@@ -373,7 +377,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -381,7 +385,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
@@ -413,4 +417,12 @@ sctp:
|
||||
# o Message Wait Duration (3000 ms)
|
||||
# message:
|
||||
# duration: 3000
|
||||
#
|
||||
# o Handover Wait Duration (Default : 300 ms)
|
||||
# Time to wait for MME to send UEContextReleaseCommand
|
||||
# to the source eNB after receiving HandoverNotify
|
||||
#
|
||||
# o Handover Wait Duration (500ms)
|
||||
# handover:
|
||||
# duration: 500
|
||||
time:
|
||||
|
||||
@@ -112,7 +112,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -120,7 +120,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -142,7 +142,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -150,7 +150,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -46,6 +46,10 @@ pcrf:
|
||||
# o Disable Stateless Address Autoconfiguration for IPv6
|
||||
# no_slaac: true
|
||||
#
|
||||
# o Legacy support for pre-release LTE 11 devices to do calling
|
||||
# - Replace IPv4/v6 local addr field in AAR Media-Subcomponent AVP by any
|
||||
# no_ipv4v6_local_addr_in_packet_filter: true
|
||||
#
|
||||
parameter:
|
||||
|
||||
#
|
||||
@@ -65,7 +69,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -73,7 +77,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -147,7 +147,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -155,7 +155,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -138,7 +138,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -146,7 +146,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -317,7 +317,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -325,7 +325,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
@@ -353,4 +353,13 @@ pool:
|
||||
# o Message Wait Duration (3000 ms)
|
||||
# message:
|
||||
# duration: 3000
|
||||
#
|
||||
# o Handover Wait Duration (Default : 300 ms)
|
||||
# Time to wait for SMF to send
|
||||
# PFCP Session Modification Request(Remove Indirect Tunnel) to the UPF
|
||||
# after sending Nsmf_PDUSession_UpdateSMContext Response(hoState:COMPLETED)
|
||||
#
|
||||
# o Handover Wait Duration (500ms)
|
||||
# handover:
|
||||
# duration: 500
|
||||
time:
|
||||
|
||||
@@ -140,7 +140,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -148,7 +148,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -142,7 +142,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -150,7 +150,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
@@ -223,7 +223,7 @@ max:
|
||||
# To connect more UEs, you need to increase the size further.
|
||||
#
|
||||
# - Pool-size 128 => 65536 Number
|
||||
# - Pool-size 256 => 8192 Number
|
||||
# - Pool-size 256 => 16384 Number
|
||||
# - Pool-size 512 => 4096 Number
|
||||
# - Pool-size 1024 => 1024 Number
|
||||
# - Pool-size 2048 => 512 Number
|
||||
@@ -231,7 +231,7 @@ max:
|
||||
# - Pool-size 1024*1024 => 8 Number
|
||||
#
|
||||
# 128: 65536
|
||||
# 256: 8192
|
||||
# 256: 16384
|
||||
# 512: 4096
|
||||
# 1024: 1024
|
||||
# 2048: 512
|
||||
|
||||
72
debian/changelog
vendored
72
debian/changelog
vendored
@@ -1,3 +1,75 @@
|
||||
open5gs (2.1.7) unstable; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Mon, 08 Feb 2021 22:27:23 -0500
|
||||
|
||||
open5gs (2.1.7~bionic) bionic; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Mon, 08 Feb 2021 22:26:08 -0500
|
||||
|
||||
open5gs (2.1.7~focal) focal; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Mon, 08 Feb 2021 22:23:55 -0500
|
||||
|
||||
open5gs (2.1.6) unstable; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Thu, 04 Feb 2021 09:18:13 -0500
|
||||
|
||||
open5gs (2.1.6~bionic1) bionic; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Thu, 04 Feb 2021 09:17:04 -0500
|
||||
|
||||
open5gs (2.1.6~focal1) focal; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Thu, 04 Feb 2021 09:14:17 -0500
|
||||
|
||||
open5gs (2.1.5) unstable; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Tue, 02 Feb 2021 14:47:59 -0500
|
||||
|
||||
open5gs (2.1.5~bionic) bionic; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Tue, 02 Feb 2021 14:46:57 -0500
|
||||
|
||||
open5gs (2.1.5~focal) focal; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Tue, 02 Feb 2021 14:45:48 -0500
|
||||
|
||||
open5gs (2.1.4) unstable; urgency=medium
|
||||
|
||||
* Paging was added
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Mon, 18 Jan 2021 19:14:26 -0500
|
||||
|
||||
open5gs (2.1.4~bionic) bionic; urgency=medium
|
||||
|
||||
* Paging was added
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Mon, 18 Jan 2021 19:13:26 -0500
|
||||
|
||||
open5gs (2.1.4~focal) focal; urgency=medium
|
||||
|
||||
* Paging was added
|
||||
|
||||
-- Sukchan Lee <acetcom@gmail.com> Mon, 18 Jan 2021 19:12:06 -0500
|
||||
|
||||
open5gs (2.1.3) unstable; urgency=medium
|
||||
|
||||
* Bug Fixed
|
||||
|
||||
@@ -414,11 +414,13 @@ target prot opt source destination
|
||||
|
||||
To enable forwarding and add the NAT rule, enter
|
||||
```bash
|
||||
### Enable IPv4 Forwarding
|
||||
$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
|
||||
### Enable IPv4/IPv6 Forwarding
|
||||
$ sudo sysctl -w net.ipv4.ip_forward=1
|
||||
$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
|
||||
### Add NAT Rule
|
||||
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
|
||||
$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -444,11 +444,13 @@ target prot opt source destination
|
||||
Chain POSTROUTING (policy ACCEPT)
|
||||
target prot opt source destination
|
||||
|
||||
### Enable IPv4 Forwarding
|
||||
$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
|
||||
### Enable IPv4/IPv6 Forwarding
|
||||
$ sudo sysctl -w net.ipv4.ip_forward=1
|
||||
$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
|
||||
### Add NAT Rule
|
||||
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
|
||||
$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
|
||||
```
|
||||
|
||||
**Note:** The above assumes you do not have any existing rules in the filter and nat tables. If a program such as docker has already set up rules, you may need to add the Open5GS related rules differently.
|
||||
|
||||
@@ -31,6 +31,7 @@ If you have tested radio hardware from a vendor not listed with Open5GS, please
|
||||
* Gemtek WLTGFC-101 (S/W version 2.1.1746.1116)
|
||||
* NOKIA FW2PC BC28 Flexi Zone G2 Outdoor Micro FDD LTE 700 MHz High Power
|
||||
* NOKIA FWH1 B38 Flexi Zone Outdoor Micro TD LTE 2600 MHz
|
||||
* Accelleran E1010 (LTE TDD B42)
|
||||
|
||||
### OpenRAN Hardware
|
||||
---
|
||||
|
||||
@@ -1,29 +1,53 @@
|
||||
---
|
||||
title: FreeBSD
|
||||
title: Mac OS X
|
||||
head_inline: "<style> .blue { color: blue; } </style>"
|
||||
---
|
||||
|
||||
This guide is based on **FreeBSD Relase 11.1**.
|
||||
This guide is based on macOS Big Sur 11.2 on a Macbook Air(Apple M1 Chips) computer.
|
||||
{: .blue}
|
||||
|
||||
### Install Xcode Command-Line Tools
|
||||
---
|
||||
|
||||
Homebrew requires the Xcode command-line tools from Apple's Xcode.
|
||||
```bash
|
||||
$ xcode-select --install
|
||||
```
|
||||
|
||||
### Installing Homebrew
|
||||
---
|
||||
|
||||
Install brew using the official Homebrew installation instructions.
|
||||
```bash
|
||||
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
|
||||
### Getting MongoDB
|
||||
---
|
||||
|
||||
Install MongoDB with package manager.
|
||||
Install MongoDB with Package Manager.
|
||||
```bash
|
||||
$ sudo pkg install mongodb
|
||||
$ brew tap mongodb/brew
|
||||
$ brew install mongodb-community
|
||||
```
|
||||
|
||||
Run MongoDB server.
|
||||
```bash
|
||||
$ mkdir -p ./data/db
|
||||
$ mongod --dbpath ./data/db
|
||||
$ mongod --config /usr/local/etc/mongod.conf
|
||||
```
|
||||
|
||||
### Setting up TUN device (No persistent after rebooting)
|
||||
**Tip:** MongoDB is persistent after rebooting with the following commands:
|
||||
`$ brew services start mongodb-community`
|
||||
{: .notice--info}
|
||||
|
||||
|
||||
### Setting up network (No persistent after rebooting)
|
||||
---
|
||||
|
||||
Configure the TUN device.
|
||||
Note that Open5GS uses built-in "utun" device driver. So, You don't have to install external TUN/TAP driver.
|
||||
{: .blue}
|
||||
|
||||
Configure the loopback interface.
|
||||
```bash
|
||||
$ sudo ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.3 netmask 255.255.255.255
|
||||
@@ -38,15 +62,26 @@ $ sudo ifconfig lo0 alias 127.0.0.10 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.11 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.12 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.13 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.14 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.15 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.16 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||
```
|
||||
|
||||
Enable IP forwarding
|
||||
Enable IP forwarding & Masquerading
|
||||
```bash
|
||||
$ sudo sysctl -w net.inet.ip.forwarding=1
|
||||
$ sudo sysctl -w net.inet6.ip6.forwarding=1
|
||||
$ sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
||||
$ sudo sh -c "echo 'nat on {en0} from cafe::1/64 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
||||
$ sudo pfctl -e -f /etc/pf.anchors/org.open5gs
|
||||
```
|
||||
|
||||
**Tip:** The script provided in [$GIT_REPO/support/network/restart.sh](https://github.com/{{ site.github_username }}/open5gs/blob/master/support/network/restart.sh) makes it easy to configure the TUN device as follows:
|
||||
`$ sudo ./support/network/restart.sh`
|
||||
**Tip:** The script provided in [$GIT_REPO/misc/netconf.sh](https://github.com/{{ site.github_username }}/open5gs/blob/master/misc/netconf.sh) makes it easy to configure the TUN device as follows:
|
||||
`$ sudo ./misc/netconf.sh`
|
||||
{: .notice--info}
|
||||
|
||||
### Building Open5GS
|
||||
@@ -54,13 +89,19 @@ $ sudo sysctl -w net.inet.ip.forwarding=1
|
||||
|
||||
Install the depedencies for building the source code.
|
||||
```bash
|
||||
$ sudo pkg install py36-pip ninja gcc bison gsed pkgconf git mongo-c-driver gnutls libgcrypt libidn libyaml libmicrohttpd curl
|
||||
$ brew install mongo-c-driver gnutls libgcrypt libidn libyaml libmicrohttpd nghttp2 pkg-config bison
|
||||
```
|
||||
|
||||
Install Meson using Python.
|
||||
Configure Homebrew PATH
|
||||
```bash
|
||||
$ sudo pip install --upgrade pip
|
||||
$ sudo pip install meson
|
||||
$ export PATH="/opt/homebrew/opt/bison/bin:/opt/homebrew/bin:$PATH"
|
||||
$ export LIBRARY_PATH=/opt/homebrew/lib
|
||||
$ export C_INCLUDE_PATH=/opt/homebrew/include
|
||||
```
|
||||
|
||||
Install Meson using Homebrew.
|
||||
```bash
|
||||
$ brew install meson
|
||||
```
|
||||
|
||||
Git clone.
|
||||
@@ -73,7 +114,7 @@ To compile with meson:
|
||||
|
||||
```bash
|
||||
$ cd open5gs
|
||||
$ meson build --prefix=`pwd`/install
|
||||
$ meson build --prefix=`pwd`/install -D c_std=c99
|
||||
$ ninja -C build
|
||||
```
|
||||
|
||||
@@ -107,13 +148,14 @@ $ ninja install
|
||||
$ cd ../
|
||||
```
|
||||
|
||||
|
||||
### Building WebUI of Open5GS
|
||||
---
|
||||
|
||||
[Node.js](https://nodejs.org/) is required to build WebUI of Open5GS
|
||||
|
||||
```bash
|
||||
$ sudo pkg install node
|
||||
$ brew install node
|
||||
```
|
||||
|
||||
Install the dependencies to run WebUI
|
||||
@@ -128,4 +170,3 @@ The WebUI runs as an [npm](https://www.npmjs.com/) script.
|
||||
```bash
|
||||
$ npm run dev
|
||||
```
|
||||
|
||||
@@ -3,14 +3,23 @@ title: Mac OS X
|
||||
head_inline: "<style> .blue { color: blue; } </style>"
|
||||
---
|
||||
|
||||
This guide is based on **macOS Big Sur 11.0.1**.
|
||||
This guide is based on macOS Big Sur 11.2 on a Macbook Pro(Intel Chips) computer.
|
||||
{: .blue}
|
||||
|
||||
### Install Xcode Command-Line Tools
|
||||
---
|
||||
|
||||
Homebrew requires the Xcode command-line tools from Apple's Xcode.
|
||||
```bash
|
||||
$ xcode-select --install
|
||||
```
|
||||
|
||||
### Installing Homebrew
|
||||
---
|
||||
|
||||
Install brew using the official Homebrew installation instructions.
|
||||
```bash
|
||||
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
|
||||
### Getting MongoDB
|
||||
@@ -32,14 +41,13 @@ $ mongod --config /usr/local/etc/mongod.conf
|
||||
{: .notice--info}
|
||||
|
||||
|
||||
### Setting up TUN device (No persistent after rebooting)
|
||||
### Setting up network (No persistent after rebooting)
|
||||
---
|
||||
|
||||
Install TUN/TAP driver
|
||||
- You can download it from [http://tuntaposx.sourceforge.net/](http://tuntaposx.sourceforge.net/)
|
||||
- And then, run tuntap_20150118.pkg to install TUN/TAP driver.
|
||||
Note that Open5GS uses built-in "utun" device driver. So, You don't have to install external TUN/TAP driver.
|
||||
{: .blue}
|
||||
|
||||
Configure the TUN device.
|
||||
Configure the loopback interface.
|
||||
```bash
|
||||
$ sudo ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.3 netmask 255.255.255.255
|
||||
@@ -54,16 +62,25 @@ $ sudo ifconfig lo0 alias 127.0.0.10 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.11 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.12 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.13 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.14 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.15 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.16 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||
```
|
||||
|
||||
Enable IP forwarding & Masquerading
|
||||
```bash
|
||||
$ sudo sysctl -w net.inet.ip.forwarding=1
|
||||
$ sudo sysctl -w net.inet6.ip6.forwarding=1
|
||||
$ sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
||||
$ sudo sh -c "echo 'nat on {en0} from cafe::1/64 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
|
||||
$ sudo pfctl -e -f /etc/pf.anchors/org.open5gs
|
||||
```
|
||||
|
||||
**Tip:** The script provided in [$GIT_REPO/misc/netconf.sh](https://github.com/{{ site.github_username }}/open5gs/blob/master/misc/netconf.sh) makes it easy to configure the TUN device as follows:
|
||||
**Tip:** The script provided in [$GIT_REPO/misc/netconf.sh](https://github.com/{{ site.github_username }}/open5gs/blob/master/misc/netconf.sh) makes it easy to configure the TUN device as follows:
|
||||
`$ sudo ./misc/netconf.sh`
|
||||
{: .notice--info}
|
||||
|
||||
@@ -152,4 +169,3 @@ The WebUI runs as an [npm](https://www.npmjs.com/) script.
|
||||
```bash
|
||||
$ npm run dev
|
||||
```
|
||||
|
||||
216
docs/_docs/platform/07-freebsd.md
Normal file
216
docs/_docs/platform/07-freebsd.md
Normal file
@@ -0,0 +1,216 @@
|
||||
---
|
||||
title: FreeBSD
|
||||
head_inline: "<style> .blue { color: blue; } </style>"
|
||||
---
|
||||
|
||||
This guide is based on **FreeBSD-11.4-STABLE**.
|
||||
{: .blue}
|
||||
|
||||
## Install **FreeBSD-11.4-STABLE** from Vagrant box (optional)
|
||||
---
|
||||
Vagrant provides a simple way to create and deploy Virtual Machines from
|
||||
pre-built images using VirtualBox, libvirt, or VMWare as a hypervisor engine.
|
||||
This allows the user to quickly create a virtual machine without the hassle
|
||||
of installing the operating system by hand.
|
||||
|
||||
### Install Vagrant
|
||||
---
|
||||
|
||||
The instructions to install Vagrant are provided at
|
||||
[vagrantup.com](https://www.vagrantup.com/).
|
||||
|
||||
|
||||
### Create a FreeBSD-11.4-STABLE Virtual Machine using Vagrant
|
||||
---
|
||||
|
||||
Use the supplied `Vagrantfile` in the `vagrant` directory to create the
|
||||
virtual machine.
|
||||
|
||||
Note that this Vagrantfile is identical to the base FreeBSD 11 box, with
|
||||
the exception that the amount of virtual memory has been increased to 1GB:
|
||||
|
||||
```bash
|
||||
cd vagrant/freebsd
|
||||
vagrant up --provider virtualbox
|
||||
```
|
||||
|
||||
### Log into the newly created FreeBSD VM
|
||||
---
|
||||
|
||||
Use SSH to log into the FreeBSD 11 VM:
|
||||
|
||||
```bash
|
||||
vagrant ssh
|
||||
```
|
||||
|
||||
Note that the Open5GS source is *not* copied into the VM. The instructions
|
||||
below provide the step by step instructions for setting up Open5GS for
|
||||
either a bare metal or virtual FreeBSD 11 system.
|
||||
|
||||
The rest of the commands below are performed inside the FreeBSD VM as the
|
||||
user 'vagrant', or on your bare metal FreeBSD 11 system as any normal user.
|
||||
|
||||
### Getting MongoDB
|
||||
---
|
||||
|
||||
Install MongoDB with package manager.
|
||||
```bash
|
||||
$ sudo pkg install mongodb44
|
||||
```
|
||||
|
||||
Run MongoDB server.
|
||||
```bash
|
||||
$ mkdir -p ./data/db
|
||||
$ mongod --dbpath ./data/db
|
||||
```
|
||||
|
||||
### Setting up network (No persistent after rebooting)
|
||||
---
|
||||
|
||||
Configure the loopback interface.
|
||||
```bash
|
||||
$ sudo ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.3 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.4 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.5 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.5 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.6 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.7 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.8 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.9 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.10 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.11 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.12 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.13 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.14 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.15 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.16 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
|
||||
$ sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
|
||||
```
|
||||
|
||||
Enable IP forwarding
|
||||
```bash
|
||||
$ sudo sysctl -w net.inet.ip.forwarding=1
|
||||
$ sudo sysctl -w net.inet6.ip6.forwarding=1
|
||||
```
|
||||
|
||||
**Tip:** The script provided in [$GIT_REPO/misc/netconf.sh](https://github.com/{{ site.github_username }}/open5gs/blob/master/misc/netconf.sh) makes it easy to configure the TUN device as follows:
|
||||
`$ sudo ./misc/netconf.sh`
|
||||
{: .notice--info}
|
||||
|
||||
### Building Open5GS
|
||||
---
|
||||
|
||||
Install the depedencies for building the source code.
|
||||
```bash
|
||||
$ sudo pkg install meson ninja gcc bison gsed pkgconf git mongo-c-driver gnutls libgcrypt libidn libyaml libmicrohttpd nghttp2
|
||||
```
|
||||
|
||||
Configure gcc PATH
|
||||
```bash
|
||||
$ setenv LIBRARY_PATH /usr/local/lib
|
||||
$ setenv C_INCLUDE_PATH /usr/local/include
|
||||
```
|
||||
|
||||
If you are using BASH instead of default CSH,
|
||||
```bash
|
||||
$ export LIBRARY_PATH=/usr/local/lib
|
||||
$ export C_INCLUDE_PATH=/usr/local/include
|
||||
```
|
||||
|
||||
Git clone.
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/{{ site.github_username }}/open5gs
|
||||
```
|
||||
|
||||
To compile with meson:
|
||||
|
||||
```bash
|
||||
$ cd open5gs
|
||||
$ meson build --prefix=`pwd`/install
|
||||
$ ninja -C build
|
||||
```
|
||||
|
||||
**Note:** No source code changes are required for FreeBSD 11.x version. However, in FreeBSD 12.x version, we'll getting a crash with segmentation fault when calling basename(3). To avoid this, you need to change the freeDiameter source code as below.
|
||||
{: .blue}
|
||||
|
||||
```diff
|
||||
$ cd open5gs/subprojects/freeDiameter
|
||||
|
||||
$ diff --git a/include/freeDiameter/libfdproto.h b/include/freeDiameter/libfdproto.h
|
||||
index 52c11ef..cd7f383 100644
|
||||
--- a/include/freeDiameter/libfdproto.h
|
||||
+++ b/include/freeDiameter/libfdproto.h
|
||||
@@ -293,7 +293,7 @@ extern int fd_g_debug_lvl;
|
||||
|
||||
/* A version of __FILE__ without the full path. This is specific to each C file being compiled */
|
||||
static char * file_bname = NULL;
|
||||
-static char * file_bname_init(char * full) { file_bname = basename(full); return file_bname; }
|
||||
+static char * file_bname_init(char * full) { file_bname = __old_basename(full); return file_bname; }
|
||||
#define __STRIPPED_FILE__ (file_bname ?: file_bname_init((char *)__FILE__))
|
||||
|
||||
```
|
||||
|
||||
Now, compile again:
|
||||
{: .blue}
|
||||
|
||||
```bash
|
||||
$ cd open5gs
|
||||
$ ninja -C build
|
||||
```
|
||||
|
||||
Check whether the compilation is correct.
|
||||
|
||||
**Note:** This should require *sudo* due to access `/dev/tun0`.
|
||||
{: .notice--danger}
|
||||
|
||||
```bash
|
||||
$ sudo ./build/tests/attach/attach ## EPC Only
|
||||
$ sudo ./build/tests/registration/registration ## 5G Core Only
|
||||
```
|
||||
|
||||
Run all test programs as below.
|
||||
|
||||
**Note:** This should require *sudo* due to access `/dev/tun0`.
|
||||
{: .notice--danger}
|
||||
|
||||
```bash
|
||||
$ cd build
|
||||
$ sudo meson test -v
|
||||
```
|
||||
|
||||
**Tip:** You can also check the result of `ninja -C build test` with a tool that captures packets. If you are running `wireshark`, select the `loopback` interface and set FILTER to `s1ap || gtpv2 || pfcp || diameter || gtp || ngap || http2.data.data || http2.headers`. You can see the virtually created packets. [testattach.pcapng]({{ site.url }}{{ site.baseurl }}/assets/pcapng/testattach.pcapng)/[testregistration.pcapng]({{ site.url }}{{ site.baseurl }}/assets/pcapng/testregistration.pcapng)
|
||||
{: .notice--info}
|
||||
|
||||
You need to perform the **installation process**.
|
||||
```bash
|
||||
$ cd build
|
||||
$ ninja install
|
||||
$ cd ../
|
||||
```
|
||||
|
||||
### Building WebUI of Open5GS
|
||||
---
|
||||
|
||||
[Node.js](https://nodejs.org/) is required to build WebUI of Open5GS
|
||||
|
||||
```bash
|
||||
$ sudo pkg install node
|
||||
```
|
||||
|
||||
Install the dependencies to run WebUI
|
||||
|
||||
```bash
|
||||
$ cd webui
|
||||
$ npm install
|
||||
```
|
||||
|
||||
The WebUI runs as an [npm](https://www.npmjs.com/) script.
|
||||
|
||||
```bash
|
||||
$ npm run dev
|
||||
```
|
||||
@@ -357,9 +357,10 @@ Timeout: 0
|
||||
|
||||
#### Is it possible to setup IP/NAT table along with Docker?
|
||||
|
||||
Enable IP Forward.
|
||||
Enable IPv4/IPv6 Forward.
|
||||
```
|
||||
$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
|
||||
$ sudo sysctl -w net.ipv4.ip_forward=1
|
||||
$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
```
|
||||
|
||||
The following is the default docker IP/NAT table.
|
||||
@@ -435,6 +436,11 @@ And then, apply **newtables** as below.
|
||||
$ sudo iptables-restore < newtables
|
||||
```
|
||||
|
||||
Docker doesn't have IPv6 NAT rules. In this case, you just add the NAT rule as below.
|
||||
```
|
||||
$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
|
||||
```
|
||||
|
||||
The above operation is the same as described in the following manuals.
|
||||
```
|
||||
### Check IP Tables
|
||||
@@ -462,11 +468,13 @@ target prot opt source destination
|
||||
Chain POSTROUTING (policy ACCEPT)
|
||||
target prot opt source destination
|
||||
|
||||
### Enable IPv4 Forwarding
|
||||
$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
|
||||
### Enable IPv4/IPv6 Forwarding
|
||||
$ sudo sysctl -w net.ipv4.ip_forward=1
|
||||
$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
|
||||
### Add NAT Rule
|
||||
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
|
||||
$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
|
||||
```
|
||||
|
||||
#### How to use a different DNN/APN for each SMF
|
||||
|
||||
@@ -308,11 +308,13 @@ target prot opt source destination
|
||||
Chain POSTROUTING (policy ACCEPT)
|
||||
target prot opt source destination
|
||||
|
||||
### Enable IPv4 Forwarding
|
||||
$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
|
||||
### Enable IPv4/IPv6 Forwarding
|
||||
$ sudo sysctl -w net.ipv4.ip_forward=1
|
||||
$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
|
||||
### Add NAT Rule
|
||||
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
|
||||
$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
|
||||
```
|
||||
|
||||
**Note:** For the first time, it is a good condition if you do not have any rules in the IP/NAT tables. If a program such as docker has already set up a rule, you will need to add a rule differently.
|
||||
|
||||
@@ -754,8 +754,8 @@ Below startup script can be used for setting up interfaces:
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
|
||||
sh -c "echo 1 > /proc/sys/net/ipv6/ip_forward"
|
||||
sudo sysctl -w net.ipv4.ip_forward=1
|
||||
sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
|
||||
ip tuntap add name ogstun mode tun
|
||||
ip addr add 192.168.100.1/24 dev ogstun
|
||||
|
||||
@@ -14,15 +14,18 @@ Open5GS is a C-language Open Source implementation of 5GC and EPC, i.e. the core
|
||||
- Support of USIM cards using Milenage
|
||||
- IPv6 support
|
||||
- Multiple PDU session
|
||||
- S1/X2 and Xn Handover
|
||||
- Handover(5GC Xn/N2 and EPC S1/X2)
|
||||
- CSFB(Circuit Switched Fall Back) and SMSoS(SMS Over SGs)
|
||||
- VoLTE(Voice over LTE)
|
||||
|
||||
#### Known Limitations
|
||||
---
|
||||
|
||||
- No OCS/OFCS
|
||||
- No NSSF
|
||||
- No VoNR(Voice over NR)
|
||||
- No Interworking with EPC
|
||||
- No NB-IoT
|
||||
- No OCS/OFCS
|
||||
- No eMBMS
|
||||
- No SRVCC
|
||||
- No Roaming
|
||||
|
||||
@@ -30,7 +30,9 @@ head_inline: "<style> ul { padding-bottom: 1em; } </style>"
|
||||
- [Debian/Ubuntu](platform/01-debian-ubuntu)
|
||||
- [CentOS](platform/02-centos)
|
||||
- [Fedora](platform/03-fedora)
|
||||
- [MacOSX](platform/05-macosx)
|
||||
- [MacOSX(Apple Silicon)](platform/05-macosx-apple-silicon)
|
||||
- [MacOSX(Intel)](platform/06-macosx-intel)
|
||||
- [FreeBSD](platform/07-freebsd)
|
||||
|
||||
- Hardware Specific Notes
|
||||
- [Tested e/gNodeBs](hardware/01-genodebs)
|
||||
|
||||
23
docs/_posts/2021-01-18-release-v2.1.4.md
Normal file
23
docs/_posts/2021-01-18-release-v2.1.4.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "v2.1.4 - Paging was added"
|
||||
date: 2021-01-18 21:23:00 -0500
|
||||
categories:
|
||||
- Release
|
||||
tags:
|
||||
- News
|
||||
- Release
|
||||
head_inline: "<style> ul { padding-bottom: 1em; } </style>"
|
||||
---
|
||||
|
||||
#### New feature
|
||||
- [5GC] Paging ([c9363b1](https://github.com/open5gs/open5gs/commit/c9363b132093581b6fd2ce794aa63cd597bf83a6))
|
||||
|
||||
#### Enhancement
|
||||
- [PFCP] Legacy support for pre-release LTE11 devices while performing VoLTE call([#757](https://github.com/open5gs/open5gs/pull/757)) -- [herlesupreeth](https://github.com/herlesupreeth)
|
||||
|
||||
#### Bug Fixes
|
||||
- [EPC] Use ESM cause(43:Invalid EPS bearer identity) if SGW-C sends GTP cause(Context Not Found) ([#755](https://github.com/open5gs/open5gs/issues/755)) -- [herlesupreeth](https://github.com/herlesupreeth)
|
||||
- [MME] fix a bug where SCTP stream number was not set while sending S1-Paging message. ([c9363b1](https://github.com/open5gs/open5gs/commit/c9363b132093581b6fd2ce794aa63cd597bf83a6))
|
||||
|
||||
Download -- [v2.1.4.tar.gz](https://github.com/open5gs/open5gs/archive/v2.1.4.tar.gz)
|
||||
{: .notice--info}
|
||||
29
docs/_posts/2021-02-02-release-v2.1.5.md
Normal file
29
docs/_posts/2021-02-02-release-v2.1.5.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: "v2.1.5 - 5G Core N2 based handover"
|
||||
date: 2021-02-02 14:52:00 -0500
|
||||
categories:
|
||||
- Release
|
||||
tags:
|
||||
- News
|
||||
- Release
|
||||
head_inline: "<style> ul { padding-bottom: 1em; } </style>"
|
||||
---
|
||||
|
||||
#### New feature
|
||||
- [5GC] N2 Handver ([49a9e58](https://github.com/open5gs/open5gs/commit/49a9e58efe3f6ecd482c3b77b98cd0841688b647), [ff5236f](https://github.com/open5gs/open5gs/commit/ff5236f3e01ee6984bc78eaacc7d84e08c321266))
|
||||
|
||||
#### Enhancement
|
||||
- [AMF/MME] Check IMEISV length == 16 digits ([388e642](https://github.com/open5gs/open5gs/commit/388e64213fcebc257eb7bd0223105c3055c56252))
|
||||
- [AMF] Add Handling Duplicated PDU Session ID ([d9417be](https://github.com/open5gs/open5gs/commit/d9417be9a62255efa91a11ee2c424ec1e739b919))
|
||||
- [ASN] S1AP/NGAP update to v16.4.0(2021-01-04) ([ada01fc](https://github.com/open5gs/open5gs/commit/ada01fca8ffaea029d2ae04e6bc1bb499ab37894))
|
||||
- [AMF/MME] Add UserLocation Handling in UplinkNASTransport ([#772](https://github.com/open5gs/open5gs/pull/772)) -- [zhonglin6666](https://github.com/zhonglin6666)
|
||||
|
||||
#### Bug Fixes
|
||||
- [UDR] Modify SmfSelectionSubscriptionData ([#785](https://github.com/open5gs/open5gs/pull/785)) -- [zhonglin6666](https://github.com/zhonglin6666)
|
||||
- [MME] ENBDirectInformationTransfer decoding problem ([#783](https://github.com/open5gs/open5gs/issues/783)) -- [kuanghanqian](https://github.com/kuanghanqian)
|
||||
- [AMF] PartOfNG-Interface in NGReset decoding problem ([#773](https://github.com/open5gs/open5gs/issues/773)) -- [acetcom](https://github.com/acetcom)
|
||||
- [AMF] Fix UE Context Request IE Handling ([#771](https://github.com/open5gs/open5gs/issues/771)) -- [kuanghanqian](https://github.com/kuanghanqian)
|
||||
- [5GC] Fix the AMF/SMF/UDM crash issues ([#770](https://github.com/open5gs/open5gs/issues/770), [#771](https://github.com/open5gs/open5gs/issues/771)) -- [kuanghanqian](https://github.com/kuanghanqian)
|
||||
|
||||
Download -- [v2.1.5.tar.gz](https://github.com/open5gs/open5gs/archive/v2.1.5.tar.gz)
|
||||
{: .notice--info}
|
||||
22
docs/_posts/2021-02-08-release-v2.1.7.md
Normal file
22
docs/_posts/2021-02-08-release-v2.1.7.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: "v2.1.7 - 5G Core Hotfix"
|
||||
date: 2021-02-07 22:31:00 -0500
|
||||
categories:
|
||||
- Release
|
||||
tags:
|
||||
- News
|
||||
- Release
|
||||
head_inline: "<style> ul { padding-bottom: 1em; } </style>"
|
||||
---
|
||||
|
||||
#### Bug Fixes
|
||||
- [5GC/EPC] Pool size adjusted to support 1,024 UEs ([#753](https://github.com/open5gs/open5gs/issues/753)) -- [zhouxiang93123](https://github.com/zhouxiang93123)
|
||||
- [AMF] Crash during handling Duplicated PDU Session ID ([#793](https://github.com/open5gs/open5gs/issues/783)) -- [kuanghanqian](https://github.com/kuanghanqian)
|
||||
|
||||
#### New Platform
|
||||
- MacOSX with Apple M1 Silicon ([7901a1](https://github.com/open5gs/open5gs/commit/7901a1164fdaa04cf72a5a944f50474d569f619d))
|
||||
- FreeBSD ([852756](https://github.com/open5gs/open5gs/commit/852756f90222a8e0821f6e1994baa32eafbdc47c))
|
||||
|
||||
|
||||
Download -- [v2.1.7.tar.gz](https://github.com/open5gs/open5gs/archive/v2.1.7.tar.gz)
|
||||
{: .notice--info}
|
||||
@@ -203,6 +203,14 @@ static void app_context_prepare(void)
|
||||
*/
|
||||
self.time.message.duration = ogs_time_from_sec(10);
|
||||
|
||||
/*
|
||||
* Handover Wait Duration : 300 ms (Default)
|
||||
*
|
||||
* Time to wait for AMF/MME to send UEContextReleaseCommand
|
||||
* to the source gNB/eNB after receiving HandoverNotify
|
||||
*/
|
||||
self.time.handover.duration = ogs_time_from_msec(300);
|
||||
|
||||
regenerate_all_timer_duration();
|
||||
}
|
||||
|
||||
@@ -327,6 +335,10 @@ int ogs_app_context_parse_config(void)
|
||||
} else if (!strcmp(parameter_key, "use_openair")) {
|
||||
self.parameter.use_openair =
|
||||
ogs_yaml_iter_bool(¶meter_iter);
|
||||
} else if (!strcmp(
|
||||
parameter_key, "no_ipv4v6_local_addr_in_packet_filter")) {
|
||||
self.parameter.no_ipv4v6_local_addr_in_packet_filter =
|
||||
ogs_yaml_iter_bool(¶meter_iter);
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", parameter_key);
|
||||
}
|
||||
@@ -478,13 +490,31 @@ int ogs_app_context_parse_config(void)
|
||||
if (!strcmp(msg_key, "duration")) {
|
||||
const char *v = ogs_yaml_iter_value(&msg_iter);
|
||||
if (v) {
|
||||
self.time.message.duration =
|
||||
self.time.message.duration =
|
||||
ogs_time_from_msec(atoll(v));
|
||||
regenerate_all_timer_duration();
|
||||
}
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", msg_key);
|
||||
}
|
||||
} else if (!strcmp(time_key, "handover")) {
|
||||
ogs_yaml_iter_t msg_iter;
|
||||
ogs_yaml_iter_recurse(&time_iter, &msg_iter);
|
||||
|
||||
while (ogs_yaml_iter_next(&msg_iter)) {
|
||||
const char *msg_key =
|
||||
ogs_yaml_iter_key(&msg_iter);
|
||||
ogs_assert(msg_key);
|
||||
|
||||
if (!strcmp(msg_key, "duration")) {
|
||||
const char *v = ogs_yaml_iter_value(&msg_iter);
|
||||
if (v) {
|
||||
self.time.handover.duration =
|
||||
ogs_time_from_msec(atoll(v));
|
||||
}
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", msg_key);
|
||||
}
|
||||
} else
|
||||
ogs_warn("unknown key `%s`", time_key);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ typedef struct ogs_app_context_s {
|
||||
int no_slaac;
|
||||
|
||||
int use_openair;
|
||||
int no_ipv4v6_local_addr_in_packet_filter;
|
||||
} parameter;
|
||||
|
||||
ogs_sockopt_t sockopt;
|
||||
@@ -145,6 +146,12 @@ typedef struct ogs_app_context_s {
|
||||
ogs_time_t no_heartbeat_duration;
|
||||
} pfcp;
|
||||
} message;
|
||||
|
||||
struct {
|
||||
ogs_time_t duration;
|
||||
ogs_time_t complete_delay;
|
||||
} handover;
|
||||
|
||||
} time;
|
||||
} ogs_app_context_t;
|
||||
|
||||
|
||||
@@ -4,447 +4,72 @@
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <ANY.h>
|
||||
#include <errno.h>
|
||||
|
||||
asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs = {
|
||||
sizeof(ANY_t),
|
||||
offsetof(ANY_t, _asn_ctx),
|
||||
ASN_OSUBV_ANY
|
||||
sizeof(ANY_t),
|
||||
offsetof(ANY_t, _asn_ctx),
|
||||
ASN_OSUBV_ANY
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_ANY = {
|
||||
OCTET_STRING_free,
|
||||
OCTET_STRING_print,
|
||||
OCTET_STRING_compare,
|
||||
OCTET_STRING_decode_ber,
|
||||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
ANY_encode_xer,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
OCTET_STRING_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
OCTET_STRING_print,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0, 0, 0, 0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OCTET_STRING_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OCTET_STRING_decode_ber,
|
||||
OCTET_STRING_encode_der,
|
||||
#else
|
||||
ANY_decode_uper,
|
||||
ANY_encode_uper,
|
||||
ANY_decode_aper,
|
||||
ANY_encode_aper,
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
0, /* Random fill is not defined for ANY type */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
ANY_encode_xer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
0,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
ANY_decode_uper,
|
||||
ANY_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
ANY_decode_aper,
|
||||
ANY_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
0, /* Random fill is not defined for ANY type */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_ANY = {
|
||||
"ANY",
|
||||
"ANY",
|
||||
&asn_OP_ANY,
|
||||
0, 0, 0, 0,
|
||||
{ 0, 0, asn_generic_no_constraint }, /* No constraints */
|
||||
0, 0, /* No members */
|
||||
&asn_SPC_ANY_specs,
|
||||
"ANY",
|
||||
"ANY",
|
||||
&asn_OP_ANY,
|
||||
0, 0, 0, 0,
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_generic_no_constraint
|
||||
}, /* No constraints */
|
||||
0, 0, /* No members */
|
||||
&asn_SPC_ANY_specs,
|
||||
};
|
||||
|
||||
#undef RETURN
|
||||
#define RETURN(_code) \
|
||||
do { \
|
||||
asn_dec_rval_t tmprval; \
|
||||
tmprval.code = _code; \
|
||||
tmprval.consumed = consumed_myself; \
|
||||
return tmprval; \
|
||||
} while(0)
|
||||
|
||||
asn_enc_rval_t
|
||||
ANY_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
|
||||
void *app_key) {
|
||||
if(flags & XER_F_CANONICAL) {
|
||||
/*
|
||||
* Canonical XER-encoding of ANY type is not supported.
|
||||
*/
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
/* Dump as binary */
|
||||
return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
|
||||
}
|
||||
|
||||
struct _callback_arg {
|
||||
uint8_t *buffer;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
|
||||
|
||||
int
|
||||
ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
|
||||
struct _callback_arg arg;
|
||||
asn_enc_rval_t erval = {0,0,0};
|
||||
|
||||
if(!st || !td) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!sptr) {
|
||||
if(st->buf) FREEMEM(st->buf);
|
||||
st->size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
arg.offset = arg.size = 0;
|
||||
arg.buffer = 0;
|
||||
|
||||
erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
|
||||
if(erval.encoded == -1) {
|
||||
if(arg.buffer) FREEMEM(arg.buffer);
|
||||
return -1;
|
||||
}
|
||||
assert((size_t)erval.encoded == arg.offset);
|
||||
|
||||
if(st->buf) FREEMEM(st->buf);
|
||||
st->buf = arg.buffer;
|
||||
st->size = arg.offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
|
||||
uint8_t *buffer = NULL;
|
||||
ssize_t erval;
|
||||
|
||||
if(!st || !td) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!sptr) {
|
||||
if(st->buf) FREEMEM(st->buf);
|
||||
st->size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
erval = aper_encode_to_new_buffer(td, td->encoding_constraints.per_constraints, sptr, (void**)&buffer);
|
||||
|
||||
if(erval == -1) {
|
||||
if(buffer) FREEMEM(buffer);
|
||||
return -1;
|
||||
}
|
||||
assert((size_t)erval > 0);
|
||||
|
||||
if(st->buf) FREEMEM(st->buf);
|
||||
st->buf = buffer;
|
||||
st->size = erval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ANY_t *
|
||||
ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
|
||||
ANY_t tmp;
|
||||
ANY_t *st;
|
||||
|
||||
if(!td || !sptr) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
|
||||
if(ANY_fromType(&tmp, td, sptr)) return 0;
|
||||
|
||||
st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
|
||||
if(st) {
|
||||
*st = tmp;
|
||||
return st;
|
||||
} else {
|
||||
FREEMEM(tmp.buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ANY_t *
|
||||
ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
|
||||
ANY_t tmp;
|
||||
ANY_t *st;
|
||||
|
||||
if(!td || !sptr) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
|
||||
if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
|
||||
|
||||
st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
|
||||
if(st) {
|
||||
*st = tmp;
|
||||
return st;
|
||||
} else {
|
||||
FREEMEM(tmp.buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
|
||||
asn_dec_rval_t rval;
|
||||
void *newst = 0;
|
||||
|
||||
if(!st || !td || !struct_ptr) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(st->buf == 0) {
|
||||
/* Nothing to convert, make it empty. */
|
||||
*struct_ptr = (void *)0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
|
||||
if(rval.code == RC_OK) {
|
||||
*struct_ptr = newst;
|
||||
return 0;
|
||||
} else {
|
||||
/* Remove possibly partially decoded data. */
|
||||
ASN_STRUCT_FREE(*td, newst);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
|
||||
asn_dec_rval_t rval;
|
||||
void *newst = 0;
|
||||
|
||||
if(!st || !td || !struct_ptr) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(st->buf == 0) {
|
||||
/* Nothing to convert, make it empty. */
|
||||
*struct_ptr = (void *)0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
|
||||
if(rval.code == RC_OK) {
|
||||
*struct_ptr = newst;
|
||||
return 0;
|
||||
} else {
|
||||
/* Remove possibly partially decoded data. */
|
||||
ASN_STRUCT_FREE(*td, newst);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
|
||||
struct _callback_arg *arg = (struct _callback_arg *)key;
|
||||
|
||||
if((arg->offset + size) >= arg->size) {
|
||||
size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
|
||||
void *p = REALLOC(arg->buffer, nsize);
|
||||
if(!p) return -1;
|
||||
arg->buffer = (uint8_t *)p;
|
||||
arg->size = nsize;
|
||||
}
|
||||
|
||||
memcpy(arg->buffer + arg->offset, buffer, size);
|
||||
arg->offset += size;
|
||||
assert(arg->offset < arg->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef ASN_DISABLE_PER_SUPPORT
|
||||
|
||||
asn_dec_rval_t
|
||||
ANY_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr,
|
||||
asn_per_data_t *pd) {
|
||||
const asn_OCTET_STRING_specifics_t *specs =
|
||||
td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_ANY_specs;
|
||||
size_t consumed_myself = 0;
|
||||
int repeat;
|
||||
ANY_t *st = (ANY_t *)*sptr;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)constraints;
|
||||
|
||||
/*
|
||||
* Allocate the structure.
|
||||
*/
|
||||
if(!st) {
|
||||
st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
ASN_DEBUG("UPER Decoding ANY type");
|
||||
|
||||
st->size = 0;
|
||||
do {
|
||||
ssize_t raw_len;
|
||||
ssize_t len_bytes;
|
||||
ssize_t len_bits;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
/* Get the PER length */
|
||||
raw_len = uper_get_length(pd, -1, 0, &repeat);
|
||||
if(raw_len < 0) RETURN(RC_WMORE);
|
||||
if(raw_len == 0 && st->buf) break;
|
||||
|
||||
ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
|
||||
repeat ? "repeat" : "once", td->name);
|
||||
len_bytes = raw_len;
|
||||
len_bits = len_bytes * 8;
|
||||
|
||||
p = REALLOC(st->buf, st->size + len_bytes + 1);
|
||||
if(!p) RETURN(RC_FAIL);
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
consumed_myself += len_bits;
|
||||
st->size += len_bytes;
|
||||
} while(repeat);
|
||||
st->buf[st->size] = 0; /* nul-terminate */
|
||||
|
||||
RETURN(RC_OK);
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
ANY_encode_uper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, const void *sptr,
|
||||
asn_per_outp_t *po) {
|
||||
const ANY_t *st = (const ANY_t *)sptr;
|
||||
asn_enc_rval_t er = {0, 0, 0};
|
||||
const uint8_t *buf;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
|
||||
|
||||
buf = st->buf;
|
||||
size = st->size;
|
||||
do {
|
||||
int need_eom = 0;
|
||||
ssize_t may_save = uper_put_length(po, size, &need_eom);
|
||||
if(may_save < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
ret = per_put_many_bits(po, buf, may_save * 8);
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
|
||||
buf += may_save;
|
||||
size -= may_save;
|
||||
assert(!(may_save & 0x07) || !size);
|
||||
if(need_eom && uper_put_length(po, 0, 0))
|
||||
ASN__ENCODE_FAILED; /* End of Message length */
|
||||
} while(size);
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr,
|
||||
asn_per_data_t *pd) {
|
||||
const asn_OCTET_STRING_specifics_t *specs =
|
||||
td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_ANY_specs;
|
||||
size_t consumed_myself = 0;
|
||||
int repeat;
|
||||
ANY_t *st = (ANY_t *)*sptr;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)constraints;
|
||||
|
||||
/*
|
||||
* Allocate the structure.
|
||||
*/
|
||||
if(!st) {
|
||||
st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
ASN_DEBUG("APER Decoding ANY type");
|
||||
|
||||
st->size = 0;
|
||||
do {
|
||||
ssize_t raw_len;
|
||||
ssize_t len_bytes;
|
||||
ssize_t len_bits;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
/* Get the PER length */
|
||||
raw_len = aper_get_length(pd, -1, 0, &repeat);
|
||||
if(raw_len < 0) RETURN(RC_WMORE);
|
||||
if(raw_len == 0 && st->buf) break;
|
||||
|
||||
ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
|
||||
repeat ? "repeat" : "once", td->name);
|
||||
len_bytes = raw_len;
|
||||
len_bits = len_bytes * 8;
|
||||
|
||||
p = REALLOC(st->buf, st->size + len_bytes + 1);
|
||||
if(!p) RETURN(RC_FAIL);
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
consumed_myself += len_bits;
|
||||
st->size += len_bytes;
|
||||
} while(repeat);
|
||||
st->buf[st->size] = 0; /* nul-terminate */
|
||||
|
||||
RETURN(RC_OK);
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
ANY_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, const void *sptr,
|
||||
asn_per_outp_t *po) {
|
||||
const ANY_t *st = (const ANY_t *)sptr;
|
||||
asn_enc_rval_t er = {0, 0, 0};
|
||||
const uint8_t *buf;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
|
||||
|
||||
buf = st->buf;
|
||||
size = st->size;
|
||||
do {
|
||||
int need_eom = 0;
|
||||
ssize_t may_save = uper_put_length(po, size, &need_eom);
|
||||
if(may_save < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
ret = per_put_many_bits(po, buf, may_save * 8);
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
|
||||
buf += may_save;
|
||||
size -= may_save;
|
||||
assert(!(may_save & 0x07) || !size);
|
||||
if(need_eom && uper_put_length(po, 0, 0))
|
||||
ASN__ENCODE_FAILED; /* End of Message length */
|
||||
} while(size);
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
|
||||
|
||||
@@ -22,23 +22,34 @@ extern asn_TYPE_descriptor_t asn_DEF_ANY;
|
||||
extern asn_TYPE_operation_t asn_OP_ANY;
|
||||
extern asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs;
|
||||
|
||||
asn_struct_free_f ANY_free;
|
||||
asn_struct_print_f ANY_print;
|
||||
ber_type_decoder_f ANY_decode_ber;
|
||||
der_type_encoder_f ANY_encode_der;
|
||||
#define ANY_free OCTET_STRING_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
#define ANY_print OCTET_STRING_print
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define ANY_compare OCTET_STRING_compare
|
||||
|
||||
#define ANY_constraint asn_generic_no_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define ANY_decode_ber OCTET_STRING_decode_ber
|
||||
#define ANY_encode_der OCTET_STRING_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define ANY_decode_xer OCTET_STRING_decode_xer_hex
|
||||
xer_type_encoder_f ANY_encode_xer;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f ANY_decode_uper;
|
||||
per_type_encoder_f ANY_encode_uper;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
per_type_decoder_f ANY_decode_aper;
|
||||
per_type_encoder_f ANY_encode_aper;
|
||||
|
||||
#define ANY_free OCTET_STRING_free
|
||||
#define ANY_print OCTET_STRING_print
|
||||
#define ANY_compare OCTET_STRING_compare
|
||||
#define ANY_constraint asn_generic_no_constraint
|
||||
#define ANY_decode_ber OCTET_STRING_decode_ber
|
||||
#define ANY_encode_der OCTET_STRING_encode_der
|
||||
#define ANY_decode_xer OCTET_STRING_decode_xer_hex
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
/******************************
|
||||
* Handy conversion routines. *
|
||||
@@ -46,13 +57,17 @@ per_type_encoder_f ANY_encode_aper;
|
||||
|
||||
/* Convert another ASN.1 type into the ANY. This implies DER encoding. */
|
||||
int ANY_fromType(ANY_t *, asn_TYPE_descriptor_t *td, void *struct_ptr);
|
||||
int ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr);
|
||||
ANY_t *ANY_new_fromType(asn_TYPE_descriptor_t *td, void *struct_ptr);
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
int ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr);
|
||||
ANY_t *ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr);
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
/* Convert the contents of the ANY type into the specified type. */
|
||||
int ANY_to_type(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
int ANY_to_type_aper(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#define ANY_fromBuf(s, buf, size) OCTET_STRING_fromBuf((s), (buf), (size))
|
||||
#define ANY_new_fromBuf(buf, size) OCTET_STRING_new_fromBuf( \
|
||||
|
||||
190
lib/asn1c/common/ANY_aper.c
Normal file
190
lib/asn1c/common/ANY_aper.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <ANY.h>
|
||||
#include <errno.h>
|
||||
|
||||
#undef RETURN
|
||||
#define RETURN(_code) \
|
||||
do { \
|
||||
asn_dec_rval_t tmprval; \
|
||||
tmprval.code = _code; \
|
||||
tmprval.consumed = consumed_myself; \
|
||||
return tmprval; \
|
||||
} while(0)
|
||||
|
||||
int
|
||||
ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
|
||||
uint8_t *buffer = NULL;
|
||||
ssize_t erval;
|
||||
|
||||
if(!st || !td) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!sptr) {
|
||||
if(st->buf) FREEMEM(st->buf);
|
||||
st->size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
erval = aper_encode_to_new_buffer(td, td->encoding_constraints.per_constraints, sptr, (void**)&buffer);
|
||||
|
||||
if(erval == -1) {
|
||||
if(buffer) FREEMEM(buffer);
|
||||
return -1;
|
||||
}
|
||||
assert((size_t)erval > 0);
|
||||
|
||||
if(st->buf) FREEMEM(st->buf);
|
||||
st->buf = buffer;
|
||||
st->size = erval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ANY_t *
|
||||
ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
|
||||
ANY_t tmp;
|
||||
ANY_t *st;
|
||||
|
||||
if(!td || !sptr) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
|
||||
if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
|
||||
|
||||
st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
|
||||
if(st) {
|
||||
*st = tmp;
|
||||
return st;
|
||||
} else {
|
||||
FREEMEM(tmp.buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
|
||||
asn_dec_rval_t rval;
|
||||
void *newst = 0;
|
||||
|
||||
if(!st || !td || !struct_ptr) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(st->buf == 0) {
|
||||
/* Nothing to convert, make it empty. */
|
||||
*struct_ptr = (void *)0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
|
||||
if(rval.code == RC_OK) {
|
||||
*struct_ptr = newst;
|
||||
return 0;
|
||||
} else {
|
||||
/* Remove possibly partially decoded data. */
|
||||
ASN_STRUCT_FREE(*td, newst);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr,
|
||||
asn_per_data_t *pd) {
|
||||
const asn_OCTET_STRING_specifics_t *specs =
|
||||
td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_ANY_specs;
|
||||
size_t consumed_myself = 0;
|
||||
int repeat;
|
||||
ANY_t *st = (ANY_t *)*sptr;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)constraints;
|
||||
|
||||
/*
|
||||
* Allocate the structure.
|
||||
*/
|
||||
if(!st) {
|
||||
st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
ASN_DEBUG("APER Decoding ANY type");
|
||||
|
||||
st->size = 0;
|
||||
do {
|
||||
ssize_t raw_len;
|
||||
ssize_t len_bytes;
|
||||
ssize_t len_bits;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
/* Get the PER length */
|
||||
raw_len = aper_get_length(pd, -1, 0, &repeat);
|
||||
if(raw_len < 0) RETURN(RC_WMORE);
|
||||
if(raw_len == 0 && st->buf) break;
|
||||
|
||||
ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
|
||||
repeat ? "repeat" : "once", td->name);
|
||||
len_bytes = raw_len;
|
||||
len_bits = len_bytes * 8;
|
||||
|
||||
p = REALLOC(st->buf, st->size + len_bytes + 1);
|
||||
if(!p) RETURN(RC_FAIL);
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
consumed_myself += len_bits;
|
||||
st->size += len_bytes;
|
||||
} while(repeat);
|
||||
st->buf[st->size] = 0; /* nul-terminate */
|
||||
|
||||
RETURN(RC_OK);
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
ANY_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, const void *sptr,
|
||||
asn_per_outp_t *po) {
|
||||
const ANY_t *st = (const ANY_t *)sptr;
|
||||
asn_enc_rval_t er = {0, 0, 0};
|
||||
const uint8_t *buf;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
|
||||
|
||||
buf = st->buf;
|
||||
size = st->size;
|
||||
do {
|
||||
int need_eom = 0;
|
||||
ssize_t may_save = aper_put_length(po, -1, size, &need_eom);
|
||||
if(may_save < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
ret = per_put_many_bits(po, buf, may_save * 8);
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
|
||||
buf += may_save;
|
||||
size -= may_save;
|
||||
assert(!(may_save & 0x07) || !size);
|
||||
if(need_eom && aper_put_length(po, -1, 0, 0))
|
||||
ASN__ENCODE_FAILED; /* End of Message length */
|
||||
} while(size);
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
@@ -4,61 +4,89 @@
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <BIT_STRING.h>
|
||||
#include <asn_internal.h>
|
||||
|
||||
/*
|
||||
* BIT STRING basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
|
||||
};
|
||||
asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs = {
|
||||
sizeof(BIT_STRING_t),
|
||||
offsetof(BIT_STRING_t, _asn_ctx),
|
||||
ASN_OSUBV_BIT
|
||||
sizeof(BIT_STRING_t),
|
||||
offsetof(BIT_STRING_t, _asn_ctx),
|
||||
ASN_OSUBV_BIT
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_BIT_STRING = {
|
||||
OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
|
||||
BIT_STRING_print,
|
||||
BIT_STRING_compare,
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_decode_xer_binary,
|
||||
BIT_STRING_encode_xer,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
BIT_STRING_print,
|
||||
#else
|
||||
BIT_STRING_decode_oer,
|
||||
BIT_STRING_encode_oer,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
BIT_STRING_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
|
||||
#else
|
||||
BIT_STRING_decode_uper, /* Unaligned PER decoder */
|
||||
BIT_STRING_encode_uper, /* Unaligned PER encoder */
|
||||
OCTET_STRING_decode_aper, /* Aligned PER decoder */
|
||||
OCTET_STRING_encode_aper, /* Aligned PER encoder */
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
BIT_STRING_random_fill,
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OCTET_STRING_decode_xer_binary,
|
||||
BIT_STRING_encode_xer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
BIT_STRING_decode_oer,
|
||||
BIT_STRING_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
BIT_STRING_decode_uper, /* Unaligned PER decoder */
|
||||
BIT_STRING_encode_uper, /* Unaligned PER encoder */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OCTET_STRING_decode_aper, /* Aligned PER decoder */
|
||||
OCTET_STRING_encode_aper, /* Aligned PER encoder */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
BIT_STRING_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
|
||||
"BIT STRING",
|
||||
"BIT_STRING",
|
||||
&asn_OP_BIT_STRING,
|
||||
asn_DEF_BIT_STRING_tags,
|
||||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
|
||||
asn_DEF_BIT_STRING_tags, /* Same as above */
|
||||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
|
||||
{ 0, 0, BIT_STRING_constraint },
|
||||
0, 0, /* No members */
|
||||
&asn_SPC_BIT_STRING_specs
|
||||
"BIT STRING",
|
||||
"BIT_STRING",
|
||||
&asn_OP_BIT_STRING,
|
||||
asn_DEF_BIT_STRING_tags,
|
||||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
|
||||
asn_DEF_BIT_STRING_tags, /* Same as above */
|
||||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
BIT_STRING_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
&asn_SPC_BIT_STRING_specs
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -87,136 +115,10 @@ BIT_STRING_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *_bit_pattern[16] = {
|
||||
"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
|
||||
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
|
||||
};
|
||||
|
||||
asn_enc_rval_t
|
||||
BIT_STRING_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, enum xer_encoder_flags_e flags,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_enc_rval_t er = {0, 0, 0};
|
||||
char scratch[128];
|
||||
char *p = scratch;
|
||||
char *scend = scratch + (sizeof(scratch) - 10);
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
int xcan = (flags & XER_F_CANONICAL);
|
||||
uint8_t *buf;
|
||||
uint8_t *end;
|
||||
|
||||
if(!st || !st->buf)
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
buf = st->buf;
|
||||
end = buf + st->size - 1; /* Last byte is special */
|
||||
|
||||
/*
|
||||
* Binary dump
|
||||
*/
|
||||
for(; buf < end; buf++) {
|
||||
int v = *buf;
|
||||
int nline = xcan?0:(((buf - st->buf) % 8) == 0);
|
||||
if(p >= scend || nline) {
|
||||
ASN__CALLBACK(scratch, p - scratch);
|
||||
p = scratch;
|
||||
if(nline) ASN__TEXT_INDENT(1, ilevel);
|
||||
}
|
||||
memcpy(p + 0, _bit_pattern[v >> 4], 4);
|
||||
memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if(!xcan && ((buf - st->buf) % 8) == 0)
|
||||
ASN__TEXT_INDENT(1, ilevel);
|
||||
ASN__CALLBACK(scratch, p - scratch);
|
||||
p = scratch;
|
||||
|
||||
if(buf == end) {
|
||||
int v = *buf;
|
||||
int ubits = st->bits_unused;
|
||||
int i;
|
||||
for(i = 7; i >= ubits; i--)
|
||||
*p++ = (v & (1 << i)) ? 0x31 : 0x30;
|
||||
ASN__CALLBACK(scratch, p - scratch);
|
||||
}
|
||||
|
||||
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
cb_failed:
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* BIT STRING specific contents printer.
|
||||
*/
|
||||
int
|
||||
BIT_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const char * const h2c = "0123456789ABCDEF";
|
||||
char scratch[64];
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
uint8_t *buf;
|
||||
uint8_t *end;
|
||||
char *p = scratch;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
|
||||
if(!st || !st->buf)
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
|
||||
ilevel++;
|
||||
buf = st->buf;
|
||||
end = buf + st->size;
|
||||
|
||||
/*
|
||||
* Hexadecimal dump.
|
||||
*/
|
||||
for(; buf < end; buf++) {
|
||||
if((buf - st->buf) % 16 == 0 && (st->size > 16)
|
||||
&& buf != st->buf) {
|
||||
_i_INDENT(1);
|
||||
/* Dump the string */
|
||||
if(cb(scratch, p - scratch, app_key) < 0) return -1;
|
||||
p = scratch;
|
||||
}
|
||||
*p++ = h2c[*buf >> 4];
|
||||
*p++ = h2c[*buf & 0x0F];
|
||||
*p++ = 0x20;
|
||||
}
|
||||
|
||||
if(p > scratch) {
|
||||
p--; /* Eat the tailing space */
|
||||
|
||||
if((st->size > 16)) {
|
||||
_i_INDENT(1);
|
||||
}
|
||||
|
||||
/* Dump the incomplete 16-bytes row */
|
||||
if(cb(scratch, p - scratch, app_key) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(st->bits_unused) {
|
||||
int ret = snprintf(scratch, sizeof(scratch), " (%d bit%s unused)",
|
||||
st->bits_unused, st->bits_unused == 1 ? "" : "s");
|
||||
assert(ret > 0 && ret < (ssize_t)sizeof(scratch));
|
||||
if(ret > 0 && ret < (ssize_t)sizeof(scratch)
|
||||
&& cb(scratch, ret, app_key) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-destructively remove the trailing 0-bits from the given bit string.
|
||||
*/
|
||||
static const BIT_STRING_t *
|
||||
const BIT_STRING_t *
|
||||
BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp) {
|
||||
const uint8_t *b;
|
||||
union {
|
||||
@@ -271,6 +173,7 @@ BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
|
||||
const BIT_STRING_t *b = BIT_STRING__compactify(bptr, &compact_b);
|
||||
const asn_OCTET_STRING_specifics_t *specs = td->specifics;
|
||||
|
||||
(void)specs;
|
||||
assert(specs && specs->subvariant == ASN_OSUBV_BIT);
|
||||
|
||||
if(a && b) {
|
||||
@@ -303,354 +206,3 @@ BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ASN_DISABLE_PER_SUPPORT
|
||||
|
||||
#undef RETURN
|
||||
#define RETURN(_code) \
|
||||
do { \
|
||||
asn_dec_rval_t tmprval; \
|
||||
tmprval.code = _code; \
|
||||
tmprval.consumed = consumed_myself; \
|
||||
return tmprval; \
|
||||
} while(0)
|
||||
|
||||
static asn_per_constraint_t asn_DEF_BIT_STRING_constraint_size = {
|
||||
APC_SEMI_CONSTRAINED, -1, -1, 0, 0};
|
||||
|
||||
asn_dec_rval_t
|
||||
BIT_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr,
|
||||
asn_per_data_t *pd) {
|
||||
const asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_BIT_STRING_specs;
|
||||
const asn_per_constraints_t *pc =
|
||||
constraints ? constraints : td->encoding_constraints.per_constraints;
|
||||
const asn_per_constraint_t *csiz;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
|
||||
ssize_t consumed_myself = 0;
|
||||
int repeat;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(pc) {
|
||||
csiz = &pc->size;
|
||||
} else {
|
||||
csiz = &asn_DEF_BIT_STRING_constraint_size;
|
||||
}
|
||||
|
||||
if(specs->subvariant != ASN_OSUBV_BIT) {
|
||||
ASN_DEBUG("Subvariant %d is not BIT OSUBV_BIT", specs->subvariant);
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the string.
|
||||
*/
|
||||
if(!st) {
|
||||
st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
|
||||
csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
|
||||
csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
|
||||
|
||||
if(csiz->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) RETURN(RC_WMORE);
|
||||
if(inext) {
|
||||
csiz = &asn_DEF_BIT_STRING_constraint_size;
|
||||
}
|
||||
}
|
||||
|
||||
if(csiz->effective_bits >= 0) {
|
||||
FREEMEM(st->buf);
|
||||
st->size = (csiz->upper_bound + 7) >> 3;
|
||||
st->buf = (uint8_t *)MALLOC(st->size + 1);
|
||||
if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
|
||||
}
|
||||
|
||||
/* X.691, #16.5: zero-length encoding */
|
||||
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
|
||||
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
|
||||
if(csiz->effective_bits == 0) {
|
||||
int ret;
|
||||
ASN_DEBUG("Encoding BIT STRING size %ld", csiz->upper_bound);
|
||||
ret = per_get_many_bits(pd, st->buf, 0, csiz->upper_bound);
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
consumed_myself += csiz->upper_bound;
|
||||
st->buf[st->size] = 0;
|
||||
st->bits_unused = (8 - (csiz->upper_bound & 0x7)) & 0x7;
|
||||
RETURN(RC_OK);
|
||||
}
|
||||
|
||||
st->size = 0;
|
||||
do {
|
||||
ssize_t raw_len;
|
||||
ssize_t len_bytes;
|
||||
ssize_t len_bits;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
/* Get the PER length */
|
||||
raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound,
|
||||
&repeat);
|
||||
if(raw_len < 0) RETURN(RC_WMORE);
|
||||
if(raw_len == 0 && st->buf) break;
|
||||
|
||||
ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
|
||||
(long)csiz->effective_bits, (long)raw_len,
|
||||
repeat ? "repeat" : "once", td->name);
|
||||
len_bits = raw_len;
|
||||
len_bytes = (len_bits + 7) >> 3;
|
||||
if(len_bits & 0x7) st->bits_unused = 8 - (len_bits & 0x7);
|
||||
/* len_bits be multiple of 16K if repeat is set */
|
||||
p = REALLOC(st->buf, st->size + len_bytes + 1);
|
||||
if(!p) RETURN(RC_FAIL);
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
st->size += len_bytes;
|
||||
} while(repeat);
|
||||
st->buf[st->size] = 0; /* nul-terminate */
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
BIT_STRING_encode_uper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const asn_OCTET_STRING_specifics_t *specs =
|
||||
td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_BIT_STRING_specs;
|
||||
const asn_per_constraints_t *pc =
|
||||
constraints ? constraints : td->encoding_constraints.per_constraints;
|
||||
const asn_per_constraint_t *csiz;
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
BIT_STRING_t compact_bstr; /* Do not modify this directly! */
|
||||
asn_enc_rval_t er = { 0, 0, 0 };
|
||||
int inext = 0; /* Lies not within extension root */
|
||||
size_t size_in_bits;
|
||||
const uint8_t *buf;
|
||||
int ret;
|
||||
int ct_extensible;
|
||||
|
||||
if(!st || (!st->buf && st->size))
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
if(specs->subvariant == ASN_OSUBV_BIT) {
|
||||
if((st->size == 0 && st->bits_unused) || (st->bits_unused & ~7))
|
||||
ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
if(pc) {
|
||||
csiz = &pc->size;
|
||||
} else {
|
||||
csiz = &asn_DEF_BIT_STRING_constraint_size;
|
||||
}
|
||||
ct_extensible = csiz->flags & APC_EXTENSIBLE;
|
||||
|
||||
/* Figure out the size without the trailing bits */
|
||||
st = BIT_STRING__compactify(st, &compact_bstr);
|
||||
size_in_bits = 8 * st->size - st->bits_unused;
|
||||
|
||||
ASN_DEBUG(
|
||||
"Encoding %s into %" ASN_PRI_SIZE " bits"
|
||||
" (%ld..%ld, effective %d)%s",
|
||||
td->name, size_in_bits, csiz->lower_bound, csiz->upper_bound,
|
||||
csiz->effective_bits, ct_extensible ? " EXT" : "");
|
||||
|
||||
/* Figure out whether size lies within PER visible constraint */
|
||||
|
||||
if(csiz->effective_bits >= 0) {
|
||||
if((ssize_t)size_in_bits > csiz->upper_bound) {
|
||||
if(ct_extensible) {
|
||||
csiz = &asn_DEF_BIT_STRING_constraint_size;
|
||||
inext = 1;
|
||||
} else {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
inext = 0;
|
||||
}
|
||||
|
||||
if(ct_extensible) {
|
||||
/* Declare whether length is [not] within extension root */
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
if(csiz->effective_bits >= 0 && !inext) {
|
||||
int add_trailer = (ssize_t)size_in_bits < csiz->lower_bound;
|
||||
ASN_DEBUG(
|
||||
"Encoding %" ASN_PRI_SIZE " bytes (%ld), length (in %d bits) trailer %d; actual "
|
||||
"value %" ASN_PRI_SSIZE "",
|
||||
st->size, size_in_bits - csiz->lower_bound, csiz->effective_bits,
|
||||
add_trailer,
|
||||
add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound);
|
||||
ret = per_put_few_bits(
|
||||
po, add_trailer ? 0 : (ssize_t)size_in_bits - csiz->lower_bound,
|
||||
csiz->effective_bits);
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
ret = per_put_many_bits(po, st->buf, size_in_bits);
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
if(add_trailer) {
|
||||
static const uint8_t zeros[16];
|
||||
size_t trailing_zero_bits = csiz->lower_bound - size_in_bits;
|
||||
while(trailing_zero_bits > 0) {
|
||||
if(trailing_zero_bits > 8 * sizeof(zeros)) {
|
||||
ret = per_put_many_bits(po, zeros, 8 * sizeof(zeros));
|
||||
trailing_zero_bits -= 8 * sizeof(zeros);
|
||||
} else {
|
||||
ret = per_put_many_bits(po, zeros, trailing_zero_bits);
|
||||
trailing_zero_bits = 0;
|
||||
}
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
}
|
||||
}
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size);
|
||||
|
||||
buf = st->buf;
|
||||
do {
|
||||
int need_eom = 0;
|
||||
ssize_t maySave = uper_put_length(po, size_in_bits, &need_eom);
|
||||
if(maySave < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "", maySave, size_in_bits);
|
||||
|
||||
ret = per_put_many_bits(po, buf, maySave);
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
|
||||
buf += maySave >> 3;
|
||||
size_in_bits -= maySave;
|
||||
assert(!(maySave & 0x07) || !size_in_bits);
|
||||
if(need_eom && uper_put_length(po, 0, 0))
|
||||
ASN__ENCODE_FAILED; /* End of Message length */
|
||||
} while(size_in_bits);
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
|
||||
asn_random_fill_result_t
|
||||
BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
const asn_OCTET_STRING_specifics_t *specs =
|
||||
td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_BIT_STRING_specs;
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
static unsigned lengths[] = {0, 1, 2, 3, 4, 8,
|
||||
126, 127, 128, 16383, 16384, 16385,
|
||||
65534, 65535, 65536, 65537};
|
||||
uint8_t *buf;
|
||||
uint8_t *bend;
|
||||
uint8_t *b;
|
||||
size_t rnd_bits, rnd_len;
|
||||
BIT_STRING_t *st;
|
||||
|
||||
if(max_length == 0) return result_skipped;
|
||||
|
||||
switch(specs->subvariant) {
|
||||
case ASN_OSUBV_ANY:
|
||||
return result_failed;
|
||||
case ASN_OSUBV_BIT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Figure out how far we should go */
|
||||
rnd_bits = lengths[asn_random_between(
|
||||
0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
|
||||
if(!constraints || !constraints->per_constraints)
|
||||
constraints = &td->encoding_constraints;
|
||||
if(constraints->per_constraints) {
|
||||
const asn_per_constraint_t *pc = &constraints->per_constraints->size;
|
||||
if(pc->flags & APC_CONSTRAINED) {
|
||||
long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
|
||||
? pc->upper_bound
|
||||
: (ssize_t)max_length;
|
||||
if(max_length < (size_t)pc->lower_bound) {
|
||||
return result_skipped;
|
||||
}
|
||||
if(pc->flags & APC_EXTENSIBLE) {
|
||||
switch(asn_random_between(0, 5)) {
|
||||
case 0:
|
||||
if(pc->lower_bound > 0) {
|
||||
rnd_bits = pc->lower_bound - 1;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case 1:
|
||||
rnd_bits = pc->upper_bound + 1;
|
||||
break;
|
||||
case 2:
|
||||
/* Keep rnd_bits from the table */
|
||||
if(rnd_bits < max_length) {
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
rnd_bits = asn_random_between(pc->lower_bound,
|
||||
suggested_upper_bound);
|
||||
}
|
||||
} else {
|
||||
rnd_bits =
|
||||
asn_random_between(pc->lower_bound, suggested_upper_bound);
|
||||
}
|
||||
} else {
|
||||
rnd_bits = asn_random_between(0, max_length - 1);
|
||||
}
|
||||
} else if(rnd_bits >= max_length) {
|
||||
rnd_bits = asn_random_between(0, max_length - 1);
|
||||
}
|
||||
|
||||
rnd_len = (rnd_bits + 7) / 8;
|
||||
buf = CALLOC(1, rnd_len + 1);
|
||||
if(!buf) return result_failed;
|
||||
|
||||
bend = &buf[rnd_len];
|
||||
|
||||
for(b = buf; b < bend; b++) {
|
||||
*(uint8_t *)b = asn_random_between(0, 255);
|
||||
}
|
||||
*b = 0; /* Zero-terminate just in case. */
|
||||
|
||||
if(*sptr) {
|
||||
st = *sptr;
|
||||
FREEMEM(st->buf);
|
||||
} else {
|
||||
st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) {
|
||||
FREEMEM(buf);
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
st->buf = buf;
|
||||
st->size = rnd_len;
|
||||
st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7;
|
||||
if(st->bits_unused) {
|
||||
assert(st->size > 0);
|
||||
st->buf[st->size-1] &= 0xff << st->bits_unused;
|
||||
}
|
||||
|
||||
result_ok.length = st->size;
|
||||
return result_ok;
|
||||
}
|
||||
|
||||
@@ -24,22 +24,45 @@ extern asn_TYPE_descriptor_t asn_DEF_BIT_STRING;
|
||||
extern asn_TYPE_operation_t asn_OP_BIT_STRING;
|
||||
extern asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs;
|
||||
|
||||
asn_struct_print_f BIT_STRING_print; /* Human-readable output */
|
||||
#define BIT_STRING_free OCTET_STRING_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f BIT_STRING_print; /* Human-readable output */
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
asn_struct_compare_f BIT_STRING_compare;
|
||||
|
||||
asn_constr_check_f BIT_STRING_constraint;
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber
|
||||
#define BIT_STRING_encode_der OCTET_STRING_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define BIT_STRING_decode_xer OCTET_STRING_decode_xer_binary
|
||||
xer_type_encoder_f BIT_STRING_encode_xer;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
oer_type_decoder_f BIT_STRING_decode_oer;
|
||||
oer_type_encoder_f BIT_STRING_encode_oer;
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f BIT_STRING_decode_uper;
|
||||
per_type_encoder_f BIT_STRING_encode_uper;
|
||||
asn_random_fill_f BIT_STRING_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#define BIT_STRING_decode_aper OCTET_STRING_decode_aper
|
||||
#define BIT_STRING_encode_aper OCTET_STRING_encode_aper
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#define BIT_STRING_free OCTET_STRING_free
|
||||
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber
|
||||
#define BIT_STRING_encode_der OCTET_STRING_encode_der
|
||||
#define BIT_STRING_decode_xer OCTET_STRING_decode_xer_binary
|
||||
#define BIT_STRING_decode_aper OCTET_STRING_decode_aper
|
||||
#define BIT_STRING_encode_aper OCTET_STRING_encode_aper
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f BIT_STRING_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
const BIT_STRING_t *BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
69
lib/asn1c/common/BIT_STRING_print.c
Normal file
69
lib/asn1c/common/BIT_STRING_print.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <BIT_STRING.h>
|
||||
|
||||
/*
|
||||
* BIT STRING specific contents printer.
|
||||
*/
|
||||
int
|
||||
BIT_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const char * const h2c = "0123456789ABCDEF";
|
||||
char scratch[64];
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
uint8_t *buf;
|
||||
uint8_t *end;
|
||||
char *p = scratch;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
|
||||
if(!st || !st->buf)
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
|
||||
ilevel++;
|
||||
buf = st->buf;
|
||||
end = buf + st->size;
|
||||
|
||||
/*
|
||||
* Hexadecimal dump.
|
||||
*/
|
||||
for(; buf < end; buf++) {
|
||||
if((buf - st->buf) % 16 == 0 && (st->size > 16)
|
||||
&& buf != st->buf) {
|
||||
_i_INDENT(1);
|
||||
/* Dump the string */
|
||||
if(cb(scratch, p - scratch, app_key) < 0) return -1;
|
||||
p = scratch;
|
||||
}
|
||||
*p++ = h2c[*buf >> 4];
|
||||
*p++ = h2c[*buf & 0x0F];
|
||||
*p++ = 0x20;
|
||||
}
|
||||
|
||||
if(p > scratch) {
|
||||
p--; /* Eat the tailing space */
|
||||
|
||||
if((st->size > 16)) {
|
||||
_i_INDENT(1);
|
||||
}
|
||||
|
||||
/* Dump the incomplete 16-bytes row */
|
||||
if(cb(scratch, p - scratch, app_key) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(st->bits_unused) {
|
||||
int ret = snprintf(scratch, sizeof(scratch), " (%d bit%s unused)",
|
||||
st->bits_unused, st->bits_unused == 1 ? "" : "s");
|
||||
assert(ret > 0 && ret < (ssize_t)sizeof(scratch));
|
||||
if(ret > 0 && ret < (ssize_t)sizeof(scratch)
|
||||
&& cb(scratch, ret, app_key) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
124
lib/asn1c/common/BIT_STRING_rfill.c
Normal file
124
lib/asn1c/common/BIT_STRING_rfill.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <BIT_STRING.h>
|
||||
|
||||
asn_random_fill_result_t
|
||||
BIT_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
const asn_OCTET_STRING_specifics_t *specs =
|
||||
td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_BIT_STRING_specs;
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
static unsigned lengths[] = {0, 1, 2, 3, 4, 8,
|
||||
126, 127, 128, 16383, 16384, 16385,
|
||||
65534, 65535, 65536, 65537};
|
||||
uint8_t *buf;
|
||||
uint8_t *bend;
|
||||
uint8_t *b;
|
||||
size_t rnd_bits, rnd_len;
|
||||
BIT_STRING_t *st;
|
||||
|
||||
if(max_length == 0) return result_skipped;
|
||||
|
||||
switch(specs->subvariant) {
|
||||
case ASN_OSUBV_ANY:
|
||||
return result_failed;
|
||||
case ASN_OSUBV_BIT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Figure out how far we should go */
|
||||
rnd_bits = lengths[asn_random_between(
|
||||
0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
if(!constraints || !constraints->per_constraints)
|
||||
constraints = &td->encoding_constraints;
|
||||
if(constraints->per_constraints) {
|
||||
const asn_per_constraint_t *pc = &constraints->per_constraints->size;
|
||||
if(pc->flags & APC_CONSTRAINED) {
|
||||
long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
|
||||
? pc->upper_bound
|
||||
: (ssize_t)max_length;
|
||||
if(max_length < (size_t)pc->lower_bound) {
|
||||
return result_skipped;
|
||||
}
|
||||
if(pc->flags & APC_EXTENSIBLE) {
|
||||
switch(asn_random_between(0, 5)) {
|
||||
case 0:
|
||||
if(pc->lower_bound > 0) {
|
||||
rnd_bits = pc->lower_bound - 1;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case 1:
|
||||
rnd_bits = pc->upper_bound + 1;
|
||||
break;
|
||||
case 2:
|
||||
/* Keep rnd_bits from the table */
|
||||
if(rnd_bits < max_length) {
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
rnd_bits = asn_random_between(pc->lower_bound,
|
||||
suggested_upper_bound);
|
||||
}
|
||||
} else {
|
||||
rnd_bits =
|
||||
asn_random_between(pc->lower_bound, suggested_upper_bound);
|
||||
}
|
||||
} else {
|
||||
rnd_bits = asn_random_between(0, max_length - 1);
|
||||
}
|
||||
} else {
|
||||
#else
|
||||
if(!constraints) constraints = &td->encoding_constraints;
|
||||
{
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
if(rnd_bits >= max_length) {
|
||||
rnd_bits = asn_random_between(0, max_length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
rnd_len = (rnd_bits + 7) / 8;
|
||||
buf = CALLOC(1, rnd_len + 1);
|
||||
if(!buf) return result_failed;
|
||||
|
||||
bend = &buf[rnd_len];
|
||||
|
||||
for(b = buf; b < bend; b++) {
|
||||
*(uint8_t *)b = asn_random_between(0, 255);
|
||||
}
|
||||
*b = 0; /* Zero-terminate just in case. */
|
||||
|
||||
if(*sptr) {
|
||||
st = *sptr;
|
||||
FREEMEM(st->buf);
|
||||
} else {
|
||||
st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) {
|
||||
FREEMEM(buf);
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
st->buf = buf;
|
||||
st->size = rnd_len;
|
||||
st->bits_unused = (8 - (rnd_bits & 0x7)) & 0x7;
|
||||
if(st->bits_unused) {
|
||||
assert(st->size > 0);
|
||||
st->buf[st->size-1] &= 0xff << st->bits_unused;
|
||||
}
|
||||
|
||||
result_ok.length = st->size;
|
||||
return result_ok;
|
||||
}
|
||||
@@ -9,50 +9,78 @@
|
||||
* GraphicString basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_GraphicString_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (25 << 2)), /* [UNIVERSAL 25] IMPLICIT ...*/
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (25 << 2)), /* [UNIVERSAL 25] IMPLICIT ...*/
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_GraphicString = {
|
||||
OCTET_STRING_free,
|
||||
OCTET_STRING_print, /* non-ascii string */
|
||||
OCTET_STRING_compare,
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
OCTET_STRING_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
OCTET_STRING_print, /* non-ascii string */
|
||||
#else
|
||||
OCTET_STRING_decode_oer,
|
||||
OCTET_STRING_encode_oer,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OCTET_STRING_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
#else
|
||||
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_uper,
|
||||
OCTET_STRING_decode_aper, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_aper,
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
OCTET_STRING_random_fill,
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
OCTET_STRING_decode_oer,
|
||||
OCTET_STRING_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OCTET_STRING_decode_aper, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
OCTET_STRING_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_GraphicString = {
|
||||
"GraphicString",
|
||||
"GraphicString",
|
||||
&asn_OP_GraphicString,
|
||||
asn_DEF_GraphicString_tags,
|
||||
sizeof(asn_DEF_GraphicString_tags)
|
||||
/ sizeof(asn_DEF_GraphicString_tags[0]) - 1,
|
||||
asn_DEF_GraphicString_tags,
|
||||
sizeof(asn_DEF_GraphicString_tags)
|
||||
/ sizeof(asn_DEF_GraphicString_tags[0]),
|
||||
{ 0, 0, asn_generic_unknown_constraint },
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
"GraphicString",
|
||||
"GraphicString",
|
||||
&asn_OP_GraphicString,
|
||||
asn_DEF_GraphicString_tags,
|
||||
sizeof(asn_DEF_GraphicString_tags)
|
||||
/ sizeof(asn_DEF_GraphicString_tags[0]) - 1,
|
||||
asn_DEF_GraphicString_tags,
|
||||
sizeof(asn_DEF_GraphicString_tags)
|
||||
/ sizeof(asn_DEF_GraphicString_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_generic_unknown_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
||||
@@ -16,18 +16,34 @@ typedef OCTET_STRING_t GraphicString_t; /* Implemented via OCTET STRING */
|
||||
extern asn_TYPE_descriptor_t asn_DEF_GraphicString;
|
||||
extern asn_TYPE_operation_t asn_OP_GraphicString;
|
||||
|
||||
#define GraphicString_free OCTET_STRING_free
|
||||
#define GraphicString_print OCTET_STRING_print
|
||||
#define GraphicString_compare OCTET_STRING_compare
|
||||
#define GraphicString_constraint asn_generic_unknown_constraint
|
||||
#define GraphicString_decode_ber OCTET_STRING_decode_ber
|
||||
#define GraphicString_encode_der OCTET_STRING_encode_der
|
||||
#define GraphicString_decode_xer OCTET_STRING_decode_xer_hex
|
||||
#define GraphicString_encode_xer OCTET_STRING_encode_xer
|
||||
#define GraphicString_decode_uper OCTET_STRING_decode_uper
|
||||
#define GraphicString_encode_uper OCTET_STRING_encode_uper
|
||||
#define GraphicString_decode_aper OCTET_STRING_decode_aper
|
||||
#define GraphicString_encode_aper OCTET_STRING_encode_aper
|
||||
#define GraphicString_free OCTET_STRING_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
#define GraphicString_print OCTET_STRING_print
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define GraphicString_compare OCTET_STRING_compare
|
||||
|
||||
#define GraphicString_constraint asn_generic_unknown_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define GraphicString_decode_ber OCTET_STRING_decode_ber
|
||||
#define GraphicString_encode_der OCTET_STRING_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define GraphicString_decode_xer OCTET_STRING_decode_xer_hex
|
||||
#define GraphicString_encode_xer OCTET_STRING_encode_xer
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
#define GraphicString_decode_uper OCTET_STRING_decode_uper
|
||||
#define GraphicString_encode_uper OCTET_STRING_encode_uper
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#define GraphicString_decode_aper OCTET_STRING_decode_aper
|
||||
#define GraphicString_encode_aper OCTET_STRING_encode_aper
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,21 +35,48 @@ typedef struct asn_INTEGER_specifics_s {
|
||||
int field_unsigned; /* Signed=0, unsigned=1 */
|
||||
} asn_INTEGER_specifics_t;
|
||||
|
||||
#define INTEGER_free ASN__PRIMITIVE_TYPE_free
|
||||
#define INTEGER_decode_ber ber_decode_primitive
|
||||
#define INTEGER_constraint asn_generic_no_constraint
|
||||
ssize_t INTEGER__dump(const asn_TYPE_descriptor_t *td,
|
||||
const INTEGER_t *st,
|
||||
asn_app_consume_bytes_f *cb,
|
||||
void *app_key, int plainOrXER);
|
||||
|
||||
#define INTEGER_free ASN__PRIMITIVE_TYPE_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f INTEGER_print;
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
asn_struct_compare_f INTEGER_compare;
|
||||
|
||||
#define INTEGER_constraint asn_generic_no_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define INTEGER_decode_ber ber_decode_primitive
|
||||
der_type_encoder_f INTEGER_encode_der;
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
xer_type_decoder_f INTEGER_decode_xer;
|
||||
xer_type_encoder_f INTEGER_encode_xer;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
oer_type_decoder_f INTEGER_decode_oer;
|
||||
oer_type_encoder_f INTEGER_encode_oer;
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f INTEGER_decode_uper;
|
||||
per_type_encoder_f INTEGER_encode_uper;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
per_type_decoder_f INTEGER_decode_aper;
|
||||
per_type_encoder_f INTEGER_encode_aper;
|
||||
asn_random_fill_f INTEGER_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f INTEGER_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
/***********************************
|
||||
* Some handy conversion routines. *
|
||||
|
||||
304
lib/asn1c/common/INTEGER_aper.c
Normal file
304
lib/asn1c/common/INTEGER_aper.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <INTEGER.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
INTEGER_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
INTEGER_t *st = (INTEGER_t *)*sptr;
|
||||
const asn_per_constraint_t *ct;
|
||||
int repeat;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(!st) {
|
||||
st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
|
||||
if(!st) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(!constraints) constraints = td->encoding_constraints.per_constraints;
|
||||
ct = constraints ? &constraints->value : 0;
|
||||
|
||||
if(ct && ct->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) ASN__DECODE_STARVED;
|
||||
if(inext) ct = 0;
|
||||
}
|
||||
|
||||
FREEMEM(st->buf);
|
||||
st->buf = 0;
|
||||
st->size = 0;
|
||||
if(ct) {
|
||||
if(ct->flags & APC_SEMI_CONSTRAINED) {
|
||||
st->buf = (uint8_t *)CALLOC(1, 2);
|
||||
if(!st->buf) ASN__DECODE_FAILED;
|
||||
st->size = 1;
|
||||
} else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
|
||||
size_t size = (ct->range_bits + 7) >> 3;
|
||||
st->buf = (uint8_t *)MALLOC(1 + size + 1);
|
||||
if(!st->buf) ASN__DECODE_FAILED;
|
||||
st->size = size;
|
||||
}
|
||||
}
|
||||
|
||||
/* X.691, #12.2.2 */
|
||||
if(ct && ct->flags != APC_UNCONSTRAINED) {
|
||||
/* #10.5.6 */
|
||||
ASN_DEBUG("Integer with range %d bits", ct->range_bits);
|
||||
if(ct->range_bits >= 0) {
|
||||
if (ct->range_bits > 16) {
|
||||
int max_range_bytes = (ct->range_bits >> 3) +
|
||||
(((ct->range_bits % 8) > 0) ? 1 : 0);
|
||||
int length = 0, i;
|
||||
long value = 0;
|
||||
|
||||
for (i = 1; ; i++) {
|
||||
int upper = 1 << i;
|
||||
if (upper >= max_range_bytes)
|
||||
break;
|
||||
}
|
||||
ASN_DEBUG("Can encode %d (%d bytes) in %d bits", ct->range_bits,
|
||||
max_range_bytes, i);
|
||||
|
||||
if ((length = per_get_few_bits(pd, i)) < 0)
|
||||
ASN__DECODE_FAILED;
|
||||
|
||||
/* X.691 #12.2.6 length determinant + lb (1) */
|
||||
length += 1;
|
||||
ASN_DEBUG("Got length %d", length);
|
||||
if (aper_get_align(pd) != 0)
|
||||
ASN__DECODE_FAILED;
|
||||
while (length--) {
|
||||
int buf = per_get_few_bits(pd, 8);
|
||||
if (buf < 0)
|
||||
ASN__DECODE_FAILED;
|
||||
value += (((long)buf) << (8 * length));
|
||||
}
|
||||
|
||||
value += ct->lower_bound;
|
||||
if((specs && specs->field_unsigned)
|
||||
? asn_uint642INTEGER(st, (unsigned long)value)
|
||||
: asn_int642INTEGER(st, value))
|
||||
ASN__DECODE_FAILED;
|
||||
ASN_DEBUG("Got value %ld + low %ld",
|
||||
value, ct->lower_bound);
|
||||
} else {
|
||||
long value = 0;
|
||||
if (ct->range_bits < 8) {
|
||||
value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
} else if (ct->range_bits == 8) {
|
||||
if (aper_get_align(pd) < 0)
|
||||
ASN__DECODE_FAILED;
|
||||
value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
} else {
|
||||
/* Align */
|
||||
if (aper_get_align(pd) < 0)
|
||||
ASN__DECODE_FAILED;
|
||||
value = per_get_few_bits(pd, 16);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
}
|
||||
value += ct->lower_bound;
|
||||
if((specs && specs->field_unsigned)
|
||||
? asn_ulong2INTEGER(st, value)
|
||||
: asn_long2INTEGER(st, value))
|
||||
ASN__DECODE_FAILED;
|
||||
ASN_DEBUG("Got value %ld + low %ld",
|
||||
value, ct->lower_bound);
|
||||
}
|
||||
return rval;
|
||||
} else {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
} else {
|
||||
ASN_DEBUG("Decoding unconstrained integer %s", td->name);
|
||||
}
|
||||
|
||||
/* X.691, #12.2.3, #12.2.4 */
|
||||
do {
|
||||
ssize_t len;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
/* Get the PER length */
|
||||
len = aper_get_length(pd, -1, -1, &repeat);
|
||||
if(len < 0) ASN__DECODE_STARVED;
|
||||
|
||||
p = REALLOC(st->buf, st->size + len + 1);
|
||||
if(!p) ASN__DECODE_FAILED;
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
|
||||
if(ret < 0) ASN__DECODE_STARVED;
|
||||
st->size += len;
|
||||
} while(repeat);
|
||||
st->buf[st->size] = 0; /* JIC */
|
||||
|
||||
/* #12.2.3 */
|
||||
if(ct && ct->lower_bound) {
|
||||
/*
|
||||
* TODO: replace by in-place arithmetics.
|
||||
*/
|
||||
long value;
|
||||
if(asn_INTEGER2long(st, &value))
|
||||
ASN__DECODE_FAILED;
|
||||
if(asn_long2INTEGER(st, value + ct->lower_bound))
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
INTEGER_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
const INTEGER_t *st = (const INTEGER_t *)sptr;
|
||||
const uint8_t *buf;
|
||||
const uint8_t *end;
|
||||
const asn_per_constraint_t *ct;
|
||||
long value = 0;
|
||||
|
||||
if(!st || st->size == 0) ASN__ENCODE_FAILED;
|
||||
|
||||
if(!constraints) constraints = td->encoding_constraints.per_constraints;
|
||||
ct = constraints ? &constraints->value : 0;
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
if(ct) {
|
||||
int inext = 0;
|
||||
if(specs && specs->field_unsigned) {
|
||||
unsigned long uval;
|
||||
if(asn_INTEGER2ulong(st, &uval))
|
||||
ASN__ENCODE_FAILED;
|
||||
/* Check proper range */
|
||||
if(ct->flags & APC_SEMI_CONSTRAINED) {
|
||||
if(uval < (unsigned long)ct->lower_bound)
|
||||
inext = 1;
|
||||
} else if(ct->range_bits >= 0) {
|
||||
if(uval < (unsigned long)ct->lower_bound
|
||||
|| uval > (unsigned long)ct->upper_bound)
|
||||
inext = 1;
|
||||
}
|
||||
ASN_DEBUG("Value %lu (%02x/%lu) lb %ld ub %ld %s",
|
||||
uval, st->buf[0], st->size,
|
||||
ct->lower_bound, ct->upper_bound,
|
||||
inext ? "ext" : "fix");
|
||||
value = uval;
|
||||
} else {
|
||||
if(asn_INTEGER2long(st, &value)) ASN__ENCODE_FAILED;
|
||||
/* Check proper range */
|
||||
if(ct->flags & APC_SEMI_CONSTRAINED) {
|
||||
if(value < ct->lower_bound)
|
||||
inext = 1;
|
||||
} else if(ct->range_bits >= 0) {
|
||||
if(value < ct->lower_bound
|
||||
|| value > ct->upper_bound)
|
||||
inext = 1;
|
||||
}
|
||||
ASN_DEBUG("Value %lu (%02x/%lu) lb %ld ub %ld %s",
|
||||
value, st->buf[0], st->size,
|
||||
ct->lower_bound, ct->upper_bound,
|
||||
inext ? "ext" : "fix");
|
||||
}
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
if(inext) ct = 0;
|
||||
} else if(inext) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* X.691, #12.2.2 */
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
unsigned long v;
|
||||
|
||||
/* #10.5.6 */
|
||||
ASN_DEBUG("Encoding integer %ld (%lu) with range %d bits",
|
||||
value, value - ct->lower_bound, ct->range_bits);
|
||||
|
||||
v = value - ct->lower_bound;
|
||||
|
||||
/* #12 <= 8 -> alignment ? */
|
||||
int range = ct->upper_bound - ct->lower_bound + 1;
|
||||
if (ct->range_bits < 8 || (ct->range_bits == 8 && range < 256)) {
|
||||
if(per_put_few_bits(po, 0x00 | v, ct->range_bits))
|
||||
ASN__ENCODE_FAILED;
|
||||
} else if (ct->range_bits == 8) {
|
||||
if(aper_put_align(po) < 0)
|
||||
ASN__ENCODE_FAILED;
|
||||
if(per_put_few_bits(po, 0x00 | v, ct->range_bits))
|
||||
ASN__ENCODE_FAILED;
|
||||
} else if (ct->range_bits <= 16) {
|
||||
/* Consume the bytes to align on octet */
|
||||
if(aper_put_align(po) < 0)
|
||||
ASN__ENCODE_FAILED;
|
||||
if(per_put_few_bits(po, 0x0000 | v, 16))
|
||||
ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
/* TODO: extend to >64 bits */
|
||||
int64_t v64 = v;
|
||||
int i, j;
|
||||
int max_range_bytes = (ct->range_bits >> 3) +
|
||||
(((ct->range_bits % 8) > 0) ? 1 : 0);
|
||||
|
||||
for (i = 1; ; i++) {
|
||||
int upper = 1 << i;
|
||||
if (upper >= max_range_bytes)
|
||||
break;
|
||||
}
|
||||
|
||||
for (j = sizeof(int64_t) -1; j != 0; j--) {
|
||||
int64_t val;
|
||||
val = v64 >> (j * 8);
|
||||
if (val != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Putting length in the minimum number of bits ex: 5 = 3bits */
|
||||
if (per_put_few_bits(po, j, i))
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
/* Consume the bits to align on octet */
|
||||
if (aper_put_align(po) < 0)
|
||||
ASN__ENCODE_FAILED;
|
||||
/* Put the value */
|
||||
for (i = 0; i <= j; i++) {
|
||||
if(per_put_few_bits(po, (v64 >> (8 * (j - i))) & 0xff, 8))
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
}
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
if(ct && ct->lower_bound) {
|
||||
ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound);
|
||||
/* TODO: adjust lower bound */
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
for(buf = st->buf, end = st->buf + st->size; buf < end;) {
|
||||
int need_eom = 0;
|
||||
ssize_t mayEncode = aper_put_length(po, -1, end - buf, &need_eom);
|
||||
if(mayEncode < 0)
|
||||
ASN__ENCODE_FAILED;
|
||||
if(per_put_many_bits(po, buf, 8 * mayEncode))
|
||||
ASN__ENCODE_FAILED;
|
||||
buf += mayEncode;
|
||||
if(need_eom && aper_put_length(po, -1, 0, 0)) ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
26
lib/asn1c/common/INTEGER_print.c
Normal file
26
lib/asn1c/common/INTEGER_print.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <INTEGER.h>
|
||||
|
||||
/*
|
||||
* INTEGER specific human-readable output.
|
||||
*/
|
||||
int
|
||||
INTEGER_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const INTEGER_t *st = (const INTEGER_t *)sptr;
|
||||
ssize_t ret;
|
||||
|
||||
(void)ilevel;
|
||||
|
||||
if(!st || !st->buf)
|
||||
ret = cb("<absent>", 8, app_key);
|
||||
else
|
||||
ret = INTEGER__dump(td, st, cb, app_key, 0);
|
||||
|
||||
return (ret < 0) ? -1 : 0;
|
||||
}
|
||||
92
lib/asn1c/common/INTEGER_rfill.c
Normal file
92
lib/asn1c/common/INTEGER_rfill.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <INTEGER.h>
|
||||
|
||||
asn_random_fill_result_t
|
||||
INTEGER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
INTEGER_t *st = *sptr;
|
||||
const asn_INTEGER_enum_map_t *emap;
|
||||
size_t emap_len;
|
||||
intmax_t value;
|
||||
int find_inside_map;
|
||||
|
||||
if(max_length == 0) return result_skipped;
|
||||
|
||||
if(st == NULL) {
|
||||
st = (INTEGER_t *)CALLOC(1, sizeof(*st));
|
||||
if(st == NULL) {
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if(specs) {
|
||||
emap = specs->value2enum;
|
||||
emap_len = specs->map_count;
|
||||
if(specs->strict_enumeration) {
|
||||
find_inside_map = emap_len > 0;
|
||||
} else {
|
||||
find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
|
||||
}
|
||||
} else {
|
||||
emap = 0;
|
||||
emap_len = 0;
|
||||
find_inside_map = 0;
|
||||
}
|
||||
|
||||
if(find_inside_map) {
|
||||
assert(emap_len > 0);
|
||||
value = emap[asn_random_between(0, emap_len - 1)].nat_value;
|
||||
} else {
|
||||
static const long variants[] = {
|
||||
-65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
|
||||
-16383, -257, -256, -255, -254, -129, -128, -127,
|
||||
-126, -1, 0, 1, 126, 127, 128, 129,
|
||||
254, 255, 256, 257, 16383, 16384, 16385, 32767,
|
||||
32768, 32769, 65534, 65535, 65536, 65537};
|
||||
if(specs && specs->field_unsigned) {
|
||||
assert(variants[18] == 0);
|
||||
value = variants[asn_random_between(
|
||||
18, sizeof(variants) / sizeof(variants[0]) - 1)];
|
||||
} else {
|
||||
value = variants[asn_random_between(
|
||||
0, sizeof(variants) / sizeof(variants[0]) - 1)];
|
||||
}
|
||||
|
||||
if(!constraints) constraints = &td->encoding_constraints;
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
const asn_per_constraints_t *ct;
|
||||
|
||||
ct = constraints ? constraints->per_constraints : 0;
|
||||
if(ct && (ct->value.flags & APC_CONSTRAINED)) {
|
||||
if(value < ct->value.lower_bound || value > ct->value.upper_bound) {
|
||||
value = asn_random_between(ct->value.lower_bound,
|
||||
ct->value.upper_bound);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
}
|
||||
|
||||
if(asn_imax2INTEGER(st, value)) {
|
||||
if(st == *sptr) {
|
||||
ASN_STRUCT_RESET(*td, st);
|
||||
} else {
|
||||
ASN_STRUCT_FREE(*td, st);
|
||||
}
|
||||
return result_failed;
|
||||
} else {
|
||||
*sptr = st;
|
||||
result_ok.length = st->size;
|
||||
return result_ok;
|
||||
}
|
||||
}
|
||||
@@ -3,55 +3,83 @@
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <asn_codecs_prim.h>
|
||||
#include <NULL.h>
|
||||
|
||||
/*
|
||||
* NULL basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_NULL_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_NULL = {
|
||||
NULL_free,
|
||||
NULL_print,
|
||||
NULL_compare,
|
||||
NULL_decode_ber,
|
||||
NULL_encode_der, /* Special handling of DER encoding */
|
||||
NULL_decode_xer,
|
||||
NULL_encode_xer,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
NULL_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
NULL_print,
|
||||
#else
|
||||
NULL_decode_oer,
|
||||
NULL_encode_oer,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
NULL_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
NULL_decode_ber,
|
||||
NULL_encode_der, /* Special handling of DER encoding */
|
||||
#else
|
||||
NULL_decode_uper, /* Unaligned PER decoder */
|
||||
NULL_encode_uper, /* Unaligned PER encoder */
|
||||
NULL_decode_aper, /* Aligned PER decoder */
|
||||
NULL_encode_aper, /* Aligned PER encoder */
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
NULL_random_fill,
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
NULL_decode_xer,
|
||||
NULL_encode_xer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
NULL_decode_oer,
|
||||
NULL_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
NULL_decode_uper, /* Unaligned PER decoder */
|
||||
NULL_encode_uper, /* Unaligned PER encoder */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
NULL_decode_aper, /* Aligned PER decoder */
|
||||
NULL_encode_aper, /* Aligned PER encoder */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
NULL_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_NULL = {
|
||||
"NULL",
|
||||
"NULL",
|
||||
&asn_OP_NULL,
|
||||
asn_DEF_NULL_tags,
|
||||
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
||||
asn_DEF_NULL_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
||||
{ 0, 0, asn_generic_no_constraint },
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
"NULL",
|
||||
"NULL",
|
||||
&asn_OP_NULL,
|
||||
asn_DEF_NULL_tags,
|
||||
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
||||
asn_DEF_NULL_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_generic_no_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
void
|
||||
@@ -71,106 +99,6 @@ NULL_free(const asn_TYPE_descriptor_t *td, void *ptr,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode NULL type.
|
||||
*/
|
||||
asn_dec_rval_t
|
||||
NULL_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **bool_value,
|
||||
const void *buf_ptr, size_t size, int tag_mode) {
|
||||
NULL_t *st = (NULL_t *)*bool_value;
|
||||
asn_dec_rval_t rval;
|
||||
ber_tlv_len_t length;
|
||||
|
||||
if(st == NULL) {
|
||||
st = (NULL_t *)(*bool_value = CALLOC(1, sizeof(*st)));
|
||||
if(st == NULL) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding %s as NULL (tm=%d)", td->name, tag_mode);
|
||||
|
||||
/*
|
||||
* Check tags.
|
||||
*/
|
||||
rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size, tag_mode, 0,
|
||||
&length, 0);
|
||||
if(rval.code != RC_OK) {
|
||||
return rval;
|
||||
}
|
||||
|
||||
// X.690-201508, #8.8.2, length shall be zero.
|
||||
if(length != 0) {
|
||||
ASN_DEBUG("Decoding %s as NULL failed: too much data", td->name);
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NULL_encode_der(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode,
|
||||
ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_enc_rval_t erval = {0,0,0};
|
||||
|
||||
erval.encoded = der_write_tags(td, 0, tag_mode, 0, tag, cb, app_key);
|
||||
if(erval.encoded == -1) {
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
}
|
||||
|
||||
ASN__ENCODED_OK(erval);
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NULL_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
|
||||
void *app_key) {
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
|
||||
(void)td;
|
||||
(void)sptr;
|
||||
(void)ilevel;
|
||||
(void)flags;
|
||||
(void)cb;
|
||||
(void)app_key;
|
||||
|
||||
/* XMLNullValue is empty */
|
||||
er.encoded = 0;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
|
||||
static enum xer_pbd_rval
|
||||
NULL__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
const void *chunk_buf, size_t chunk_size) {
|
||||
(void)td;
|
||||
(void)sptr;
|
||||
(void)chunk_buf; /* Going to be empty according to the rules below. */
|
||||
|
||||
/*
|
||||
* There must be no content in self-terminating <NULL/> tag.
|
||||
*/
|
||||
if(chunk_size)
|
||||
return XPBD_BROKEN_ENCODING;
|
||||
else
|
||||
return XPBD_BODY_CONSUMED;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NULL_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const char *opt_mname, const void *buf_ptr, size_t size) {
|
||||
return xer_decode_primitive(opt_codec_ctx, td,
|
||||
sptr, sizeof(NULL_t), opt_mname, buf_ptr, size,
|
||||
NULL__xer_body_decode);
|
||||
}
|
||||
|
||||
int
|
||||
NULL_compare(const asn_TYPE_descriptor_t *td, const void *a, const void *b) {
|
||||
(void)td;
|
||||
@@ -178,180 +106,3 @@ NULL_compare(const asn_TYPE_descriptor_t *td, const void *a, const void *b) {
|
||||
(void)b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NULL_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(sptr) {
|
||||
return (cb("<present>", 9, app_key) < 0) ? -1 : 0;
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ASN_DISABLE_OER_SUPPORT
|
||||
|
||||
asn_dec_rval_t
|
||||
NULL_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_oer_constraints_t *constraints, void **sptr,
|
||||
const void *ptr, size_t size) {
|
||||
asn_dec_rval_t rv = {RC_OK, 0};
|
||||
(void)opt_codec_ctx;
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)ptr;
|
||||
(void)size;
|
||||
|
||||
if(!*sptr) {
|
||||
*sptr = MALLOC(sizeof(NULL_t));
|
||||
if(*sptr) {
|
||||
*(NULL_t *)*sptr = 0;
|
||||
} else {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NULL_encode_oer(const asn_TYPE_descriptor_t *td,
|
||||
const asn_oer_constraints_t *constraints, const void *sptr,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
|
||||
(void)td;
|
||||
(void)sptr;
|
||||
(void)constraints;
|
||||
(void)cb;
|
||||
(void)app_key;
|
||||
|
||||
er.encoded = 0; /* Encoding in 0 bytes. */
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
|
||||
#ifndef ASN_DISABLE_PER_SUPPORT
|
||||
|
||||
asn_dec_rval_t
|
||||
NULL_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr,
|
||||
asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)pd;
|
||||
|
||||
if(!*sptr) {
|
||||
*sptr = MALLOC(sizeof(NULL_t));
|
||||
if(*sptr) {
|
||||
*(NULL_t *)*sptr = 0;
|
||||
} else {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NULL type does not have content octets.
|
||||
*/
|
||||
|
||||
rv.code = RC_OK;
|
||||
rv.consumed = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NULL_encode_uper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, const void *sptr,
|
||||
asn_per_outp_t *po) {
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)sptr;
|
||||
(void)po;
|
||||
|
||||
er.encoded = 0;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NULL_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv = {RC_OK, 0};
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)pd;
|
||||
|
||||
if(!*sptr) {
|
||||
*sptr = MALLOC(sizeof(NULL_t));
|
||||
if(*sptr) {
|
||||
*(NULL_t *)*sptr = 0;
|
||||
} else {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NULL type does not have content octets.
|
||||
*/
|
||||
|
||||
rv.code = RC_OK;
|
||||
rv.consumed = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
asn_enc_rval_t
|
||||
NULL_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)sptr;
|
||||
(void)po;
|
||||
|
||||
er.encoded = 0;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
|
||||
asn_random_fill_result_t
|
||||
NULL_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constr,
|
||||
size_t max_length) {
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
NULL_t *st = *sptr;
|
||||
|
||||
(void)td;
|
||||
(void)constr;
|
||||
|
||||
if(max_length == 0) return result_skipped;
|
||||
|
||||
if(st == NULL) {
|
||||
st = (NULL_t *)(*sptr = CALLOC(1, sizeof(*st)));
|
||||
if(st == NULL) {
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return result_ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,21 +21,42 @@ extern asn_TYPE_descriptor_t asn_DEF_NULL;
|
||||
extern asn_TYPE_operation_t asn_OP_NULL;
|
||||
|
||||
asn_struct_free_f NULL_free;
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f NULL_print;
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
asn_struct_compare_f NULL_compare;
|
||||
|
||||
#define NULL_constraint asn_generic_no_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
ber_type_decoder_f NULL_decode_ber;
|
||||
der_type_encoder_f NULL_encode_der;
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
xer_type_decoder_f NULL_decode_xer;
|
||||
xer_type_encoder_f NULL_encode_xer;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
oer_type_decoder_f NULL_decode_oer;
|
||||
oer_type_encoder_f NULL_encode_oer;
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f NULL_decode_uper;
|
||||
per_type_encoder_f NULL_encode_uper;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
per_type_decoder_f NULL_decode_aper;
|
||||
per_type_encoder_f NULL_encode_aper;
|
||||
asn_random_fill_f NULL_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#define NULL_constraint asn_generic_no_constraint
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f NULL_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
52
lib/asn1c/common/NULL_aper.c
Normal file
52
lib/asn1c/common/NULL_aper.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <NULL.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
NULL_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv = {RC_OK, 0};
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)pd;
|
||||
|
||||
if(!*sptr) {
|
||||
*sptr = MALLOC(sizeof(NULL_t));
|
||||
if(*sptr) {
|
||||
*(NULL_t *)*sptr = 0;
|
||||
} else {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NULL type does not have content octets.
|
||||
*/
|
||||
|
||||
rv.code = RC_OK;
|
||||
rv.consumed = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
asn_enc_rval_t
|
||||
NULL_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)sptr;
|
||||
(void)po;
|
||||
|
||||
er.encoded = 0;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
20
lib/asn1c/common/NULL_print.c
Normal file
20
lib/asn1c/common/NULL_print.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <NULL.h>
|
||||
|
||||
int
|
||||
NULL_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(sptr) {
|
||||
return (cb("<present>", 9, app_key) < 0) ? -1 : 0;
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
31
lib/asn1c/common/NULL_rfill.c
Normal file
31
lib/asn1c/common/NULL_rfill.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <NULL.h>
|
||||
|
||||
asn_random_fill_result_t
|
||||
NULL_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constr,
|
||||
size_t max_length) {
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
NULL_t *st = *sptr;
|
||||
|
||||
(void)td;
|
||||
(void)constr;
|
||||
|
||||
if(max_length == 0) return result_skipped;
|
||||
|
||||
if(st == NULL) {
|
||||
st = (NULL_t *)(*sptr = CALLOC(1, sizeof(*st)));
|
||||
if(st == NULL) {
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return result_ok;
|
||||
}
|
||||
@@ -16,360 +16,88 @@
|
||||
* NativeEnumerated basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_NativeEnumerated = {
|
||||
NativeInteger_free,
|
||||
NativeInteger_print,
|
||||
NativeInteger_compare,
|
||||
NativeInteger_decode_ber,
|
||||
NativeInteger_encode_der,
|
||||
NativeInteger_decode_xer,
|
||||
NativeEnumerated_encode_xer,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
NativeInteger_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
NativeInteger_print,
|
||||
#else
|
||||
NativeEnumerated_decode_oer,
|
||||
NativeEnumerated_encode_oer,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
NativeInteger_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
NativeInteger_decode_ber,
|
||||
NativeInteger_encode_der,
|
||||
#else
|
||||
NativeEnumerated_decode_uper,
|
||||
NativeEnumerated_encode_uper,
|
||||
NativeEnumerated_decode_aper,
|
||||
NativeEnumerated_encode_aper,
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
NativeEnumerated_random_fill,
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
NativeInteger_decode_xer,
|
||||
NativeEnumerated_encode_xer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
NativeEnumerated_decode_oer,
|
||||
NativeEnumerated_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
NativeEnumerated_decode_uper,
|
||||
NativeEnumerated_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
NativeEnumerated_decode_aper,
|
||||
NativeEnumerated_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
NativeEnumerated_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
|
||||
"ENUMERATED", /* The ASN.1 type is still ENUMERATED */
|
||||
"ENUMERATED",
|
||||
&asn_OP_NativeEnumerated,
|
||||
asn_DEF_NativeEnumerated_tags,
|
||||
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
||||
asn_DEF_NativeEnumerated_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
||||
{ 0, 0, asn_generic_no_constraint },
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
"ENUMERATED", /* The ASN.1 type is still ENUMERATED */
|
||||
"ENUMERATED",
|
||||
&asn_OP_NativeEnumerated,
|
||||
asn_DEF_NativeEnumerated_tags,
|
||||
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
||||
asn_DEF_NativeEnumerated_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_generic_no_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeEnumerated_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, enum xer_encoder_flags_e flags,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
const long *native = (const long *)sptr;
|
||||
const asn_INTEGER_enum_map_t *el;
|
||||
|
||||
(void)ilevel;
|
||||
(void)flags;
|
||||
|
||||
if(!native) ASN__ENCODE_FAILED;
|
||||
|
||||
el = INTEGER_map_value2enum(specs, *native);
|
||||
if(el) {
|
||||
er.encoded =
|
||||
asn__format_to_callback(cb, app_key, "<%s/>", el->enum_name);
|
||||
if(er.encoded < 0) ASN__ENCODE_FAILED;
|
||||
ASN__ENCODED_OK(er);
|
||||
} else {
|
||||
ASN_DEBUG(
|
||||
"ASN.1 forbids dealing with "
|
||||
"unknown value of ENUMERATED type");
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeEnumerated_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
void **sptr, asn_per_data_t *pd) {
|
||||
const asn_INTEGER_specifics_t *specs = td->specifics;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
long *native = (long *)*sptr;
|
||||
const asn_per_constraint_t *ct;
|
||||
long value;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ASN__DECODE_FAILED; /* Mandatory! */
|
||||
if(!specs) ASN__DECODE_FAILED;
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
|
||||
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) ASN__DECODE_STARVED;
|
||||
if(inext) ct = 0;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
if(value >= (specs->extension
|
||||
? specs->extension - 1 : specs->map_count))
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
if(!specs->extension)
|
||||
ASN__DECODE_FAILED;
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
value = uper_get_nsnnwn(pd);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
value += specs->extension - 1;
|
||||
if(value >= specs->map_count)
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
*native = specs->value2enum[value].nat_value;
|
||||
ASN_DEBUG("Decoded %s = %ld", td->name, *native);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
int
|
||||
NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {
|
||||
const asn_INTEGER_enum_map_t *a = ap;
|
||||
const asn_INTEGER_enum_map_t *b = bp;
|
||||
if(a->nat_value == b->nat_value)
|
||||
return 0;
|
||||
if(a->nat_value < b->nat_value)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeEnumerated_encode_uper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
long native, value;
|
||||
const asn_per_constraint_t *ct;
|
||||
int inext = 0;
|
||||
asn_INTEGER_enum_map_t key;
|
||||
const asn_INTEGER_enum_map_t *kf;
|
||||
|
||||
if(!sptr) ASN__ENCODE_FAILED;
|
||||
if(!specs) ASN__ENCODE_FAILED;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ASN__ENCODE_FAILED; /* Mandatory! */
|
||||
|
||||
ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
native = *(const long *)sptr;
|
||||
|
||||
key.nat_value = native;
|
||||
kf = bsearch(&key, specs->value2enum, specs->map_count,
|
||||
sizeof(key), NativeEnumerated__compar_value2enum);
|
||||
if(!kf) {
|
||||
ASN_DEBUG("No element corresponds to %ld", native);
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
value = kf - specs->value2enum;
|
||||
|
||||
if(ct->range_bits >= 0) {
|
||||
int cmpWith = specs->extension
|
||||
? specs->extension - 1 : specs->map_count;
|
||||
if(value >= cmpWith)
|
||||
inext = 1;
|
||||
}
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
if(inext) ct = 0;
|
||||
} else if(inext) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, value, ct->range_bits))
|
||||
ASN__ENCODE_FAILED;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
if(!specs->extension)
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
|
||||
value, specs->extension, inext,
|
||||
value - (inext ? (specs->extension - 1) : 0));
|
||||
if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeEnumerated_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
void **sptr, asn_per_data_t *pd) {
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
long *native = (long *)*sptr;
|
||||
const asn_per_constraint_t *ct;
|
||||
long value;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ASN__DECODE_FAILED; /* Mandatory! */
|
||||
if(!specs) ASN__DECODE_FAILED;
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
|
||||
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) ASN__DECODE_STARVED;
|
||||
if(inext) ct = 0;
|
||||
}
|
||||
|
||||
/* Deal with APER padding */
|
||||
if(ct && ct->upper_bound >= 255) {
|
||||
int padding = 0;
|
||||
padding = (8 - (pd->moved % 8)) % 8;
|
||||
ASN_DEBUG("For NativeEnumerated %s,offset= %lu Padding bits = %d", td->name, pd->moved, padding);
|
||||
ASN_DEBUG("For NativeEnumerated %s, upper bound = %lu", td->name, ct->upper_bound);
|
||||
if(padding > 0)
|
||||
per_get_few_bits(pd, padding);
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
if(value >= (specs->extension
|
||||
? specs->extension - 1 : specs->map_count))
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
if(!specs->extension)
|
||||
ASN__DECODE_FAILED;
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
|
||||
/* XXX handle indefinite index length > 64k */
|
||||
value = aper_get_nsnnwn(pd, 65537);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
value += specs->extension - 1;
|
||||
//if(value >= specs->map_count)
|
||||
// ASN__DECODE_FAILED;
|
||||
if(value >= specs->map_count) {
|
||||
ASN_DEBUG("Decoded unknown index value %s = %ld", td->name, value);
|
||||
/* unknown index. Workaround => set the first enumeration value */
|
||||
*native = specs->value2enum[0].nat_value;
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
||||
*native = specs->value2enum[value].nat_value;
|
||||
ASN_DEBUG("Decoded %s = %ld", td->name, *native);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
long native, value;
|
||||
const asn_per_constraint_t *ct;
|
||||
int inext = 0;
|
||||
asn_INTEGER_enum_map_t key;
|
||||
asn_INTEGER_enum_map_t *kf;
|
||||
|
||||
if(!sptr) ASN__ENCODE_FAILED;
|
||||
if(!specs) ASN__ENCODE_FAILED;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ASN__ENCODE_FAILED; /* Mandatory! */
|
||||
|
||||
ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
native = *(const long *)sptr;
|
||||
if(native < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
key.nat_value = native;
|
||||
kf = bsearch(&key, specs->value2enum, specs->map_count,
|
||||
sizeof(key), NativeEnumerated__compar_value2enum);
|
||||
if(!kf) {
|
||||
ASN_DEBUG("No element corresponds to %ld", native);
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
value = kf - specs->value2enum;
|
||||
|
||||
if(ct->range_bits >= 0) {
|
||||
int cmpWith = specs->extension
|
||||
? specs->extension - 1 : specs->map_count;
|
||||
if(value >= cmpWith)
|
||||
inext = 1;
|
||||
}
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
if(inext) ct = 0;
|
||||
} else if(inext) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, value, ct->range_bits))
|
||||
ASN__ENCODE_FAILED;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
if(!specs->extension)
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
|
||||
value, specs->extension, inext,
|
||||
value - (inext ? (specs->extension - 1) : 0));
|
||||
if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
const asn_INTEGER_enum_map_t *a = ap;
|
||||
const asn_INTEGER_enum_map_t *b = bp;
|
||||
if(a->nat_value == b->nat_value)
|
||||
return 0;
|
||||
if(a->nat_value < b->nat_value)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
@@ -21,22 +21,49 @@ extern "C" {
|
||||
extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
|
||||
extern asn_TYPE_operation_t asn_OP_NativeEnumerated;
|
||||
|
||||
xer_type_encoder_f NativeEnumerated_encode_xer;
|
||||
oer_type_decoder_f NativeEnumerated_decode_oer;
|
||||
oer_type_encoder_f NativeEnumerated_encode_oer;
|
||||
per_type_decoder_f NativeEnumerated_decode_uper;
|
||||
per_type_encoder_f NativeEnumerated_encode_uper;
|
||||
per_type_decoder_f NativeEnumerated_decode_aper;
|
||||
per_type_encoder_f NativeEnumerated_encode_aper;
|
||||
#define NativeEnumerated_free NativeInteger_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
#define NativeEnumerated_print NativeInteger_print
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define NativeEnumerated_compare NativeInteger_compare
|
||||
|
||||
#define NativeEnumerated_free NativeInteger_free
|
||||
#define NativeEnumerated_print NativeInteger_print
|
||||
#define NativeEnumerated_compare NativeInteger_compare
|
||||
#define NativeEnumerated_random_fill NativeInteger_random_fill
|
||||
#define NativeEnumerated_constraint asn_generic_no_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define NativeEnumerated_decode_ber NativeInteger_decode_ber
|
||||
#define NativeEnumerated_encode_der NativeInteger_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define NativeEnumerated_decode_xer NativeInteger_decode_xer
|
||||
xer_type_encoder_f NativeEnumerated_encode_xer;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
oer_type_decoder_f NativeEnumerated_decode_oer;
|
||||
oer_type_encoder_f NativeEnumerated_encode_oer;
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f NativeEnumerated_decode_uper;
|
||||
per_type_encoder_f NativeEnumerated_encode_uper;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
per_type_decoder_f NativeEnumerated_decode_aper;
|
||||
per_type_encoder_f NativeEnumerated_encode_aper;
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
#define NativeEnumerated_random_fill NativeInteger_random_fill
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
int NativeEnumerated__compar_value2enum(
|
||||
const void *ap,
|
||||
const void *bp);
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
155
lib/asn1c/common/NativeEnumerated_aper.c
Normal file
155
lib/asn1c/common/NativeEnumerated_aper.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <NativeEnumerated.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeEnumerated_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
void **sptr, asn_per_data_t *pd) {
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
long *native = (long *)*sptr;
|
||||
const asn_per_constraint_t *ct;
|
||||
long value;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ASN__DECODE_FAILED; /* Mandatory! */
|
||||
if(!specs) ASN__DECODE_FAILED;
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
|
||||
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) ASN__DECODE_STARVED;
|
||||
if(inext) ct = 0;
|
||||
}
|
||||
|
||||
/* Deal with APER padding */
|
||||
if(ct && ct->upper_bound >= 255) {
|
||||
int padding = 0;
|
||||
padding = (8 - (pd->moved % 8)) % 8;
|
||||
ASN_DEBUG("For NativeEnumerated %s,offset= %lu Padding bits = %d", td->name, pd->moved, padding);
|
||||
ASN_DEBUG("For NativeEnumerated %s, upper bound = %lu", td->name, ct->upper_bound);
|
||||
if(padding > 0)
|
||||
per_get_few_bits(pd, padding);
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
if(value >= (specs->extension
|
||||
? specs->extension - 1 : specs->map_count))
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
if(!specs->extension)
|
||||
ASN__DECODE_FAILED;
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
|
||||
/* XXX handle indefinite index length > 64k */
|
||||
value = aper_get_nsnnwn(pd, 65537);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
value += specs->extension - 1;
|
||||
//if(value >= specs->map_count)
|
||||
// ASN__DECODE_FAILED;
|
||||
if(value >= specs->map_count) {
|
||||
ASN_DEBUG("Decoded unknown index value %s = %ld", td->name, value);
|
||||
/* unknown index. Workaround => set the first enumeration value */
|
||||
*native = specs->value2enum[0].nat_value;
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
||||
*native = specs->value2enum[value].nat_value;
|
||||
ASN_DEBUG("Decoded %s = %ld", td->name, *native);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
long native, value;
|
||||
const asn_per_constraint_t *ct;
|
||||
int inext = 0;
|
||||
asn_INTEGER_enum_map_t key;
|
||||
asn_INTEGER_enum_map_t *kf;
|
||||
|
||||
if(!sptr) ASN__ENCODE_FAILED;
|
||||
if(!specs) ASN__ENCODE_FAILED;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ASN__ENCODE_FAILED; /* Mandatory! */
|
||||
|
||||
ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
native = *(const long *)sptr;
|
||||
if(native < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
key.nat_value = native;
|
||||
kf = bsearch(&key, specs->value2enum, specs->map_count,
|
||||
sizeof(key), NativeEnumerated__compar_value2enum);
|
||||
if(!kf) {
|
||||
ASN_DEBUG("No element corresponds to %ld", native);
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
value = kf - specs->value2enum;
|
||||
|
||||
if(ct->range_bits >= 0) {
|
||||
int cmpWith = specs->extension
|
||||
? specs->extension - 1 : specs->map_count;
|
||||
if(value >= cmpWith)
|
||||
inext = 1;
|
||||
}
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
if(inext) ct = 0;
|
||||
} else if(inext) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, value, ct->range_bits))
|
||||
ASN__ENCODE_FAILED;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
if(!specs->extension)
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
|
||||
value, specs->extension, inext,
|
||||
value - (inext ? (specs->extension - 1) : 0));
|
||||
if(aper_put_nsnnwn(po,
|
||||
ct->upper_bound - ct->lower_bound + 1,
|
||||
value - (inext ? (specs->extension - 1) : 0)))
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
@@ -17,408 +17,79 @@
|
||||
* NativeInteger basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_NativeInteger = {
|
||||
NativeInteger_free,
|
||||
NativeInteger_print,
|
||||
NativeInteger_compare,
|
||||
NativeInteger_decode_ber,
|
||||
NativeInteger_encode_der,
|
||||
NativeInteger_decode_xer,
|
||||
NativeInteger_encode_xer,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
NativeInteger_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
NativeInteger_print,
|
||||
#else
|
||||
NativeInteger_decode_oer, /* OER decoder */
|
||||
NativeInteger_encode_oer, /* Canonical OER encoder */
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
NativeInteger_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
NativeInteger_decode_ber,
|
||||
NativeInteger_encode_der,
|
||||
#else
|
||||
NativeInteger_decode_uper, /* Unaligned PER decoder */
|
||||
NativeInteger_encode_uper, /* Unaligned PER encoder */
|
||||
NativeInteger_decode_aper, /* Aligned PER decoder */
|
||||
NativeInteger_encode_aper, /* Aligned PER encoder */
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
NativeInteger_random_fill,
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
NativeInteger_decode_xer,
|
||||
NativeInteger_encode_xer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
NativeInteger_decode_oer, /* OER decoder */
|
||||
NativeInteger_encode_oer, /* Canonical OER encoder */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
NativeInteger_decode_uper, /* Unaligned PER decoder */
|
||||
NativeInteger_encode_uper, /* Unaligned PER encoder */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
NativeInteger_decode_aper, /* Aligned PER decoder */
|
||||
NativeInteger_encode_aper, /* Aligned PER encoder */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
NativeInteger_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
|
||||
"INTEGER", /* The ASN.1 type is still INTEGER */
|
||||
"INTEGER",
|
||||
&asn_OP_NativeInteger,
|
||||
asn_DEF_NativeInteger_tags,
|
||||
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
||||
asn_DEF_NativeInteger_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
||||
{ 0, 0, asn_generic_no_constraint },
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
"INTEGER", /* The ASN.1 type is still INTEGER */
|
||||
"INTEGER",
|
||||
&asn_OP_NativeInteger,
|
||||
asn_DEF_NativeInteger_tags,
|
||||
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
||||
asn_DEF_NativeInteger_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_generic_no_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
/*
|
||||
* Decode INTEGER type.
|
||||
*/
|
||||
asn_dec_rval_t
|
||||
NativeInteger_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **nint_ptr,
|
||||
const void *buf_ptr, size_t size, int tag_mode) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
long *native = (long *)*nint_ptr;
|
||||
asn_dec_rval_t rval;
|
||||
ber_tlv_len_t length;
|
||||
|
||||
/*
|
||||
* If the structure is not there, allocate it.
|
||||
*/
|
||||
if(native == NULL) {
|
||||
native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
|
||||
if(native == NULL) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
|
||||
td->name, tag_mode);
|
||||
|
||||
/*
|
||||
* Check tags.
|
||||
*/
|
||||
rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
|
||||
tag_mode, 0, &length, 0);
|
||||
if(rval.code != RC_OK)
|
||||
return rval;
|
||||
|
||||
ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
|
||||
|
||||
/*
|
||||
* Make sure we have this length.
|
||||
*/
|
||||
buf_ptr = ((const char *)buf_ptr) + rval.consumed;
|
||||
size -= rval.consumed;
|
||||
if(length > (ber_tlv_len_t)size) {
|
||||
rval.code = RC_WMORE;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* ASN.1 encoded INTEGER: buf_ptr, length
|
||||
* Fill the native, at the same time checking for overflow.
|
||||
* If overflow occurred, return with RC_FAIL.
|
||||
*/
|
||||
{
|
||||
INTEGER_t tmp;
|
||||
union {
|
||||
const void *constbuf;
|
||||
void *nonconstbuf;
|
||||
} unconst_buf;
|
||||
long l;
|
||||
|
||||
unconst_buf.constbuf = buf_ptr;
|
||||
tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
|
||||
tmp.size = length;
|
||||
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
|
||||
: asn_INTEGER2long(&tmp, &l)) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
|
||||
*native = l;
|
||||
}
|
||||
|
||||
rval.code = RC_OK;
|
||||
rval.consumed += length;
|
||||
|
||||
ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
|
||||
(long)rval.consumed, (long)length, td->name, (long)*native);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode the NativeInteger using the standard INTEGER type DER encoder.
|
||||
*/
|
||||
asn_enc_rval_t
|
||||
NativeInteger_encode_der(const asn_TYPE_descriptor_t *sd, const void *ptr,
|
||||
int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
unsigned long native = *(const unsigned long *)ptr; /* Disable sign ext. */
|
||||
asn_enc_rval_t erval = {0,0,0};
|
||||
INTEGER_t tmp;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
|
||||
|
||||
tmp.buf = (uint8_t *)&native;
|
||||
tmp.size = sizeof(native);
|
||||
|
||||
#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
|
||||
uint8_t buf[sizeof(native)];
|
||||
uint8_t *p;
|
||||
|
||||
/* Prepare a fake INTEGER */
|
||||
for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
|
||||
*p = (uint8_t)native;
|
||||
|
||||
tmp.buf = buf;
|
||||
tmp.size = sizeof(buf);
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
/* Encode fake INTEGER */
|
||||
erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
|
||||
if(erval.structure_ptr == &tmp) {
|
||||
erval.structure_ptr = ptr;
|
||||
}
|
||||
return erval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode the chunk of XML text encoding INTEGER.
|
||||
*/
|
||||
asn_dec_rval_t
|
||||
NativeInteger_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const char *opt_mname, const void *buf_ptr,
|
||||
size_t size) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval;
|
||||
INTEGER_t st;
|
||||
void *st_ptr = (void *)&st;
|
||||
long *native = (long *)*sptr;
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
memset(&st, 0, sizeof(st));
|
||||
rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
|
||||
opt_mname, buf_ptr, size);
|
||||
if(rval.code == RC_OK) {
|
||||
long l;
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&st, (unsigned long *)&l) /* sic */
|
||||
: asn_INTEGER2long(&st, &l)) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
} else {
|
||||
*native = l;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Cannot restart from the middle;
|
||||
* there is no place to save state in the native type.
|
||||
* Request a continuation from the very beginning.
|
||||
*/
|
||||
rval.consumed = 0;
|
||||
}
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &st);
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeInteger_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, enum xer_encoder_flags_e flags,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
char scratch[32]; /* Enough for 64-bit int */
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
const long *native = (const long *)sptr;
|
||||
|
||||
(void)ilevel;
|
||||
(void)flags;
|
||||
|
||||
if(!native) ASN__ENCODE_FAILED;
|
||||
|
||||
er.encoded = snprintf(scratch, sizeof(scratch),
|
||||
(specs && specs->field_unsigned)
|
||||
? "%lu" : "%ld", *native);
|
||||
if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
|
||||
|| cb(scratch, er.encoded, app_key) < 0)
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
#ifndef ASN_DISABLE_PER_SUPPORT
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeInteger_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr,
|
||||
asn_per_data_t *pd) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval;
|
||||
long *native = (long *)*sptr;
|
||||
INTEGER_t tmpint;
|
||||
void *tmpintptr = &tmpint;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
memset(&tmpint, 0, sizeof tmpint);
|
||||
rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
|
||||
&tmpintptr, pd);
|
||||
if(rval.code == RC_OK) {
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
|
||||
: asn_INTEGER2long(&tmpint, native))
|
||||
rval.code = RC_FAIL;
|
||||
else
|
||||
ASN_DEBUG("NativeInteger %s got value %ld",
|
||||
td->name, *native);
|
||||
}
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeInteger_encode_uper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
long native;
|
||||
INTEGER_t tmpint;
|
||||
|
||||
if(!sptr) ASN__ENCODE_FAILED;
|
||||
|
||||
native = *(const long *)sptr;
|
||||
|
||||
ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
|
||||
|
||||
memset(&tmpint, 0, sizeof(tmpint));
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_ulong2INTEGER(&tmpint, native)
|
||||
: asn_long2INTEGER(&tmpint, native))
|
||||
ASN__ENCODE_FAILED;
|
||||
er = INTEGER_encode_uper(td, constraints, &tmpint, po);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
return er;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeInteger_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval;
|
||||
long *native = (long *)*sptr;
|
||||
INTEGER_t tmpint;
|
||||
void *tmpintptr = &tmpint;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
ASN_DEBUG("Decoding NativeInteger %s (APER)", td->name);
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
memset(&tmpint, 0, sizeof tmpint);
|
||||
rval = INTEGER_decode_aper(opt_codec_ctx, td, constraints,
|
||||
&tmpintptr, pd);
|
||||
if(rval.code == RC_OK) {
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
|
||||
: asn_INTEGER2long(&tmpint, native))
|
||||
rval.code = RC_FAIL;
|
||||
else
|
||||
ASN_DEBUG("NativeInteger %s got value %ld",
|
||||
td->name, *native);
|
||||
}
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeInteger_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
long native;
|
||||
INTEGER_t tmpint;
|
||||
|
||||
if(!sptr) ASN__ENCODE_FAILED;
|
||||
|
||||
native = *(const long *)sptr;
|
||||
|
||||
ASN_DEBUG("Encoding NativeInteger %s %ld (APER)", td->name, native);
|
||||
|
||||
memset(&tmpint, 0, sizeof(tmpint));
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_ulong2INTEGER(&tmpint, (unsigned long)native)
|
||||
: asn_long2INTEGER(&tmpint, native))
|
||||
ASN__ENCODE_FAILED;
|
||||
er = INTEGER_encode_aper(td, constraints, &tmpint, po);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
return er;
|
||||
}
|
||||
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
|
||||
/*
|
||||
* INTEGER specific human-readable output.
|
||||
*/
|
||||
int
|
||||
NativeInteger_print(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
const long *native = (const long *)sptr;
|
||||
char scratch[32]; /* Enough for 64-bit int */
|
||||
int ret;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(native) {
|
||||
long value = *native;
|
||||
ret = snprintf(scratch, sizeof(scratch),
|
||||
(specs && specs->field_unsigned) ? "%lu" : "%ld", value);
|
||||
assert(ret > 0 && (size_t)ret < sizeof(scratch));
|
||||
if(cb(scratch, ret, app_key) < 0) return -1;
|
||||
if(specs && (value >= 0 || !specs->field_unsigned)) {
|
||||
const asn_INTEGER_enum_map_t *el =
|
||||
INTEGER_map_value2enum(specs, value);
|
||||
if(el) {
|
||||
if(cb(" (", 2, app_key) < 0) return -1;
|
||||
if(cb(el->enum_name, el->enum_len, app_key) < 0) return -1;
|
||||
if(cb(")", 1, app_key) < 0) return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NativeInteger_free(const asn_TYPE_descriptor_t *td, void *ptr,
|
||||
enum asn_struct_free_method method) {
|
||||
@@ -474,77 +145,3 @@ NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const v
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
asn_random_fill_result_t
|
||||
NativeInteger_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
long *st = *sptr;
|
||||
const asn_INTEGER_enum_map_t *emap;
|
||||
size_t emap_len;
|
||||
intmax_t value;
|
||||
int find_inside_map;
|
||||
|
||||
if(max_length == 0) return result_skipped;
|
||||
|
||||
if(st == NULL) {
|
||||
st = (long *)CALLOC(1, sizeof(*st));
|
||||
if(st == NULL) {
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if(specs) {
|
||||
emap = specs->value2enum;
|
||||
emap_len = specs->map_count;
|
||||
if(specs->strict_enumeration) {
|
||||
find_inside_map = emap_len > 0;
|
||||
} else {
|
||||
find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
|
||||
}
|
||||
} else {
|
||||
emap = 0;
|
||||
emap_len = 0;
|
||||
find_inside_map = 0;
|
||||
}
|
||||
|
||||
if(find_inside_map) {
|
||||
assert(emap_len > 0);
|
||||
value = emap[asn_random_between(0, emap_len - 1)].nat_value;
|
||||
} else {
|
||||
const asn_per_constraints_t *ct;
|
||||
|
||||
static const long variants[] = {
|
||||
-65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
|
||||
-16383, -257, -256, -255, -254, -129, -128, -127,
|
||||
-126, -1, 0, 1, 126, 127, 128, 129,
|
||||
254, 255, 256, 257, 16383, 16384, 16385, 32767,
|
||||
32768, 32769, 65534, 65535, 65536, 65537};
|
||||
if(specs && specs->field_unsigned) {
|
||||
assert(variants[18] == 0);
|
||||
value = variants[asn_random_between(
|
||||
18, sizeof(variants) / sizeof(variants[0]) - 1)];
|
||||
} else {
|
||||
value = variants[asn_random_between(
|
||||
0, sizeof(variants) / sizeof(variants[0]) - 1)];
|
||||
}
|
||||
|
||||
if(!constraints) constraints = &td->encoding_constraints;
|
||||
ct = constraints ? constraints->per_constraints : 0;
|
||||
if(ct && (ct->value.flags & APC_CONSTRAINED)) {
|
||||
if(value < ct->value.lower_bound || value > ct->value.upper_bound) {
|
||||
value = asn_random_between(ct->value.lower_bound,
|
||||
ct->value.upper_bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*sptr = st;
|
||||
*st = value;
|
||||
return result_ok;
|
||||
}
|
||||
|
||||
@@ -22,22 +22,43 @@ extern "C" {
|
||||
extern asn_TYPE_descriptor_t asn_DEF_NativeInteger;
|
||||
extern asn_TYPE_operation_t asn_OP_NativeInteger;
|
||||
|
||||
asn_struct_free_f NativeInteger_free;
|
||||
asn_struct_free_f NativeInteger_free;
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f NativeInteger_print;
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
asn_struct_compare_f NativeInteger_compare;
|
||||
|
||||
#define NativeInteger_constraint asn_generic_no_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
ber_type_decoder_f NativeInteger_decode_ber;
|
||||
der_type_encoder_f NativeInteger_encode_der;
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
xer_type_decoder_f NativeInteger_decode_xer;
|
||||
xer_type_encoder_f NativeInteger_encode_xer;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
oer_type_decoder_f NativeInteger_decode_oer;
|
||||
oer_type_encoder_f NativeInteger_encode_oer;
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f NativeInteger_decode_uper;
|
||||
per_type_encoder_f NativeInteger_encode_uper;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
per_type_decoder_f NativeInteger_decode_aper;
|
||||
per_type_encoder_f NativeInteger_encode_aper;
|
||||
asn_random_fill_f NativeInteger_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#define NativeInteger_constraint asn_generic_no_constraint
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f NativeInteger_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
69
lib/asn1c/common/NativeInteger_aper.c
Normal file
69
lib/asn1c/common/NativeInteger_aper.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <NativeInteger.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeInteger_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval;
|
||||
long *native = (long *)*sptr;
|
||||
INTEGER_t tmpint;
|
||||
void *tmpintptr = &tmpint;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
ASN_DEBUG("Decoding NativeInteger %s (APER)", td->name);
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
memset(&tmpint, 0, sizeof tmpint);
|
||||
rval = INTEGER_decode_aper(opt_codec_ctx, td, constraints,
|
||||
&tmpintptr, pd);
|
||||
if(rval.code == RC_OK) {
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
|
||||
: asn_INTEGER2long(&tmpint, native))
|
||||
rval.code = RC_FAIL;
|
||||
else
|
||||
ASN_DEBUG("NativeInteger %s got value %ld",
|
||||
td->name, *native);
|
||||
}
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeInteger_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
|
||||
const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
long native;
|
||||
INTEGER_t tmpint;
|
||||
|
||||
if(!sptr) ASN__ENCODE_FAILED;
|
||||
|
||||
native = *(const long *)sptr;
|
||||
|
||||
ASN_DEBUG("Encoding NativeInteger %s %ld (APER)", td->name, native);
|
||||
|
||||
memset(&tmpint, 0, sizeof(tmpint));
|
||||
if((specs&&specs->field_unsigned)
|
||||
? asn_ulong2INTEGER(&tmpint, (unsigned long)native)
|
||||
: asn_long2INTEGER(&tmpint, native))
|
||||
ASN__ENCODE_FAILED;
|
||||
er = INTEGER_encode_aper(td, constraints, &tmpint, po);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
return er;
|
||||
}
|
||||
43
lib/asn1c/common/NativeInteger_print.c
Normal file
43
lib/asn1c/common/NativeInteger_print.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <NativeInteger.h>
|
||||
|
||||
/*
|
||||
* INTEGER specific human-readable output.
|
||||
*/
|
||||
int
|
||||
NativeInteger_print(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
const long *native = (const long *)sptr;
|
||||
char scratch[32]; /* Enough for 64-bit int */
|
||||
int ret;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(native) {
|
||||
long value = *native;
|
||||
ret = snprintf(scratch, sizeof(scratch),
|
||||
(specs && specs->field_unsigned) ? "%lu" : "%ld", value);
|
||||
assert(ret > 0 && (size_t)ret < sizeof(scratch));
|
||||
if(cb(scratch, ret, app_key) < 0) return -1;
|
||||
if(specs && (value >= 0 || !specs->field_unsigned)) {
|
||||
const asn_INTEGER_enum_map_t *el =
|
||||
INTEGER_map_value2enum(specs, value);
|
||||
if(el) {
|
||||
if(cb(" (", 2, app_key) < 0) return -1;
|
||||
if(cb(el->enum_name, el->enum_len, app_key) < 0) return -1;
|
||||
if(cb(")", 1, app_key) < 0) return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
83
lib/asn1c/common/NativeInteger_rfill.c
Normal file
83
lib/asn1c/common/NativeInteger_rfill.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <NativeInteger.h>
|
||||
|
||||
asn_random_fill_result_t
|
||||
NativeInteger_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
const asn_INTEGER_specifics_t *specs =
|
||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
long *st = *sptr;
|
||||
const asn_INTEGER_enum_map_t *emap;
|
||||
size_t emap_len;
|
||||
intmax_t value;
|
||||
int find_inside_map;
|
||||
|
||||
if(max_length == 0) return result_skipped;
|
||||
|
||||
if(st == NULL) {
|
||||
st = (long *)CALLOC(1, sizeof(*st));
|
||||
if(st == NULL) {
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if(specs) {
|
||||
emap = specs->value2enum;
|
||||
emap_len = specs->map_count;
|
||||
if(specs->strict_enumeration) {
|
||||
find_inside_map = emap_len > 0;
|
||||
} else {
|
||||
find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
|
||||
}
|
||||
} else {
|
||||
emap = 0;
|
||||
emap_len = 0;
|
||||
find_inside_map = 0;
|
||||
}
|
||||
|
||||
if(find_inside_map) {
|
||||
assert(emap_len > 0);
|
||||
value = emap[asn_random_between(0, emap_len - 1)].nat_value;
|
||||
} else {
|
||||
static const long variants[] = {
|
||||
-65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
|
||||
-16383, -257, -256, -255, -254, -129, -128, -127,
|
||||
-126, -1, 0, 1, 126, 127, 128, 129,
|
||||
254, 255, 256, 257, 16383, 16384, 16385, 32767,
|
||||
32768, 32769, 65534, 65535, 65536, 65537};
|
||||
if(specs && specs->field_unsigned) {
|
||||
assert(variants[18] == 0);
|
||||
value = variants[asn_random_between(
|
||||
18, sizeof(variants) / sizeof(variants[0]) - 1)];
|
||||
} else {
|
||||
value = variants[asn_random_between(
|
||||
0, sizeof(variants) / sizeof(variants[0]) - 1)];
|
||||
}
|
||||
|
||||
if(!constraints) constraints = &td->encoding_constraints;
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
const asn_per_constraints_t *ct;
|
||||
|
||||
ct = constraints ? constraints->per_constraints : 0;
|
||||
if(ct && (ct->value.flags & APC_CONSTRAINED)) {
|
||||
if(value < ct->value.lower_bound || value > ct->value.upper_bound) {
|
||||
value = asn_random_between(ct->value.lower_bound,
|
||||
ct->value.upper_bound);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
}
|
||||
|
||||
*sptr = st;
|
||||
*st = value;
|
||||
return result_ok;
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <asn_internal.h>
|
||||
#include <INTEGER.h>
|
||||
#include <OBJECT_IDENTIFIER.h>
|
||||
#include <OCTET_STRING.h>
|
||||
#include <asn_codecs_prim.h>
|
||||
#include <limits.h> /* for CHAR_BIT */
|
||||
#include <errno.h>
|
||||
|
||||
@@ -13,50 +13,79 @@
|
||||
* OBJECT IDENTIFIER basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER = {
|
||||
ASN__PRIMITIVE_TYPE_free,
|
||||
OBJECT_IDENTIFIER_print,
|
||||
OCTET_STRING_compare, /* Implemented in terms of a string comparison */
|
||||
ber_decode_primitive,
|
||||
der_encode_primitive,
|
||||
OBJECT_IDENTIFIER_decode_xer,
|
||||
OBJECT_IDENTIFIER_encode_xer,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
ASN__PRIMITIVE_TYPE_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
OBJECT_IDENTIFIER_print,
|
||||
#else
|
||||
OBJECT_IDENTIFIER_decode_oer,
|
||||
OBJECT_IDENTIFIER_encode_oer,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OCTET_STRING_compare, /* Implemented in terms of a string comparison */
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
ber_decode_primitive,
|
||||
der_encode_primitive,
|
||||
#else
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
OBJECT_IDENTIFIER_random_fill,
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OBJECT_IDENTIFIER_decode_xer,
|
||||
OBJECT_IDENTIFIER_encode_xer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
OBJECT_IDENTIFIER_decode_oer,
|
||||
OBJECT_IDENTIFIER_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
OBJECT_IDENTIFIER_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
|
||||
"OBJECT IDENTIFIER",
|
||||
"OBJECT_IDENTIFIER",
|
||||
&asn_OP_OBJECT_IDENTIFIER,
|
||||
asn_DEF_OBJECT_IDENTIFIER_tags,
|
||||
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
|
||||
/ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
|
||||
asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */
|
||||
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
|
||||
/ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
|
||||
{ 0, 0, OBJECT_IDENTIFIER_constraint },
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
"OBJECT IDENTIFIER",
|
||||
"OBJECT_IDENTIFIER",
|
||||
&asn_OP_OBJECT_IDENTIFIER,
|
||||
asn_DEF_OBJECT_IDENTIFIER_tags,
|
||||
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
|
||||
/ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
|
||||
asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */
|
||||
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
|
||||
/ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
OBJECT_IDENTIFIER_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
int
|
||||
@@ -143,11 +172,12 @@ OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, size_t arcbuf_len,
|
||||
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ssize_t
|
||||
OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
char scratch[32];
|
||||
asn_oid_arc_t arc0, arc1;
|
||||
asn_oid_arc_t arc0 = 0;
|
||||
asn_oid_arc_t arc1 = 0;
|
||||
size_t produced = 0;
|
||||
size_t off = 0;
|
||||
ssize_t rd;
|
||||
@@ -195,105 +225,11 @@ OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st,
|
||||
return produced;
|
||||
}
|
||||
|
||||
static enum xer_pbd_rval
|
||||
OBJECT_IDENTIFIER__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
const void *chunk_buf, size_t chunk_size) {
|
||||
OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
|
||||
const char *chunk_end = (const char *)chunk_buf + chunk_size;
|
||||
const char *endptr;
|
||||
asn_oid_arc_t s_arcs[10];
|
||||
asn_oid_arc_t *arcs = s_arcs;
|
||||
ssize_t num_arcs;
|
||||
ssize_t ret;
|
||||
|
||||
(void)td;
|
||||
|
||||
num_arcs = OBJECT_IDENTIFIER_parse_arcs(
|
||||
(const char *)chunk_buf, chunk_size, arcs,
|
||||
sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr);
|
||||
if(num_arcs < 0) {
|
||||
/* Expecting more than zero arcs */
|
||||
return XPBD_BROKEN_ENCODING;
|
||||
} else if(num_arcs == 0) {
|
||||
return XPBD_NOT_BODY_IGNORE;
|
||||
}
|
||||
assert(endptr == chunk_end);
|
||||
|
||||
if((size_t)num_arcs > sizeof(s_arcs)/sizeof(s_arcs[0])) {
|
||||
arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(asn_oid_arc_t));
|
||||
if(!arcs) return XPBD_SYSTEM_FAILURE;
|
||||
ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size,
|
||||
arcs, num_arcs, &endptr);
|
||||
if(ret != num_arcs)
|
||||
return XPBD_SYSTEM_FAILURE; /* assert?.. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert arcs into BER representation.
|
||||
*/
|
||||
ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, num_arcs);
|
||||
if(arcs != s_arcs) FREEMEM(arcs);
|
||||
|
||||
return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
OBJECT_IDENTIFIER_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const char *opt_mname, const void *buf_ptr,
|
||||
size_t size) {
|
||||
return xer_decode_primitive(opt_codec_ctx, td,
|
||||
sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,
|
||||
buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode);
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
OBJECT_IDENTIFIER_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, enum xer_encoder_flags_e flags,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
|
||||
(void)ilevel;
|
||||
(void)flags;
|
||||
|
||||
if(!st || !st->buf) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
|
||||
if(er.encoded < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
int
|
||||
OBJECT_IDENTIFIER_print(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, asn_app_consume_bytes_f *cb,
|
||||
void *app_key) {
|
||||
const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(!st || !st->buf)
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
|
||||
/* Dump preamble */
|
||||
if(cb("{ ", 2, app_key) < 0)
|
||||
return -1;
|
||||
|
||||
if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (cb(" }", 2, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *st, asn_oid_arc_t *arcs,
|
||||
size_t arc_slots) {
|
||||
asn_oid_arc_t arc0, arc1;
|
||||
asn_oid_arc_t arc0 = 0;
|
||||
asn_oid_arc_t arc1 = 0;
|
||||
size_t num_arcs = 0;
|
||||
size_t off;
|
||||
ssize_t rd;
|
||||
@@ -588,69 +524,3 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
|
||||
errno = EINVAL; /* Broken OID */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate values from the list of interesting values, or just a random
|
||||
* value up to the upper limit.
|
||||
*/
|
||||
static asn_oid_arc_t
|
||||
OBJECT_IDENTIFIER__biased_random_arc(asn_oid_arc_t upper_bound) {
|
||||
const asn_oid_arc_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
|
||||
size_t idx;
|
||||
|
||||
switch(asn_random_between(0, 2)) {
|
||||
case 0:
|
||||
idx = asn_random_between(0, sizeof(values) / sizeof(values[0]) - 1);
|
||||
if(values[idx] < upper_bound) {
|
||||
return values[idx];
|
||||
}
|
||||
/* Fall through */
|
||||
case 1:
|
||||
return asn_random_between(0, upper_bound);
|
||||
case 2:
|
||||
default:
|
||||
return upper_bound;
|
||||
}
|
||||
}
|
||||
|
||||
asn_random_fill_result_t
|
||||
OBJECT_IDENTIFIER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
OBJECT_IDENTIFIER_t *st;
|
||||
asn_oid_arc_t arcs[5];
|
||||
size_t arcs_len = asn_random_between(2, 5);
|
||||
size_t i;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
if(max_length < arcs_len) return result_skipped;
|
||||
|
||||
if(*sptr) {
|
||||
st = *sptr;
|
||||
} else {
|
||||
st = CALLOC(1, sizeof(*st));
|
||||
}
|
||||
|
||||
arcs[0] = asn_random_between(0, 2);
|
||||
arcs[1] = OBJECT_IDENTIFIER__biased_random_arc(
|
||||
arcs[0] <= 1 ? 39 : (ASN_OID_ARC_MAX - 80));
|
||||
for(i = 2; i < arcs_len; i++) {
|
||||
arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(ASN_OID_ARC_MAX);
|
||||
}
|
||||
|
||||
if(OBJECT_IDENTIFIER_set_arcs(st, arcs, arcs_len)) {
|
||||
if(st != *sptr) {
|
||||
ASN_STRUCT_FREE(*td, st);
|
||||
}
|
||||
return result_failed;
|
||||
}
|
||||
|
||||
*sptr = st;
|
||||
|
||||
result_ok.length = st->size;
|
||||
return result_ok;
|
||||
}
|
||||
|
||||
@@ -21,23 +21,47 @@ typedef ASN__PRIMITIVE_TYPE_t OBJECT_IDENTIFIER_t;
|
||||
extern asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER;
|
||||
extern asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER;
|
||||
|
||||
ssize_t OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st,
|
||||
asn_app_consume_bytes_f *cb,
|
||||
void *app_key);
|
||||
|
||||
#define OBJECT_IDENTIFIER_free ASN__PRIMITIVE_TYPE_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f OBJECT_IDENTIFIER_print;
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define OBJECT_IDENTIFIER_compare OCTET_STRING_compare
|
||||
|
||||
asn_constr_check_f OBJECT_IDENTIFIER_constraint;
|
||||
der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define OBJECT_IDENTIFIER_decode_ber ber_decode_primitive
|
||||
#define OBJECT_IDENTIFIER_encode_der der_encode_primitive
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
xer_type_decoder_f OBJECT_IDENTIFIER_decode_xer;
|
||||
xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
|
||||
asn_random_fill_f OBJECT_IDENTIFIER_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#define OBJECT_IDENTIFIER_free ASN__PRIMITIVE_TYPE_free
|
||||
#define OBJECT_IDENTIFIER_compare OCTET_STRING_compare
|
||||
#define OBJECT_IDENTIFIER_decode_ber ber_decode_primitive
|
||||
#define OBJECT_IDENTIFIER_encode_der der_encode_primitive
|
||||
#define OBJECT_IDENTIFIER_decode_oer oer_decode_primitive
|
||||
#define OBJECT_IDENTIFIER_encode_oer oer_encode_primitive
|
||||
#define OBJECT_IDENTIFIER_decode_uper OCTET_STRING_decode_uper
|
||||
#define OBJECT_IDENTIFIER_encode_uper OCTET_STRING_encode_uper
|
||||
#define OBJECT_IDENTIFIER_decode_aper OCTET_STRING_decode_aper
|
||||
#define OBJECT_IDENTIFIER_encode_aper OCTET_STRING_encode_aper
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
#define OBJECT_IDENTIFIER_decode_oer oer_decode_primitive
|
||||
#define OBJECT_IDENTIFIER_encode_oer oer_encode_primitive
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
#define OBJECT_IDENTIFIER_decode_uper OCTET_STRING_decode_uper
|
||||
#define OBJECT_IDENTIFIER_encode_uper OCTET_STRING_encode_uper
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#define OBJECT_IDENTIFIER_decode_aper OCTET_STRING_decode_aper
|
||||
#define OBJECT_IDENTIFIER_encode_aper OCTET_STRING_encode_aper
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f OBJECT_IDENTIFIER_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
/**********************************
|
||||
* Some handy conversion routines *
|
||||
|
||||
30
lib/asn1c/common/OBJECT_IDENTIFIER_print.c
Normal file
30
lib/asn1c/common/OBJECT_IDENTIFIER_print.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <OBJECT_IDENTIFIER.h>
|
||||
|
||||
int
|
||||
OBJECT_IDENTIFIER_print(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, asn_app_consume_bytes_f *cb,
|
||||
void *app_key) {
|
||||
const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(!st || !st->buf)
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
|
||||
/* Dump preamble */
|
||||
if(cb("{ ", 2, app_key) < 0)
|
||||
return -1;
|
||||
|
||||
if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (cb(" }", 2, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
73
lib/asn1c/common/OBJECT_IDENTIFIER_rfill.c
Normal file
73
lib/asn1c/common/OBJECT_IDENTIFIER_rfill.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <OBJECT_IDENTIFIER.h>
|
||||
|
||||
/*
|
||||
* Generate values from the list of interesting values, or just a random
|
||||
* value up to the upper limit.
|
||||
*/
|
||||
static asn_oid_arc_t
|
||||
OBJECT_IDENTIFIER__biased_random_arc(asn_oid_arc_t upper_bound) {
|
||||
const asn_oid_arc_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
|
||||
size_t idx;
|
||||
|
||||
switch(asn_random_between(0, 2)) {
|
||||
case 0:
|
||||
idx = asn_random_between(0, sizeof(values) / sizeof(values[0]) - 1);
|
||||
if(values[idx] < upper_bound) {
|
||||
return values[idx];
|
||||
}
|
||||
/* Fall through */
|
||||
case 1:
|
||||
return asn_random_between(0, upper_bound);
|
||||
case 2:
|
||||
default:
|
||||
return upper_bound;
|
||||
}
|
||||
}
|
||||
|
||||
asn_random_fill_result_t
|
||||
OBJECT_IDENTIFIER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
OBJECT_IDENTIFIER_t *st;
|
||||
asn_oid_arc_t arcs[5];
|
||||
size_t arcs_len = asn_random_between(2, 5);
|
||||
size_t i;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
if(max_length < arcs_len) return result_skipped;
|
||||
|
||||
if(*sptr) {
|
||||
st = *sptr;
|
||||
} else {
|
||||
st = CALLOC(1, sizeof(*st));
|
||||
}
|
||||
|
||||
arcs[0] = asn_random_between(0, 2);
|
||||
arcs[1] = OBJECT_IDENTIFIER__biased_random_arc(
|
||||
arcs[0] <= 1 ? 39 : (ASN_OID_ARC_MAX - 80));
|
||||
for(i = 2; i < arcs_len; i++) {
|
||||
arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(ASN_OID_ARC_MAX);
|
||||
}
|
||||
|
||||
if(OBJECT_IDENTIFIER_set_arcs(st, arcs, arcs_len)) {
|
||||
if(st != *sptr) {
|
||||
ASN_STRUCT_FREE(*td, st);
|
||||
}
|
||||
return result_failed;
|
||||
}
|
||||
|
||||
*sptr = st;
|
||||
|
||||
result_ok.length = st->size;
|
||||
return result_ok;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,27 +22,68 @@ extern asn_TYPE_descriptor_t asn_DEF_OCTET_STRING;
|
||||
extern asn_TYPE_operation_t asn_OP_OCTET_STRING;
|
||||
|
||||
asn_struct_free_f OCTET_STRING_free;
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f OCTET_STRING_print;
|
||||
asn_struct_print_f OCTET_STRING_print_utf8;
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
asn_struct_compare_f OCTET_STRING_compare;
|
||||
|
||||
#define OCTET_STRING_constraint asn_generic_no_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
ber_type_decoder_f OCTET_STRING_decode_ber;
|
||||
der_type_encoder_f OCTET_STRING_encode_der;
|
||||
xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */
|
||||
xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */
|
||||
xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */
|
||||
xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */
|
||||
xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
|
||||
xer_type_encoder_f OCTET_STRING_encode_xer;
|
||||
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
oer_type_decoder_f OCTET_STRING_decode_oer;
|
||||
oer_type_encoder_f OCTET_STRING_encode_oer;
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f OCTET_STRING_decode_uper;
|
||||
per_type_encoder_f OCTET_STRING_encode_uper;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
per_type_decoder_f OCTET_STRING_decode_aper;
|
||||
per_type_encoder_f OCTET_STRING_encode_aper;
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f OCTET_STRING_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
#define OCTET_STRING_constraint asn_generic_no_constraint
|
||||
#define OCTET_STRING_decode_xer OCTET_STRING_decode_xer_hex
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
int OCTET_STRING_per_get_characters(
|
||||
asn_per_data_t *po,
|
||||
uint8_t *buf,
|
||||
size_t units,
|
||||
unsigned int bpc,
|
||||
unsigned int unit_bits,
|
||||
long lb,
|
||||
long ub,
|
||||
const asn_per_constraints_t *pc);
|
||||
|
||||
int OCTET_STRING_per_put_characters(
|
||||
asn_per_outp_t *po,
|
||||
const uint8_t *buf,
|
||||
size_t units,
|
||||
unsigned int bpc,
|
||||
unsigned int unit_bits,
|
||||
long lb,
|
||||
long ub,
|
||||
const asn_per_constraints_t *pc);
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
/******************************
|
||||
* Handy conversion routines. *
|
||||
******************************/
|
||||
@@ -95,6 +136,23 @@ size_t OCTET_STRING_random_length_constrained(
|
||||
const asn_TYPE_descriptor_t *, const asn_encoding_constraints_t *,
|
||||
size_t max_length);
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
struct _stack_el {
|
||||
ber_tlv_len_t left; /* What's left to read (or -1) */
|
||||
ber_tlv_len_t got; /* What was actually processed */
|
||||
unsigned cont_level; /* Depth of subcontainment */
|
||||
int want_nulls; /* Want null "end of content" octets? */
|
||||
int bits_chopped; /* Flag in BIT STRING mode */
|
||||
ber_tlv_tag_t tag; /* For debugging purposes */
|
||||
struct _stack_el *prev;
|
||||
struct _stack_el *next;
|
||||
};
|
||||
struct _stack {
|
||||
struct _stack_el *tail;
|
||||
struct _stack_el *cur_ptr;
|
||||
};
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
412
lib/asn1c/common/OCTET_STRING_aper.c
Normal file
412
lib/asn1c/common/OCTET_STRING_aper.c
Normal file
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <OCTET_STRING.h>
|
||||
#include <BIT_STRING.h> /* for .bits_unused member */
|
||||
|
||||
#undef RETURN
|
||||
#define RETURN(_code) do {\
|
||||
asn_dec_rval_t tmprval;\
|
||||
tmprval.code = _code;\
|
||||
tmprval.consumed = consumed_myself;\
|
||||
return tmprval;\
|
||||
} while(0)
|
||||
|
||||
static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
|
||||
{ APC_CONSTRAINED, 8, 8, 0, 255 },
|
||||
{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
|
||||
0, 0
|
||||
};
|
||||
|
||||
asn_dec_rval_t
|
||||
OCTET_STRING_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
void **sptr, asn_per_data_t *pd) {
|
||||
|
||||
const asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_OCTET_STRING_specs;
|
||||
const asn_per_constraints_t *pc = constraints
|
||||
? constraints
|
||||
: td->encoding_constraints.per_constraints;
|
||||
const asn_per_constraint_t *cval;
|
||||
const asn_per_constraint_t *csiz;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
|
||||
ssize_t consumed_myself = 0;
|
||||
int repeat;
|
||||
enum {
|
||||
OS__BPC_BIT = 0,
|
||||
OS__BPC_CHAR = 1,
|
||||
OS__BPC_U16 = 2,
|
||||
OS__BPC_U32 = 4
|
||||
} bpc; /* Bytes per character */
|
||||
unsigned int unit_bits;
|
||||
unsigned int canonical_unit_bits;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(pc) {
|
||||
cval = &pc->value;
|
||||
csiz = &pc->size;
|
||||
} else {
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
}
|
||||
|
||||
switch(specs->subvariant) {
|
||||
default:
|
||||
/*
|
||||
case ASN_OSUBV_ANY:
|
||||
ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
|
||||
RETURN(RC_FAIL);
|
||||
*/
|
||||
case ASN_OSUBV_BIT:
|
||||
canonical_unit_bits = unit_bits = 1;
|
||||
bpc = OS__BPC_BIT;
|
||||
break;
|
||||
case ASN_OSUBV_ANY:
|
||||
case ASN_OSUBV_STR:
|
||||
canonical_unit_bits = unit_bits = 8;
|
||||
/*
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
*/
|
||||
bpc = OS__BPC_CHAR;
|
||||
break;
|
||||
case ASN_OSUBV_U16:
|
||||
canonical_unit_bits = unit_bits = 16;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U16;
|
||||
break;
|
||||
case ASN_OSUBV_U32:
|
||||
canonical_unit_bits = unit_bits = 32;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U32;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the string.
|
||||
*/
|
||||
if(!st) {
|
||||
st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
|
||||
csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
|
||||
csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
|
||||
|
||||
if(csiz->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) RETURN(RC_WMORE);
|
||||
if(inext) {
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
unit_bits = canonical_unit_bits;
|
||||
}
|
||||
}
|
||||
|
||||
if(csiz->effective_bits >= 0) {
|
||||
FREEMEM(st->buf);
|
||||
if(bpc) {
|
||||
st->size = csiz->upper_bound * bpc;
|
||||
} else {
|
||||
st->size = (csiz->upper_bound + 7) >> 3;
|
||||
}
|
||||
st->buf = (uint8_t *)MALLOC(st->size + 1);
|
||||
if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
|
||||
}
|
||||
|
||||
/* X.691, #16.5: zero-length encoding */
|
||||
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
|
||||
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
|
||||
if(csiz->effective_bits == 0) {
|
||||
int ret;
|
||||
/* X.691 #16 NOTE 1 for fixed length (<= 16 bits) strings */
|
||||
if (st->size > 2 || csiz->range_bits != 0) {
|
||||
if (aper_get_align(pd) < 0)
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
if(bpc) {
|
||||
ASN_DEBUG("Decoding OCTET STRING size %ld",
|
||||
csiz->upper_bound);
|
||||
ret = OCTET_STRING_per_get_characters(pd, st->buf,
|
||||
csiz->upper_bound,
|
||||
bpc, unit_bits,
|
||||
cval->lower_bound,
|
||||
cval->upper_bound,
|
||||
pc);
|
||||
if(ret > 0) RETURN(RC_FAIL);
|
||||
} else {
|
||||
ASN_DEBUG("Decoding BIT STRING size %ld",
|
||||
csiz->upper_bound);
|
||||
ret = per_get_many_bits(pd, st->buf, 0,
|
||||
unit_bits * csiz->upper_bound);
|
||||
}
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
consumed_myself += unit_bits * csiz->upper_bound;
|
||||
st->buf[st->size] = 0;
|
||||
if(bpc == 0) {
|
||||
int ubs = (csiz->upper_bound & 0x7);
|
||||
st->bits_unused = ubs ? 8 - ubs : 0;
|
||||
}
|
||||
RETURN(RC_OK);
|
||||
}
|
||||
|
||||
st->size = 0;
|
||||
do {
|
||||
ssize_t raw_len;
|
||||
ssize_t len_bytes;
|
||||
ssize_t len_bits;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
repeat = 0;
|
||||
/* Get the PER length */
|
||||
if (csiz->upper_bound - csiz->lower_bound == 0)
|
||||
/* Indefinite length case */
|
||||
raw_len = aper_get_length(pd, -1, csiz->effective_bits, &repeat);
|
||||
else
|
||||
raw_len = aper_get_length(pd, csiz->upper_bound - csiz->lower_bound + 1, csiz->effective_bits, &repeat);
|
||||
if(raw_len < 0) RETURN(RC_WMORE);
|
||||
raw_len += csiz->lower_bound;
|
||||
|
||||
ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
|
||||
(long)csiz->effective_bits, (long)raw_len,
|
||||
repeat ? "repeat" : "once", td->name);
|
||||
|
||||
/* X.691 #16 NOTE 1 for fixed length (<=16 bits) strings */
|
||||
if ((raw_len > 2) || (csiz->upper_bound > 2) || (csiz->range_bits != 0))
|
||||
{
|
||||
if (aper_get_align(pd) < 0)
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
if(bpc) {
|
||||
len_bytes = raw_len * bpc;
|
||||
len_bits = len_bytes * unit_bits;
|
||||
} else {
|
||||
len_bits = raw_len;
|
||||
len_bytes = (len_bits + 7) >> 3;
|
||||
if(len_bits & 0x7)
|
||||
st->bits_unused = 8 - (len_bits & 0x7);
|
||||
/* len_bits be multiple of 16K if repeat is set */
|
||||
}
|
||||
p = REALLOC(st->buf, st->size + len_bytes + 1);
|
||||
if(!p) RETURN(RC_FAIL);
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
if(bpc) {
|
||||
ret = OCTET_STRING_per_get_characters(pd,
|
||||
&st->buf[st->size],
|
||||
raw_len, bpc,
|
||||
unit_bits,
|
||||
cval->lower_bound,
|
||||
cval->upper_bound,
|
||||
pc);
|
||||
if(ret > 0) RETURN(RC_FAIL);
|
||||
} else {
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size],
|
||||
0, len_bits);
|
||||
}
|
||||
if(ret < 0) RETURN(RC_WMORE);
|
||||
st->size += len_bytes;
|
||||
} while(repeat);
|
||||
st->buf[st->size] = 0; /* nul-terminate */
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
OCTET_STRING_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
|
||||
const asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_OCTET_STRING_specs;
|
||||
const asn_per_constraints_t *pc = constraints
|
||||
? constraints
|
||||
: td->encoding_constraints.per_constraints;
|
||||
const asn_per_constraint_t *cval;
|
||||
const asn_per_constraint_t *csiz;
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
asn_enc_rval_t er = { 0, 0, 0 };
|
||||
int inext = 0; /* Lies not within extension root */
|
||||
unsigned int unit_bits;
|
||||
unsigned int canonical_unit_bits;
|
||||
unsigned int sizeinunits;
|
||||
const uint8_t *buf;
|
||||
int ret;
|
||||
enum {
|
||||
OS__BPC_BIT = 0,
|
||||
OS__BPC_CHAR = 1,
|
||||
OS__BPC_U16 = 2,
|
||||
OS__BPC_U32 = 4
|
||||
} bpc; /* Bytes per character */
|
||||
int ct_extensible;
|
||||
|
||||
if(!st || (!st->buf && st->size))
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
if(pc) {
|
||||
cval = &pc->value;
|
||||
csiz = &pc->size;
|
||||
} else {
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
}
|
||||
ct_extensible = csiz->flags & APC_EXTENSIBLE;
|
||||
|
||||
switch(specs->subvariant) {
|
||||
default:
|
||||
/*
|
||||
case ASN_OSUBV_ANY:
|
||||
ASN__ENCODE_FAILED;
|
||||
*/
|
||||
case ASN_OSUBV_BIT:
|
||||
canonical_unit_bits = unit_bits = 1;
|
||||
bpc = OS__BPC_BIT;
|
||||
sizeinunits = st->size * 8 - (st->bits_unused & 0x07);
|
||||
ASN_DEBUG("BIT STRING of %d bytes",
|
||||
sizeinunits);
|
||||
break;
|
||||
case ASN_OSUBV_ANY:
|
||||
case ASN_OSUBV_STR:
|
||||
canonical_unit_bits = unit_bits = 8;
|
||||
/*
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = 8;
|
||||
*/
|
||||
bpc = OS__BPC_CHAR;
|
||||
sizeinunits = st->size;
|
||||
break;
|
||||
case ASN_OSUBV_U16:
|
||||
canonical_unit_bits = unit_bits = 16;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U16;
|
||||
sizeinunits = st->size / 2;
|
||||
break;
|
||||
case ASN_OSUBV_U32:
|
||||
canonical_unit_bits = unit_bits = 32;
|
||||
if(cval->flags & APC_CONSTRAINED)
|
||||
unit_bits = cval->range_bits;
|
||||
bpc = OS__BPC_U32;
|
||||
sizeinunits = st->size / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %s into %d units of %d bits"
|
||||
" (%ld..%ld, effective %d)%s",
|
||||
td->name, sizeinunits, unit_bits,
|
||||
csiz->lower_bound, csiz->upper_bound,
|
||||
csiz->effective_bits, ct_extensible ? " EXT" : "");
|
||||
|
||||
/* Figure out wheter size lies within PER visible constraint */
|
||||
|
||||
if(csiz->effective_bits >= 0) {
|
||||
if((int)sizeinunits < csiz->lower_bound
|
||||
|| (int)sizeinunits > csiz->upper_bound) {
|
||||
if(ct_extensible) {
|
||||
cval = &asn_DEF_OCTET_STRING_constraints.value;
|
||||
csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
||||
unit_bits = canonical_unit_bits;
|
||||
inext = 1;
|
||||
} else
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
} else {
|
||||
inext = 0;
|
||||
}
|
||||
|
||||
if(ct_extensible) {
|
||||
/* Declare whether length is [not] within extension root */
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
/* X.691, #16.5: zero-length encoding */
|
||||
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
|
||||
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
|
||||
if(csiz->effective_bits >= 0) {
|
||||
ASN_DEBUG("Encoding %lu bytes (%ld), length in %d bits",
|
||||
st->size, sizeinunits - csiz->lower_bound,
|
||||
csiz->effective_bits);
|
||||
if (csiz->effective_bits > 0) {
|
||||
ret = aper_put_length(po,
|
||||
csiz->upper_bound - csiz->lower_bound + 1,
|
||||
sizeinunits - csiz->lower_bound, 0);
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
}
|
||||
if (csiz->effective_bits > 0 || (st->size > 2)
|
||||
|| (csiz->upper_bound > (2 * 8 / unit_bits))
|
||||
|| (csiz->range_bits != 0))
|
||||
{ /* X.691 #16 NOTE 1 for fixed length (<=16 bits) strings*/
|
||||
if (aper_put_align(po) < 0)
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
if(bpc) {
|
||||
ret = OCTET_STRING_per_put_characters(po, st->buf,
|
||||
sizeinunits,
|
||||
bpc, unit_bits,
|
||||
cval->lower_bound,
|
||||
cval->upper_bound,
|
||||
pc);
|
||||
} else {
|
||||
ret = per_put_many_bits(po, st->buf,
|
||||
sizeinunits * unit_bits);
|
||||
}
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %lu bytes", st->size);
|
||||
|
||||
if(sizeinunits == 0) {
|
||||
if(aper_put_length(po, -1, 0, 0))
|
||||
ASN__ENCODE_FAILED;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
buf = st->buf;
|
||||
while(sizeinunits) {
|
||||
int need_eom = 0;
|
||||
ssize_t maySave = aper_put_length(po, -1, sizeinunits, &need_eom);
|
||||
|
||||
if(maySave < 0) ASN__ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Encoding %ld of %ld",
|
||||
(long)maySave, (long)sizeinunits);
|
||||
|
||||
if(bpc) {
|
||||
ret = OCTET_STRING_per_put_characters(po, buf, maySave,
|
||||
bpc, unit_bits,
|
||||
cval->lower_bound,
|
||||
cval->upper_bound,
|
||||
pc);
|
||||
} else {
|
||||
ret = per_put_many_bits(po, buf, maySave * unit_bits);
|
||||
}
|
||||
if(ret) ASN__ENCODE_FAILED;
|
||||
|
||||
if(bpc)
|
||||
buf += maySave * bpc;
|
||||
else
|
||||
buf += maySave >> 3;
|
||||
sizeinunits -= maySave;
|
||||
assert(!(maySave & 0x07) || !sizeinunits);
|
||||
if(need_eom && aper_put_length(po, -1, 0, 0))
|
||||
ASN__ENCODE_FAILED; /* End of Message length */
|
||||
}
|
||||
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
65
lib/asn1c/common/OCTET_STRING_print.c
Normal file
65
lib/asn1c/common/OCTET_STRING_print.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
int
|
||||
OCTET_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const char * const h2c = "0123456789ABCDEF";
|
||||
const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
|
||||
char scratch[16 * 3 + 4];
|
||||
char *p = scratch;
|
||||
uint8_t *buf;
|
||||
uint8_t *end;
|
||||
size_t i;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
|
||||
if(!st || (!st->buf && st->size))
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
|
||||
/*
|
||||
* Dump the contents of the buffer in hexadecimal.
|
||||
*/
|
||||
buf = st->buf;
|
||||
end = buf + st->size;
|
||||
for(i = 0; buf < end; buf++, i++) {
|
||||
if(!(i % 16) && (i || st->size > 16)) {
|
||||
if(cb(scratch, p - scratch, app_key) < 0)
|
||||
return -1;
|
||||
_i_INDENT(1);
|
||||
p = scratch;
|
||||
}
|
||||
*p++ = h2c[(*buf >> 4) & 0x0F];
|
||||
*p++ = h2c[*buf & 0x0F];
|
||||
*p++ = 0x20;
|
||||
}
|
||||
|
||||
if(p > scratch) {
|
||||
p--; /* Remove the tail space */
|
||||
if(cb(scratch, p - scratch, app_key) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
OCTET_STRING_print_utf8(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int ilevel, asn_app_consume_bytes_f *cb,
|
||||
void *app_key) {
|
||||
const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(st && (st->buf || !st->size)) {
|
||||
return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
209
lib/asn1c/common/OCTET_STRING_rfill.c
Normal file
209
lib/asn1c/common/OCTET_STRING_rfill.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
/*
|
||||
* Biased function for randomizing character values around their limits.
|
||||
*/
|
||||
static uint32_t
|
||||
OCTET_STRING__random_char(unsigned long lb, unsigned long ub) {
|
||||
assert(lb <= ub);
|
||||
switch(asn_random_between(0, 16)) {
|
||||
case 0:
|
||||
if(lb < ub) return lb + 1;
|
||||
/* Fall through */
|
||||
case 1:
|
||||
return lb;
|
||||
case 2:
|
||||
if(lb < ub) return ub - 1;
|
||||
/* Fall through */
|
||||
case 3:
|
||||
return ub;
|
||||
default:
|
||||
return asn_random_between(lb, ub);
|
||||
}
|
||||
}
|
||||
|
||||
asn_random_fill_result_t
|
||||
OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
const asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? (const asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_SPC_OCTET_STRING_specs;
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
unsigned int unit_bytes = 1;
|
||||
unsigned long clb = 0; /* Lower bound on char */
|
||||
unsigned long cub = 255; /* Higher bound on char value */
|
||||
uint8_t *buf;
|
||||
uint8_t *bend;
|
||||
uint8_t *b;
|
||||
size_t rnd_len;
|
||||
OCTET_STRING_t *st;
|
||||
|
||||
if(max_length == 0 && !*sptr) return result_skipped;
|
||||
|
||||
switch(specs->subvariant) {
|
||||
default:
|
||||
case ASN_OSUBV_ANY:
|
||||
return result_failed;
|
||||
case ASN_OSUBV_BIT:
|
||||
/* Handled by BIT_STRING itself. */
|
||||
return result_failed;
|
||||
case ASN_OSUBV_STR:
|
||||
unit_bytes = 1;
|
||||
clb = 0;
|
||||
cub = 255;
|
||||
break;
|
||||
case ASN_OSUBV_U16:
|
||||
unit_bytes = 2;
|
||||
clb = 0;
|
||||
cub = 65535;
|
||||
break;
|
||||
case ASN_OSUBV_U32:
|
||||
unit_bytes = 4;
|
||||
clb = 0;
|
||||
cub = 0x10FFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
if(!constraints || !constraints->per_constraints)
|
||||
constraints = &td->encoding_constraints;
|
||||
if(constraints->per_constraints) {
|
||||
const asn_per_constraint_t *pc = &constraints->per_constraints->value;
|
||||
if(pc->flags & APC_SEMI_CONSTRAINED) {
|
||||
clb = pc->lower_bound;
|
||||
} else if(pc->flags & APC_CONSTRAINED) {
|
||||
clb = pc->lower_bound;
|
||||
cub = pc->upper_bound;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(!constraints) constraints = &td->encoding_constraints;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
rnd_len =
|
||||
OCTET_STRING_random_length_constrained(td, constraints, max_length);
|
||||
|
||||
buf = CALLOC(unit_bytes, rnd_len + 1);
|
||||
if(!buf) return result_failed;
|
||||
|
||||
bend = &buf[unit_bytes * rnd_len];
|
||||
|
||||
switch(unit_bytes) {
|
||||
case 1:
|
||||
for(b = buf; b < bend; b += unit_bytes) {
|
||||
*(uint8_t *)b = OCTET_STRING__random_char(clb, cub);
|
||||
}
|
||||
*(uint8_t *)b = 0;
|
||||
break;
|
||||
case 2:
|
||||
for(b = buf; b < bend; b += unit_bytes) {
|
||||
uint32_t code = OCTET_STRING__random_char(clb, cub);
|
||||
b[0] = code >> 8;
|
||||
b[1] = code;
|
||||
}
|
||||
*(uint16_t *)b = 0;
|
||||
break;
|
||||
case 4:
|
||||
for(b = buf; b < bend; b += unit_bytes) {
|
||||
uint32_t code = OCTET_STRING__random_char(clb, cub);
|
||||
b[0] = code >> 24;
|
||||
b[1] = code >> 16;
|
||||
b[2] = code >> 8;
|
||||
b[3] = code;
|
||||
}
|
||||
*(uint32_t *)b = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(*sptr) {
|
||||
st = *sptr;
|
||||
FREEMEM(st->buf);
|
||||
} else {
|
||||
st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
|
||||
if(!st) {
|
||||
FREEMEM(buf);
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
st->buf = buf;
|
||||
st->size = unit_bytes * rnd_len;
|
||||
|
||||
result_ok.length = st->size;
|
||||
return result_ok;
|
||||
}
|
||||
|
||||
size_t
|
||||
OCTET_STRING_random_length_constrained(
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_encoding_constraints_t *constraints, size_t max_length) {
|
||||
const unsigned lengths[] = {0, 1, 2, 3, 4, 8,
|
||||
126, 127, 128, 16383, 16384, 16385,
|
||||
65534, 65535, 65536, 65537};
|
||||
size_t rnd_len;
|
||||
|
||||
/* Figure out how far we should go */
|
||||
rnd_len = lengths[asn_random_between(
|
||||
0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
if(!constraints || !constraints->per_constraints)
|
||||
constraints = &td->encoding_constraints;
|
||||
if(constraints->per_constraints) {
|
||||
const asn_per_constraint_t *pc = &constraints->per_constraints->size;
|
||||
if(pc->flags & APC_CONSTRAINED) {
|
||||
long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
|
||||
? pc->upper_bound
|
||||
: (ssize_t)max_length;
|
||||
if(max_length <= (size_t)pc->lower_bound) {
|
||||
return pc->lower_bound;
|
||||
}
|
||||
if(pc->flags & APC_EXTENSIBLE) {
|
||||
switch(asn_random_between(0, 5)) {
|
||||
case 0:
|
||||
if(pc->lower_bound > 0) {
|
||||
rnd_len = pc->lower_bound - 1;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case 1:
|
||||
rnd_len = pc->upper_bound + 1;
|
||||
break;
|
||||
case 2:
|
||||
/* Keep rnd_len from the table */
|
||||
if(rnd_len <= max_length) {
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
rnd_len = asn_random_between(pc->lower_bound,
|
||||
suggested_upper_bound);
|
||||
}
|
||||
} else {
|
||||
rnd_len =
|
||||
asn_random_between(pc->lower_bound, suggested_upper_bound);
|
||||
}
|
||||
} else {
|
||||
rnd_len = asn_random_between(0, max_length);
|
||||
}
|
||||
} else {
|
||||
#else
|
||||
if(!constraints) constraints = &td->encoding_constraints;
|
||||
{
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
if(rnd_len > max_length) {
|
||||
rnd_len = asn_random_between(0, max_length);
|
||||
}
|
||||
}
|
||||
|
||||
return rnd_len;
|
||||
}
|
||||
@@ -5,505 +5,54 @@
|
||||
#include <asn_internal.h>
|
||||
#include <OPEN_TYPE.h>
|
||||
#include <constr_CHOICE.h>
|
||||
#include <per_opentype.h>
|
||||
#include <errno.h>
|
||||
|
||||
asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
|
||||
OPEN_TYPE_free,
|
||||
OPEN_TYPE_print,
|
||||
OPEN_TYPE_compare,
|
||||
OPEN_TYPE_decode_ber,
|
||||
OPEN_TYPE_encode_der,
|
||||
OPEN_TYPE_decode_xer,
|
||||
OPEN_TYPE_encode_xer,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0, 0, /* No OER support, use "-gen-OER" to enable */
|
||||
OPEN_TYPE_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
OPEN_TYPE_print,
|
||||
#else
|
||||
OPEN_TYPE_decode_oer,
|
||||
OPEN_TYPE_encode_oer,
|
||||
#endif
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0, 0, 0, 0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OPEN_TYPE_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OPEN_TYPE_decode_ber,
|
||||
OPEN_TYPE_encode_der,
|
||||
#else
|
||||
OPEN_TYPE_decode_uper,
|
||||
OPEN_TYPE_encode_uper,
|
||||
OPEN_TYPE_decode_aper,
|
||||
OPEN_TYPE_encode_aper,
|
||||
#endif
|
||||
0, /* Random fill is not supported for open type */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OPEN_TYPE_decode_xer,
|
||||
OPEN_TYPE_encode_xer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
OPEN_TYPE_decode_oer,
|
||||
OPEN_TYPE_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
OPEN_TYPE_decode_uper,
|
||||
OPEN_TYPE_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OPEN_TYPE_decode_aper,
|
||||
OPEN_TYPE_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
0, /* Random fill is not supported for open type */
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
|
||||
#undef ADVANCE
|
||||
#define ADVANCE(num_bytes) \
|
||||
do { \
|
||||
size_t num = num_bytes; \
|
||||
ptr = ((const char *)ptr) + num; \
|
||||
size -= num; \
|
||||
consumed_myself += num; \
|
||||
} while(0)
|
||||
|
||||
asn_dec_rval_t
|
||||
OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
|
||||
size_t consumed_myself = 0;
|
||||
asn_type_selector_result_t selected;
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
void *inner_value;
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
if(!(elm->flags & ATF_OPEN_TYPE)) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(!elm->type_selector) {
|
||||
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
|
||||
td->name, elm->name, elm->type->name);
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
selected = elm->type_selector(td, sptr);
|
||||
if(!selected.presence_index) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
if(*memb_ptr2 != NULL) {
|
||||
/* Make sure we reset the structure first before encoding */
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
inner_value =
|
||||
(char *)*memb_ptr2
|
||||
+ elm->type->elements[selected.presence_index - 1].memb_offset;
|
||||
|
||||
ASN_DEBUG("presence %d\n", selected.presence_index);
|
||||
|
||||
rv = selected.type_descriptor->op->ber_decoder(
|
||||
opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
|
||||
elm->tag_mode);
|
||||
ADVANCE(rv.consumed);
|
||||
rv.consumed = 0;
|
||||
switch(rv.code) {
|
||||
case RC_OK:
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
|
||||
selected.presence_index)
|
||||
== 0) {
|
||||
rv.code = RC_OK;
|
||||
rv.consumed = consumed_myself;
|
||||
return rv;
|
||||
} else {
|
||||
/* Oh, now a full-blown failure failure */
|
||||
}
|
||||
/* Fall through */
|
||||
case RC_FAIL:
|
||||
rv.consumed = consumed_myself;
|
||||
/* Fall through */
|
||||
case RC_WMORE:
|
||||
break;
|
||||
}
|
||||
|
||||
if(*memb_ptr2) {
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
|
||||
*memb_ptr2 = NULL;
|
||||
} else {
|
||||
ASN_STRUCT_RESET(*selected.type_descriptor,
|
||||
inner_value);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
|
||||
size_t consumed_myself = 0;
|
||||
asn_type_selector_result_t selected;
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
void *inner_value;
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
int xer_context = 0;
|
||||
ssize_t ch_size;
|
||||
pxer_chunk_type_e ch_type;
|
||||
|
||||
if(!(elm->flags & ATF_OPEN_TYPE)) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(!elm->type_selector) {
|
||||
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
|
||||
td->name, elm->name, elm->type->name);
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
selected = elm->type_selector(td, sptr);
|
||||
if(!selected.presence_index) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
assert(elm->flags == ATF_OPEN_TYPE);
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
if(*memb_ptr2 != NULL) {
|
||||
/* Make sure we reset the structure first before encoding */
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
|
||||
!= 0) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Confirm wrapper.
|
||||
*/
|
||||
for(;;) {
|
||||
ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
|
||||
if(ch_size < 0) {
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
switch(ch_type) {
|
||||
case PXER_WMORE:
|
||||
ASN__DECODE_STARVED;
|
||||
case PXER_COMMENT:
|
||||
case PXER_TEXT:
|
||||
ADVANCE(ch_size);
|
||||
continue;
|
||||
case PXER_TAG:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper value confirmed.
|
||||
*/
|
||||
switch(xer_check_tag(ptr, ch_size, elm->name)) {
|
||||
case XCT_OPENING:
|
||||
ADVANCE(ch_size);
|
||||
break;
|
||||
case XCT_BROKEN:
|
||||
default:
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
inner_value =
|
||||
(char *)*memb_ptr2
|
||||
+ elm->type->elements[selected.presence_index - 1].memb_offset;
|
||||
|
||||
rv = selected.type_descriptor->op->xer_decoder(
|
||||
opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
|
||||
ADVANCE(rv.consumed);
|
||||
rv.consumed = 0;
|
||||
switch(rv.code) {
|
||||
case RC_OK:
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
|
||||
selected.presence_index)
|
||||
== 0) {
|
||||
break;
|
||||
} else {
|
||||
rv.code = RC_FAIL;
|
||||
}
|
||||
/* Fall through */
|
||||
case RC_FAIL:
|
||||
/* Point to a best position where failure occurred */
|
||||
rv.consumed = consumed_myself;
|
||||
/* Fall through */
|
||||
case RC_WMORE:
|
||||
/* Wrt. rv.consumed==0:
|
||||
* In case a genuine RC_WMORE, the whole Open Type decoding
|
||||
* will have to be restarted.
|
||||
*/
|
||||
if(*memb_ptr2) {
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
|
||||
*memb_ptr2 = NULL;
|
||||
} else {
|
||||
ASN_STRUCT_RESET(*selected.type_descriptor,
|
||||
inner_value);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize wrapper.
|
||||
*/
|
||||
for(;;) {
|
||||
ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
|
||||
if(ch_size < 0) {
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
switch(ch_type) {
|
||||
case PXER_WMORE:
|
||||
ASN__DECODE_STARVED;
|
||||
case PXER_COMMENT:
|
||||
case PXER_TEXT:
|
||||
ADVANCE(ch_size);
|
||||
continue;
|
||||
case PXER_TAG:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper value confirmed.
|
||||
*/
|
||||
switch(xer_check_tag(ptr, ch_size, elm->name)) {
|
||||
case XCT_CLOSING:
|
||||
ADVANCE(ch_size);
|
||||
break;
|
||||
case XCT_BROKEN:
|
||||
default:
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
rv.consumed += consumed_myself;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ASN_DISABLE_PER_SUPPORT
|
||||
|
||||
asn_dec_rval_t
|
||||
OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
|
||||
asn_type_selector_result_t selected;
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
void *inner_value;
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
if(!(elm->flags & ATF_OPEN_TYPE)) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(!elm->type_selector) {
|
||||
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
|
||||
td->name, elm->name, elm->type->name);
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
selected = elm->type_selector(td, sptr);
|
||||
if(!selected.presence_index) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
assert(elm->flags == ATF_OPEN_TYPE);
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
if(*memb_ptr2 != NULL) {
|
||||
/* Make sure we reset the structure first before encoding */
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
|
||||
!= 0) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
inner_value =
|
||||
(char *)*memb_ptr2
|
||||
+ elm->type->elements[selected.presence_index - 1].memb_offset;
|
||||
|
||||
rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
|
||||
&inner_value, pd);
|
||||
switch(rv.code) {
|
||||
case RC_OK:
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
|
||||
selected.presence_index)
|
||||
== 0) {
|
||||
break;
|
||||
} else {
|
||||
rv.code = RC_FAIL;
|
||||
}
|
||||
/* Fall through */
|
||||
case RC_WMORE:
|
||||
case RC_FAIL:
|
||||
if(*memb_ptr2) {
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
|
||||
*memb_ptr2 = NULL;
|
||||
} else {
|
||||
ASN_STRUCT_RESET(*selected.type_descriptor,
|
||||
inner_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const void *memb_ptr; /* Pointer to the member */
|
||||
asn_TYPE_member_t *elm; /* CHOICE's element */
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
unsigned present;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
present = CHOICE_variant_get_presence(td, sptr);
|
||||
if(present == 0 || present > td->elements_count) {
|
||||
ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
present--;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
|
||||
|
||||
elm = &td->elements[present];
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
memb_ptr =
|
||||
*(const void *const *)((const char *)sptr + elm->memb_offset);
|
||||
if(!memb_ptr) ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
memb_ptr = (const char *)sptr + elm->memb_offset;
|
||||
}
|
||||
|
||||
if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
er.encoded = 0;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
|
||||
asn_type_selector_result_t selected;
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
void *inner_value;
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
if(!(elm->flags & ATF_OPEN_TYPE)) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(!elm->type_selector) {
|
||||
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
|
||||
td->name, elm->name, elm->type->name);
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
selected = elm->type_selector(td, sptr);
|
||||
if(!selected.presence_index) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
assert(elm->flags == ATF_OPEN_TYPE);
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
if(*memb_ptr2 != NULL) {
|
||||
/* Make sure we reset the structure first before encoding */
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
|
||||
!= 0) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
inner_value =
|
||||
(char *)*memb_ptr2
|
||||
+ elm->type->elements[selected.presence_index - 1].memb_offset;
|
||||
|
||||
rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
|
||||
&inner_value, pd);
|
||||
switch(rv.code) {
|
||||
case RC_OK:
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
|
||||
selected.presence_index)
|
||||
== 0) {
|
||||
break;
|
||||
} else {
|
||||
rv.code = RC_FAIL;
|
||||
}
|
||||
/* Fall through */
|
||||
case RC_WMORE:
|
||||
case RC_FAIL:
|
||||
if(*memb_ptr2) {
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
|
||||
*memb_ptr2 = NULL;
|
||||
} else {
|
||||
ASN_STRUCT_RESET(*selected.type_descriptor,
|
||||
inner_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const void *memb_ptr; /* Pointer to the member */
|
||||
asn_TYPE_member_t *elm; /* CHOICE's element */
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
unsigned present;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
present = CHOICE_variant_get_presence(td, sptr);
|
||||
if(present == 0 || present > td->elements_count) {
|
||||
ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
present--;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
|
||||
|
||||
elm = &td->elements[present];
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
memb_ptr =
|
||||
*(const void *const *)((const char *)sptr + elm->memb_offset);
|
||||
if(!memb_ptr) ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
memb_ptr = (const char *)sptr + elm->memb_offset;
|
||||
}
|
||||
|
||||
if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
er.encoded = 0;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
|
||||
@@ -6,69 +6,97 @@
|
||||
#define ASN_OPEN_TYPE_H
|
||||
|
||||
#include <asn_application.h>
|
||||
///////////#include <per_support.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OPEN_TYPE_free CHOICE_free
|
||||
#define OPEN_TYPE_print CHOICE_print
|
||||
#define OPEN_TYPE_compare CHOICE_compare
|
||||
#define OPEN_TYPE_constraint CHOICE_constraint
|
||||
#define OPEN_TYPE_decode_ber NULL
|
||||
#define OPEN_TYPE_encode_der CHOICE_encode_der
|
||||
#define OPEN_TYPE_decode_xer NULL
|
||||
#define OPEN_TYPE_encode_xer CHOICE_encode_xer
|
||||
#define OPEN_TYPE_decode_oer NULL
|
||||
#define OPEN_TYPE_encode_oer CHOICE_encode_oer
|
||||
#define OPEN_TYPE_decode_uper NULL
|
||||
#define OPEN_TYPE_decode_aper NULL
|
||||
|
||||
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;
|
||||
|
||||
/*
|
||||
* Decode an Open Type which is potentially constraiend
|
||||
* by the other members of the parent structure.
|
||||
*/
|
||||
asn_dec_rval_t OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
const void *ptr, size_t size);
|
||||
|
||||
asn_dec_rval_t OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
const void *ptr, size_t size);
|
||||
#undef ADVANCE
|
||||
#define ADVANCE(num_bytes) \
|
||||
do { \
|
||||
size_t num = num_bytes; \
|
||||
ptr = ((const char *)ptr) + num; \
|
||||
size -= num; \
|
||||
consumed_myself += num; \
|
||||
} while(0)
|
||||
|
||||
asn_dec_rval_t OPEN_TYPE_oer_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
asn_TYPE_member_t *element, const void *ptr,
|
||||
size_t size);
|
||||
#define OPEN_TYPE_free CHOICE_free
|
||||
|
||||
asn_dec_rval_t OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
asn_per_data_t *pd);
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
#define OPEN_TYPE_print CHOICE_print
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
asn_dec_rval_t OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
asn_per_data_t *pd);
|
||||
#define OPEN_TYPE_compare CHOICE_compare
|
||||
|
||||
#define OPEN_TYPE_constraint CHOICE_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
asn_dec_rval_t OPEN_TYPE_ber_get(
|
||||
const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
const void *ptr, size_t size);
|
||||
#define OPEN_TYPE_decode_ber NULL
|
||||
#define OPEN_TYPE_encode_der CHOICE_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
asn_dec_rval_t OPEN_TYPE_xer_get(
|
||||
const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
const void *ptr, size_t size);
|
||||
#define OPEN_TYPE_decode_xer NULL
|
||||
#define OPEN_TYPE_encode_xer CHOICE_encode_xer
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
asn_dec_rval_t OPEN_TYPE_oer_get(
|
||||
const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
asn_TYPE_member_t *element, const void *ptr,
|
||||
size_t size);
|
||||
#define OPEN_TYPE_decode_oer NULL
|
||||
#define OPEN_TYPE_encode_oer CHOICE_encode_oer
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
asn_dec_rval_t OPEN_TYPE_uper_get(
|
||||
const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
asn_per_data_t *pd);
|
||||
#define OPEN_TYPE_decode_uper NULL
|
||||
asn_enc_rval_t OPEN_TYPE_encode_uper(
|
||||
const asn_TYPE_descriptor_t *type_descriptor,
|
||||
const asn_per_constraints_t *constraints, const void *struct_ptr,
|
||||
asn_per_outp_t *per_output);
|
||||
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
asn_dec_rval_t OPEN_TYPE_aper_get(
|
||||
const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *parent_type,
|
||||
void *parent_structure,
|
||||
const asn_TYPE_member_t *element,
|
||||
asn_per_data_t *pd);
|
||||
#define OPEN_TYPE_decode_aper NULL
|
||||
asn_enc_rval_t OPEN_TYPE_encode_aper(
|
||||
const asn_TYPE_descriptor_t *type_descriptor,
|
||||
const asn_per_constraints_t *constraints, const void *struct_ptr,
|
||||
asn_per_outp_t *per_output);
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
119
lib/asn1c/common/OPEN_TYPE_aper.c
Normal file
119
lib/asn1c/common/OPEN_TYPE_aper.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <OPEN_TYPE.h>
|
||||
#include <constr_CHOICE.h>
|
||||
#include <aper_opentype.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
|
||||
asn_type_selector_result_t selected;
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
void *inner_value;
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
if(!(elm->flags & ATF_OPEN_TYPE)) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(!elm->type_selector) {
|
||||
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
|
||||
td->name, elm->name, elm->type->name);
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
selected = elm->type_selector(td, sptr);
|
||||
if(!selected.presence_index) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
assert(elm->flags == ATF_OPEN_TYPE);
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
if(*memb_ptr2 != NULL) {
|
||||
/* Make sure we reset the structure first before encoding */
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
|
||||
!= 0) {
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
inner_value =
|
||||
(char *)*memb_ptr2
|
||||
+ elm->type->elements[selected.presence_index - 1].memb_offset;
|
||||
|
||||
rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
|
||||
&inner_value, pd);
|
||||
switch(rv.code) {
|
||||
case RC_OK:
|
||||
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
|
||||
selected.presence_index)
|
||||
== 0) {
|
||||
break;
|
||||
} else {
|
||||
rv.code = RC_FAIL;
|
||||
}
|
||||
/* Fall through */
|
||||
case RC_WMORE:
|
||||
case RC_FAIL:
|
||||
if(*memb_ptr2) {
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
|
||||
*memb_ptr2 = NULL;
|
||||
} else {
|
||||
ASN_STRUCT_RESET(*selected.type_descriptor,
|
||||
inner_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const void *memb_ptr; /* Pointer to the member */
|
||||
asn_TYPE_member_t *elm; /* CHOICE's element */
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
unsigned present;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
present = CHOICE_variant_get_presence(td, sptr);
|
||||
if(present == 0 || present > td->elements_count) {
|
||||
ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
present--;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
|
||||
|
||||
elm = &td->elements[present];
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
memb_ptr =
|
||||
*(const void *const *)((const char *)sptr + elm->memb_offset);
|
||||
if(!memb_ptr) ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
memb_ptr = (const char *)sptr + elm->memb_offset;
|
||||
}
|
||||
|
||||
if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
er.encoded = 0;
|
||||
ASN__ENCODED_OK(er);
|
||||
}
|
||||
@@ -9,50 +9,78 @@
|
||||
* ObjectDescriptor basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_ObjectDescriptor_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (7 << 2)), /* [UNIVERSAL 7] IMPLICIT ... */
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (7 << 2)), /* [UNIVERSAL 7] IMPLICIT ... */
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_ObjectDescriptor = {
|
||||
OCTET_STRING_free,
|
||||
OCTET_STRING_print_utf8, /* Treat as ASCII subset (it's not) */
|
||||
OCTET_STRING_compare,
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
OCTET_STRING_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
OCTET_STRING_print_utf8, /* Treat as ASCII subset (it's not) */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OCTET_STRING_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
#else
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
0, /* Not supported for ObjectDescriptor */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
0,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
0, /* Not supported for ObjectDescriptor */
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = {
|
||||
"ObjectDescriptor",
|
||||
"ObjectDescriptor",
|
||||
&asn_OP_ObjectDescriptor,
|
||||
asn_DEF_ObjectDescriptor_tags,
|
||||
sizeof(asn_DEF_ObjectDescriptor_tags)
|
||||
/ sizeof(asn_DEF_ObjectDescriptor_tags[0]) - 1,
|
||||
asn_DEF_ObjectDescriptor_tags,
|
||||
sizeof(asn_DEF_ObjectDescriptor_tags)
|
||||
/ sizeof(asn_DEF_ObjectDescriptor_tags[0]),
|
||||
{ 0, 0, asn_generic_unknown_constraint },
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
"ObjectDescriptor",
|
||||
"ObjectDescriptor",
|
||||
&asn_OP_ObjectDescriptor,
|
||||
asn_DEF_ObjectDescriptor_tags,
|
||||
sizeof(asn_DEF_ObjectDescriptor_tags)
|
||||
/ sizeof(asn_DEF_ObjectDescriptor_tags[0]) - 1,
|
||||
asn_DEF_ObjectDescriptor_tags,
|
||||
sizeof(asn_DEF_ObjectDescriptor_tags)
|
||||
/ sizeof(asn_DEF_ObjectDescriptor_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_generic_unknown_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
||||
@@ -16,17 +16,32 @@ typedef GraphicString_t ObjectDescriptor_t; /* Implemented via GraphicString */
|
||||
extern asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor;
|
||||
extern asn_TYPE_operation_t asn_OP_ObjectDescriptor;
|
||||
|
||||
#define ObjectDescriptor_free OCTET_STRING_free
|
||||
#define ObjectDescriptor_print OCTET_STRING_print_utf8
|
||||
#define ObjectDescriptor_constraint asn_generic_unknown_constraint
|
||||
#define ObjectDescriptor_decode_ber OCTET_STRING_decode_ber
|
||||
#define ObjectDescriptor_encode_der OCTET_STRING_encode_der
|
||||
#define ObjectDescriptor_decode_xer OCTET_STRING_decode_xer_utf8
|
||||
#define ObjectDescriptor_encode_xer OCTET_STRING_encode_xer_utf8
|
||||
#define ObjectDescriptor_decode_uper OCTET_STRING_decode_uper
|
||||
#define ObjectDescriptor_encode_uper OCTET_STRING_encode_uper
|
||||
#define ObjectDescriptor_decode_aper OCTET_STRING_decode_aper
|
||||
#define ObjectDescriptor_encode_aper OCTET_STRING_encode_aper
|
||||
#define ObjectDescriptor_free OCTET_STRING_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
#define ObjectDescriptor_print OCTET_STRING_print_utf8
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define ObjectDescriptor_constraint asn_generic_unknown_constraint
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define ObjectDescriptor_decode_ber OCTET_STRING_decode_ber
|
||||
#define ObjectDescriptor_encode_der OCTET_STRING_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define ObjectDescriptor_decode_xer OCTET_STRING_decode_xer_utf8
|
||||
#define ObjectDescriptor_encode_xer OCTET_STRING_encode_xer_utf8
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
#define ObjectDescriptor_decode_uper OCTET_STRING_decode_uper
|
||||
#define ObjectDescriptor_encode_uper OCTET_STRING_encode_uper
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#define ObjectDescriptor_decode_aper OCTET_STRING_decode_aper
|
||||
#define ObjectDescriptor_encode_aper OCTET_STRING_encode_aper
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -30,68 +30,98 @@ static const int _PrintableString_code2value[74] = {
|
||||
* PrintableString basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_PrintableString_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (19 << 2)), /* [UNIVERSAL 19] IMPLICIT ...*/
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (19 << 2)), /* [UNIVERSAL 19] IMPLICIT ...*/
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
|
||||
};
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
static int asn_DEF_PrintableString_v2c(unsigned int value) {
|
||||
return _PrintableString_alphabet[value > 255 ? 0 : value] - 1;
|
||||
return _PrintableString_alphabet[value > 255 ? 0 : value] - 1;
|
||||
}
|
||||
static int asn_DEF_PrintableString_c2v(unsigned int code) {
|
||||
if(code < 74)
|
||||
return _PrintableString_code2value[code];
|
||||
return -1;
|
||||
if(code < 74)
|
||||
return _PrintableString_code2value[code];
|
||||
return -1;
|
||||
}
|
||||
static asn_per_constraints_t asn_DEF_PrintableString_per_constraints = {
|
||||
{ APC_CONSTRAINED, 4, 4, 0x20, 0x39 }, /* Value */
|
||||
{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
|
||||
asn_DEF_PrintableString_v2c,
|
||||
asn_DEF_PrintableString_c2v
|
||||
{ APC_CONSTRAINED, 4, 4, 0x20, 0x39 }, /* Value */
|
||||
{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
|
||||
asn_DEF_PrintableString_v2c,
|
||||
asn_DEF_PrintableString_c2v
|
||||
};
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_TYPE_operation_t asn_OP_PrintableString = {
|
||||
OCTET_STRING_free,
|
||||
OCTET_STRING_print_utf8, /* ASCII subset */
|
||||
OCTET_STRING_compare,
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
OCTET_STRING_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
OCTET_STRING_print_utf8, /* ASCII subset */
|
||||
#else
|
||||
OCTET_STRING_decode_oer,
|
||||
OCTET_STRING_encode_oer,
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OCTET_STRING_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
#else
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
OCTET_STRING_random_fill,
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
OCTET_STRING_decode_oer,
|
||||
OCTET_STRING_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
OCTET_STRING_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_PrintableString = {
|
||||
"PrintableString",
|
||||
"PrintableString",
|
||||
&asn_OP_PrintableString,
|
||||
asn_DEF_PrintableString_tags,
|
||||
sizeof(asn_DEF_PrintableString_tags)
|
||||
/ sizeof(asn_DEF_PrintableString_tags[0]) - 1,
|
||||
asn_DEF_PrintableString_tags,
|
||||
sizeof(asn_DEF_PrintableString_tags)
|
||||
/ sizeof(asn_DEF_PrintableString_tags[0]),
|
||||
{ 0, &asn_DEF_PrintableString_per_constraints, PrintableString_constraint },
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
"PrintableString",
|
||||
"PrintableString",
|
||||
&asn_OP_PrintableString,
|
||||
asn_DEF_PrintableString_tags,
|
||||
sizeof(asn_DEF_PrintableString_tags)
|
||||
/ sizeof(asn_DEF_PrintableString_tags[0]) - 1,
|
||||
asn_DEF_PrintableString_tags,
|
||||
sizeof(asn_DEF_PrintableString_tags)
|
||||
/ sizeof(asn_DEF_PrintableString_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
&asn_DEF_PrintableString_per_constraints,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
PrintableString_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
PrintableString_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
asn_app_constraint_failed_f *ctfailcb,
|
||||
|
||||
@@ -16,19 +16,34 @@ typedef OCTET_STRING_t PrintableString_t; /* Implemented via OCTET STRING */
|
||||
extern asn_TYPE_descriptor_t asn_DEF_PrintableString;
|
||||
extern asn_TYPE_operation_t asn_OP_PrintableString;
|
||||
|
||||
#define PrintableString_free OCTET_STRING_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
#define PrintableString_print OCTET_STRING_print_utf8
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define PrintableString_compare OCTET_STRING_compare
|
||||
|
||||
asn_constr_check_f PrintableString_constraint;
|
||||
|
||||
#define PrintableString_free OCTET_STRING_free
|
||||
#define PrintableString_print OCTET_STRING_print_utf8
|
||||
#define PrintableString_compare OCTET_STRING_compare
|
||||
#define PrintableString_decode_ber OCTET_STRING_decode_ber
|
||||
#define PrintableString_encode_der OCTET_STRING_encode_der
|
||||
#define PrintableString_decode_xer OCTET_STRING_decode_xer_utf8
|
||||
#define PrintableString_encode_xer OCTET_STRING_encode_xer_utf8
|
||||
#define PrintableString_decode_uper OCTET_STRING_decode_uper
|
||||
#define PrintableString_encode_uper OCTET_STRING_encode_uper
|
||||
#define PrintableString_decode_aper OCTET_STRING_decode_aper
|
||||
#define PrintableString_encode_aper OCTET_STRING_encode_aper
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define PrintableString_decode_ber OCTET_STRING_decode_ber
|
||||
#define PrintableString_encode_der OCTET_STRING_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define PrintableString_decode_xer OCTET_STRING_decode_xer_utf8
|
||||
#define PrintableString_encode_xer OCTET_STRING_encode_xer_utf8
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
#define PrintableString_decode_uper OCTET_STRING_decode_uper
|
||||
#define PrintableString_encode_uper OCTET_STRING_encode_uper
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#define PrintableString_decode_aper OCTET_STRING_decode_aper
|
||||
#define PrintableString_encode_aper OCTET_STRING_encode_aper
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
219
lib/asn1c/common/UTF8String.c
Normal file
219
lib/asn1c/common/UTF8String.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <UTF8String.h>
|
||||
|
||||
/*
|
||||
* UTF8String basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_UTF8String_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (12 << 2)), /* [UNIVERSAL 12] IMPLICIT ...*/
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), /* ... OCTET STRING */
|
||||
};
|
||||
asn_TYPE_operation_t asn_OP_UTF8String = {
|
||||
OCTET_STRING_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
UTF8String_print,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OCTET_STRING_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
OCTET_STRING_decode_oer,
|
||||
OCTET_STRING_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
UTF8String_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_UTF8String = {
|
||||
"UTF8String",
|
||||
"UTF8String",
|
||||
&asn_OP_UTF8String,
|
||||
asn_DEF_UTF8String_tags,
|
||||
sizeof(asn_DEF_UTF8String_tags)
|
||||
/ sizeof(asn_DEF_UTF8String_tags[0]) - 1,
|
||||
asn_DEF_UTF8String_tags,
|
||||
sizeof(asn_DEF_UTF8String_tags)
|
||||
/ sizeof(asn_DEF_UTF8String_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
UTF8String_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the table of length expectations.
|
||||
* The second half of this table is only applicable to the long sequences.
|
||||
*/
|
||||
static const int UTF8String_ht[2][16] = {
|
||||
{ /* 0x0 ... 0x7 */
|
||||
/* 0000..0111 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 1000..1011(0), 1100..1101(2), 1110(3), 1111(-1) */
|
||||
0, 0, 0, 0, 2, 2, 3, -1 },
|
||||
{ /* 0xF0 .. 0xF7 */
|
||||
/* 11110000..11110111 */
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 6, 6, -1, -1 }
|
||||
};
|
||||
static const int32_t UTF8String_mv[7] = { 0, 0,
|
||||
0x00000080,
|
||||
0x00000800,
|
||||
0x00010000,
|
||||
0x00200000,
|
||||
0x04000000
|
||||
};
|
||||
|
||||
/* Internal aliases for return codes */
|
||||
#define U8E_TRUNC -1 /* UTF-8 sequence truncated */
|
||||
#define U8E_ILLSTART -2 /* Illegal UTF-8 sequence start */
|
||||
#define U8E_NOTCONT -3 /* Continuation expectation failed */
|
||||
#define U8E_NOTMIN -4 /* Not minimal length encoding */
|
||||
#define U8E_EINVAL -5 /* Invalid arguments */
|
||||
|
||||
int
|
||||
UTF8String_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
|
||||
ssize_t len = UTF8String_length((const UTF8String_t *)sptr);
|
||||
switch(len) {
|
||||
case U8E_EINVAL:
|
||||
ASN__CTFAIL(app_key, td, sptr,
|
||||
"%s: value not given", td->name);
|
||||
break;
|
||||
case U8E_TRUNC:
|
||||
ASN__CTFAIL(app_key, td, sptr,
|
||||
"%s: truncated UTF-8 sequence (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
break;
|
||||
case U8E_ILLSTART:
|
||||
ASN__CTFAIL(app_key, td, sptr,
|
||||
"%s: UTF-8 illegal start of encoding (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
break;
|
||||
case U8E_NOTCONT:
|
||||
ASN__CTFAIL(app_key, td, sptr,
|
||||
"%s: UTF-8 not continuation (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
break;
|
||||
case U8E_NOTMIN:
|
||||
ASN__CTFAIL(app_key, td, sptr,
|
||||
"%s: UTF-8 not minimal sequence (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
break;
|
||||
}
|
||||
return (len < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
UTF8String__process(const UTF8String_t *st, uint32_t *dst, size_t dstlen) {
|
||||
size_t length;
|
||||
uint8_t *buf = st->buf;
|
||||
uint8_t *end = buf + st->size;
|
||||
uint32_t *dstend = dst + dstlen;
|
||||
|
||||
for(length = 0; buf < end; length++) {
|
||||
int ch = *buf;
|
||||
uint8_t *cend;
|
||||
int32_t value;
|
||||
int want;
|
||||
|
||||
/* Compute the sequence length */
|
||||
want = UTF8String_ht[0][ch >> 4];
|
||||
switch(want) {
|
||||
case -1:
|
||||
/* Second half of the table, long sequence */
|
||||
want = UTF8String_ht[1][ch & 0x0F];
|
||||
if(want != -1) break;
|
||||
/* Fall through */
|
||||
case 0:
|
||||
return U8E_ILLSTART;
|
||||
}
|
||||
|
||||
/* assert(want >= 1 && want <= 6) */
|
||||
|
||||
/* Check character sequence length */
|
||||
if(buf + want > end) return U8E_TRUNC;
|
||||
|
||||
value = ch & (0xff >> want);
|
||||
cend = buf + want;
|
||||
for(buf++; buf < cend; buf++) {
|
||||
ch = *buf;
|
||||
if(ch < 0x80 || ch > 0xbf) return U8E_NOTCONT;
|
||||
value = (value << 6) | (ch & 0x3F);
|
||||
}
|
||||
if(value < UTF8String_mv[want])
|
||||
return U8E_NOTMIN;
|
||||
if(dst < dstend)
|
||||
*dst++ = value; /* Record value */
|
||||
}
|
||||
|
||||
if(dst < dstend) *dst = 0; /* zero-terminate */
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
UTF8String_length(const UTF8String_t *st) {
|
||||
if(st && st->buf) {
|
||||
return UTF8String__process(st, 0, 0);
|
||||
} else {
|
||||
return U8E_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
UTF8String_to_wcs(const UTF8String_t *st, uint32_t *dst, size_t dstlen) {
|
||||
if(st && st->buf) {
|
||||
ssize_t ret = UTF8String__process(st, dst, dstlen);
|
||||
return (ret < 0) ? 0 : ret;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
80
lib/asn1c/common/UTF8String.h
Normal file
80
lib/asn1c/common/UTF8String.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _UTF8String_H_
|
||||
#define _UTF8String_H_
|
||||
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef OCTET_STRING_t UTF8String_t; /* Implemented via OCTET STRING */
|
||||
|
||||
extern asn_TYPE_descriptor_t asn_DEF_UTF8String;
|
||||
extern asn_TYPE_operation_t asn_OP_UTF8String;
|
||||
|
||||
#define UTF8String_free OCTET_STRING_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f UTF8String_print;
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define UTF8String_compare OCTET_STRING_compare
|
||||
|
||||
asn_constr_check_f UTF8String_constraint;
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define UTF8String_decode_ber OCTET_STRING_decode_ber
|
||||
#define UTF8String_encode_der OCTET_STRING_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define UTF8String_decode_xer OCTET_STRING_decode_xer_utf8
|
||||
#define UTF8String_encode_xer OCTET_STRING_encode_xer_utf8
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
#define UTF8String_decode_uper OCTET_STRING_decode_uper
|
||||
#define UTF8String_encode_uper OCTET_STRING_encode_uper
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#define UTF8String_decode_aper OCTET_STRING_decode_aper
|
||||
#define UTF8String_encode_aper OCTET_STRING_encode_aper
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f UTF8String_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
/*
|
||||
* Returns length of the given UTF-8 string in characters,
|
||||
* or a negative error code:
|
||||
* -1: UTF-8 sequence truncated
|
||||
* -2: Illegal UTF-8 sequence start
|
||||
* -3: Continuation expectation failed
|
||||
* -4: Not minimal length encoding
|
||||
* -5: Invalid arguments
|
||||
*/
|
||||
ssize_t UTF8String_length(const UTF8String_t *st);
|
||||
|
||||
/*
|
||||
* Convert the UTF-8 string into a sequence of wide characters.
|
||||
* Returns the number of characters necessary.
|
||||
* Returned value might be greater than dstlen.
|
||||
* In case of conversion error, 0 is returned.
|
||||
*
|
||||
* If st points to a valid UTF-8 string, calling
|
||||
* UTF8String_to_wcs(st, 0, 0);
|
||||
* is equivalent to
|
||||
* UTF8String_length(const UTF8String_t *st);
|
||||
*/
|
||||
size_t UTF8String_to_wcs(const UTF8String_t *st, uint32_t *dst, size_t dstlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UTF8String_H_ */
|
||||
22
lib/asn1c/common/UTF8String_print.c
Normal file
22
lib/asn1c/common/UTF8String_print.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <UTF8String.h>
|
||||
|
||||
int
|
||||
UTF8String_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const UTF8String_t *st = (const UTF8String_t *)sptr;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
(void)ilevel; /* Unused argument */
|
||||
|
||||
if(st && st->buf) {
|
||||
return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
96
lib/asn1c/common/UTF8String_rfill.c
Normal file
96
lib/asn1c/common/UTF8String_rfill.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <UTF8String.h>
|
||||
|
||||
/*
|
||||
* Biased function for randomizing UTF-8 sequences.
|
||||
*/
|
||||
static size_t
|
||||
UTF8String__random_char(uint8_t *b, size_t size) {
|
||||
static const struct rnd_value {
|
||||
const char *value;
|
||||
size_t size;
|
||||
} values[] = {{"\0", 1},
|
||||
{"\x01", 1},
|
||||
{"\x7f", 1},
|
||||
{"\xc2\xa2", 2},
|
||||
{"\xe2\x82\xac", 3},
|
||||
{"\xf0\x90\x8d\x88", 4},
|
||||
{"\xf4\x8f\xbf\xbf", 4}};
|
||||
|
||||
const struct rnd_value *v;
|
||||
size_t max_idx = 0;
|
||||
|
||||
switch(size) {
|
||||
case 0:
|
||||
assert(size != 0);
|
||||
return 0;
|
||||
case 1:
|
||||
max_idx = 2;
|
||||
break;
|
||||
case 2:
|
||||
max_idx = 3;
|
||||
break;
|
||||
default:
|
||||
case 4:
|
||||
max_idx = sizeof(values) / sizeof(values[0]) - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
v = &values[asn_random_between(0, max_idx)];
|
||||
memcpy(b, v->value, v->size);
|
||||
return v->size;
|
||||
}
|
||||
|
||||
asn_random_fill_result_t
|
||||
UTF8String_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const asn_encoding_constraints_t *constraints,
|
||||
size_t max_length) {
|
||||
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
|
||||
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
|
||||
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
|
||||
uint8_t *buf;
|
||||
uint8_t *bend;
|
||||
uint8_t *b;
|
||||
size_t rnd_len;
|
||||
size_t idx;
|
||||
UTF8String_t *st;
|
||||
|
||||
if(max_length == 0 && !*sptr) return result_skipped;
|
||||
|
||||
/* Figure out how far we should go */
|
||||
rnd_len = OCTET_STRING_random_length_constrained(td, constraints,
|
||||
max_length / 4);
|
||||
|
||||
buf = CALLOC(4, rnd_len + 1);
|
||||
if(!buf) return result_failed;
|
||||
|
||||
bend = &buf[4 * rnd_len];
|
||||
|
||||
for(b = buf, idx = 0; idx < rnd_len; idx++) {
|
||||
b += UTF8String__random_char(b, (bend - b));
|
||||
}
|
||||
*(uint8_t *)b = 0;
|
||||
|
||||
if(*sptr) {
|
||||
st = *sptr;
|
||||
FREEMEM(st->buf);
|
||||
} else {
|
||||
st = (OCTET_STRING_t *)(*sptr = CALLOC(1, sizeof(UTF8String_t)));
|
||||
if(!st) {
|
||||
FREEMEM(buf);
|
||||
return result_failed;
|
||||
}
|
||||
}
|
||||
|
||||
st->buf = buf;
|
||||
st->size = b - buf;
|
||||
|
||||
assert(UTF8String_length(st) == (ssize_t)rnd_len);
|
||||
|
||||
return result_ok;
|
||||
}
|
||||
130
lib/asn1c/common/VisibleString.c
Normal file
130
lib/asn1c/common/VisibleString.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <VisibleString.h>
|
||||
|
||||
/*
|
||||
* VisibleString basic type description.
|
||||
*/
|
||||
static const ber_tlv_tag_t asn_DEF_VisibleString_tags[] = {
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
|
||||
(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */
|
||||
};
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
static asn_per_constraints_t asn_DEF_VisibleString_constraints = {
|
||||
{ APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */
|
||||
{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */
|
||||
0, 0
|
||||
};
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
asn_TYPE_operation_t asn_OP_VisibleString = {
|
||||
OCTET_STRING_free,
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
OCTET_STRING_print_utf8, /* ASCII subset */
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
OCTET_STRING_compare,
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_encode_der,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
OCTET_STRING_decode_oer,
|
||||
OCTET_STRING_encode_oer,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
OCTET_STRING_decode_uper,
|
||||
OCTET_STRING_encode_uper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
OCTET_STRING_decode_aper,
|
||||
OCTET_STRING_encode_aper,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
OCTET_STRING_random_fill,
|
||||
#else
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
0 /* Use generic outmost tag fetcher */
|
||||
};
|
||||
asn_TYPE_descriptor_t asn_DEF_VisibleString = {
|
||||
"VisibleString",
|
||||
"VisibleString",
|
||||
&asn_OP_VisibleString,
|
||||
asn_DEF_VisibleString_tags,
|
||||
sizeof(asn_DEF_VisibleString_tags)
|
||||
/ sizeof(asn_DEF_VisibleString_tags[0]) - 1,
|
||||
asn_DEF_VisibleString_tags,
|
||||
sizeof(asn_DEF_VisibleString_tags)
|
||||
/ sizeof(asn_DEF_VisibleString_tags[0]),
|
||||
{
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
0,
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
&asn_DEF_VisibleString_constraints,
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
VisibleString_constraint
|
||||
},
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
int
|
||||
VisibleString_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
|
||||
const VisibleString_t *st = (const VisibleString_t *)sptr;
|
||||
|
||||
if(st && st->buf) {
|
||||
uint8_t *buf = st->buf;
|
||||
uint8_t *end = buf + st->size;
|
||||
|
||||
/*
|
||||
* Check the alphabet of the VisibleString.
|
||||
* ISO646, ISOReg#6
|
||||
* The alphabet is a subset of ASCII between the space
|
||||
* and "~" (tilde).
|
||||
*/
|
||||
for(; buf < end; buf++) {
|
||||
if(*buf < 0x20 || *buf > 0x7e) {
|
||||
ASN__CTFAIL(app_key, td, sptr,
|
||||
"%s: value byte %ld (%d) "
|
||||
"not in VisibleString alphabet (%s:%d)",
|
||||
td->name,
|
||||
(long)((buf - st->buf) + 1),
|
||||
*buf,
|
||||
__FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ASN__CTFAIL(app_key, td, sptr,
|
||||
"%s: value not given (%s:%d)",
|
||||
td->name, __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
52
lib/asn1c/common/VisibleString.h
Normal file
52
lib/asn1c/common/VisibleString.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _VisibleString_H_
|
||||
#define _VisibleString_H_
|
||||
|
||||
#include <OCTET_STRING.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef OCTET_STRING_t VisibleString_t; /* Implemented via OCTET STRING */
|
||||
|
||||
extern asn_TYPE_descriptor_t asn_DEF_VisibleString;
|
||||
extern asn_TYPE_operation_t asn_OP_VisibleString;
|
||||
|
||||
#define VisibleString_free OCTET_STRING_free
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
#define VisibleString_print OCTET_STRING_print
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
#define VisibleString_compare OCTET_STRING_compare
|
||||
|
||||
asn_constr_check_f VisibleString_constraint;
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
#define VisibleString_decode_ber OCTET_STRING_decode_ber
|
||||
#define VisibleString_encode_der OCTET_STRING_encode_der
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
#define VisibleString_decode_xer OCTET_STRING_decode_xer_hex
|
||||
#define VisibleString_encode_xer OCTET_STRING_encode_xer
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
#define VisibleString_decode_uper OCTET_STRING_decode_uper
|
||||
#define VisibleString_encode_uper OCTET_STRING_encode_uper
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#define VisibleString_decode_aper OCTET_STRING_decode_aper
|
||||
#define VisibleString_encode_aper OCTET_STRING_encode_aper
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _VisibleString_H_ */
|
||||
91
lib/asn1c/common/aper_decoder.c
Normal file
91
lib/asn1c/common/aper_decoder.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <asn_application.h>
|
||||
#include <asn_internal.h>
|
||||
#include <aper_decoder.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
aper_decode_complete(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const void *buffer, size_t size) {
|
||||
asn_dec_rval_t rval;
|
||||
|
||||
rval = aper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0);
|
||||
if(rval.consumed) {
|
||||
/*
|
||||
* We've always given 8-aligned data,
|
||||
* so convert bits to integral bytes.
|
||||
*/
|
||||
rval.consumed += 7;
|
||||
rval.consumed >>= 3;
|
||||
} else if(rval.code == RC_OK) {
|
||||
if(size) {
|
||||
if(((const uint8_t *)buffer)[0] == 0) {
|
||||
rval.consumed = 1; /* 1 byte */
|
||||
} else {
|
||||
ASN_DEBUG("Expecting single zeroed byte");
|
||||
rval.code = RC_FAIL;
|
||||
}
|
||||
} else {
|
||||
/* Must contain at least 8 bits. */
|
||||
rval.code = RC_WMORE;
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
aper_decode(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **sptr, const void *buffer,
|
||||
size_t size, int skip_bits, int unused_bits) {
|
||||
asn_codec_ctx_t s_codec_ctx;
|
||||
asn_dec_rval_t rval;
|
||||
asn_per_data_t pd;
|
||||
|
||||
if(skip_bits < 0 || skip_bits > 7
|
||||
|| unused_bits < 0 || unused_bits > 7
|
||||
|| (unused_bits > 0 && !size))
|
||||
ASN__DECODE_FAILED;
|
||||
|
||||
/*
|
||||
* Stack checker requires that the codec context
|
||||
* must be allocated on the stack.
|
||||
*/
|
||||
if(opt_codec_ctx) {
|
||||
if(opt_codec_ctx->max_stack_size) {
|
||||
s_codec_ctx = *opt_codec_ctx;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
} else {
|
||||
/* If context is not given, be security-conscious anyway */
|
||||
memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
|
||||
s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
|
||||
/* Fill in the position indicator */
|
||||
memset(&pd, 0, sizeof(pd));
|
||||
pd.buffer = (const uint8_t *)buffer;
|
||||
pd.nboff = skip_bits;
|
||||
pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
|
||||
if(pd.nboff > pd.nbits)
|
||||
ASN__DECODE_FAILED;
|
||||
|
||||
/*
|
||||
* Invoke type-specific decoder.
|
||||
*/
|
||||
if(!td->op->aper_decoder)
|
||||
ASN__DECODE_FAILED; /* PER is not compiled in */
|
||||
rval = td->op->aper_decoder(opt_codec_ctx, td, 0, sptr, &pd);
|
||||
if(rval.code == RC_OK) {
|
||||
/* Return the number of consumed bits */
|
||||
rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
|
||||
+ pd.nboff - skip_bits;
|
||||
ASN_DEBUG("PER decoding consumed %zu, counted %zu",
|
||||
rval.consumed, pd.moved);
|
||||
assert(rval.consumed == pd.moved);
|
||||
} else {
|
||||
/* PER codec is not a restartable */
|
||||
rval.consumed = 0;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
47
lib/asn1c/common/aper_decoder.h
Normal file
47
lib/asn1c/common/aper_decoder.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*-
|
||||
* Copyright (c) 2005-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _APER_DECODER_H_
|
||||
#define _APER_DECODER_H_
|
||||
|
||||
#include <asn_application.h>
|
||||
#include <aper_support.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* Aligned PER decoder of a "complete encoding" as per X.691#10.1.
|
||||
* On success, this call always returns (.consumed >= 1), in BITS, as per X.691#10.1.3.
|
||||
*/
|
||||
asn_dec_rval_t aper_decode_complete(
|
||||
const struct asn_codec_ctx_s *opt_codec_ctx,
|
||||
const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
|
||||
void **struct_ptr, /* Pointer to a target structure's pointer */
|
||||
const void *buffer, /* Data to be decoded */
|
||||
size_t size /* Size of data buffer */
|
||||
);
|
||||
|
||||
/*
|
||||
* Aligned PER decoder of any ASN.1 type. May be invoked by the application.
|
||||
* WARNING: This call returns the number of BITS read from the stream. Beware.
|
||||
*/
|
||||
asn_dec_rval_t aper_decode(
|
||||
const struct asn_codec_ctx_s *opt_codec_ctx,
|
||||
const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
|
||||
void **struct_ptr, /* Pointer to a target structure's pointer */
|
||||
const void *buffer, /* Data to be decoded */
|
||||
size_t size, /* Size of data buffer */
|
||||
int skip_bits, /* Number of unused leading bits, 0..7 */
|
||||
int unused_bits /* Number of unused tailing bits, 0..7 */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APER_DECODER_H_ */
|
||||
129
lib/asn1c/common/aper_encoder.c
Normal file
129
lib/asn1c/common/aper_encoder.c
Normal file
@@ -0,0 +1,129 @@
|
||||
#include <asn_application.h>
|
||||
#include <asn_internal.h>
|
||||
#include <aper_encoder.h>
|
||||
|
||||
/*
|
||||
* Argument type and callback necessary for aper_encode_to_buffer().
|
||||
*/
|
||||
typedef struct enc_to_buf_arg {
|
||||
void *buffer;
|
||||
size_t left;
|
||||
} enc_to_buf_arg;
|
||||
static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
|
||||
enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
|
||||
|
||||
if(arg->left < size)
|
||||
return -1; /* Data exceeds the available buffer size */
|
||||
|
||||
memcpy(arg->buffer, buffer, size);
|
||||
arg->buffer = ((char *)arg->buffer) + size;
|
||||
arg->left -= size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
aper_encode_to_buffer(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, void *buffer, size_t buffer_size) {
|
||||
enc_to_buf_arg key;
|
||||
|
||||
key.buffer = buffer;
|
||||
key.left = buffer_size;
|
||||
|
||||
if(td) ASN_DEBUG("Encoding \"%s\" using ALIGNED PER", td->name);
|
||||
|
||||
return aper_encode(td, constraints, sptr, encode_to_buffer_cb, &key);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
aper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, void **buffer_r) {
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
enc_dyn_arg key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
er = aper_encode(td, constraints, sptr, encode_dyn_cb, &key);
|
||||
switch(er.encoded) {
|
||||
case -1:
|
||||
FREEMEM(key.buffer);
|
||||
return -1;
|
||||
case 0:
|
||||
FREEMEM(key.buffer);
|
||||
key.buffer = MALLOC(1);
|
||||
if(key.buffer) {
|
||||
*(char *)key.buffer = '\0';
|
||||
*buffer_r = key.buffer;
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
*buffer_r = key.buffer;
|
||||
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
|
||||
return ((er.encoded + 7) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Internally useful functions.
|
||||
*/
|
||||
|
||||
/* Flush partially filled buffer */
|
||||
static int
|
||||
_aper_encode_flush_outp(asn_per_outp_t *po) {
|
||||
uint8_t *buf;
|
||||
|
||||
if(po->nboff == 0 && po->buffer == po->tmpspace)
|
||||
return 0;
|
||||
|
||||
buf = po->buffer + (po->nboff >> 3);
|
||||
/* Make sure we account for the last, partially filled */
|
||||
if(po->nboff & 0x07) {
|
||||
buf[0] &= 0xff << (8 - (po->nboff & 0x07));
|
||||
buf++;
|
||||
}
|
||||
|
||||
if (po->output) {
|
||||
return po->output(po->tmpspace, buf - po->tmpspace, po->op_key);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
aper_encode(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_per_outp_t po;
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
|
||||
/*
|
||||
* Invoke type-specific encoder.
|
||||
*/
|
||||
if(!td || !td->op->aper_encoder)
|
||||
ASN__ENCODE_FAILED; /* PER is not compiled in */
|
||||
|
||||
po.buffer = po.tmpspace;
|
||||
po.nboff = 0;
|
||||
po.nbits = 8 * sizeof(po.tmpspace);
|
||||
po.output = cb ? cb : ignore_output;
|
||||
po.op_key = app_key;
|
||||
po.flushed_bytes = 0;
|
||||
|
||||
er = td->op->aper_encoder(td, constraints, sptr, &po);
|
||||
if(er.encoded != -1) {
|
||||
size_t bits_to_flush;
|
||||
|
||||
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
|
||||
|
||||
/* Set number of bits encoded to a firm value */
|
||||
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
|
||||
|
||||
if(_aper_encode_flush_outp(&po))
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
return er;
|
||||
}
|
||||
63
lib/asn1c/common/aper_encoder.h
Normal file
63
lib/asn1c/common/aper_encoder.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*-
|
||||
* Copyright (c) 2006-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _APER_ENCODER_H_
|
||||
#define _APER_ENCODER_H_
|
||||
|
||||
#include <asn_application.h>
|
||||
#include <aper_support.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* Aligned PER encoder of any ASN.1 type. May be invoked by the application.
|
||||
* WARNING: This function returns the number of encoded bits in the .encoded
|
||||
* field of the return value. Use the following formula to convert to bytes:
|
||||
* bytes = ((.encoded + 7) / 8)
|
||||
*/
|
||||
asn_enc_rval_t aper_encode(
|
||||
const struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *struct_ptr, /* Structure to be encoded */
|
||||
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
|
||||
void *app_key /* Arbitrary callback argument */
|
||||
);
|
||||
|
||||
/*
|
||||
* A variant of aper_encode() which encodes data into the existing buffer
|
||||
* WARNING: This function returns the number of encoded bits in the .encoded
|
||||
* field of the return value.
|
||||
*/
|
||||
asn_enc_rval_t aper_encode_to_buffer(
|
||||
const struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *struct_ptr, /* Structure to be encoded */
|
||||
void *buffer, /* Pre-allocated buffer */
|
||||
size_t buffer_size /* Initial buffer size (max) */
|
||||
);
|
||||
|
||||
/*
|
||||
* A variant of aper_encode_to_buffer() which allocates buffer itself.
|
||||
* Returns the number of bytes in the buffer or -1 in case of failure.
|
||||
* WARNING: This function produces a "Production of the complete encoding",
|
||||
* with length of at least one octet. Contrast this to precise bit-packing
|
||||
* encoding of aper_encode() and aper_encode_to_buffer().
|
||||
*/
|
||||
ssize_t
|
||||
aper_encode_to_new_buffer(
|
||||
const struct asn_TYPE_descriptor_s *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr,
|
||||
void **buffer_r
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APER_ENCODER_H_ */
|
||||
149
lib/asn1c/common/aper_opentype.c
Normal file
149
lib/asn1c/common/aper_opentype.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <aper_encoder.h>
|
||||
#include <aper_support.h>
|
||||
#include <aper_opentype.h>
|
||||
|
||||
static asn_dec_rval_t
|
||||
aper_open_type_get_simple(const asn_codec_ctx_t *ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv;
|
||||
ssize_t chunk_bytes;
|
||||
int repeat;
|
||||
uint8_t *buf = 0;
|
||||
size_t bufLen = 0;
|
||||
size_t bufSize = 0;
|
||||
asn_per_data_t spd;
|
||||
size_t padding;
|
||||
|
||||
ASN__STACK_OVERFLOW_CHECK(ctx);
|
||||
|
||||
ASN_DEBUG("Getting open type %s...", td->name);
|
||||
|
||||
do {
|
||||
chunk_bytes = aper_get_length(pd, -1, -1, &repeat);
|
||||
if(chunk_bytes < 0) {
|
||||
FREEMEM(buf);
|
||||
ASN__DECODE_STARVED;
|
||||
}
|
||||
if(bufLen + chunk_bytes > bufSize) {
|
||||
void *ptr;
|
||||
bufSize = chunk_bytes + (bufSize << 2);
|
||||
ptr = REALLOC(buf, bufSize);
|
||||
if(!ptr) {
|
||||
FREEMEM(buf);
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
buf = ptr;
|
||||
}
|
||||
if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {
|
||||
FREEMEM(buf);
|
||||
ASN__DECODE_STARVED;
|
||||
}
|
||||
bufLen += chunk_bytes;
|
||||
} while(repeat);
|
||||
|
||||
ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
|
||||
(long)bufLen);
|
||||
|
||||
memset(&spd, 0, sizeof(spd));
|
||||
spd.buffer = buf;
|
||||
spd.nbits = bufLen << 3;
|
||||
|
||||
ASN_DEBUG_INDENT_ADD(+4);
|
||||
rv = td->op->aper_decoder(ctx, td, constraints, sptr, &spd);
|
||||
ASN_DEBUG_INDENT_ADD(-4);
|
||||
|
||||
if(rv.code == RC_OK) {
|
||||
/* Check padding validity */
|
||||
padding = spd.nbits - spd.nboff;
|
||||
if (((padding > 0 && padding < 8) ||
|
||||
/* X.691#10.1.3 */
|
||||
(spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
|
||||
per_get_few_bits(&spd, padding) == 0) {
|
||||
/* Everything is cool */
|
||||
FREEMEM(buf);
|
||||
return rv;
|
||||
}
|
||||
FREEMEM(buf);
|
||||
if(padding >= 8) {
|
||||
ASN_DEBUG("Too large padding %d in open type", (int)padding);
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
ASN_DEBUG("No padding");
|
||||
}
|
||||
} else {
|
||||
FREEMEM(buf);
|
||||
/* rv.code could be RC_WMORE, nonsense in this context */
|
||||
rv.code = RC_FAIL; /* Noone would give us more */
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
aper_open_type_put(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
void *buf;
|
||||
void *bptr;
|
||||
ssize_t size;
|
||||
size_t toGo;
|
||||
|
||||
ASN_DEBUG("Open type put %s ...", td->name);
|
||||
|
||||
size = aper_encode_to_new_buffer(td, constraints, sptr, &buf);
|
||||
if(size <= 0) return -1;
|
||||
|
||||
for(bptr = buf, toGo = size; toGo;) {
|
||||
int need_eom = 0;
|
||||
ssize_t maySave = aper_put_length(po, -1, toGo, &need_eom);
|
||||
if(maySave < 0) break;
|
||||
if(per_put_many_bits(po, bptr, maySave * 8)) break;
|
||||
bptr = (char *)bptr + maySave;
|
||||
toGo -= maySave;
|
||||
if(need_eom && aper_put_length(po, -1, 0, 0)) {
|
||||
FREEMEM(buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
FREEMEM(buf);
|
||||
if(toGo) return -1;
|
||||
|
||||
ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",
|
||||
td->name, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
aper_open_type_get(const asn_codec_ctx_t *ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
void **sptr, asn_per_data_t *pd) {
|
||||
|
||||
return aper_open_type_get_simple(ctx, td, constraints, sptr, pd);
|
||||
}
|
||||
|
||||
int
|
||||
aper_open_type_skip(const asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
|
||||
asn_TYPE_descriptor_t s_td;
|
||||
asn_dec_rval_t rv;
|
||||
asn_TYPE_operation_t op_t;
|
||||
|
||||
memset(&op_t, 0, sizeof(op_t));
|
||||
s_td.name = "<unknown extension>";
|
||||
s_td.op = &op_t;
|
||||
s_td.op->aper_decoder = uper_sot_suck;
|
||||
|
||||
rv = aper_open_type_get(ctx, &s_td, 0, 0, pd);
|
||||
if(rv.code != RC_OK)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
30
lib/asn1c/common/aper_opentype.h
Normal file
30
lib/asn1c/common/aper_opentype.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _APER_OPENTYPE_H_
|
||||
#define _APER_OPENTYPE_H_
|
||||
|
||||
#include <per_opentype.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
asn_dec_rval_t aper_open_type_get(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
void **sptr, asn_per_data_t *pd);
|
||||
|
||||
|
||||
int aper_open_type_skip(const asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd);
|
||||
|
||||
int aper_open_type_put(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APER_OPENTYPE_H_ */
|
||||
292
lib/asn1c/common/aper_support.c
Normal file
292
lib/asn1c/common/aper_support.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_system.h>
|
||||
#include <asn_internal.h>
|
||||
#include <aper_support.h>
|
||||
|
||||
int32_t
|
||||
aper_get_align(asn_per_data_t *pd) {
|
||||
|
||||
if(pd->nboff & 0x7) {
|
||||
ASN_DEBUG("Aligning %ld bits", 8 - ((unsigned long)pd->nboff & 0x7));
|
||||
return per_get_few_bits(pd, 8 - (pd->nboff & 0x7));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
aper_get_length(asn_per_data_t *pd, int range, int ebits, int *repeat) {
|
||||
ssize_t value;
|
||||
|
||||
*repeat = 0;
|
||||
|
||||
/*
|
||||
* ITU-T X.691(08/2015)
|
||||
* #11.9.4.2
|
||||
*
|
||||
* If the length determinant "n" to be encoded is a normally small length,
|
||||
* or a constrained whole number with "ub" greater than or equal to 64K,
|
||||
* or is a semi-constrained whole number, then "n" shall be encoded
|
||||
* as specified in 11.9.3.4 to 11.9.3.8.4.
|
||||
*
|
||||
* NOTE – Thus, if "ub" is greater than or equal to 64K,
|
||||
* the encoding of the length determinant is the same as it would be
|
||||
* if the length were unconstrained.
|
||||
*/
|
||||
if (range <= 65535 && range >= 0)
|
||||
return aper_get_nsnnwn(pd, range);
|
||||
|
||||
if (aper_get_align(pd) < 0)
|
||||
return -1;
|
||||
|
||||
if(ebits >= 0) return per_get_few_bits(pd, ebits);
|
||||
|
||||
value = per_get_few_bits(pd, 8);
|
||||
if(value < 0) return -1;
|
||||
if((value & 128) == 0) /* #11.9.3.6 */
|
||||
return (value & 0x7F);
|
||||
if((value & 64) == 0) { /* #11.9.3.7 */
|
||||
value = ((value & 63) << 8) | per_get_few_bits(pd, 8);
|
||||
if(value < 0) return -1;
|
||||
return value;
|
||||
}
|
||||
value &= 63; /* this is "m" from X.691, #11.9.3.8 */
|
||||
if(value < 1 || value > 4)
|
||||
return -1;
|
||||
*repeat = 1;
|
||||
return (16384 * value);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
aper_get_nslength(asn_per_data_t *pd) {
|
||||
ssize_t length;
|
||||
|
||||
ASN_DEBUG("Getting normally small length");
|
||||
|
||||
if(per_get_few_bits(pd, 1) == 0) {
|
||||
length = per_get_few_bits(pd, 6) + 1;
|
||||
if(length <= 0) return -1;
|
||||
ASN_DEBUG("l=%ld", length);
|
||||
return length;
|
||||
} else {
|
||||
int repeat;
|
||||
length = aper_get_length(pd, -1, -1, &repeat);
|
||||
if(length >= 0 && !repeat) return length;
|
||||
return -1; /* Error, or do not support >16K extensions */
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(USE_OLDER_APER_NSNNWN)
|
||||
ssize_t
|
||||
aper_get_nsnnwn(asn_per_data_t *pd, int range) {
|
||||
ssize_t value;
|
||||
int bytes = 0;
|
||||
|
||||
ASN_DEBUG("getting nsnnwn with range %d", range);
|
||||
|
||||
if(range <= 255) {
|
||||
int i;
|
||||
|
||||
if (range < 0) return -1;
|
||||
/* 1 -> 8 bits */
|
||||
for (i = 1; i <= 8; i++) {
|
||||
int upper = 1 << i;
|
||||
if (upper >= range)
|
||||
break;
|
||||
}
|
||||
value = per_get_few_bits(pd, i);
|
||||
return value;
|
||||
} else if (range == 256){
|
||||
/* 1 byte */
|
||||
bytes = 1;
|
||||
} else if (range <= 65536) {
|
||||
/* 2 bytes */
|
||||
bytes = 2;
|
||||
} else {
|
||||
//return -1;
|
||||
int length;
|
||||
|
||||
/* handle indefinite range */
|
||||
length = per_get_few_bits(pd, 1);
|
||||
if (length == 0)
|
||||
return per_get_few_bits(pd, 6);
|
||||
|
||||
if (aper_get_align(pd) < 0)
|
||||
return -1;
|
||||
|
||||
length = per_get_few_bits(pd, 8);
|
||||
/* the length is not likely to be that big */
|
||||
if (length > 4)
|
||||
return -1;
|
||||
value = 0;
|
||||
if (per_get_many_bits(pd, (uint8_t *)&value, 0, length * 8) < 0)
|
||||
return -1;
|
||||
return value;
|
||||
}
|
||||
if (aper_get_align(pd) < 0)
|
||||
return -1;
|
||||
value = per_get_few_bits(pd, 8 * bytes);
|
||||
return value;
|
||||
}
|
||||
#else /* old APER codec */
|
||||
ssize_t
|
||||
aper_get_nsnnwn(asn_per_data_t *pd, int dummy_range) {
|
||||
ssize_t value;
|
||||
|
||||
ASN_DEBUG("Get the normally small non-negative whole number APER");
|
||||
|
||||
value = per_get_few_bits(pd, 7);
|
||||
if(value & 64) { /* implicit (value < 0) */
|
||||
value &= 63;
|
||||
value <<= 2;
|
||||
value |= per_get_few_bits(pd, 2);
|
||||
if(value & 128) /* implicit (value < 0) */
|
||||
return -1;
|
||||
if(value == 0)
|
||||
return 0;
|
||||
if(value >= 3)
|
||||
return -1;
|
||||
value = per_get_few_bits(pd, 8 * value);
|
||||
return value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
#endif /* don't use old APER */
|
||||
|
||||
int aper_put_align(asn_per_outp_t *po) {
|
||||
|
||||
if(po->nboff & 0x7) {
|
||||
ASN_DEBUG("Aligning %ld bits", 8 - ((unsigned long)po->nboff & 0x7));
|
||||
if(per_put_few_bits(po, 0x00, (8 - (po->nboff & 0x7))))
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
aper_put_length(asn_per_outp_t *po, int range, size_t length, int *need_eom) {
|
||||
int dummy = 0;
|
||||
if(!need_eom) need_eom = &dummy;
|
||||
|
||||
*need_eom = 0;
|
||||
|
||||
ASN_DEBUG("APER put length %zu with range %d", length, range);
|
||||
|
||||
/* 11.9 X.691 Note 2 */
|
||||
if (range <= 65536 && range >= 0)
|
||||
return aper_put_nsnnwn(po, range, length);
|
||||
|
||||
if (aper_put_align(po) < 0)
|
||||
return -1;
|
||||
|
||||
if(length <= 127) /* #11.9.3.6 */{
|
||||
return per_put_few_bits(po, length, 8)
|
||||
? -1 : (ssize_t)length;
|
||||
}
|
||||
else if(length < 16384) /* #11.9.3.7 */
|
||||
return per_put_few_bits(po, length|0x8000, 16)
|
||||
? -1 : (ssize_t)length;
|
||||
|
||||
*need_eom = 0 == (length & 16383);
|
||||
length >>= 14;
|
||||
if(length > 4) {
|
||||
*need_eom = 0;
|
||||
length = 4;
|
||||
}
|
||||
|
||||
return per_put_few_bits(po, 0xC0 | length, 8)
|
||||
? -1 : (ssize_t)(length << 14);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
aper_put_nslength(asn_per_outp_t *po, size_t length) {
|
||||
|
||||
if(length <= 64) {
|
||||
/* #11.9.3.4 */
|
||||
if(length == 0) return -1;
|
||||
return per_put_few_bits(po, length-1, 7) ? -1 : 0;
|
||||
} else {
|
||||
if(aper_put_length(po, -1, length, 0) != (ssize_t)length) {
|
||||
/* This might happen in case of >16K extensions */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(USE_OLDER_APER_NSNNWN)
|
||||
int
|
||||
aper_put_nsnnwn(asn_per_outp_t *po, int range, int number) {
|
||||
int bytes;
|
||||
|
||||
ASN_DEBUG("aper put nsnnwn %d with range %d", number, range);
|
||||
/* 10.5.7.1 X.691 */
|
||||
if(range < 0) {
|
||||
int i;
|
||||
for (i = 1; ; i++) {
|
||||
int bits = 1 << (8 * i);
|
||||
if (number <= bits)
|
||||
break;
|
||||
}
|
||||
bytes = i;
|
||||
assert(i <= 4);
|
||||
}
|
||||
if(range <= 255) {
|
||||
int i;
|
||||
for (i = 1; i <= 8; i++) {
|
||||
int bits = 1 << i;
|
||||
if (range <= bits)
|
||||
break;
|
||||
}
|
||||
return per_put_few_bits(po, number, i);
|
||||
} else if(range == 256) {
|
||||
bytes = 1;
|
||||
} else if(range <= 65536) {
|
||||
bytes = 2;
|
||||
} else { /* Ranges > 64K */
|
||||
int i;
|
||||
for (i = 1; ; i++) {
|
||||
int bits = 1 << (8 * i);
|
||||
if (range <= bits)
|
||||
break;
|
||||
}
|
||||
assert(i <= 4);
|
||||
bytes = i;
|
||||
}
|
||||
if(aper_put_align(po) < 0) /* Aligning on octet */
|
||||
return -1;
|
||||
/* if(per_put_few_bits(po, bytes, 8))
|
||||
return -1;
|
||||
*/
|
||||
return per_put_few_bits(po, number, 8 * bytes);
|
||||
}
|
||||
#else /* preserve old code base in case */
|
||||
int
|
||||
aper_put_nsnnwn(asn_per_outp_t *po, int dummy_range, int n) {
|
||||
int bytes;
|
||||
|
||||
ASN_DEBUG("aper_put_nsnnwn");
|
||||
|
||||
if(n <= 63) {
|
||||
if(n < 0) return -1;
|
||||
return per_put_few_bits(po, n, 7);
|
||||
}
|
||||
if(n < 256)
|
||||
bytes = 1;
|
||||
else if(n < 65536)
|
||||
bytes = 2;
|
||||
else if(n < 256 * 65536)
|
||||
bytes = 3;
|
||||
else
|
||||
return -1; /* This is not a "normally small" value */
|
||||
if(per_put_few_bits(po, bytes, 8))
|
||||
return -1;
|
||||
|
||||
return per_put_few_bits(po, n, 8 * bytes);
|
||||
}
|
||||
#endif /* which aper_put_nsnnwn() */
|
||||
62
lib/asn1c/common/aper_support.h
Normal file
62
lib/asn1c/common/aper_support.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _APER_SUPPORT_H_
|
||||
#define _APER_SUPPORT_H_
|
||||
|
||||
#include <asn_system.h> /* Platform-specific types */
|
||||
#include <per_support.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* X.691 (08/2015) #11.9 "General rules for encoding a length determinant"
|
||||
* Get the length "n" from the Aligned PER stream.
|
||||
*/
|
||||
ssize_t aper_get_length(asn_per_data_t *pd, int range,
|
||||
int effective_bound_bits, int *repeat);
|
||||
|
||||
/*
|
||||
* Get the normally small length "n".
|
||||
*/
|
||||
ssize_t aper_get_nslength(asn_per_data_t *pd);
|
||||
|
||||
/*
|
||||
* Get the normally small non-negative whole number.
|
||||
*/
|
||||
ssize_t aper_get_nsnnwn(asn_per_data_t *pd, int range);
|
||||
|
||||
/*
|
||||
* X.691 (08/2015) #11.9 "General rules for encoding a length determinant"
|
||||
* Put the length "whole_length" to the Aligned PER stream.
|
||||
* If (opt_need_eom) is given, it will be set to 1 if final 0-length is needed.
|
||||
* In that case, invoke uper_put_length(po, 0, 0) after encoding the last block.
|
||||
* This function returns the number of units which may be flushed
|
||||
* in the next units saving iteration.
|
||||
*/
|
||||
ssize_t aper_put_length(asn_per_outp_t *po, int range, size_t length,
|
||||
int *opt_need_eom);
|
||||
|
||||
/* Align the current bit position to octet bundary */
|
||||
int aper_put_align(asn_per_outp_t *po);
|
||||
int32_t aper_get_align(asn_per_data_t *pd);
|
||||
|
||||
/*
|
||||
* Put the normally small length "n" to the Unaligned PER stream.
|
||||
* Returns 0 or -1.
|
||||
*/
|
||||
int aper_put_nslength(asn_per_outp_t *po, size_t length);
|
||||
|
||||
/*
|
||||
* Put the normally small non-negative whole number.
|
||||
*/
|
||||
int aper_put_nsnnwn(asn_per_outp_t *po, int range, int number);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _APER_SUPPORT_H_ */
|
||||
@@ -226,7 +226,9 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
asn_app_consume_bytes_f *callback, void *callback_key) {
|
||||
asn_enc_rval_t er = {0,0,0};
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
enum xer_encoder_flags_e xer_flags = XER_F_CANONICAL;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
(void)opt_codec_ctx; /* Parameters are not checked on encode yet. */
|
||||
|
||||
@@ -265,6 +267,7 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
errno = ENOENT; /* Randomization doesn't make sense on output. */
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
case ATS_BER:
|
||||
/* BER is a superset of DER. */
|
||||
/* Fall through. */
|
||||
@@ -273,27 +276,29 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
er = der_encode(td, sptr, callback, callback_key);
|
||||
if(er.encoded == -1) {
|
||||
if(er.failed_type && er.failed_type->op->der_encoder) {
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
} else {
|
||||
errno = ENOENT; /* DER is not defined for this type. */
|
||||
errno = ENOENT; /* DER is not defined for this type. */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
break;
|
||||
case ATS_CER:
|
||||
errno = ENOENT; /* Transfer syntax is not defined for any type. */
|
||||
errno = ENOENT; /* Transfer syntax is not defined for any type. */
|
||||
ASN__ENCODE_FAILED;
|
||||
#else
|
||||
case ATS_BER:
|
||||
case ATS_DER:
|
||||
case ATS_CER:
|
||||
errno = ENOENT; /* BER is not defined. */
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
case ATS_BASIC_OER:
|
||||
case ATS_CANONICAL_OER:
|
||||
errno = ENOENT; /* PER is not defined. */
|
||||
ASN__ENCODE_FAILED;
|
||||
break;
|
||||
#else /* ASN_DISABLE_OER_SUPPORT */
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
case ATS_BASIC_OER:
|
||||
/* CANONICAL-OER is a superset of BASIC-OER. */
|
||||
/* Fall through. */
|
||||
@@ -302,27 +307,25 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
er = oer_encode(td, sptr, callback, callback_key);
|
||||
if(er.encoded == -1) {
|
||||
if(er.failed_type && er.failed_type->op->oer_encoder) {
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
} else {
|
||||
errno = ENOENT; /* OER is not defined for this type. */
|
||||
errno = ENOENT; /* OER is not defined for this type. */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
break;
|
||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
case ATS_UNALIGNED_BASIC_PER:
|
||||
case ATS_UNALIGNED_CANONICAL_PER:
|
||||
case ATS_ALIGNED_BASIC_PER:
|
||||
case ATS_ALIGNED_CANONICAL_PER:
|
||||
errno = ENOENT; /* PER is not defined. */
|
||||
#else
|
||||
case ATS_BASIC_OER:
|
||||
case ATS_CANONICAL_OER:
|
||||
errno = ENOENT; /* OER is not defined. */
|
||||
ASN__ENCODE_FAILED;
|
||||
break;
|
||||
#else /* ASN_DISABLE_PER_SUPPORT */
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
case ATS_UNALIGNED_BASIC_PER:
|
||||
/* CANONICAL-UPER is a superset of BASIC-UPER. */
|
||||
/* Fall through. */
|
||||
@@ -331,9 +334,9 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
er = uper_encode(td, 0, sptr, callback, callback_key);
|
||||
if(er.encoded == -1) {
|
||||
if(er.failed_type && er.failed_type->op->uper_encoder) {
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
} else {
|
||||
errno = ENOENT; /* UPER is not defined for this type. */
|
||||
errno = ENOENT; /* UPER is not defined for this type. */
|
||||
}
|
||||
} else {
|
||||
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
|
||||
@@ -343,16 +346,24 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
errno = EBADF;
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
er.encoded = 8; /* Exactly 8 zero bits is added. */
|
||||
er.encoded = 8; /* Exactly 8 zero bits is added. */
|
||||
}
|
||||
/* Convert bits into bytes */
|
||||
er.encoded = (er.encoded + 7) >> 3;
|
||||
}
|
||||
} else {
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case ATS_UNALIGNED_BASIC_PER:
|
||||
case ATS_UNALIGNED_CANONICAL_PER:
|
||||
errno = ENOENT; /* UPER is not defined. */
|
||||
ASN__ENCODE_FAILED;
|
||||
break;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
case ATS_ALIGNED_BASIC_PER:
|
||||
/* CANONICAL-APER is a superset of BASIC-APER. */
|
||||
/* Fall through. */
|
||||
@@ -361,9 +372,9 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
er = aper_encode(td, 0, sptr, callback, callback_key);
|
||||
if(er.encoded == -1) {
|
||||
if(er.failed_type && er.failed_type->op->aper_encoder) {
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
} else {
|
||||
errno = ENOENT; /* APER is not defined for this type. */
|
||||
errno = ENOENT; /* APER is not defined for this type. */
|
||||
}
|
||||
} else {
|
||||
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
|
||||
@@ -373,18 +384,25 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
errno = EBADF;
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
er.encoded = 8; /* Exactly 8 zero bits is added. */
|
||||
er.encoded = 8; /* Exactly 8 zero bits is added. */
|
||||
}
|
||||
/* Convert bits into bytes */
|
||||
er.encoded = (er.encoded + 7) >> 3;
|
||||
}
|
||||
} else {
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
break;
|
||||
#endif /* ASN_DISABLE_PER_SUPPORT */
|
||||
#else
|
||||
case ATS_ALIGNED_BASIC_PER:
|
||||
case ATS_ALIGNED_CANONICAL_PER:
|
||||
errno = ENOENT; /* APER is not defined. */
|
||||
ASN__ENCODE_FAILED;
|
||||
break;
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
case ATS_BASIC_XER:
|
||||
/* CANONICAL-XER is a superset of BASIC-XER. */
|
||||
xer_flags &= ~XER_F_CANONICAL;
|
||||
@@ -395,16 +413,23 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
er = xer_encode(td, sptr, xer_flags, callback, callback_key);
|
||||
if(er.encoded == -1) {
|
||||
if(er.failed_type && er.failed_type->op->xer_encoder) {
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
errno = EBADF; /* Structure has incorrect form. */
|
||||
} else {
|
||||
errno = ENOENT; /* XER is not defined for this type. */
|
||||
errno = ENOENT; /* XER is not defined for this type. */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
errno = ENOENT; /* Transfer syntax is not defined for this type. */
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case ATS_BASIC_XER:
|
||||
case ATS_CANONICAL_XER:
|
||||
errno = ENOENT; /* XER is not defined. */
|
||||
ASN__ENCODE_FAILED;
|
||||
break;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
default:
|
||||
errno = ENOENT;
|
||||
@@ -430,6 +455,7 @@ asn_decode(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
ASN__DECODE_FAILED;
|
||||
|
||||
case ATS_RANDOM:
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
if(!td->op->random_fill) {
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
@@ -441,41 +467,55 @@ asn_decode(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
}
|
||||
}
|
||||
break;
|
||||
#else
|
||||
errno = ENOENT;
|
||||
ASN__DECODE_FAILED;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
case ATS_DER:
|
||||
case ATS_BER:
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
return ber_decode(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#else
|
||||
errno = ENOENT;
|
||||
ASN__DECODE_FAILED;
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
case ATS_BASIC_OER:
|
||||
case ATS_CANONICAL_OER:
|
||||
#ifdef ASN_DISABLE_OER_SUPPORT
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
return oer_decode(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#else
|
||||
errno = ENOENT;
|
||||
ASN__DECODE_FAILED;
|
||||
#else
|
||||
return oer_decode(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#endif
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
case ATS_UNALIGNED_BASIC_PER:
|
||||
case ATS_UNALIGNED_CANONICAL_PER:
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
return uper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#else
|
||||
errno = ENOENT;
|
||||
ASN__DECODE_FAILED;
|
||||
#else
|
||||
return uper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#endif
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
|
||||
case ATS_ALIGNED_BASIC_PER:
|
||||
case ATS_ALIGNED_CANONICAL_PER:
|
||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
return aper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#else
|
||||
errno = ENOENT;
|
||||
ASN__DECODE_FAILED;
|
||||
#else
|
||||
return aper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#endif
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
case ATS_BASIC_XER:
|
||||
case ATS_CANONICAL_XER:
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
return xer_decode(opt_codec_ctx, td, sptr, buffer, size);
|
||||
#else
|
||||
errno = ENOENT;
|
||||
ASN__DECODE_FAILED;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "asn_system.h" /* for platform-dependent types */
|
||||
#include "asn_codecs.h" /* for ASN.1 codecs specifics */
|
||||
#include "asn_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -4,115 +4,6 @@
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <asn_codecs_prim.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* Decode an always-primitive type.
|
||||
*/
|
||||
asn_dec_rval_t
|
||||
ber_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
const void *buf_ptr, size_t size, int tag_mode) {
|
||||
ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
|
||||
asn_dec_rval_t rval;
|
||||
ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */
|
||||
|
||||
/*
|
||||
* If the structure is not there, allocate it.
|
||||
*/
|
||||
if(st == NULL) {
|
||||
st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));
|
||||
if(st == NULL) ASN__DECODE_FAILED;
|
||||
*sptr = (void *)st;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding %s as plain primitive (tm=%d)",
|
||||
td->name, tag_mode);
|
||||
|
||||
/*
|
||||
* Check tags and extract value length.
|
||||
*/
|
||||
rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
|
||||
tag_mode, 0, &length, 0);
|
||||
if(rval.code != RC_OK)
|
||||
return rval;
|
||||
|
||||
ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
|
||||
|
||||
/*
|
||||
* Make sure we have this length.
|
||||
*/
|
||||
buf_ptr = ((const char *)buf_ptr) + rval.consumed;
|
||||
size -= rval.consumed;
|
||||
if(length > (ber_tlv_len_t)size) {
|
||||
rval.code = RC_WMORE;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
|
||||
st->size = (int)length;
|
||||
/* The following better be optimized away. */
|
||||
if(sizeof(st->size) != sizeof(length)
|
||||
&& (ber_tlv_len_t)st->size != length) {
|
||||
st->size = 0;
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
st->buf = (uint8_t *)MALLOC(length + 1);
|
||||
if(!st->buf) {
|
||||
st->size = 0;
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
memcpy(st->buf, buf_ptr, length);
|
||||
st->buf[length] = '\0'; /* Just in case */
|
||||
|
||||
rval.code = RC_OK;
|
||||
rval.consumed += length;
|
||||
|
||||
ASN_DEBUG("Took %ld/%ld bytes to encode %s",
|
||||
(long)rval.consumed,
|
||||
(long)length, td->name);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode an always-primitive type using DER.
|
||||
*/
|
||||
asn_enc_rval_t
|
||||
der_encode_primitive(const asn_TYPE_descriptor_t *td, const void *sptr,
|
||||
int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn_enc_rval_t erval = {0,0,0};
|
||||
const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr;
|
||||
|
||||
ASN_DEBUG("%s %s as a primitive type (tm=%d)",
|
||||
cb?"Encoding":"Estimating", td->name, tag_mode);
|
||||
|
||||
erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag,
|
||||
cb, app_key);
|
||||
ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded);
|
||||
if(erval.encoded == -1) {
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = sptr;
|
||||
return erval;
|
||||
}
|
||||
|
||||
if(cb && st->buf) {
|
||||
if(cb(st->buf, st->size, app_key) < 0) {
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = sptr;
|
||||
return erval;
|
||||
}
|
||||
} else {
|
||||
assert(st->buf || st->size == 0);
|
||||
}
|
||||
|
||||
erval.encoded += st->size;
|
||||
ASN__ENCODED_OK(erval);
|
||||
}
|
||||
|
||||
void
|
||||
ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
@@ -138,180 +29,3 @@ ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local internal type passed around as an argument.
|
||||
*/
|
||||
struct xdp_arg_s {
|
||||
const asn_TYPE_descriptor_t *type_descriptor;
|
||||
void *struct_key;
|
||||
xer_primitive_body_decoder_f *prim_body_decoder;
|
||||
int decoded_something;
|
||||
int want_more;
|
||||
};
|
||||
|
||||
/*
|
||||
* Since some kinds of primitive values can be encoded using value-specific
|
||||
* tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must
|
||||
* be supplied with such tags to parse them as needed.
|
||||
*/
|
||||
static int
|
||||
xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
|
||||
struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
|
||||
enum xer_pbd_rval bret;
|
||||
|
||||
/*
|
||||
* The chunk_buf is guaranteed to start at '<'.
|
||||
*/
|
||||
assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);
|
||||
|
||||
/*
|
||||
* Decoding was performed once already. Prohibit doing it again.
|
||||
*/
|
||||
if(arg->decoded_something)
|
||||
return -1;
|
||||
|
||||
bret = arg->prim_body_decoder(arg->type_descriptor,
|
||||
arg->struct_key, chunk_buf, chunk_size);
|
||||
switch(bret) {
|
||||
case XPBD_SYSTEM_FAILURE:
|
||||
case XPBD_DECODER_LIMIT:
|
||||
case XPBD_BROKEN_ENCODING:
|
||||
break;
|
||||
case XPBD_BODY_CONSUMED:
|
||||
/* Tag decoded successfully */
|
||||
arg->decoded_something = 1;
|
||||
/* Fall through */
|
||||
case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
|
||||
struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
|
||||
enum xer_pbd_rval bret;
|
||||
size_t lead_wsp_size;
|
||||
|
||||
if(arg->decoded_something) {
|
||||
if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {
|
||||
/*
|
||||
* Example:
|
||||
* "<INTEGER>123<!--/--> </INTEGER>"
|
||||
* ^- chunk_buf position.
|
||||
*/
|
||||
return chunk_size;
|
||||
}
|
||||
/*
|
||||
* Decoding was done once already. Prohibit doing it again.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!have_more) {
|
||||
/*
|
||||
* If we've received something like "1", we can't really
|
||||
* tell whether it is really `1` or `123`, until we know
|
||||
* that there is no more data coming.
|
||||
* The have_more argument will be set to 1 once something
|
||||
* like this is available to the caller of this callback:
|
||||
* "1<tag_start..."
|
||||
*/
|
||||
arg->want_more = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size);
|
||||
chunk_buf = (const char *)chunk_buf + lead_wsp_size;
|
||||
chunk_size -= lead_wsp_size;
|
||||
|
||||
bret = arg->prim_body_decoder(arg->type_descriptor,
|
||||
arg->struct_key, chunk_buf, chunk_size);
|
||||
switch(bret) {
|
||||
case XPBD_SYSTEM_FAILURE:
|
||||
case XPBD_DECODER_LIMIT:
|
||||
case XPBD_BROKEN_ENCODING:
|
||||
break;
|
||||
case XPBD_BODY_CONSUMED:
|
||||
/* Tag decoded successfully */
|
||||
arg->decoded_something = 1;
|
||||
/* Fall through */
|
||||
case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
|
||||
return lead_wsp_size + chunk_size;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
asn_dec_rval_t
|
||||
xer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td, void **sptr,
|
||||
size_t struct_size, const char *opt_mname,
|
||||
const void *buf_ptr, size_t size,
|
||||
xer_primitive_body_decoder_f *prim_body_decoder) {
|
||||
const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
|
||||
asn_struct_ctx_t s_ctx;
|
||||
struct xdp_arg_s s_arg;
|
||||
asn_dec_rval_t rc;
|
||||
|
||||
/*
|
||||
* Create the structure if does not exist.
|
||||
*/
|
||||
if(!*sptr) {
|
||||
*sptr = CALLOC(1, struct_size);
|
||||
if(!*sptr) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
memset(&s_ctx, 0, sizeof(s_ctx));
|
||||
s_arg.type_descriptor = td;
|
||||
s_arg.struct_key = *sptr;
|
||||
s_arg.prim_body_decoder = prim_body_decoder;
|
||||
s_arg.decoded_something = 0;
|
||||
s_arg.want_more = 0;
|
||||
|
||||
rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
|
||||
xml_tag, buf_ptr, size,
|
||||
xer_decode__unexpected_tag, xer_decode__primitive_body);
|
||||
switch(rc.code) {
|
||||
case RC_OK:
|
||||
if(!s_arg.decoded_something) {
|
||||
char ch;
|
||||
ASN_DEBUG("Primitive body is not recognized, "
|
||||
"supplying empty one");
|
||||
/*
|
||||
* Decoding opportunity has come and gone.
|
||||
* Where's the result?
|
||||
* Try to feed with empty body, see if it eats it.
|
||||
*/
|
||||
if(prim_body_decoder(s_arg.type_descriptor,
|
||||
s_arg.struct_key, &ch, 0)
|
||||
!= XPBD_BODY_CONSUMED) {
|
||||
/*
|
||||
* This decoder does not like empty stuff.
|
||||
*/
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RC_WMORE:
|
||||
/*
|
||||
* Redo the whole thing later.
|
||||
* We don't have a context to save intermediate parsing state.
|
||||
*/
|
||||
rc.consumed = 0;
|
||||
break;
|
||||
case RC_FAIL:
|
||||
rc.consumed = 0;
|
||||
if(s_arg.want_more)
|
||||
rc.code = RC_WMORE;
|
||||
else
|
||||
ASN__DECODE_FAILED;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,23 +12,27 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ASN__PRIMITIVE_TYPE_s {
|
||||
uint8_t *buf; /* Buffer with consecutive primitive encoding bytes */
|
||||
size_t size; /* Size of the buffer */
|
||||
} ASN__PRIMITIVE_TYPE_t; /* Do not use this type directly! */
|
||||
uint8_t *buf; /* Buffer with consecutive primitive encoding bytes */
|
||||
size_t size; /* Size of the buffer */
|
||||
} ASN__PRIMITIVE_TYPE_t; /* Do not use this type directly! */
|
||||
|
||||
asn_struct_free_f ASN__PRIMITIVE_TYPE_free;
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
ber_type_decoder_f ber_decode_primitive;
|
||||
der_type_encoder_f der_encode_primitive;
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
/*
|
||||
* A callback specification for the xer_decode_primitive() function below.
|
||||
*/
|
||||
enum xer_pbd_rval {
|
||||
XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */
|
||||
XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */
|
||||
XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */
|
||||
XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */
|
||||
XPBD_BODY_CONSUMED /* Body is recognized and consumed */
|
||||
XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */
|
||||
XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */
|
||||
XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */
|
||||
XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */
|
||||
XPBD_BODY_CONSUMED /* Body is recognized and consumed */
|
||||
};
|
||||
typedef enum xer_pbd_rval(xer_primitive_body_decoder_f)(
|
||||
const asn_TYPE_descriptor_t *td, void *struct_ptr, const void *chunk_buf,
|
||||
@@ -43,6 +47,7 @@ asn_dec_rval_t xer_decode_primitive(
|
||||
const asn_TYPE_descriptor_t *type_descriptor, void **struct_ptr,
|
||||
size_t struct_size, const char *opt_mname, const void *buf_ptr, size_t size,
|
||||
xer_primitive_body_decoder_f *prim_body_decoder);
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
6
lib/asn1c/common/asn_config.h
Normal file
6
lib/asn1c/common/asn_config.h
Normal file
@@ -0,0 +1,6 @@
|
||||
// Generated automatically. Don't edit manually!
|
||||
|
||||
#define ASN_DISABLE_BER_SUPPORT 1
|
||||
#define ASN_DISABLE_XER_SUPPORT 1
|
||||
#define ASN_DISABLE_OER_SUPPORT 1
|
||||
#define ASN_DISABLE_UPER_SUPPORT 1
|
||||
@@ -21,6 +21,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
#include <uper_decoder.h>
|
||||
#include <uper_encoder.h>
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
#include <aper_decoder.h>
|
||||
#include <aper_encoder.h>
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
/* Environment version might be used to avoid running with the old library */
|
||||
#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */
|
||||
int get_asn1c_environment_version(void); /* Run-time version */
|
||||
@@ -136,6 +145,13 @@ asn__format_to_callback(
|
||||
* Check stack against overflow, if limit is set.
|
||||
*/
|
||||
#define ASN__DEFAULT_STACK_MAX (30000)
|
||||
#ifdef ASN_DISABLE_STACK_OVERFLOW_CHECK
|
||||
static int CC_NOTUSED
|
||||
ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx) {
|
||||
(void)ctx;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int CC_NOTUSED
|
||||
ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx) {
|
||||
if(ctx && ctx->max_stack_size) {
|
||||
@@ -153,6 +169,7 @@ ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -43,12 +43,17 @@ asn_random_between(intmax_t lb, intmax_t rb) {
|
||||
uintmax_t value = 0;
|
||||
uintmax_t got_entropy = 0;
|
||||
|
||||
(void)intmax_max;
|
||||
assert(RAND_MAX > 0xffffff); /* Seen 7ffffffd! */
|
||||
assert(range < intmax_max);
|
||||
|
||||
for(; got_entropy < range;) {
|
||||
got_entropy = (got_entropy << 24) | 0xffffff;
|
||||
#ifdef HAVE_RANDOM
|
||||
value = (value << 24) | (random() % 0xffffff);
|
||||
#else
|
||||
value = (value << 24) | (rand() % 0xffffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
return lb + (intmax_t)(value % (range + 1));
|
||||
|
||||
@@ -75,7 +75,9 @@ typedef unsigned int uint32_t;
|
||||
#else /* !defined(__vxworks) */
|
||||
|
||||
#include <inttypes.h> /* C99 specifies this file */
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h> /* for ntohl() */
|
||||
#endif
|
||||
#define sys_ntohl(foo) ntohl(foo)
|
||||
#endif /* defined(__vxworks) */
|
||||
|
||||
@@ -86,11 +88,25 @@ typedef unsigned int uint32_t;
|
||||
#else
|
||||
#define CC_ATTRIBUTE(attr)
|
||||
#endif
|
||||
#define CC_PRINTFLIKE(fmt, var) CC_ATTRIBUTE(format(printf, fmt, var))
|
||||
#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__>= 4) || __GNUC__ > 4)
|
||||
#define CC_PRINTFLIKE(fmt, var) CC_ATTRIBUTE(format(gnu_printf, fmt, var))
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(ANDROID)
|
||||
#define CC_PRINTFLIKE(fmt, var) CC_ATTRIBUTE(__format__(__printf__, fmt, var))
|
||||
#else
|
||||
#define CC_PRINTFLIKE(fmt, var) CC_ATTRIBUTE(format(printf, fmt, var))
|
||||
#endif
|
||||
#else
|
||||
#define CC_PRINTFLIKE(fmt, var)
|
||||
#endif
|
||||
#define CC_NOTUSED CC_ATTRIBUTE(unused)
|
||||
#ifndef CC_ATTR_NO_SANITIZE
|
||||
#if __GNUC__ < 8
|
||||
#define CC_ATTR_NO_SANITIZE(what)
|
||||
#else
|
||||
#define CC_ATTR_NO_SANITIZE(what) CC_ATTRIBUTE(no_sanitize(what))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Figure out if thread safety is requested */
|
||||
#if !defined(ASN_THREAD_SAFE) && (defined(THREAD_SAFE) || defined(_REENTRANT))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,23 +40,58 @@ typedef struct asn_CHOICE_specifics_s {
|
||||
* A set specialized functions dealing with the CHOICE type.
|
||||
*/
|
||||
asn_struct_free_f CHOICE_free;
|
||||
|
||||
#if !defined(ASN_DISABLE_PRINT_SUPPORT)
|
||||
asn_struct_print_f CHOICE_print;
|
||||
#endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
|
||||
|
||||
asn_struct_compare_f CHOICE_compare;
|
||||
|
||||
asn_constr_check_f CHOICE_constraint;
|
||||
|
||||
#if !defined(ASN_DISABLE_BER_SUPPORT)
|
||||
ber_type_decoder_f CHOICE_decode_ber;
|
||||
der_type_encoder_f CHOICE_encode_der;
|
||||
#endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_XER_SUPPORT)
|
||||
xer_type_decoder_f CHOICE_decode_xer;
|
||||
xer_type_encoder_f CHOICE_encode_xer;
|
||||
#endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_OER_SUPPORT)
|
||||
oer_type_decoder_f CHOICE_decode_oer;
|
||||
oer_type_encoder_f CHOICE_encode_oer;
|
||||
#endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_UPER_SUPPORT)
|
||||
per_type_decoder_f CHOICE_decode_uper;
|
||||
per_type_encoder_f CHOICE_encode_uper;
|
||||
#endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
|
||||
#if !defined(ASN_DISABLE_APER_SUPPORT)
|
||||
per_type_decoder_f CHOICE_decode_aper;
|
||||
per_type_encoder_f CHOICE_encode_aper;
|
||||
asn_outmost_tag_f CHOICE_outmost_tag;
|
||||
#endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
|
||||
|
||||
#if !defined(ASN_DISABLE_RFILL_SUPPORT)
|
||||
asn_random_fill_f CHOICE_random_fill;
|
||||
#endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
|
||||
|
||||
asn_outmost_tag_f CHOICE_outmost_tag;
|
||||
|
||||
extern asn_TYPE_operation_t asn_OP_CHOICE;
|
||||
|
||||
unsigned _fetch_present_idx(
|
||||
const void *struct_ptr,
|
||||
unsigned off,
|
||||
unsigned size);
|
||||
|
||||
void _set_present_idx(
|
||||
void *sptr,
|
||||
unsigned offset,
|
||||
unsigned size,
|
||||
unsigned present);
|
||||
|
||||
/*
|
||||
* Return the 1-based choice variant presence index.
|
||||
* Returns 0 in case of error.
|
||||
|
||||
188
lib/asn1c/common/constr_CHOICE_aper.c
Normal file
188
lib/asn1c/common/constr_CHOICE_aper.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <constr_CHOICE.h>
|
||||
#include <aper_opentype.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
|
||||
const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rv;
|
||||
const asn_per_constraint_t *ct;
|
||||
asn_TYPE_member_t *elm; /* CHOICE's element */
|
||||
void *memb_ptr;
|
||||
void **memb_ptr2;
|
||||
void *st = *sptr;
|
||||
int value;
|
||||
|
||||
if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
||||
ASN__DECODE_FAILED;
|
||||
|
||||
/*
|
||||
* Create the target structure if it is not present already.
|
||||
*/
|
||||
if(!st) {
|
||||
st = *sptr = CALLOC(1, specs->struct_size);
|
||||
if(!st) ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ct = 0;
|
||||
|
||||
if(ct && ct->flags & APC_EXTENSIBLE) {
|
||||
value = per_get_few_bits(pd, 1);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
if(value) ct = 0; /* Not restricted */
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
ASN_DEBUG("CHOICE %s got index %d in range %d",
|
||||
td->name, value, ct->range_bits);
|
||||
if(value > ct->upper_bound)
|
||||
ASN__DECODE_FAILED;
|
||||
} else {
|
||||
if(specs->ext_start == -1)
|
||||
ASN__DECODE_FAILED;
|
||||
/* modified by acetcom for https://github.com/open5gs/open5gs/issues/783 */
|
||||
#if 1
|
||||
if (ct) {
|
||||
#endif
|
||||
value = aper_get_nsnnwn(pd, ct->upper_bound - ct->lower_bound + 1);
|
||||
if(value < 0) ASN__DECODE_STARVED;
|
||||
value += specs->ext_start;
|
||||
/* modified by acetcom for https://github.com/open5gs/open5gs/issues/783 */
|
||||
#if 1
|
||||
} else {
|
||||
value = specs->ext_start;
|
||||
}
|
||||
#endif
|
||||
if((unsigned)value >= td->elements_count)
|
||||
ASN__DECODE_FAILED;
|
||||
}
|
||||
|
||||
/* Adjust if canonical order is different from natural order */
|
||||
if(specs->from_canonical_order)
|
||||
value = specs->from_canonical_order[value];
|
||||
|
||||
/* Set presence to be able to free it later */
|
||||
_set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1);
|
||||
|
||||
elm = &td->elements[value];
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)st + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
|
||||
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
|
||||
} else {
|
||||
rv = aper_open_type_get(opt_codec_ctx, elm->type,
|
||||
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
|
||||
}
|
||||
|
||||
if(rv.code != RC_OK)
|
||||
ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d",
|
||||
elm->name, td->name, rv.code);
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
CHOICE_encode_aper(const asn_TYPE_descriptor_t *td,
|
||||
const asn_per_constraints_t *constraints,
|
||||
const void *sptr, asn_per_outp_t *po) {
|
||||
const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
|
||||
const asn_TYPE_member_t *elm; /* CHOICE's element */
|
||||
const asn_per_constraint_t *ct;
|
||||
const void *memb_ptr;
|
||||
int present;
|
||||
|
||||
if(!sptr) ASN__ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name);
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->encoding_constraints.per_constraints)
|
||||
ct = &td->encoding_constraints.per_constraints->value;
|
||||
else ct = 0;
|
||||
|
||||
present = _fetch_present_idx(sptr,
|
||||
specs->pres_offset, specs->pres_size);
|
||||
|
||||
/*
|
||||
* If the structure was not initialized properly, it cannot be encoded:
|
||||
* can't deduce what to encode in the choice type.
|
||||
*/
|
||||
if(present <= 0 || (unsigned)present > td->elements_count)
|
||||
ASN__ENCODE_FAILED;
|
||||
else
|
||||
present--;
|
||||
|
||||
/* Adjust if canonical order is different from natural order */
|
||||
if(specs->to_canonical_order)
|
||||
present = specs->to_canonical_order[present];
|
||||
|
||||
ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(present < ct->lower_bound
|
||||
|| present > ct->upper_bound) {
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, 1, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
ct = 0;
|
||||
}
|
||||
}
|
||||
if(ct && ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, 0, 1))
|
||||
ASN__ENCODE_FAILED;
|
||||
}
|
||||
|
||||
elm = &td->elements[present];
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
memb_ptr = *(const void *const *)((const char *)sptr + elm->memb_offset);
|
||||
if(!memb_ptr) ASN__ENCODE_FAILED;
|
||||
} else {
|
||||
memb_ptr = (const char *)sptr + elm->memb_offset;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, present, ct->range_bits))
|
||||
ASN__ENCODE_FAILED;
|
||||
|
||||
return elm->type->op->aper_encoder(elm->type, elm->encoding_constraints.per_constraints,
|
||||
memb_ptr, po);
|
||||
} else {
|
||||
asn_enc_rval_t rval = {0,0,0};
|
||||
if(specs->ext_start == -1)
|
||||
ASN__ENCODE_FAILED;
|
||||
int n = present - specs->ext_start;
|
||||
if(n <= 63) {
|
||||
if(n < 0) ASN__ENCODE_FAILED;
|
||||
if(per_put_few_bits(po, n, 7)) ASN__ENCODE_FAILED;
|
||||
} else
|
||||
ASN__ENCODE_FAILED;
|
||||
if(aper_open_type_put(elm->type, elm->encoding_constraints.per_constraints,
|
||||
memb_ptr, po))
|
||||
ASN__ENCODE_FAILED;
|
||||
rval.encoded = 0;
|
||||
ASN__ENCODED_OK(rval);
|
||||
}
|
||||
}
|
||||
48
lib/asn1c/common/constr_CHOICE_print.c
Normal file
48
lib/asn1c/common/constr_CHOICE_print.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <constr_CHOICE.h>
|
||||
|
||||
int
|
||||
CHOICE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
|
||||
unsigned present;
|
||||
|
||||
if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
|
||||
/*
|
||||
* Figure out which CHOICE element is encoded.
|
||||
*/
|
||||
present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
|
||||
|
||||
/*
|
||||
* Print that element.
|
||||
*/
|
||||
if(present > 0 && present <= td->elements_count) {
|
||||
asn_TYPE_member_t *elm = &td->elements[present-1];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
|
||||
if(!memb_ptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
} else {
|
||||
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
||||
}
|
||||
|
||||
/* Print member's name and stuff */
|
||||
if(0) {
|
||||
if(cb(elm->name, strlen(elm->name), app_key) < 0
|
||||
|| cb(": ", 2, app_key) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return elm->type->op->print_struct(elm->type, memb_ptr, ilevel,
|
||||
cb, app_key);
|
||||
} else {
|
||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user