mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-10-30 19:43:43 +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